阅片及影像预览页更新
parent
1491d7ee78
commit
62533db147
17
package.json
17
package.json
|
@ -13,13 +13,6 @@
|
|||
"i18n:en": "node i18nGenerate.js lang=en keyCol=5 valCol=7"
|
||||
},
|
||||
"dependencies": {
|
||||
"@cornerstonejs/calculate-suv": "^1.1.0",
|
||||
"@cornerstonejs/core": "^1.27.4",
|
||||
"@cornerstonejs/dicom-image-loader": "^1.27.4",
|
||||
"@cornerstonejs/streaming-image-volume-loader": "1.23.2",
|
||||
"@cornerstonejs/tools": "^1.27.4",
|
||||
"@ffmpeg/core": "^0.10.0",
|
||||
"@ffmpeg/ffmpeg": "^0.10.1",
|
||||
"@microsoft/signalr": "^6.0.8",
|
||||
"@riophae/vue-treeselect": "0.4.0",
|
||||
"ali-oss": "^6.17.1",
|
||||
|
@ -27,10 +20,10 @@
|
|||
"babel-eslint": "7.2.3",
|
||||
"copy-webpack-plugin": "^4.5.2",
|
||||
"core-js": "^3.8.3",
|
||||
"cornerstone-core": "^2.3.0",
|
||||
"cornerstone-math": "^0.1.8",
|
||||
"cornerstone-tools": "^6.0.8",
|
||||
"cornerstone-wado-image-loader": "^3.1.2",
|
||||
"cornerstone-core": "^2.6.1",
|
||||
"cornerstone-math": "^0.1.10",
|
||||
"cornerstone-tools": "^6.0.10",
|
||||
"cornerstone-wado-image-loader": "^4.13.2",
|
||||
"dcmjs": "^0.29.8",
|
||||
"dicom-parser": "^1.8.9",
|
||||
"dicomedit": "^0.1.0",
|
||||
|
@ -44,7 +37,6 @@
|
|||
"jszip": "^3.7.1",
|
||||
"moment": "^2.27.0",
|
||||
"node-polyfill-webpack-plugin": "^2.0.1",
|
||||
"streamsaver": "^2.0.6",
|
||||
"node-sass": "^4.14.1",
|
||||
"normalize.css": "7.0.0",
|
||||
"nprogress": "0.2.0",
|
||||
|
@ -54,6 +46,7 @@
|
|||
"sass-loader": "^8.0.0",
|
||||
"screenfull": "^4.2.0",
|
||||
"sortablejs": "^1.15.0",
|
||||
"streamsaver": "^2.0.6",
|
||||
"v-viewer": "^1.6.4",
|
||||
"vcrontab": "^0.3.5",
|
||||
"vue": "^2.6.11",
|
||||
|
|
|
@ -226,3 +226,17 @@ export function confirmTaskReminder(param) {
|
|||
data: param
|
||||
})
|
||||
}
|
||||
export function setSkipReadingCache(param) {
|
||||
return request({
|
||||
url: `/ReadingImageTask/setSkipReadingCache`,
|
||||
method: 'post',
|
||||
data: param
|
||||
})
|
||||
}
|
||||
export function resetReadingTask(param) {
|
||||
return request({
|
||||
url: `/ReadingImageTask/resetReadingTask`,
|
||||
method: 'post',
|
||||
data: param
|
||||
})
|
||||
}
|
||||
|
|
|
@ -8,7 +8,6 @@
|
|||
style="width:100%;height:100%;position:relative;"
|
||||
class="cornerstone-element"
|
||||
@contextmenu.prevent="onContextmenu"
|
||||
@mousemove="sliderMousemove"
|
||||
@mouseup="sliderMouseup"
|
||||
>
|
||||
<div v-show="dicomInfo.series" class="info-series">
|
||||
|
@ -54,7 +53,7 @@
|
|||
<!-- <div v-show="dicomInfo.acc">ACC {{ dicomInfo.acc }}</div> -->
|
||||
<!-- <div>{{ dicomInfo.time }}</div> -->
|
||||
</div>
|
||||
<div ref="sliderBox" class="my_slider_box" style="position: absolute;right: 1px;height: calc(100% - 100px);transform: translateY(-50%);top: calc(50% - 30px);width: 10px;background: #333;cursor: pointer">
|
||||
<div ref="sliderBox" class="my_slider_box" style="position: absolute;right: 1px;height: calc(100% - 100px);transform: translateY(-50%);top: calc(50% - 30px);width: 10px;background: #333;cursor: pointer" @click.stop="goViewer($event)">
|
||||
<div :style="{top: height + '%'}" style="z-index:10;background: #9e9e9e;height: 20px;width: 100%;position: absolute;top: 0;cursor: move" @mousedown="sliderMousedown($event)" />
|
||||
</div>
|
||||
<div style="position: absolute;left: 50%;top: 15px;color: #f44336;">
|
||||
|
@ -82,16 +81,25 @@
|
|||
<!-- <div v-show="stack.firstImageLoading" class="load-indicator">
|
||||
Loading Series #{{ stack.seriesNumber }}...
|
||||
</div>-->
|
||||
<el-dialog
|
||||
v-if="dcmTag.visible"
|
||||
:visible.sync="dcmTag.visible"
|
||||
:close-on-click-modal="false"
|
||||
:title="dcmTag.title"
|
||||
width="1000px"
|
||||
custom-class="base-dialog-wrapper"
|
||||
append-to-body
|
||||
>
|
||||
<DicomTags :image-id="stack.imageIds[stack.currentImageIdIndex]" @close="dcmTag.visible = false" />
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Vue from 'vue'
|
||||
import Contextmenu from 'vue-contextmenujs'
|
||||
Vue.use(Contextmenu)
|
||||
import * as cornerstone from 'cornerstone-core'
|
||||
import * as cornerstoneMath from 'cornerstone-math'
|
||||
import * as cornerstoneTools from 'cornerstone-tools'
|
||||
|
||||
const scroll = cornerstoneTools.import('util/scrollToIndex')
|
||||
import Hammer from 'hammerjs'
|
||||
import getOrientationString from '@/views/trials/trials-panel/reading/dicoms/tools/OrientationMarkers/getOrientationString'
|
||||
|
@ -109,8 +117,10 @@ cornerstoneTools.toolColors.setActiveColor('rgb(0, 255, 0)')
|
|||
// cornerstoneTools.init({ showSVGCursors: true })
|
||||
cornerstoneTools.init()
|
||||
const ToolStateManager = cornerstoneTools.globalImageIdSpecificToolStateManager
|
||||
import DicomTags from './DicomTags'
|
||||
export default {
|
||||
name: 'DicomCanvas',
|
||||
components: { DicomTags },
|
||||
data() {
|
||||
return {
|
||||
loading: false,
|
||||
|
@ -163,7 +173,10 @@ export default {
|
|||
isMove: false
|
||||
},
|
||||
mousePosition: { x: '', y: '', mo: '' },
|
||||
markers: { top: '', right: '', bottom: '', left: '' }
|
||||
markers: { top: '', right: '', bottom: '', left: '' },
|
||||
orientationMarkers: [],
|
||||
originalMarkers: [],
|
||||
dcmTag: { visible: false, title: this.$t('trials:dicom-tag:title') }
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -186,6 +199,9 @@ export default {
|
|||
document.addEventListener('mouseup', () => {
|
||||
this.sliderMouseup()
|
||||
})
|
||||
document.addEventListener('mousemove', (e) => {
|
||||
this.sliderMousemove(e)
|
||||
})
|
||||
this.canvas.addEventListener('cornerstonetoolsstackscroll', this.stackScrollCallback)
|
||||
},
|
||||
|
||||
|
@ -196,7 +212,7 @@ export default {
|
|||
this.stack.seriesId = dicomSeries.seriesId
|
||||
this.stack.seriesNumber = dicomSeries.seriesNumber
|
||||
this.stack.imageIds = dicomSeries.imageIds
|
||||
this.stack.currentImageIdIndex = dicomSeries.imageIdIndex ? dicomSeries.imageIdIndex : 0
|
||||
this.stack.currentImageIdIndex = dicomSeries.imageIdIndex && dicomSeries.imageIdIndex < dicomSeries.imageIds.length ? dicomSeries.imageIdIndex : 0
|
||||
this.stack.firstImageLoading = true
|
||||
this.stack.description = dicomSeries.description
|
||||
this.toolState.viewportInvert = false
|
||||
|
@ -205,15 +221,19 @@ export default {
|
|||
var instanceId = imageId.split('/')[imageId.split('/').length - 1]
|
||||
instanceId = instanceId.split('.')[0]
|
||||
this.stack.instanceId = instanceId
|
||||
if (this.toolState.clipPlaying) this.toggleClipPlay()
|
||||
this.toolState.clipPlaying = false
|
||||
const element = this.$refs.canvas
|
||||
cornerstone.enable(element)
|
||||
cornerstoneTools.stopClip(this.canvas)
|
||||
this.toolState.clipPlaying = false
|
||||
this.loading = true
|
||||
|
||||
cornerstone.loadAndCacheImage(this.stack.imageIds[this.stack.currentImageIdIndex])
|
||||
.then(image => {
|
||||
this.loading = false
|
||||
this.onFirstImageLoaded(image)
|
||||
if (this.stack.imageIds.indexOf(image.imageId) !== -1) {
|
||||
this.onFirstImageLoaded(image)
|
||||
}
|
||||
}).catch((error) => {
|
||||
this.loading = false
|
||||
if (error.error && error.error.message) {
|
||||
|
@ -242,7 +262,13 @@ export default {
|
|||
apiTool
|
||||
)
|
||||
if (!toolAlreadyAddedToElement) {
|
||||
cornerstoneTools.addToolForElement(element, apiTool)
|
||||
if (toolName === 'RectangleRoi') {
|
||||
cornerstoneTools.addToolForElement(element, apiTool, { configuration: { showMinMax: true, showStatsText: true}})
|
||||
} else if (toolName === 'EllipticalRoi') {
|
||||
cornerstoneTools.addToolForElement(element, apiTool, { configuration: { showMinMax: true}})
|
||||
} else {
|
||||
cornerstoneTools.addToolForElement(element, apiTool)
|
||||
}
|
||||
}
|
||||
}
|
||||
// Setup button listener
|
||||
|
@ -302,7 +328,7 @@ export default {
|
|||
// cornerstoneTools.addStackStateManager(this.canvas, ['stack', 'stackPrefetch', 'playClip'])
|
||||
cornerstoneTools.addToolState(this.canvas, 'stack', this.stack)
|
||||
// cornerstoneTools.stackPrefetch.enable(this.canvas)
|
||||
cornerstone.updateImage(element, true)
|
||||
cornerstone.updateImage(element, true)
|
||||
// cornerstoneTools.stackPrefetch.setConfiguration({ maxImagesToPrefetch: Infinity,
|
||||
// preserveExistingPool: true })
|
||||
// cornerstoneTools.stackPrefetch.enable(this.canvas)
|
||||
|
@ -356,6 +382,12 @@ export default {
|
|||
if (this.dicomInfo.thick) {
|
||||
this.dicomInfo.thick = this.dicomInfo.thick.toFixed(2)
|
||||
}
|
||||
const newImageIdIndex = this.stack.imageIds.findIndex(i => i === e.detail.image.imageId)
|
||||
if (newImageIdIndex === -1) return
|
||||
this.stack.currentImageIdIndex = newImageIdIndex
|
||||
this.stack.imageIdIndex = newImageIdIndex
|
||||
this.series.imageIdIndex = newImageIdIndex
|
||||
this.height = (this.stack.currentImageIdIndex) * 100 / (this.stack.imageIds.length - 1)
|
||||
},
|
||||
stackScrollCallback(e) {
|
||||
const { detail } = e
|
||||
|
@ -403,6 +435,7 @@ export default {
|
|||
this.dicomInfo.location = position
|
||||
},
|
||||
getOrientationMarker(element) {
|
||||
console.log('getOrientationMarker')
|
||||
const enabledElement = cornerstone.getEnabledElement(element)
|
||||
const imagePlane = cornerstone.metaData.get(
|
||||
'imagePlaneModule',
|
||||
|
@ -426,6 +459,7 @@ export default {
|
|||
if (!markers) {
|
||||
return
|
||||
}
|
||||
|
||||
this.orientationMarkers = [oppositeColumn, row, column, oppositeRow]
|
||||
this.originalMarkers = [oppositeColumn, row, column, oppositeRow]
|
||||
this.setMarkers()
|
||||
|
@ -438,10 +472,10 @@ export default {
|
|||
}
|
||||
},
|
||||
onImageLoaded(e) {
|
||||
var image = e.detail.image
|
||||
// var seriesIndex = -1
|
||||
var seriesUid = image.data.string('x0020000e')
|
||||
console.log(seriesUid)
|
||||
// var image = e.detail.image
|
||||
// // var seriesIndex = -1
|
||||
// var seriesUid = image.data.string('x0020000e')
|
||||
// console.log(seriesUid)
|
||||
},
|
||||
getToolForElement(toolName) {
|
||||
var isExist = false
|
||||
|
@ -521,6 +555,9 @@ export default {
|
|||
this.sliderInfo.oldB = parseInt(e.srcElement.style.top) * boxHeight / 100
|
||||
this.sliderInfo.oldM = e.clientY
|
||||
this.sliderInfo.isMove = true
|
||||
e.stopImmediatePropagation()
|
||||
e.stopPropagation()
|
||||
e.preventDefault()
|
||||
},
|
||||
sliderMousemove(e) {
|
||||
if (!this.sliderInfo.isMove) return
|
||||
|
@ -540,6 +577,13 @@ export default {
|
|||
sliderMouseup(e) {
|
||||
this.sliderInfo.isMove = false
|
||||
},
|
||||
goViewer(e) {
|
||||
// console.log(this.$refs['sliderBox'].clientHeight)
|
||||
var height = e.offsetY * 100 / this.$refs['sliderBox'].clientHeight
|
||||
this.height = height
|
||||
var index = Math.trunc(this.stack.imageIds.length * this.height / 100)
|
||||
scroll(this.canvas, index)
|
||||
},
|
||||
onClipStopped() {
|
||||
this.toolState.clipPlaying = false
|
||||
},
|
||||
|
@ -610,6 +654,7 @@ export default {
|
|||
enabledElement.renderingTools.renderCanvasData = renderCanvasData
|
||||
},
|
||||
scrollPage(offset) {
|
||||
if (this.loading) return
|
||||
var index = this.stack.currentImageIdIndex + offset
|
||||
if (index < 0) index = 0
|
||||
else if (index >= this.stack.imageIds.length) {
|
||||
|
@ -621,6 +666,7 @@ export default {
|
|||
},
|
||||
|
||||
toggleClipPlay() {
|
||||
if (this.loading) return
|
||||
if (this.toolState.clipPlaying) {
|
||||
cornerstoneTools.stopClip(this.canvas)
|
||||
this.toolState.clipPlaying = false
|
||||
|
@ -640,7 +686,7 @@ export default {
|
|||
resetWwwc() {
|
||||
this.toolState.viewportInvert = false
|
||||
var viewport = cornerstone.getViewport(this.canvas)
|
||||
viewport.invert = false
|
||||
// viewport.invert = false
|
||||
var image = cornerstone.getImage(this.canvas)
|
||||
viewport.voi.windowWidth = image.windowWidth
|
||||
viewport.voi.windowCenter = image.windowCenter
|
||||
|
@ -675,8 +721,11 @@ export default {
|
|||
},
|
||||
|
||||
resetRotate() {
|
||||
this.orientationMarkers = [...this.originalMarkers]
|
||||
this.setMarkers()
|
||||
if (this.originalMarkers.length > 0) {
|
||||
this.orientationMarkers = [...this.originalMarkers]
|
||||
this.setMarkers()
|
||||
}
|
||||
|
||||
var viewport = cornerstone.getViewport(this.canvas)
|
||||
viewport.hflip = false
|
||||
viewport.vflip = false
|
||||
|
@ -685,24 +734,26 @@ export default {
|
|||
},
|
||||
|
||||
setRotate(hflip, vflip, angle, type) {
|
||||
var markers = [...this.orientationMarkers]
|
||||
if (type === 2) {
|
||||
// 垂直翻转
|
||||
this.orientationMarkers[1] = markers[3]
|
||||
if (this.orientationMarkers.length > 0) {
|
||||
var markers = [...this.orientationMarkers]
|
||||
if (type === 2) {
|
||||
// 垂直翻转
|
||||
this.orientationMarkers[1] = markers[3]
|
||||
|
||||
this.orientationMarkers[3] = markers[1]
|
||||
} else if (type === 3) {
|
||||
// 水平翻转
|
||||
this.orientationMarkers[0] = markers[2]
|
||||
this.orientationMarkers[2] = markers[0]
|
||||
} else if (type === 4) {
|
||||
// 左转90度
|
||||
this.orientationMarkers = markers.slice(1, 4).concat(markers[0])
|
||||
} else if (type === 5) {
|
||||
// 右转90度
|
||||
this.orientationMarkers = [markers[3]].concat(markers.slice(0, 3))
|
||||
this.orientationMarkers[3] = markers[1]
|
||||
} else if (type === 3) {
|
||||
// 水平翻转
|
||||
this.orientationMarkers[0] = markers[2]
|
||||
this.orientationMarkers[2] = markers[0]
|
||||
} else if (type === 4) {
|
||||
// 左转90度
|
||||
this.orientationMarkers = markers.slice(1, 4).concat(markers[0])
|
||||
} else if (type === 5) {
|
||||
// 右转90度
|
||||
this.orientationMarkers = [markers[3]].concat(markers.slice(0, 3))
|
||||
}
|
||||
this.setMarkers()
|
||||
}
|
||||
this.setMarkers()
|
||||
var viewport = cornerstone.getViewport(this.canvas)
|
||||
if (hflip) viewport.hflip = !viewport.hflip
|
||||
if (vflip) viewport.vflip = !viewport.vflip
|
||||
|
@ -714,6 +765,9 @@ export default {
|
|||
var uid = cornerstone.getImage(this.canvas).data.string('x00080018')
|
||||
cornerstoneTools.SaveAs(this.canvas, `${uid}.png`)
|
||||
},
|
||||
showTags() {
|
||||
this.dcmTag.visible = true
|
||||
},
|
||||
fitToWindow() {
|
||||
if (this.stack.seriesNumber) {
|
||||
cornerstone.fitToWindow(this.canvas)
|
||||
|
@ -840,194 +894,197 @@ export default {
|
|||
synchronizer.remove(this.$refs.canvas)
|
||||
this.setAllToolsPassive()
|
||||
},
|
||||
onContextmenu(event) {
|
||||
const colormapsList = cornerstone.colors.getColormapsList()
|
||||
const colorItems = []
|
||||
colorItems.push({
|
||||
label: '默认值',
|
||||
onClick: () => {
|
||||
this.setColormap()
|
||||
}
|
||||
})
|
||||
colormapsList.forEach(colormap => {
|
||||
const item = {}
|
||||
item.label = colormap.name
|
||||
item.onClick = () => {
|
||||
this.setColormap(colormap.id)
|
||||
}
|
||||
colorItems.push(item)
|
||||
})
|
||||
this.$contextmenu({
|
||||
items: [
|
||||
{
|
||||
label: '移动',
|
||||
divided: true,
|
||||
onClick: () => {
|
||||
this.setToolActive('Pan')
|
||||
}
|
||||
},
|
||||
{
|
||||
label: '缩放',
|
||||
divided: true,
|
||||
children: [
|
||||
{
|
||||
label: '自由缩放',
|
||||
onClick: () => {
|
||||
this.setToolActive('Zoom')
|
||||
}
|
||||
},
|
||||
{
|
||||
label: '适应图像',
|
||||
onClick: () => {
|
||||
this.fitToWindow()
|
||||
}
|
||||
},
|
||||
{
|
||||
label: '适应窗口',
|
||||
onClick: () => {
|
||||
this.fitToImage()
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
label: '透镜',
|
||||
divided: true,
|
||||
onClick: () => {
|
||||
this.setToolActive('Magnify')
|
||||
}
|
||||
},
|
||||
{
|
||||
label: '旋转',
|
||||
divided: true,
|
||||
children: [
|
||||
{
|
||||
label: '默认值',
|
||||
onClick: () => {
|
||||
this.resetRotate()
|
||||
}
|
||||
},
|
||||
{
|
||||
label: '自由旋转',
|
||||
onClick: () => {
|
||||
this.setToolActive('Rotate')
|
||||
}
|
||||
},
|
||||
{
|
||||
label: '水平翻转',
|
||||
onClick: () => {
|
||||
this.setRotate(true, false, 0)
|
||||
}
|
||||
},
|
||||
{
|
||||
label: '垂直翻转',
|
||||
onClick: () => {
|
||||
this.setRotate(false, true, 0)
|
||||
}
|
||||
},
|
||||
{
|
||||
label: '左转90度',
|
||||
onClick: () => {
|
||||
this.setRotate(false, false, -90)
|
||||
}
|
||||
},
|
||||
{
|
||||
label: '右转90度',
|
||||
onClick: () => {
|
||||
this.setRotate(false, false, 90)
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
onContextmenu(e) {
|
||||
e.stopImmediatePropagation()
|
||||
e.stopPropagation()
|
||||
e.preventDefault()
|
||||
// const colormapsList = cornerstone.colors.getColormapsList()
|
||||
// const colorItems = []
|
||||
// colorItems.push({
|
||||
// label: '默认值',
|
||||
// onClick: () => {
|
||||
// this.setColormap()
|
||||
// }
|
||||
// })
|
||||
// colormapsList.forEach(colormap => {
|
||||
// const item = {}
|
||||
// item.label = colormap.name
|
||||
// item.onClick = () => {
|
||||
// this.setColormap(colormap.id)
|
||||
// }
|
||||
// colorItems.push(item)
|
||||
// })
|
||||
// this.$contextmenu({
|
||||
// items: [
|
||||
// {
|
||||
// label: '移动',
|
||||
// divided: true,
|
||||
// onClick: () => {
|
||||
// this.setToolActive('Pan')
|
||||
// }
|
||||
// },
|
||||
// {
|
||||
// label: '缩放',
|
||||
// divided: true,
|
||||
// children: [
|
||||
// {
|
||||
// label: '自由缩放',
|
||||
// onClick: () => {
|
||||
// this.setToolActive('Zoom')
|
||||
// }
|
||||
// },
|
||||
// {
|
||||
// label: '适应图像',
|
||||
// onClick: () => {
|
||||
// this.fitToWindow()
|
||||
// }
|
||||
// },
|
||||
// {
|
||||
// label: '适应窗口',
|
||||
// onClick: () => {
|
||||
// this.fitToImage()
|
||||
// }
|
||||
// }
|
||||
// ]
|
||||
// },
|
||||
// {
|
||||
// label: '透镜',
|
||||
// divided: true,
|
||||
// onClick: () => {
|
||||
// this.setToolActive('Magnify')
|
||||
// }
|
||||
// },
|
||||
// {
|
||||
// label: '旋转',
|
||||
// divided: true,
|
||||
// children: [
|
||||
// {
|
||||
// label: '默认值',
|
||||
// onClick: () => {
|
||||
// this.resetRotate()
|
||||
// }
|
||||
// },
|
||||
// {
|
||||
// label: '自由旋转',
|
||||
// onClick: () => {
|
||||
// this.setToolActive('Rotate')
|
||||
// }
|
||||
// },
|
||||
// {
|
||||
// label: '水平翻转',
|
||||
// onClick: () => {
|
||||
// this.setRotate(true, false, 0)
|
||||
// }
|
||||
// },
|
||||
// {
|
||||
// label: '垂直翻转',
|
||||
// onClick: () => {
|
||||
// this.setRotate(false, true, 0)
|
||||
// }
|
||||
// },
|
||||
// {
|
||||
// label: '左转90度',
|
||||
// onClick: () => {
|
||||
// this.setRotate(false, false, -90)
|
||||
// }
|
||||
// },
|
||||
// {
|
||||
// label: '右转90度',
|
||||
// onClick: () => {
|
||||
// this.setRotate(false, false, 90)
|
||||
// }
|
||||
// }
|
||||
// ]
|
||||
// },
|
||||
|
||||
{
|
||||
label: '测量',
|
||||
divided: true,
|
||||
minWidth: 0,
|
||||
children: [
|
||||
{
|
||||
label: '探针',
|
||||
onClick: () => {
|
||||
this.setToolActive('Probe')
|
||||
}
|
||||
},
|
||||
{
|
||||
label: '长度测量',
|
||||
onClick: () => {
|
||||
this.setToolActive('Length')
|
||||
}
|
||||
},
|
||||
{
|
||||
label: '角度测量',
|
||||
onClick: () => {
|
||||
this.setToolActive('Angle')
|
||||
}
|
||||
},
|
||||
{
|
||||
label: 'Cobb测量',
|
||||
onClick: () => {
|
||||
this.setToolActive('CobbAngle')
|
||||
}
|
||||
},
|
||||
{
|
||||
label: '椭圆测量',
|
||||
onClick: () => {
|
||||
this.setToolActive('EllipticalRoi')
|
||||
}
|
||||
},
|
||||
{
|
||||
label: '矩形测量',
|
||||
onClick: () => {
|
||||
this.setToolActive('RectangleRoi')
|
||||
}
|
||||
},
|
||||
{
|
||||
label: '多边形标记',
|
||||
onClick: () => {
|
||||
this.setToolActive('FreehandRoi')
|
||||
}
|
||||
},
|
||||
{
|
||||
label: '十字线',
|
||||
onClick: () => {
|
||||
this.setToolActive('Bidirectional')
|
||||
}
|
||||
},
|
||||
{
|
||||
label: '文字标注',
|
||||
onClick: () => {
|
||||
this.setToolActive('ArrowAnnotate')
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
label: '调窗',
|
||||
divided: true,
|
||||
onClick: () => {
|
||||
this.setToolActive('Wwwc')
|
||||
}
|
||||
},
|
||||
{
|
||||
label: '反色',
|
||||
divided: true,
|
||||
onClick: () => {
|
||||
this.toggleInvert()
|
||||
}
|
||||
},
|
||||
{
|
||||
label: '伪彩',
|
||||
children: colorItems
|
||||
}
|
||||
],
|
||||
event,
|
||||
// x: event.clientX,
|
||||
// y: event.clientY,
|
||||
customClass: 'class-a',
|
||||
zIndex: 3,
|
||||
minWidth: 100
|
||||
})
|
||||
return false
|
||||
// {
|
||||
// label: '测量',
|
||||
// divided: true,
|
||||
// minWidth: 0,
|
||||
// children: [
|
||||
// {
|
||||
// label: '探针',
|
||||
// onClick: () => {
|
||||
// this.setToolActive('Probe')
|
||||
// }
|
||||
// },
|
||||
// {
|
||||
// label: '长度测量',
|
||||
// onClick: () => {
|
||||
// this.setToolActive('Length')
|
||||
// }
|
||||
// },
|
||||
// {
|
||||
// label: '角度测量',
|
||||
// onClick: () => {
|
||||
// this.setToolActive('Angle')
|
||||
// }
|
||||
// },
|
||||
// {
|
||||
// label: 'Cobb测量',
|
||||
// onClick: () => {
|
||||
// this.setToolActive('CobbAngle')
|
||||
// }
|
||||
// },
|
||||
// {
|
||||
// label: '椭圆测量',
|
||||
// onClick: () => {
|
||||
// this.setToolActive('EllipticalRoi')
|
||||
// }
|
||||
// },
|
||||
// {
|
||||
// label: '矩形测量',
|
||||
// onClick: () => {
|
||||
// this.setToolActive('RectangleRoi')
|
||||
// }
|
||||
// },
|
||||
// {
|
||||
// label: '多边形标记',
|
||||
// onClick: () => {
|
||||
// this.setToolActive('FreehandRoi')
|
||||
// }
|
||||
// },
|
||||
// {
|
||||
// label: '十字线',
|
||||
// onClick: () => {
|
||||
// this.setToolActive('Bidirectional')
|
||||
// }
|
||||
// },
|
||||
// {
|
||||
// label: '文字标注',
|
||||
// onClick: () => {
|
||||
// this.setToolActive('ArrowAnnotate')
|
||||
// }
|
||||
// }
|
||||
// ]
|
||||
// },
|
||||
// {
|
||||
// label: '调窗',
|
||||
// divided: true,
|
||||
// onClick: () => {
|
||||
// this.setToolActive('Wwwc')
|
||||
// }
|
||||
// },
|
||||
// {
|
||||
// label: '反色',
|
||||
// divided: true,
|
||||
// onClick: () => {
|
||||
// this.toggleInvert()
|
||||
// }
|
||||
// },
|
||||
// {
|
||||
// label: '伪彩',
|
||||
// children: colorItems
|
||||
// }
|
||||
// ],
|
||||
// event,
|
||||
// // x: event.clientX,
|
||||
// // y: event.clientY,
|
||||
// customClass: 'class-a',
|
||||
// zIndex: 3,
|
||||
// minWidth: 100
|
||||
// })
|
||||
// return false
|
||||
},
|
||||
getToolSate() {
|
||||
const toolROITypes = [
|
||||
|
|
|
@ -0,0 +1,287 @@
|
|||
<template>
|
||||
<div class="dcm-tag">
|
||||
<el-input
|
||||
v-model="search"
|
||||
size="mini"
|
||||
:placeholder="$t('trials:dicom-tag:keywords')"
|
||||
style="width:200px"
|
||||
/>
|
||||
|
||||
<el-table
|
||||
:data="filterList(list)"
|
||||
row-key="id"
|
||||
default-expand-all
|
||||
:tree-props="{children: 'child', hasChildren: 'hasChildren'}"
|
||||
:default-sort="{prop: 'tagCode', order: 'ascending'}"
|
||||
height="500"
|
||||
>
|
||||
<el-table-column
|
||||
prop="tagCode"
|
||||
label="Tag"
|
||||
min-width="120"
|
||||
sortable
|
||||
/>
|
||||
<el-table-column
|
||||
prop="tagName"
|
||||
label="Description"
|
||||
min-width="150"
|
||||
show-overflow-tooltip
|
||||
sortable
|
||||
/>
|
||||
<el-table-column
|
||||
prop="vr"
|
||||
label="VR"
|
||||
min-width="50"
|
||||
show-overflow-tooltip
|
||||
sortable
|
||||
/>
|
||||
<el-table-column
|
||||
prop="tagLength"
|
||||
label="Length"
|
||||
min-width="80"
|
||||
show-overflow-tooltip
|
||||
sortable
|
||||
/>
|
||||
<el-table-column
|
||||
prop="value"
|
||||
label="Value"
|
||||
min-width="200"
|
||||
show-overflow-tooltip
|
||||
sortable
|
||||
/>
|
||||
</el-table>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import TAG_DICT from './dataDictionary'
|
||||
import * as cornerstone from 'cornerstone-core'
|
||||
import dicomParser from 'dicom-parser'
|
||||
export default {
|
||||
name: 'DicomTags',
|
||||
props: {
|
||||
imageId: {
|
||||
type: String,
|
||||
required: true
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
list: [],
|
||||
idx: 0,
|
||||
search: ''
|
||||
}
|
||||
},
|
||||
async mounted() {
|
||||
const image = await cornerstone.loadAndCacheImage(this.imageId)
|
||||
var dataSet = dicomParser.parseDicom(image.data.byteArray)
|
||||
var output = []
|
||||
this.dumpDataSet(dataSet, output)
|
||||
this.list = output
|
||||
},
|
||||
methods: {
|
||||
filterList(list) {
|
||||
if (list.length === 0) return []
|
||||
if (!this.search) {
|
||||
return list
|
||||
} else {
|
||||
const search = isNaN(parseFloat(this.search)) ? this.search.toLowerCase() : String(this.search)
|
||||
const arr = list.filter(data => {
|
||||
if (data.tagCode && data.tagCode.toLowerCase().includes(search)) {
|
||||
return data
|
||||
} else if (data.tagName && data.tagName.toLowerCase().includes(search)) {
|
||||
return data
|
||||
} else if (data.value) {
|
||||
let v = ''
|
||||
if (!isNaN(parseFloat(data.value))) {
|
||||
v = String(data.value)
|
||||
} else {
|
||||
v = data.value.toLowerCase()
|
||||
}
|
||||
if (v.includes(search)) {
|
||||
return data
|
||||
}
|
||||
}
|
||||
})
|
||||
return arr
|
||||
}
|
||||
},
|
||||
dumpDataSet(dataSet, output) {
|
||||
try {
|
||||
for (const propertyName in dataSet.elements) {
|
||||
const elementObject = {}
|
||||
const element = dataSet.elements[propertyName]
|
||||
const tag = this.getTag(element.tag)
|
||||
elementObject.id = `${this.idx++}${new Date().getTime()}`
|
||||
if (!tag) {
|
||||
const group = element.tag.substring(1, 5)
|
||||
const el = element.tag.substring(5, 9)
|
||||
elementObject.tagCode = ('(' + group + ',' + el + ')').toUpperCase()
|
||||
} else {
|
||||
elementObject.tagCode = tag ? tag.tag : ''
|
||||
elementObject.tagName = tag ? tag.name : ''
|
||||
}
|
||||
|
||||
elementObject.tagLength = element.length
|
||||
elementObject.value = ''
|
||||
elementObject.child = []
|
||||
|
||||
if (element.items) {
|
||||
element.items.forEach(item => {
|
||||
const childOutput = []
|
||||
this.dumpDataSet(item.dataSet, childOutput)
|
||||
elementObject.child.push(...childOutput)
|
||||
})
|
||||
} else if (element.fragments) {
|
||||
// 多帧处理
|
||||
} else {
|
||||
var vr
|
||||
if (element.vr !== undefined) {
|
||||
vr = element.vr
|
||||
} else {
|
||||
if (tag !== undefined) {
|
||||
vr = tag.vr
|
||||
}
|
||||
}
|
||||
elementObject.vr = vr
|
||||
if (element.length < 128) {
|
||||
// const str = dataSet.string(propertyName)
|
||||
// if (elementObject.tagCode === 'x00280010') {
|
||||
// console.log(str)
|
||||
// }
|
||||
// const stringIsAscii = this.isASCII(str)
|
||||
// if (stringIsAscii && str !== undefined) {
|
||||
// elementObject.value = str
|
||||
// }
|
||||
|
||||
if (element.vr === undefined && tag === undefined) {
|
||||
if (element.length === 2) {
|
||||
elementObject.value = dataSet.uint16(propertyName)
|
||||
} else if (element.length === 4) {
|
||||
elementObject.value = dataSet.uint32(propertyName)
|
||||
}
|
||||
const str = dataSet.string(propertyName)
|
||||
const stringIsAscii = this.isASCII(str)
|
||||
|
||||
if (stringIsAscii) {
|
||||
if (str !== undefined) {
|
||||
elementObject.value = str
|
||||
}
|
||||
} else {
|
||||
if (element.length !== 2 && element.length !== 4) {
|
||||
// elementObject.value = 'binary data'
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (this.isStringVr(vr)) {
|
||||
const str = dataSet.string(propertyName)
|
||||
const stringIsAscii = this.isASCII(str)
|
||||
|
||||
if (stringIsAscii) {
|
||||
if (str !== undefined) {
|
||||
elementObject.value = str
|
||||
}
|
||||
} else {
|
||||
if (element.length !== 2 && element.length !== 4) {
|
||||
// elementObject.value = 'binary data'
|
||||
}
|
||||
}
|
||||
} else if (vr === 'US') {
|
||||
let text = dataSet.uint16(propertyName)
|
||||
for (let i = 1; i < dataSet.elements[propertyName].length / 2; i++) {
|
||||
text += '\\' + dataSet.uint16(propertyName, i)
|
||||
}
|
||||
elementObject.value = text
|
||||
} else if (vr === 'SS') {
|
||||
let text = dataSet.int16(propertyName)
|
||||
for (let i = 1; i < dataSet.elements[propertyName].length / 2; i++) {
|
||||
text += '\\' + dataSet.int16(propertyName, i)
|
||||
}
|
||||
elementObject.value = text
|
||||
} else if (vr === 'UL') {
|
||||
let text = dataSet.uint32(propertyName)
|
||||
for (let i = 1; i < dataSet.elements[propertyName].length / 4; i++) {
|
||||
text += '\\' + dataSet.uint32(propertyName, i)
|
||||
}
|
||||
elementObject.value = text
|
||||
} else if (vr === 'SL') {
|
||||
let text = dataSet.int32(propertyName)
|
||||
for (let i = 1; i < dataSet.elements[propertyName].length / 4; i++) {
|
||||
text += '\\' + dataSet.int32(propertyName, i)
|
||||
}
|
||||
elementObject.value = text
|
||||
} else if (vr === 'FD') {
|
||||
let text = dataSet.double(propertyName)
|
||||
for (let i = 1; i < dataSet.elements[propertyName].length / 8; i++) {
|
||||
text += '\\' + dataSet.double(propertyName, i)
|
||||
}
|
||||
elementObject.value = text
|
||||
} else if (vr === 'FL') {
|
||||
let text = dataSet.float(propertyName)
|
||||
for (let i = 1; i < dataSet.elements[propertyName].length / 4; i++) {
|
||||
text += '\\' + dataSet.float(propertyName, i)
|
||||
}
|
||||
elementObject.value = text
|
||||
} else if (vr === 'OB' || vr === 'OW' || vr === 'UN' || vr === 'OF' || vr === 'UT') {
|
||||
if (element.length === 2) {
|
||||
elementObject.value = dataSet.uint16(propertyName)
|
||||
} else if (element.length === 4) {
|
||||
elementObject.value = dataSet.uint32(propertyName)
|
||||
} else {
|
||||
|
||||
}
|
||||
} else if (vr === 'AT') {
|
||||
// var group = dataSet.uint16(propertyName, 0);
|
||||
// var groupHexStr = ("0000" + group.toString(16)).substr(-4);
|
||||
// var element = dataSet.uint16(propertyName, 1);
|
||||
// var elementHexStr = ("0000" + element.toString(16)).substr(-4);
|
||||
// text += "x" + groupHexStr + elementHexStr;
|
||||
} else if (vr === 'SQ') {
|
||||
} else {
|
||||
// no display code for VR yet, sorry!
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
output.push(elementObject)
|
||||
}
|
||||
} catch (err) {
|
||||
const ex = {
|
||||
exception: err,
|
||||
output: output
|
||||
}
|
||||
console.log(ex)
|
||||
}
|
||||
},
|
||||
getTag(tag) {
|
||||
var group = tag.substring(1, 5)
|
||||
var element = tag.substring(5, 9)
|
||||
var tagIndex = ('(' + group + ',' + element + ')').toUpperCase()
|
||||
var attr = TAG_DICT[tagIndex]
|
||||
return attr
|
||||
},
|
||||
isASCII(str) {
|
||||
return /^[\x00-\x7F]*$/.test(str)
|
||||
},
|
||||
isStringVr(vr) {
|
||||
if (vr === 'AT' || vr === 'FL' || vr === 'FD' || vr === 'OB' || vr === 'OF' || vr === 'OW' || vr === 'SI' || vr === 'SQ' || vr === 'SS' || vr === 'UL' || vr === 'US') {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.dcm-tag{
|
||||
// user-select: none;
|
||||
::-webkit-scrollbar {
|
||||
width: 8px;
|
||||
height: 15px;
|
||||
}
|
||||
::-webkit-scrollbar-thumb {
|
||||
border-radius: 10px;
|
||||
background: #d0d0d0;
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -162,6 +162,19 @@
|
|||
<button :title="$t('trials:dicom-show:lens')" class="btn-link" data-tool="Magnify" @click="setToolActive($event,'Magnify')">
|
||||
<svg-icon icon-class="zoom" style="font-size:20px;" />
|
||||
</button>
|
||||
<button :title="$t('trials:reading:button:rotate')" class="btn-link dropdown" data-tool="Rotate">
|
||||
<svg-icon icon-class="rotate" style="font-size:20px;" />
|
||||
<div class="dropdown-content">
|
||||
<div @click.stop="setDicomCanvasRotate(1)">{{ $t('trials:reading:button:rotateDefault') }}</div>
|
||||
<div @click.stop="setDicomCanvasRotate(2)">{{ $t('trials:reading:button:rotateHorizontal') }}</div>
|
||||
<div @click.stop="setDicomCanvasRotate(3)">{{ $t('trials:reading:button:rotateVertical') }}</div>
|
||||
<div @click.stop="setDicomCanvasRotate(4)">{{ $t('trials:reading:button:rotateTurnLeft') }}</div>
|
||||
<div @click.stop="setDicomCanvasRotate(5)">{{ $t('trials:reading:button:rotateTurnRight') }}</div>
|
||||
</div>
|
||||
</button>
|
||||
<button :title="$t('trials:reading:button:move')" class="btn-link" data-tool="Pan" @click="setToolActive($event,'Pan')">
|
||||
<svg-icon icon-class="move" style="font-size:20px;" />
|
||||
</button>
|
||||
<button :title="$t('trials:reading:button:fitWindow')" class="btn-link" data-tool="fitToWindow" @click="fitToType($event,'fitToWindow')">
|
||||
<svg-icon icon-class="fitToWindow" style="font-size:20px;" />
|
||||
</button>
|
||||
|
@ -169,19 +182,7 @@
|
|||
<svg-icon icon-class="fitToImage" style="font-size:20px;" />
|
||||
</button>
|
||||
<!-- <button title="旋转" class="btn-link dropdown" data-tool="Rotate" @click="setToolActive($event,'Rotate')"> -->
|
||||
<button :title="$t('trials:reading:button:rotate')" class="btn-link dropdown" data-tool="Rotate">
|
||||
<svg-icon icon-class="rotate" style="font-size:20px;" />
|
||||
<div class="dropdown-content">
|
||||
<p @click.stop="setDicomCanvasRotate(1)">{{ $t('trials:reading:button:rotateDefault') }}</p>
|
||||
<p @click.stop="setDicomCanvasRotate(2)">{{ $t('trials:reading:button:rotateHorizontal') }}</p>
|
||||
<p @click.stop="setDicomCanvasRotate(3)">{{ $t('trials:reading:button:rotateVertical') }}</p>
|
||||
<p @click.stop="setDicomCanvasRotate(4)">{{ $t('trials:reading:button:rotateTurnLeft') }}</p>
|
||||
<p @click.stop="setDicomCanvasRotate(5)">{{ $t('trials:reading:button:rotateTurnRight') }}</p>
|
||||
</div>
|
||||
</button>
|
||||
<button :title="$t('trials:reading:button:move')" class="btn-link" data-tool="Pan" @click="setToolActive($event,'Pan')">
|
||||
<svg-icon icon-class="move" style="font-size:20px;" />
|
||||
</button>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<!-- 测量标注 -->
|
||||
|
@ -232,6 +233,10 @@
|
|||
<button :title="$t('trials:dicom-show:image')" class="btn-link" @click="currentDicomCanvas.saveImage()">
|
||||
<svg-icon icon-class="image" style="font-size:20px;" />
|
||||
</button>
|
||||
<!-- 标签 -->
|
||||
<button :title="$t('trials:dicom-show:tags')" class="btn-link" @click="currentDicomCanvas.showTags()">
|
||||
<svg-icon icon-class="dictionary" style="font-size:20px;" />
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="measureTool-wrapper">
|
||||
|
@ -247,7 +252,7 @@
|
|||
<svg-icon icon-class="previousframe" style="font-size:20px;" />
|
||||
</button>
|
||||
<!-- 播放 -->
|
||||
<button class="btn-link" :title="$t('trials:dicom-show:play')" @click="currentDicomCanvas.toggleClipPlay()">
|
||||
<button class="btn-link" :title="$t('trials:dicom-show:play')" @click="clipPlay">
|
||||
<svg-icon
|
||||
:icon-class="currentDicomCanvas.toolState.clipPlaying ? 'stop' : 'play'"
|
||||
style="font-size:20px;"
|
||||
|
@ -261,9 +266,10 @@
|
|||
<button class="btn-link" :title="$t('trials:dicom-show:lastframe')" @click="currentDicomCanvas.scrollPage(9999)">
|
||||
<svg-icon icon-class="lastframe" style="font-size:20px;" />
|
||||
</button>
|
||||
<select class="sidetool-select" style="width:60px" @change="setDicomCanvasfps($event)">
|
||||
<select v-model="fps" class="sidetool-select" style="width:60px" @change="setDicomCanvasfps($event)">
|
||||
<!-- 默认值 -->
|
||||
<option :value="10">{{ $t('trials:dicom-show:default') }}</option>
|
||||
<option :value="5">5</option>
|
||||
<option :value="10">10</option>
|
||||
<option :value="15">15</option>
|
||||
<option :value="20">20</option>
|
||||
<option :value="30">30</option>
|
||||
|
@ -386,7 +392,8 @@ export default {
|
|||
wwwcList: [],
|
||||
layout: null,
|
||||
seriesList: [],
|
||||
customWwc: { visible: false, title: null }
|
||||
customWwc: { visible: false, title: null },
|
||||
fps: 15
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
|
@ -400,8 +407,10 @@ export default {
|
|||
|
||||
methods: {
|
||||
loadImageStack(dicomSeries) {
|
||||
this.currentDicomCanvas.toolState.clipPlaying = false
|
||||
this.$nextTick(() => {
|
||||
this.currentDicomCanvas.loadImageStack(dicomSeries)
|
||||
const series = Object.assign({}, dicomSeries)
|
||||
this.currentDicomCanvas.loadImageStack(series)
|
||||
})
|
||||
},
|
||||
loadOtherImageStack(seriesList) {
|
||||
|
@ -411,7 +420,8 @@ export default {
|
|||
Array.from(elements).forEach((element, index) => {
|
||||
const canvasIndex = element.getAttribute('data-index')
|
||||
if (index < seriesList.length && element.style.display !== 'none') {
|
||||
this.$refs[`dicomCanvas${canvasIndex}`].loadImageStack(seriesList[index])
|
||||
const series = Object.assign({}, seriesList[index])
|
||||
this.$refs[`dicomCanvas${canvasIndex}`].loadImageStack(series)
|
||||
}
|
||||
})
|
||||
})
|
||||
|
@ -565,6 +575,10 @@ export default {
|
|||
setDicomCanvasfps(event) {
|
||||
this.currentDicomCanvas.setFps(event.target.value)
|
||||
},
|
||||
clipPlay() {
|
||||
this.currentDicomCanvas.setFps(this.fps)
|
||||
this.currentDicomCanvas.toggleClipPlay()
|
||||
},
|
||||
fitToType(e, type) {
|
||||
const toolButtons = document.querySelectorAll('[data-tool]')
|
||||
Array.from(toolButtons).forEach((toolBtn) => {
|
||||
|
@ -879,13 +893,19 @@ export default {
|
|||
background-color: #323232;
|
||||
min-width: 80px;
|
||||
box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2);
|
||||
border: 1px solid #4e4e4e;
|
||||
padding: 5px;
|
||||
}
|
||||
.dicom-wrapper .dropdown:hover .dropdown-content {
|
||||
display: block;
|
||||
}
|
||||
.dicom-wrapper .dropdown-content p{
|
||||
.dicom-wrapper .dropdown-content div{
|
||||
height: 25px;
|
||||
line-height: 25px;
|
||||
cursor:point;
|
||||
}
|
||||
.dicom-wrapper .dropdown-content div:hover{
|
||||
background-color: #16477b90;
|
||||
}
|
||||
|
||||
</style>
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -23,11 +23,11 @@
|
|||
</template>
|
||||
|
||||
<script>
|
||||
import { createFFmpeg, fetchFile } from '@ffmpeg/ffmpeg'
|
||||
const ffmpeg = createFFmpeg({
|
||||
log: true,
|
||||
corePath: './ffmpeg-core.js'
|
||||
})
|
||||
// import { createFFmpeg, fetchFile } from '@ffmpeg/ffmpeg'
|
||||
// const ffmpeg = createFFmpeg({
|
||||
// log: true,
|
||||
// corePath: './ffmpeg-core.js'
|
||||
// })
|
||||
|
||||
export default {
|
||||
props: {
|
||||
|
@ -73,41 +73,41 @@ export default {
|
|||
async videoToMp4() {
|
||||
// 页面是否在安全上下文中
|
||||
// https 或者 本地开发环境才是安全上下文
|
||||
if (!window.isSecureContext) {
|
||||
this.$alert(this.$t('components:uploadvideo:message:xf3'))
|
||||
return
|
||||
}
|
||||
// 顶部文档是否开启跨源隔离
|
||||
if (!window.crossOriginIsolated) {
|
||||
this.$alert(this.$t('components:uploadvideo:message:xf4'))
|
||||
return
|
||||
}
|
||||
this.$message.success(this.$t('components:uploadvideo:message:xf5'))
|
||||
if (!ffmpeg.isLoaded()) {
|
||||
await ffmpeg.load()
|
||||
}
|
||||
this.percentage = 0
|
||||
this.isVideoToMp4 = true
|
||||
ffmpeg.setProgress(({ ratio }) => {
|
||||
console.log(ratio)
|
||||
if (ratio * 100 < 1) {
|
||||
this.percentage = parseInt(0)
|
||||
} else {
|
||||
this.percentage = parseInt(ratio * 100)
|
||||
}
|
||||
})
|
||||
ffmpeg.FS('writeFile', 'input.mp4', await fetchFile(this.videoSrc))
|
||||
await ffmpeg.run('-i', 'input.mp4', 'output.mp4')
|
||||
this.videoSrc = null
|
||||
const data = ffmpeg.FS('readFile', 'output.mp4')
|
||||
this.dataBuffer = new Blob([data.buffer], { type: 'video/mp4' })
|
||||
this.$message.success(this.$t('components:uploadvideo:message:xf6'))
|
||||
setTimeout(() => {
|
||||
this.videoSrc = URL.createObjectURL(this.dataBuffer)
|
||||
this.isVideoToMp4 = false
|
||||
this.isNeedToMp4 = false
|
||||
process.exit(0)
|
||||
}, 50)
|
||||
// if (!window.isSecureContext) {
|
||||
// this.$alert(this.$t('components:uploadvideo:message:xf3'))
|
||||
// return
|
||||
// }
|
||||
// // 顶部文档是否开启跨源隔离
|
||||
// if (!window.crossOriginIsolated) {
|
||||
// this.$alert(this.$t('components:uploadvideo:message:xf4'))
|
||||
// return
|
||||
// }
|
||||
// this.$message.success(this.$t('components:uploadvideo:message:xf5'))
|
||||
// if (!ffmpeg.isLoaded()) {
|
||||
// await ffmpeg.load()
|
||||
// }
|
||||
// this.percentage = 0
|
||||
// this.isVideoToMp4 = true
|
||||
// ffmpeg.setProgress(({ ratio }) => {
|
||||
// console.log(ratio)
|
||||
// if (ratio * 100 < 1) {
|
||||
// this.percentage = parseInt(0)
|
||||
// } else {
|
||||
// this.percentage = parseInt(ratio * 100)
|
||||
// }
|
||||
// })
|
||||
// ffmpeg.FS('writeFile', 'input.mp4', await fetchFile(this.videoSrc))
|
||||
// await ffmpeg.run('-i', 'input.mp4', 'output.mp4')
|
||||
// this.videoSrc = null
|
||||
// const data = ffmpeg.FS('readFile', 'output.mp4')
|
||||
// this.dataBuffer = new Blob([data.buffer], { type: 'video/mp4' })
|
||||
// this.$message.success(this.$t('components:uploadvideo:message:xf6'))
|
||||
// setTimeout(() => {
|
||||
// this.videoSrc = URL.createObjectURL(this.dataBuffer)
|
||||
// this.isVideoToMp4 = false
|
||||
// this.isNeedToMp4 = false
|
||||
// process.exit(0)
|
||||
// }, 50)
|
||||
},
|
||||
fileChange(e) {
|
||||
this.videoSrc = null
|
||||
|
|
|
@ -30,30 +30,55 @@ const getDefaultState = () => {
|
|||
activeSeries: {},
|
||||
lastCanvasTaskId: '',
|
||||
imageQuality: null,
|
||||
imageQualityIssues: null
|
||||
imageQualityIssues: null,
|
||||
currentLoadIns: []
|
||||
}
|
||||
}
|
||||
function getQuestions(questions) {
|
||||
const criterionType = parseInt(localStorage.getItem('CriterionType'))
|
||||
questions.forEach(item => {
|
||||
if (item.Type === 'table' && item.TableQuestions && item.TableQuestions.Answers.length > 0) {
|
||||
if ((item.Type === 'table' || item.Type === 'basicTable') && item.TableQuestions && item.TableQuestions.Answers.length > 0) {
|
||||
item.TableQuestions.Answers.forEach(answerObj => {
|
||||
answerObj.lesionPart = getQuestionAnswer(item.TableQuestions.Questions, 8, answerObj)
|
||||
answerObj.loctation = getQuestionAnswer(item.TableQuestions.Questions, 6, answerObj)
|
||||
answerObj.lesionLength = getQuestionAnswer(item.TableQuestions.Questions, 0, answerObj)
|
||||
answerObj.lesionShort = getQuestionAnswer(item.TableQuestions.Questions, 1, answerObj)
|
||||
answerObj.isDicomReading = answerObj.IsDicomReading === 'True'
|
||||
var isLymphLesion = getQuestionAnswer(item.TableQuestions.Questions, 2, answerObj)
|
||||
isLymphLesion = isLymphLesion ? parseInt(isLymphLesion) : null
|
||||
answerObj.isLymphLesion = isLymphLesion
|
||||
answerObj.lesionState = getQuestionAnswer(item.TableQuestions.Questions, 7, answerObj)
|
||||
var lesionNum = getQuestionAnswer(item.TableQuestions.Questions, 11, answerObj)
|
||||
answerObj.lesionNum = lesionNum
|
||||
|
||||
if (answerObj.RowId) {
|
||||
var idx = item.TableQuestions.Questions.findIndex(i => i.QuestionMark === 11)
|
||||
if (idx > -1) {
|
||||
if (criterionType === 10) {
|
||||
// pcwg
|
||||
var lesionNum = getQuestionAnswer(item.TableQuestions.Questions, 11, answerObj)
|
||||
answerObj.lesionNum = lesionNum
|
||||
answerObj.saveTypeEnum = isNaN(parseInt(answerObj.lesionNum)) ? 1 : 2
|
||||
} else if (criterionType === 19) {
|
||||
// ivus
|
||||
answerObj.area1 = getQuestionAnswer(item.TableQuestions.Questions, 1001, answerObj)
|
||||
answerObj.area2 = getQuestionAnswer(item.TableQuestions.Questions, 1002, answerObj)
|
||||
const v = getQuestionAnswer(item.TableQuestions.Questions, 1003, answerObj)
|
||||
answerObj.diff = v
|
||||
answerObj.saveTypeEnum = isNaN(parseFloat(v)) ? 1 : 2
|
||||
} else if (criterionType === 20) {
|
||||
// oct
|
||||
if (item.LesionType === 101) {
|
||||
answerObj.l1 = getQuestionAnswer(item.TableQuestions.Questions, 1011, answerObj)
|
||||
answerObj.l2 = getQuestionAnswer(item.TableQuestions.Questions, 1012, answerObj)
|
||||
answerObj.l3 = getQuestionAnswer(item.TableQuestions.Questions, 1013, answerObj)
|
||||
const min = getQuestionAnswer(item.TableQuestions.Questions, 1014, answerObj)
|
||||
answerObj.min = min
|
||||
const mean = getQuestionAnswer(item.TableQuestions.Questions, 1015, answerObj)
|
||||
answerObj.mean = mean
|
||||
answerObj.saveTypeEnum = (isNaN(parseFloat(min)) || isNaN(parseFloat(mean))) ? 1 : 2
|
||||
} else if (item.LesionType === 103) {
|
||||
const angle = getQuestionAnswer(item.TableQuestions.Questions, 1016, answerObj)
|
||||
answerObj.angle = angle
|
||||
answerObj.saveTypeEnum = isNaN(parseFloat(angle)) ? 1 : 2
|
||||
}
|
||||
} else {
|
||||
answerObj.lesionPart = getQuestionAnswer(item.TableQuestions.Questions, 8, answerObj)
|
||||
answerObj.loctation = getQuestionAnswer(item.TableQuestions.Questions, 6, answerObj)
|
||||
answerObj.lesionLength = getQuestionAnswer(item.TableQuestions.Questions, 0, answerObj)
|
||||
answerObj.lesionShort = getQuestionAnswer(item.TableQuestions.Questions, 1, answerObj)
|
||||
let isLymphLesion = getQuestionAnswer(item.TableQuestions.Questions, 2, answerObj)
|
||||
isLymphLesion = isLymphLesion ? parseInt(isLymphLesion) : null
|
||||
answerObj.isLymphLesion = isLymphLesion
|
||||
answerObj.lesionState = getQuestionAnswer(item.TableQuestions.Questions, 7, answerObj)
|
||||
answerObj.saveTypeEnum = isNaN(parseInt(answerObj.lesionState)) ? 1 : 2
|
||||
}
|
||||
} else {
|
||||
|
@ -69,7 +94,7 @@ function getQuestions(questions) {
|
|||
}
|
||||
function findQuestionAndRemoveLesion(questions, obj) {
|
||||
for (var i = 0; i < questions.length; i++) {
|
||||
if (questions[i].Type === 'table' && questions[i].TableQuestions && (questions[i].LesionType === obj.lesionType) && questions[i].TableQuestions.Answers.length > 0) {
|
||||
if ((questions[i].Type === 'table' || questions[i].Type === 'basicTable') && questions[i].TableQuestions && (questions[i].LesionType === obj.lesionType) && questions[i].TableQuestions.Answers.length > 0) {
|
||||
var idx = questions[i].TableQuestions.Answers.findIndex(i => String(i.RowIndex) === String(obj.rowIndex))
|
||||
if (idx > -1) {
|
||||
questions[i].TableQuestions.Answers.splice(idx, 1)
|
||||
|
@ -85,7 +110,7 @@ function findQuestionAndRemoveLesion(questions, obj) {
|
|||
function findQuestionAndUpdateLesion(questions, obj) {
|
||||
for (var i = 0; i < questions.length; i++) {
|
||||
var item = questions[i]
|
||||
if (item.Type === 'table' && item.Id === obj.questionId) {
|
||||
if ((item.Type === 'table' || item.Type === 'basicTable') && item.Id === obj.questionId) {
|
||||
var idx = item.TableQuestions.Answers.findIndex(i => i.RowIndex === obj.rowIndex)
|
||||
item.TableQuestions.Answers[idx].isLymphLesion = obj.isLymphLesion
|
||||
item.TableQuestions.Answers[idx].loctation = obj.lesionOrgan
|
||||
|
@ -114,10 +139,10 @@ function findQuestionAndUpdateLesion(questions, obj) {
|
|||
}
|
||||
function findQuestionAndAddLesion(questions, obj) {
|
||||
for (var i = 0; i < questions.length; i++) {
|
||||
if (questions[i].Type === 'table' && questions[i].TableQuestions && (questions[i].LesionType === obj.lesionType)) {
|
||||
if ((questions[i].Type === 'table' || questions[i].Type === 'basicTable') && questions[i].TableQuestions && (questions[i].LesionType === obj.lesionType)) {
|
||||
var sourceObj = {}
|
||||
questions[i].TableQuestions.Questions.forEach(item => {
|
||||
sourceObj[item.Id] = ''
|
||||
sourceObj[item.Id] = null
|
||||
})
|
||||
var targetObj = Object.assign(sourceObj, obj.lesionObj)
|
||||
targetObj.IsCurrentTaskAdd = 'True'
|
||||
|
@ -139,6 +164,22 @@ function getQuestionAnswer(questions, questionMark, answers) {
|
|||
return ''
|
||||
}
|
||||
}
|
||||
// function getKeySeriesInfo(keyInstance, series) {
|
||||
// const obj = {}
|
||||
// const set = new Set()
|
||||
// var instances = series.instanceList.concat(keyInstance).filter((item) => {
|
||||
// if (set.has(item)) {
|
||||
// return true
|
||||
// } else {
|
||||
// set.add(item)
|
||||
// return false
|
||||
// }
|
||||
// })
|
||||
// instances.map(item => {
|
||||
// obj[item] = { seriesId: series.seriesId, studyIndex: series.studyIndex, seriesIndex: series.seriesIndex }
|
||||
// })
|
||||
// return obj
|
||||
// }
|
||||
|
||||
const state = getDefaultState
|
||||
|
||||
|
@ -190,6 +231,7 @@ const actions = {
|
|||
},
|
||||
getMasterSeries({ state }, obj) {
|
||||
return new Promise(resolve => {
|
||||
console.log('getMasterSeries')
|
||||
var seriesInfo = {}
|
||||
var i = state.visitTaskList.findIndex(i => i.VisitTaskId === obj.visitTaskId)
|
||||
getReadingVisitStudyList(obj.trialId, obj.visitId, obj.visitTaskId).then(res => {
|
||||
|
@ -209,14 +251,28 @@ const actions = {
|
|||
var seriesList = []
|
||||
study.SeriesList.forEach((series, index) => {
|
||||
const imageIds = []
|
||||
|
||||
series.InstancePathList.forEach((path) => {
|
||||
imageIds.push(`wadouri:${localStorage.getItem('location') !== 'USA' ? Vue.prototype.OSSclientConfig.basePath : Vue.prototype.OSSclientConfig.basePath}${path}`)
|
||||
const instanceList = []
|
||||
// series.InstancePathList.forEach((path) => {
|
||||
// imageIds.push(`wadouri:${localStorage.getItem('location') !== 'USA' ? Vue.prototype.OSSclientConfig.basePath : Vue.prototype.OSSclientConfig.basePath}${path}`)
|
||||
// })
|
||||
series.InstanceInfoList.forEach(instance => {
|
||||
if (instance.NumberOfFrames && instance.NumberOfFrames > 1) {
|
||||
for (let i = 0; i < instance.NumberOfFrames; i++) {
|
||||
const imageId = `wadouri:${localStorage.getItem('location') !== 'USA' ? Vue.prototype.OSSclientConfig.basePath : Vue.prototype.OSSclientConfig.basePath}${instance.Path}?frame=${i}&instanceId=${instance.Id}&visitTaskId=${obj.visitTaskId}&idx=0|0`
|
||||
imageIds.push(imageId)
|
||||
}
|
||||
} else {
|
||||
const imageId = `wadouri:${localStorage.getItem('location') !== 'USA' ? Vue.prototype.OSSclientConfig.basePath : Vue.prototype.OSSclientConfig.basePath}${instance.Path}?instanceId=${instance.Id}&visitTaskId=${obj.visitTaskId}&idx=0|0`
|
||||
imageIds.push(imageId)
|
||||
}
|
||||
instance.ImageId = `wadouri:${localStorage.getItem('location') !== 'USA' ? Vue.prototype.OSSclientConfig.basePath : Vue.prototype.OSSclientConfig.basePath}${instance.Path}?instanceId=${instance.Id}&visitTaskId=${obj.visitTaskId}&idx=0|0`
|
||||
instanceList.push(instance.Id)
|
||||
})
|
||||
seriesList.push({
|
||||
isDicom: study.IsDicom,
|
||||
imageIds: imageIds,
|
||||
instanceList: series.InstanceList,
|
||||
instanceInfoList: series.InstanceInfoList,
|
||||
instanceList: instanceList,
|
||||
seriesId: series.Id,
|
||||
imageIdIndex: 0,
|
||||
seriesUid: series.SeriesInstanceUid,
|
||||
|
@ -481,24 +537,28 @@ const actions = {
|
|||
return new Promise(async resolve => {
|
||||
var index = state.visitTaskList.findIndex(i => i.VisitTaskId === obj.visitTaskId)
|
||||
var measureData = state.visitTaskList[index].MeasureData
|
||||
|
||||
console.log('removeCustomizeMeasuredData', obj, state.visitTaskList[index].MeasureData)
|
||||
// var uuid = obj.measureData.data.uuid
|
||||
// var idx = measureData.findIndex(item => item.MeasureData && item.MeasureData.data && item.MeasureData.data.uuid === uuid)
|
||||
console.log(obj, measureData)
|
||||
var idx = measureData.findIndex(item => item.Id === obj.questionInfo.Id)
|
||||
console.log('idx', idx)
|
||||
if (idx > -1) {
|
||||
if (measureData[idx].FristAddTaskId) {
|
||||
measureData[idx].MeasureData = ''
|
||||
console.log('清除标记成功', idx)
|
||||
} else {
|
||||
measureData.splice(idx, 1)
|
||||
console.log('移除标记成功', idx)
|
||||
// console.log(obj, measureData)
|
||||
if (obj.questionInfo.Id) {
|
||||
var idx = measureData.findIndex(item => item.Id === obj.questionInfo.Id)
|
||||
console.log('idx', idx)
|
||||
if (idx > -1) {
|
||||
if (measureData[idx].FristAddTaskId) {
|
||||
measureData[idx].MeasureData = ''
|
||||
console.log('清除标记成功', idx)
|
||||
} else {
|
||||
measureData.splice(idx, 1)
|
||||
console.log('移除标记成功', idx)
|
||||
}
|
||||
if (obj.questionInfo.Id && state.currentReadingTaskState < 2) {
|
||||
await deleteCustomTag(obj.questionInfo.Id)
|
||||
}
|
||||
state.visitTaskList[index].MeasureData = measureData
|
||||
}
|
||||
await deleteCustomTag(obj.questionInfo.Id)
|
||||
state.visitTaskList[index].MeasureData = measureData
|
||||
} else if (obj.orderMarkName) {
|
||||
const i = measureData.findIndex(item => item.QuestionId === obj.questionId && item.OrderMarkName === obj.orderMarkName)
|
||||
const i = measureData.findIndex(item => item.MeasureData.data.remark === obj.orderMarkName)
|
||||
if (i > -1) {
|
||||
if (measureData[i].FristAddTaskId) {
|
||||
measureData[i].MeasureData = ''
|
||||
|
@ -508,7 +568,9 @@ const actions = {
|
|||
console.log('移除标记成功', i)
|
||||
}
|
||||
}
|
||||
await deleteCustomTag(obj.questionInfo.Id)
|
||||
if (obj.questionInfo.Id && state.currentReadingTaskState < 2) {
|
||||
await deleteCustomTag(obj.questionInfo.Id)
|
||||
}
|
||||
state.visitTaskList[index].MeasureData = measureData
|
||||
}
|
||||
// sessionStorage.setItem('visitTaskList', state.visitTaskList.length > 0 ? JSON.stringify(state.visitTaskList) : '')
|
||||
|
@ -590,6 +652,7 @@ const actions = {
|
|||
var index = state.visitTaskList.findIndex(i => i.VisitTaskId === obj.visitTaskId)
|
||||
var measureData = state.visitTaskList[index].MeasureData
|
||||
console.log('addOrUpdateNonTargetMeasuredData')
|
||||
// item.MeasureData.data.remark === obj.orderMarkName
|
||||
var idx = measureData.findIndex(item => item.QuestionId === obj.data.QuestionId && item.OrderMarkName === obj.data.OrderMarkName)
|
||||
if (idx > -1) {
|
||||
for (const k in state.visitTaskList[index].MeasureData[idx]) {
|
||||
|
@ -632,29 +695,39 @@ const actions = {
|
|||
var measureData = state.visitTaskList[index].MeasureData
|
||||
console.log(measureData, obj)
|
||||
// var idx = measureData.findIndex(item => item.MeasureData.uuid === obj.data.MeasureData.data.uuid)
|
||||
if (!obj.questionInfo) {
|
||||
state.visitTaskList[index].MeasureData.push({
|
||||
MeasureData: obj,
|
||||
SeriesId: obj.seriesId,
|
||||
StudyId: obj.studyId,
|
||||
InstanceId: obj.instanceId,
|
||||
Id: obj.Id
|
||||
})
|
||||
console.log('新增标记成功')
|
||||
// sessionStorage.setItem('visitTaskList', state.visitTaskList.length > 0 ? JSON.stringify(state.visitTaskList) : '')
|
||||
resolve()
|
||||
}
|
||||
var idx = measureData.findIndex(item => item.Id === obj.questionInfo.Id)
|
||||
// if (!obj.questionInfo) {
|
||||
// state.visitTaskList[index].MeasureData.push({
|
||||
// MeasureData: obj,
|
||||
// SeriesId: obj.seriesId,
|
||||
// StudyId: obj.studyId,
|
||||
// InstanceId: obj.instanceId,
|
||||
// Id: obj.Id
|
||||
// })
|
||||
// console.log('新增标记成功')
|
||||
// resolve()
|
||||
// }
|
||||
var idx = measureData.findIndex(item => item.MeasureData.data.remark === obj.measureData.data.remark)
|
||||
if (idx > -1) {
|
||||
for (const k in state.visitTaskList[index].MeasureData[idx]) {
|
||||
if (k !== 'Id' && obj.MeasureData.data[k]) {
|
||||
state.visitTaskList[index].MeasureData[idx][k] = obj.MeasureData.data[k]
|
||||
}
|
||||
}
|
||||
// state.visitTaskList[index].MeasureData[idx].InstanceId = obj.instanceId
|
||||
state.visitTaskList[index].MeasureData[idx].MeasureData = obj.measureData
|
||||
// state.visitTaskList[index].MeasureData[idx].SeriesId = obj.seriesId
|
||||
// state.visitTaskList[index].MeasureData[idx].StudyId = obj.studyId
|
||||
// for (const k in state.visitTaskList[index].MeasureData[idx]) {
|
||||
// if (k !== 'Id' && obj.MeasureData.data[k]) {
|
||||
// state.visitTaskList[index].MeasureData[idx][k] = obj.MeasureData.data[k]
|
||||
// }
|
||||
// }
|
||||
// state.visitTaskList[index].MeasureData[idx].MeasureData = obj.data.MeasureData
|
||||
console.log('更新标记成功', idx)
|
||||
} else {
|
||||
state.visitTaskList[index].MeasureData.push(obj.MeasureData.data)
|
||||
// state.visitTaskList[index].MeasureData.push(obj.MeasureData.data)
|
||||
state.visitTaskList[index].MeasureData.push({
|
||||
MeasureData: obj.measureData,
|
||||
SeriesId: obj.measureData.seriesId,
|
||||
StudyId: obj.measureData.studyId,
|
||||
InstanceId: obj.measureData.instanceId,
|
||||
Id: obj.id
|
||||
})
|
||||
console.log('新增标记成功')
|
||||
}
|
||||
// sessionStorage.setItem('visitTaskList', state.visitTaskList.length > 0 ? JSON.stringify(state.visitTaskList) : '')
|
||||
|
@ -720,15 +793,24 @@ const actions = {
|
|||
})
|
||||
},
|
||||
getStudyInfo({ state }, obj) {
|
||||
console.log('getStudyInfo')
|
||||
return new Promise(resolve => {
|
||||
var index = state.visitTaskList.findIndex(i => i.VisitTaskId === obj.visitTaskId)
|
||||
if (state.visitTaskList[index].studyListInit) {
|
||||
resolve()
|
||||
} else {
|
||||
var studyList = []
|
||||
// getVisitStudyList
|
||||
// getReadingVisitStudyList
|
||||
var keyImages = []
|
||||
getReadingVisitStudyList(obj.trialId, obj.subjectVisitId, obj.visitTaskId).then(res => {
|
||||
const i = res.Result.findIndex(i => i.IsCriticalSequence)
|
||||
if (i > -1) {
|
||||
const seriesList = res.Result[i].SeriesList && res.Result[i].SeriesList
|
||||
seriesList.map(i => {
|
||||
i.InstanceInfoList.map(k => {
|
||||
keyImages.push({ instanceId: k.Id })
|
||||
})
|
||||
})
|
||||
}
|
||||
res.Result.forEach((study, studyIndex) => {
|
||||
const data = {}
|
||||
data.StudyId = study.StudyId
|
||||
|
@ -743,19 +825,47 @@ const actions = {
|
|||
var seriesList = []
|
||||
study.SeriesList.forEach((series, seriesIndex) => {
|
||||
const imageIds = []
|
||||
try {
|
||||
// if (~window.location.href.indexOf('3c210000-3e2c-0016-4247-08dabf28e96b')) {
|
||||
series.InstancePathList.forEach((path) => {
|
||||
// var path = id.split('/')[id.split('/').length - 1]
|
||||
imageIds.push(`wadouri:${localStorage.getItem('location') !== 'USA' ? Vue.prototype.OSSclientConfig.basePath : Vue.prototype.OSSclientConfig.basePath}${path}`)
|
||||
})
|
||||
} catch (e) {
|
||||
console.log(e)
|
||||
}
|
||||
const instanceList = []
|
||||
// try {
|
||||
// series.InstancePathList.forEach((path) => {
|
||||
// imageIds.push(`wadouri:${localStorage.getItem('location') !== 'USA' ? Vue.prototype.OSSclientConfig.basePath : Vue.prototype.OSSclientConfig.basePath}${path}`)
|
||||
// })
|
||||
// } catch (e) {
|
||||
// console.log(e)
|
||||
// }
|
||||
series.InstanceInfoList.forEach(instance => {
|
||||
if (instance.NumberOfFrames && instance.NumberOfFrames > 1) {
|
||||
if (study.IsCriticalSequence && instance.KeyFramesList.length > 0) {
|
||||
instance.KeyFramesList.map(i => {
|
||||
const imageId = `wadouri:${localStorage.getItem('location') !== 'USA' ? Vue.prototype.OSSclientConfig.basePath : Vue.prototype.OSSclientConfig.basePath}${instance.Path}?frame=${i}&instanceId=${instance.Id}&visitTaskId=${obj.visitTaskId}&idx=${studyIndex}|${seriesIndex}|${index}`
|
||||
imageIds.push(imageId)
|
||||
})
|
||||
} else {
|
||||
for (let i = 0; i < instance.NumberOfFrames; i++) {
|
||||
const imageId = `wadouri:${localStorage.getItem('location') !== 'USA' ? Vue.prototype.OSSclientConfig.basePath : Vue.prototype.OSSclientConfig.basePath}${instance.Path}?frame=${i}&instanceId=${instance.Id}&visitTaskId=${obj.visitTaskId}&idx=${studyIndex}|${seriesIndex}|${index}`
|
||||
imageIds.push(imageId)
|
||||
}
|
||||
}
|
||||
instance.ImageId = `wadouri:${localStorage.getItem('location') !== 'USA' ? Vue.prototype.OSSclientConfig.basePath : Vue.prototype.OSSclientConfig.basePath}${instance.Path}?frame=${0}&instanceId=${instance.Id}&visitTaskId=${obj.visitTaskId}&idx=${studyIndex}|${seriesIndex}|${index}`
|
||||
} else {
|
||||
const imageId = `wadouri:${localStorage.getItem('location') !== 'USA' ? Vue.prototype.OSSclientConfig.basePath : Vue.prototype.OSSclientConfig.basePath}${instance.Path}?instanceId=${instance.Id}&visitTaskId=${obj.visitTaskId}&idx=${studyIndex}|${seriesIndex}|${index}`
|
||||
imageIds.push(imageId)
|
||||
instance.ImageId = imageId
|
||||
}
|
||||
if (!study.IsCriticalSequence && series.IsBeMark) {
|
||||
const i = keyImages.findIndex(i => i.instanceId === instance.Id)
|
||||
if (i > -1) {
|
||||
keyImages[i].studyIndex = studyIndex
|
||||
keyImages[i].seriesIndex = seriesIndex
|
||||
}
|
||||
}
|
||||
instanceList.push(instance.Id)
|
||||
})
|
||||
seriesList.push({
|
||||
isDicom: study.IsDicom,
|
||||
imageIds: imageIds,
|
||||
instanceList: series.InstanceList,
|
||||
instanceInfoList: series.InstanceInfoList,
|
||||
instanceList: instanceList,
|
||||
seriesId: series.Id,
|
||||
imageIdIndex: 0,
|
||||
seriesUid: series.SeriesInstanceUid,
|
||||
|
@ -782,7 +892,8 @@ const actions = {
|
|||
isLoading: false,
|
||||
isBeMark: series.IsBeMark,
|
||||
ww: series.WindowWidth,
|
||||
wc: series.WindowCenter
|
||||
wc: series.WindowCenter,
|
||||
isExistMutiFrames: series.IsExistMutiFrames
|
||||
})
|
||||
})
|
||||
data.SeriesList = seriesList
|
||||
|
@ -790,6 +901,7 @@ const actions = {
|
|||
})
|
||||
state.visitTaskList[index].StudyList = studyList
|
||||
state.visitTaskList[index].studyListInit = true
|
||||
state.visitTaskList[index].KeyImages = keyImages
|
||||
// sessionStorage.setItem('visitTaskList', state.visitTaskList.length > 0 ? JSON.stringify(state.visitTaskList) : '')
|
||||
resolve()
|
||||
}).catch(() => { resolve() })
|
||||
|
@ -848,6 +960,115 @@ const actions = {
|
|||
resolve()
|
||||
})
|
||||
},
|
||||
setImageLoadedProgress({ state }, obj) {
|
||||
const studyIndex = parseInt(obj.idx.split('|')[0])
|
||||
const seriesIndex = parseInt(obj.idx.split('|')[1])
|
||||
const visitTaskIndex = parseInt(obj.idx.split('|')[2])
|
||||
let pStudyIndex = null
|
||||
let pSeriesIndex = null
|
||||
let pSeries = null
|
||||
try {
|
||||
const study = state.visitTaskList[visitTaskIndex].StudyList[studyIndex]
|
||||
const series = state.visitTaskList[visitTaskIndex].StudyList[studyIndex].SeriesList[seriesIndex]
|
||||
const keyImages = state.visitTaskList[visitTaskIndex].KeyImages
|
||||
if (study.IsCriticalSequence) {
|
||||
const i = keyImages.findIndex(i => i.instanceId === obj.instanceId)
|
||||
if (i > -1) {
|
||||
pStudyIndex = keyImages[i].studyIndex
|
||||
pSeriesIndex = keyImages[i].seriesIndex
|
||||
}
|
||||
} else if (series.isBeMark) {
|
||||
if (keyImages.length > 0) {
|
||||
pStudyIndex = 0
|
||||
pSeriesIndex = 0
|
||||
}
|
||||
}
|
||||
if (pStudyIndex !== null && pSeriesIndex !== null) {
|
||||
pSeries = state.visitTaskList[visitTaskIndex].StudyList[pStudyIndex].SeriesList[pSeriesIndex]
|
||||
}
|
||||
|
||||
var prefetchInstanceCount = series.prefetchInstanceCount
|
||||
var instanceCount = series.instanceCount
|
||||
var prefetchInstanceCount2 = pSeries ? pSeries.prefetchInstanceCount : null
|
||||
var instanceCount2 = pSeries ? pSeries.instanceCount : null
|
||||
if (series.imageloadedArr.indexOf(obj.instanceId) < 0) {
|
||||
const i = state.currentLoadIns.findIndex(i => i.instanceId === obj.instanceId)
|
||||
if (i > -1) {
|
||||
prefetchInstanceCount = prefetchInstanceCount + obj.percentComplete - state.currentLoadIns[i].percentComplete
|
||||
prefetchInstanceCount2 = prefetchInstanceCount2 !== null ? prefetchInstanceCount2 + obj.percentComplete - state.currentLoadIns[i].percentComplete : null
|
||||
state.currentLoadIns[i].percentComplete = obj.percentComplete
|
||||
if (obj.percentComplete >= 100) {
|
||||
state.currentLoadIns.splice(i, 1)
|
||||
}
|
||||
} else {
|
||||
if (obj.percentComplete !== 100) {
|
||||
state.currentLoadIns.push({ instanceId: obj.instanceId, percentComplete: obj.percentComplete })
|
||||
}
|
||||
prefetchInstanceCount = prefetchInstanceCount + obj.percentComplete
|
||||
prefetchInstanceCount2 = prefetchInstanceCount2 !== null ? prefetchInstanceCount2 + obj.percentComplete : null
|
||||
}
|
||||
series.prefetchInstanceCount = prefetchInstanceCount
|
||||
if (pSeries) {
|
||||
pSeries.prefetchInstanceCount = prefetchInstanceCount2
|
||||
}
|
||||
if (obj.percentComplete >= 100) {
|
||||
series.imageloadedArr.push(obj.instanceId)
|
||||
if (pSeries) {
|
||||
pSeries.imageloadedArr.push(obj.instanceId)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (prefetchInstanceCount >= instanceCount * 100) {
|
||||
series.prefetchInstanceCount = instanceCount * 100
|
||||
// 设置当前序列状态为已下载完成
|
||||
series.loadStatus = true
|
||||
}
|
||||
if (prefetchInstanceCount2 !== null && instanceCount2 !== null && prefetchInstanceCount2 >= instanceCount2 * 100) {
|
||||
pSeries.prefetchInstanceCount = instanceCount2 * 100
|
||||
// 设置当前序列状态为已下载完成
|
||||
pSeries.loadStatus = true
|
||||
}
|
||||
} catch (e) {
|
||||
console.log('error')
|
||||
}
|
||||
},
|
||||
setImageloadedInfo({ state }, obj) {
|
||||
console.log('setImageloadedInfo', obj)
|
||||
// if(obj.instance === '20dd8fc9-51b0-ec63-942b-cb3006c72650')
|
||||
// var index = state.visitTaskList.findIndex(i => i.VisitTaskId === obj.visitTaskId)
|
||||
// // const prefetchInstanceCount = state.visitTaskList[index].StudyList[obj.studyIndex].SeriesList[obj.seriesIndex].prefetchInstanceCount
|
||||
// const instanceList = state.visitTaskList[index].StudyList[obj.studyIndex].SeriesList[obj.seriesIndex].instanceList
|
||||
// const idx = state.visitTaskList[index].StudyList.findIndex(i => i.IsCriticalSequence)
|
||||
|
||||
// if (!state.visitTaskList[index].StudyList[obj.studyIndex].IsCriticalSequence) {
|
||||
// // 当前下载的非关键序列
|
||||
// console.log('当前下载的非关键序列')
|
||||
// if (idx > -1) {
|
||||
// const keyInstance = state.visitTaskList[index].StudyList[idx].SeriesList[0].instanceList
|
||||
// obj.markedImages = getKeySeriesInfo(keyInstance, state.visitTaskList[index].StudyList[obj.studyIndex].SeriesList[obj.seriesIndex])
|
||||
// instanceList.map(i => {
|
||||
// if (obj.markedImages.hasOwnProperty(i) && state.visitTaskList[index].StudyList[idx].SeriesList[0].imageloadedArr.indexOf(i) < 0) {
|
||||
// state.visitTaskList[index].StudyList[idx].SeriesList[0].imageloadedArr.push(i)
|
||||
// state.visitTaskList[index].StudyList[idx].SeriesList[0].prefetchInstanceCount = state.visitTaskList[index].StudyList[idx].SeriesList[0].prefetchInstanceCount + 100
|
||||
// }
|
||||
// })
|
||||
// if (state.visitTaskList[index].StudyList[idx].SeriesList[0].imageloadedArr >= state.visitTaskList[index].StudyList[idx].SeriesList[0].instanceCount) {
|
||||
// state.visitTaskList[index].StudyList[idx].SeriesList[0].loadStatus = true
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// state.visitTaskList[index].StudyList[obj.studyIndex].SeriesList[obj.seriesIndex].prefetchInstanceCount = state.visitTaskList[index].StudyList[obj.studyIndex].SeriesList[obj.seriesIndex].instanceCount * 100
|
||||
// state.visitTaskList[index].StudyList[obj.studyIndex].SeriesList[obj.seriesIndex].imageloadedArr = instanceList
|
||||
// state.visitTaskList[index].StudyList[obj.studyIndex].SeriesList[obj.seriesIndex].loadStatus = true
|
||||
// const imageloadedArr = state.visitTaskList[index].StudyList[obj.studyIndex].SeriesList[obj.seriesIndex].imageloadedArr
|
||||
// if (imageloadedArr.indexOf())
|
||||
|
||||
// if (state.visitTaskList[index].StudyList[0].IsCriticalSequence){
|
||||
// state.visitTaskList[index].StudyList[0].SeriesList[0].prefetchInstanceCount = prefetchInstanceCount + 100
|
||||
// state.visitTaskList[index].StudyList[obj.studyIndex].SeriesList[obj.seriesIndex].imageloadedArr.push(obj.imageId)
|
||||
// }
|
||||
},
|
||||
setStatus({ state }, obj) {
|
||||
var index = state.visitTaskList.findIndex(i => i.VisitTaskId === obj.visitTaskId)
|
||||
state.visitTaskList[index].IsInit = true
|
||||
|
@ -861,7 +1082,15 @@ const actions = {
|
|||
},
|
||||
setLastCanvasTaskId({ state }, taskId) {
|
||||
return new Promise(resolve => {
|
||||
state.lastCanvasTaskId = taskId
|
||||
var isReadingTaskViewInOrder = localStorage.getItem('isReadingTaskViewInOrder')
|
||||
if (parseInt(isReadingTaskViewInOrder) === 2) {
|
||||
if (!state.lastCanvasTaskId) {
|
||||
console.log('setLastCanvasTaskId')
|
||||
state.lastCanvasTaskId = taskId
|
||||
}
|
||||
} else {
|
||||
state.lastCanvasTaskId = taskId
|
||||
}
|
||||
resolve()
|
||||
})
|
||||
},
|
||||
|
|
|
@ -0,0 +1,103 @@
|
|||
import * as cornerstoneWADOImageLoader from 'cornerstone-wado-image-loader'
|
||||
function parseImageId(imageId) {
|
||||
// build a url by parsing out the url scheme and frame index from the imageId
|
||||
const firstColonIndex = imageId.indexOf(':');
|
||||
|
||||
let url = imageId.substring(firstColonIndex + 1);
|
||||
const frameIndex = url.indexOf('frame=');
|
||||
|
||||
let frame;
|
||||
|
||||
if (frameIndex !== -1) {
|
||||
const frameStr = url.substr(frameIndex + 6);
|
||||
|
||||
frame = parseInt(frameStr, 10);
|
||||
url = url.substr(0, frameIndex - 1);
|
||||
}
|
||||
|
||||
return {
|
||||
scheme: imageId.substr(0, firstColonIndex),
|
||||
url,
|
||||
frame,
|
||||
};
|
||||
}
|
||||
function getNumberValues(dataSet, tag, minimumLength) {
|
||||
const values = [];
|
||||
const valueAsString = dataSet.string(tag);
|
||||
|
||||
if (!valueAsString) {
|
||||
return;
|
||||
}
|
||||
const split = valueAsString.split('\\');
|
||||
|
||||
if (minimumLength && split.length < minimumLength) {
|
||||
return;
|
||||
}
|
||||
for (let i = 0; i < split.length; i++) {
|
||||
values.push(parseFloat(split[i]));
|
||||
}
|
||||
|
||||
return values;
|
||||
}
|
||||
function metaDataProvider(type, imageId) {
|
||||
const parsedImageId = parseImageId(imageId);
|
||||
const dataSet = cornerstoneWADOImageLoader.wadouri.dataSetCacheManager.get(parsedImageId.url);
|
||||
|
||||
if (!dataSet) {
|
||||
return;
|
||||
}
|
||||
if (type === 'imagePlaneModule') {
|
||||
const imageOrientationPatient = getNumberValues(dataSet, 'x00200037', 6);
|
||||
const imagePositionPatient = getNumberValues(dataSet, 'x00200032', 3);
|
||||
const pixelSpacing = getNumberValues(dataSet, 'x00280030', 2);
|
||||
const imagePixelSpacing = getNumberValues(dataSet, 'x00181164', 2);
|
||||
const estimatedRadiographicMagnificationFactor = getNumberValues(dataSet, 'x00181114', 2);
|
||||
let columnPixelSpacing = null;
|
||||
|
||||
let rowPixelSpacing = null;
|
||||
|
||||
if (pixelSpacing) {
|
||||
rowPixelSpacing = pixelSpacing[0];
|
||||
columnPixelSpacing = pixelSpacing[1];
|
||||
} else if (imagePixelSpacing && estimatedRadiographicMagnificationFactor) {
|
||||
rowPixelSpacing = imagePixelSpacing[0] / estimatedRadiographicMagnificationFactor[0];
|
||||
columnPixelSpacing = imagePixelSpacing[1] / estimatedRadiographicMagnificationFactor[1];
|
||||
} else if (imagePixelSpacing && !estimatedRadiographicMagnificationFactor) {
|
||||
rowPixelSpacing = imagePixelSpacing[0];
|
||||
columnPixelSpacing = imagePixelSpacing[1];
|
||||
}
|
||||
|
||||
let rowCosines = null;
|
||||
|
||||
let columnCosines = null;
|
||||
|
||||
if (imageOrientationPatient) {
|
||||
rowCosines = [
|
||||
parseFloat(imageOrientationPatient[0]),
|
||||
parseFloat(imageOrientationPatient[1]),
|
||||
parseFloat(imageOrientationPatient[2]),
|
||||
];
|
||||
columnCosines = [
|
||||
parseFloat(imageOrientationPatient[3]),
|
||||
parseFloat(imageOrientationPatient[4]),
|
||||
parseFloat(imageOrientationPatient[5]),
|
||||
];
|
||||
}
|
||||
|
||||
return {
|
||||
frameOfReferenceUID: dataSet.string('x00200052'),
|
||||
rows: dataSet.uint16('x00280010'),
|
||||
columns: dataSet.uint16('x00280011'),
|
||||
imageOrientationPatient,
|
||||
rowCosines,
|
||||
columnCosines,
|
||||
imagePositionPatient,
|
||||
sliceThickness: dataSet.floatString('x00180050'),
|
||||
sliceLocation: dataSet.floatString('x00201041'),
|
||||
pixelSpacing,
|
||||
rowPixelSpacing,
|
||||
columnPixelSpacing,
|
||||
};
|
||||
}
|
||||
}
|
||||
export default metaDataProvider;
|
|
@ -8,10 +8,10 @@
|
|||
<!-- <div class="studyDesc" style="border-bottom:1px solid #9e9e9e;" @click="closeDialog()">
|
||||
<span style="font-size:14px;color:#d0d0d0;margin:5px 0px;line-height: 25px;">返回列表</span>
|
||||
</div> -->
|
||||
<div class="studyDesc" style="line-height: 10px;">
|
||||
<div class="studyDesc">
|
||||
{{ studyTitle }}
|
||||
</div>
|
||||
<div class="studyDesc" style="line-height: 10px">
|
||||
<div class="studyDesc">
|
||||
{{ seriesCount }} Series
|
||||
</div>
|
||||
<div class="viewerSidethumbs ps" style="position: relative;">
|
||||
|
@ -38,11 +38,12 @@
|
|||
</span>
|
||||
</span>-->
|
||||
<div class="viewernavitextwrapper">
|
||||
<div style="padding: 1px;">#{{ item.seriesTitle }}</div>
|
||||
<div style="padding: 1px;">#{{ item.seriesNumber }}</div>
|
||||
<div style="padding: 1px;">{{ item.description }}</div>
|
||||
<div
|
||||
v-show="item.instanceCount"
|
||||
style="padding: 1px;"
|
||||
>{{ item.instanceCount }} image
|
||||
>{{ item.modality }} : {{ item.instanceCount }} image
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -63,20 +64,24 @@
|
|||
import * as dicomParser from 'dicom-parser'
|
||||
import * as cornerstone from 'cornerstone-core'
|
||||
import * as cornerstoneWADOImageLoader from 'cornerstone-wado-image-loader'
|
||||
import dicomStore from '@/utils/dicom-store.js'
|
||||
// import dicomStore from '@/utils/dicom-store'
|
||||
import dicomViewer from '@/components/Dicom/DicomViewer'
|
||||
import dicomPreview from '@/components/Dicom/DicomPreview'
|
||||
|
||||
import metaDataProvider from '@/utils/metaDataProvider'
|
||||
cornerstone.metaData.addProvider(metaDataProvider, { priority: 10 });
|
||||
var config = {
|
||||
maxWebWorkers: 4,
|
||||
startWebWorkersOnDemand: true,
|
||||
taskConfiguration: {
|
||||
decodeTask: {
|
||||
initializeCodecsOnStartup: false
|
||||
}
|
||||
}
|
||||
}
|
||||
cornerstoneWADOImageLoader.webWorkerManager.initialize(config)
|
||||
cornerstoneWADOImageLoader.external.dicomParser = dicomParser
|
||||
cornerstoneWADOImageLoader.external.cornerstone = cornerstone
|
||||
// cornerstoneWADOImageLoader.webWorkerManager.initialize({
|
||||
// webWorkerPath: './webWorker.js',
|
||||
// taskConfiguration: {
|
||||
// decodeTask: {
|
||||
// codecsPath: './dicomCodecs.js'
|
||||
// }
|
||||
// }
|
||||
// })
|
||||
|
||||
export default {
|
||||
components: {
|
||||
dicomViewer,
|
||||
|
@ -86,6 +91,11 @@ export default {
|
|||
uid: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
studyList: {
|
||||
type: Array,
|
||||
// eslint-disable-next-line vue/require-valid-default-prop
|
||||
default: []
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -102,7 +112,7 @@ export default {
|
|||
var totalHeight = window.innerHeight || document.body.clientHeight
|
||||
var wrapper = this.$refs['preview-wrapper']
|
||||
wrapper.style.height = (totalHeight - 70) + 'px'
|
||||
if (!dicomStore.studyList || !this.uid) return
|
||||
if (!this.studyList || !this.uid) return
|
||||
this.loadStudy()
|
||||
},
|
||||
|
||||
|
@ -120,15 +130,14 @@ export default {
|
|||
return newObj
|
||||
},
|
||||
loadStudy() {
|
||||
var studyList = dicomStore.studyList
|
||||
var studyList = this.studyList
|
||||
var studyUid = this.uid
|
||||
var studyItem = studyList.find(function(item) {
|
||||
return item.dicomInfo.studyUid === studyUid
|
||||
})
|
||||
if (!studyItem) return
|
||||
|
||||
this.studyTitle =
|
||||
studyItem.dicomInfo.patientName || studyItem.dicomInfo.description
|
||||
this.studyTitle = studyItem.dicomInfo.description
|
||||
this.seriesCount = studyItem.seriesList.length
|
||||
var scope = this
|
||||
|
||||
|
@ -151,7 +160,8 @@ export default {
|
|||
|
||||
scope.seriesList.push({
|
||||
seriesNumber: series.seriesNumber,
|
||||
seriesTitle: series.description || series.modality || '(Anonymous)',
|
||||
description: series.description,
|
||||
modality: series.modality,
|
||||
instanceCount: series.instanceList.length,
|
||||
imageIds: imageIds,
|
||||
previewImageId: imageIds[0]
|
||||
|
@ -253,7 +263,7 @@ export default {
|
|||
text-align: center;
|
||||
background: rgb(88 84 83);
|
||||
color: #d0d0d0;
|
||||
padding: 2px;
|
||||
padding: 5px;
|
||||
}
|
||||
|
||||
.ps {
|
||||
|
|
|
@ -128,7 +128,7 @@ export default {
|
|||
// imageIds.push(`wadouri:/api/instance/content/${item}`)
|
||||
// })
|
||||
// seriesInfo.InstanceList.forEach((id) => {
|
||||
// imageIds.push(`wadouri:http://106.14.89.110:7000/instance/content/${id}`)
|
||||
// imageIds.push(`wadouri:http://123.56.94.154:7000/instance/content/${id}`)
|
||||
// })
|
||||
seriesInfo.InstancePathList.forEach((path) => {
|
||||
imageIds.push(`wadouri:${localStorage.getItem('location') !== 'USA' ? this.OSSclientConfig.basePath : this.OSSclientConfig.basePath}${path}`)
|
||||
|
|
|
@ -43,45 +43,73 @@
|
|||
fit="fill"
|
||||
>
|
||||
<div class="viewernavitextwrapper">
|
||||
<div v-if="item.keySeries" style="padding: 1px;color:red">
|
||||
Key Images
|
||||
</div>
|
||||
<div v-else style="padding: 1px;">
|
||||
#{{ item.seriesNumber }}
|
||||
<div style="padding: 1px 5px 1px 1px;display: flex;justify-content: space-between;">
|
||||
<div v-if="item.keySeries" style="color:red">
|
||||
Key Images
|
||||
</div>
|
||||
<div v-else>
|
||||
#{{ item.seriesNumber }}
|
||||
</div>
|
||||
<div v-if="item.isExistMutiFrames && item.instanceCount > 1">
|
||||
<el-popover
|
||||
placement="right"
|
||||
trigger="hover"
|
||||
popper-class="instance_frame_wrapper"
|
||||
>
|
||||
<div class="frame_list">
|
||||
<div
|
||||
v-for="(instance, idx) in item.instanceInfoList"
|
||||
:key="instance.Id"
|
||||
class="frame_content"
|
||||
:style="{'margin-bottom':idx<item.instanceInfoList.length-1? '5px':'0px'}"
|
||||
@click="showMultiFrames(item, index, instance)"
|
||||
>
|
||||
<div>
|
||||
<div>{{ instance.InstanceNumber }}</div>
|
||||
<div>{{ `${instance.NumberOfFrames > 0 ? instance.NumberOfFrames : 1} frame` }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<i slot="reference" class="el-icon-connection" style="font-size: 15px;cursor: pointer;" />
|
||||
</el-popover>
|
||||
</div>
|
||||
</div>
|
||||
<div v-show="item.instanceCount" style="padding: 1px;">
|
||||
{{ item.modality }}: {{ item.instanceCount }} image
|
||||
</div>
|
||||
<div v-show="!item.keySeries && item.sliceThickness" style="padding: 1px;">
|
||||
T: {{ item.sliceThickness }}
|
||||
T: {{ parseFloat(item.sliceThickness).toFixed(2) }}
|
||||
</div>
|
||||
<div v-show="!item.keySeries &&item.description" style="width: 120px;white-space: nowrap;overflow: hidden;text-overflow: ellipsis;padding: 1x;">
|
||||
{{ item.description }}
|
||||
</div>
|
||||
<div v-if="!item.keySeries" style="padding: 1px;">
|
||||
{{ item.prefetchInstanceCount }}/{{ item.instanceCount }}
|
||||
{{ item.imageloadedArr.length }}/{{ item.instanceCount }}
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="showDelete" @click.stop="">
|
||||
<div v-if="showDelete" style="display: flex;flex-direction: row;justify-content: space-between;" @click.stop="">
|
||||
|
||||
<span style="font-size: 12px;">{{ $t('trials:audit:table:isReading') }}</span>
|
||||
<el-switch
|
||||
v-model="item.isReading"
|
||||
size="mini"
|
||||
@change="changeReadingStatus($event, item)"
|
||||
/>
|
||||
|
||||
<span style="font-size: 12px;">{{ $t('trials:audit:table:isDelete') }}</span>
|
||||
<el-switch
|
||||
v-model="item.isDeleted"
|
||||
size="mini"
|
||||
@change="changeDeleteStatus($event, item)"
|
||||
/>
|
||||
<div>
|
||||
<span style="font-size: 12px;margin-right: 5px">{{ $t('trials:audit:table:isReading') }}</span>
|
||||
<el-switch
|
||||
v-model="item.isReading"
|
||||
size="mini"
|
||||
@change="changeReadingStatus($event, item)"
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<span style="font-size: 12px;margin-right: 5px">{{ $t('trials:audit:table:isDelete') }}</span>
|
||||
<el-switch
|
||||
v-model="item.isDeleted"
|
||||
size="mini"
|
||||
@change="changeDeleteStatus($event, item)"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="item.prefetchInstanceCount>0 && item.prefetchInstanceCount<item.instanceCount">
|
||||
<el-progress :percentage="parseInt(((item.prefetchInstanceCount/item.instanceCount)*100).toFixed(2))" />
|
||||
<div v-if="item.prefetchInstanceCount>0 && item.prefetchInstanceCount<item.instanceCount * 100">
|
||||
<el-progress :percentage="parseInt((item.prefetchInstanceCount/item.instanceCount).toFixed(2))" />
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
@ -110,13 +138,27 @@ import * as cornerstone from 'cornerstone-core'
|
|||
import * as cornerstoneWADOImageLoader from 'cornerstone-wado-image-loader'
|
||||
import dicomViewer from '@/components/Dicom/DicomViewer'
|
||||
import { getStudyInfo, getSeriesList } from '@/api/reading'
|
||||
import { getInstanceList, setSeriesStatus, getPatientSeriesList } from '@/api/trials'
|
||||
import { getInstanceList, getPatientSeriesList, setSeriesStatus } from '@/api/trials'
|
||||
|
||||
import requestPoolManager from '@/utils/request-pool'
|
||||
import store from '@/store'
|
||||
import { changeURLStatic } from '@/utils/history.js'
|
||||
import metaDataProvider from '@/utils/metaDataProvider'
|
||||
cornerstone.metaData.addProvider(metaDataProvider, { priority: 10 });
|
||||
var config = {
|
||||
maxWebWorkers: 4,
|
||||
startWebWorkersOnDemand: true,
|
||||
taskConfiguration: {
|
||||
decodeTask: {
|
||||
initializeCodecsOnStartup: false
|
||||
}
|
||||
}
|
||||
}
|
||||
cornerstoneWADOImageLoader.webWorkerManager.initialize(config)
|
||||
cornerstoneWADOImageLoader.external.dicomParser = dicomParser
|
||||
cornerstoneWADOImageLoader.external.cornerstone = cornerstone
|
||||
const maximumSizeInBytes = 1024 * 1024 * 1024 // 1 GB
|
||||
const maximumSizeInBytes = 1024 * 1024 * 1024 * 6
|
||||
cornerstone.imageCache.setMaximumSizeBytes(maximumSizeInBytes)
|
||||
export default {
|
||||
components: {
|
||||
'dicom-viewer': dicomViewer
|
||||
|
@ -151,20 +193,25 @@ export default {
|
|||
firstInstanceId: '',
|
||||
showDelete: false,
|
||||
loading: false,
|
||||
imageList: []
|
||||
imageList: [],
|
||||
showSeriesList: [],
|
||||
currentLoadIns: [],
|
||||
isFromCRCUpload: false
|
||||
}
|
||||
},
|
||||
created: function() {
|
||||
requestPoolManager.resetRequestPool()
|
||||
this.type = this.$router.currentRoute.query.type ? this.$router.currentRoute.query.type : ''
|
||||
|
||||
this.visitNum = this.$router.currentRoute.query.visitNum ? parseInt(this.$router.currentRoute.query.visitNum) : 0
|
||||
cornerstone.events.addEventListener('cornerstoneimageloaded', this.cornerstoneImageLoaded)
|
||||
// cornerstone.events.addEventListener('cornerstoneimageloaded', this.cornerstoneImageLoaded)
|
||||
// cornerstone.events.addEventListener('datasetscachechanged', this.datasetsCacheChanged)
|
||||
if (this.$router.currentRoute.query.TokenKey) {
|
||||
store.dispatch('user/setToken', this.$router.currentRoute.query.TokenKey)
|
||||
changeURLStatic('TokenKey', '')
|
||||
}
|
||||
this.studyId = this.$router.currentRoute.query.studyId
|
||||
this.isFromCRCUpload = !!this.$router.currentRoute.query.isFromCRCUpload
|
||||
if (this.type === 'Series') {
|
||||
// this.initStudy()
|
||||
this.showDelete = parseInt(this.$router.currentRoute.query.showDelete)
|
||||
|
@ -176,50 +223,63 @@ export default {
|
|||
this.loadStudy()
|
||||
} else if (this.type === 'Patient') {
|
||||
this.loadPatientStudy()
|
||||
}
|
||||
}
|
||||
cornerstone.events.addEventListener('cornerstoneimageloadprogress', this.cornerstoneimageloadprogress)
|
||||
window.addEventListener('beforeunload', e => {
|
||||
cornerstone.imageCache.purgeCache()
|
||||
requestPoolManager.resetRequestPool()
|
||||
})
|
||||
},
|
||||
beforeDestroy() {
|
||||
requestPoolManager.stopTaskTimer()
|
||||
window.removeEventListener('beforeunload', e => {
|
||||
cornerstone.imageCache.purgeCache()
|
||||
requestPoolManager.resetRequestPool()
|
||||
})
|
||||
},
|
||||
methods: {
|
||||
loadStudy() {
|
||||
var scope = this
|
||||
getStudyInfo(scope.studyId).then(data => {
|
||||
if (data.IsSuccess) {
|
||||
scope.studyCode = data.Result.StudyCode
|
||||
scope.modality = data.Result.Modalities
|
||||
scope.seriesCount = data.Result.SeriesCount
|
||||
scope.description = data.Result.Description
|
||||
var url = `/series/list/${scope.studyId}`
|
||||
scope.getSeriesList(url)
|
||||
async loadStudy() {
|
||||
const data = await getStudyInfo(this.studyId)
|
||||
if (data.IsSuccess) {
|
||||
if (data.Result) {
|
||||
this.studyCode = data.Result.StudyCode
|
||||
this.modality = data.Result.Modalities
|
||||
this.seriesCount = data.Result.SeriesCount
|
||||
this.description = data.Result.Description
|
||||
}
|
||||
})
|
||||
const url = `/series/list/${this.studyId}`
|
||||
this.getSeriesList(url)
|
||||
}
|
||||
},
|
||||
getSeriesList(url) {
|
||||
var scope = this
|
||||
getSeriesList(url).then(data => {
|
||||
async loadPatientStudy() {
|
||||
try {
|
||||
const data = await getPatientSeriesList(this.studyId)
|
||||
if (data.IsSuccess) {
|
||||
const { Result } = data
|
||||
var seriesList = []
|
||||
Result.forEach(function(item) {
|
||||
Result.forEach((item, index) => {
|
||||
const imageIds = []
|
||||
// item.InstanceList.forEach(function(id) {
|
||||
// imageIds.push(`wadouri:/api/instance/content/${id}`)
|
||||
// })
|
||||
// item.InstanceList.forEach((id) => {
|
||||
// imageIds.push(`wadouri:http://106.14.89.110:7000/instance/content/${id}`)
|
||||
// })
|
||||
item.InstancePathList.forEach((path) => {
|
||||
imageIds.push(`wadouri:${localStorage.getItem('location') !== 'USA' ? scope.OSSclientConfig.basePath : scope.OSSclientConfig.basePath}${path}`)
|
||||
item.InstanceInfoList.forEach(i => {
|
||||
if (i.NumberOfFrames && i.NumberOfFrames > 1) {
|
||||
for (let j = 0; j < i.NumberOfFrames; j++) {
|
||||
imageIds.push(`wadouri:${localStorage.getItem('location') !== 'USA' ? this.OSSclientConfig.basePath : this.OSSclientConfig.basePath}${i.Path}?frame=${j}&instanceId=${i.Id}&seriesIndex=${index}`)
|
||||
}
|
||||
i.ImageId = `wadouri:${localStorage.getItem('location') !== 'USA' ? this.OSSclientConfig.basePath : this.OSSclientConfig.basePath}${i.Path}?frame=0&instanceId=${i.Id}&seriesIndex=${index}`
|
||||
} else {
|
||||
const imageId = `wadouri:${localStorage.getItem('location') !== 'USA' ? this.OSSclientConfig.basePath : this.OSSclientConfig.basePath}${i.Path}?instanceId=${i.Id}&seriesIndex=${index}`
|
||||
imageIds.push(imageId)
|
||||
i.ImageId = imageId
|
||||
}
|
||||
})
|
||||
var subjectVisitId = scope.$router.currentRoute.query.subjectVisitId
|
||||
var studyId = scope.$router.currentRoute.query.studyId
|
||||
var trialId = scope.$router.currentRoute.query.trialId
|
||||
var subjectVisitId = this.$router.currentRoute.query.subjectVisitId
|
||||
var studyId = this.$router.currentRoute.query.studyId
|
||||
var trialId = this.$router.currentRoute.query.trialId
|
||||
seriesList.push({
|
||||
trialId,
|
||||
subjectVisitId,
|
||||
studyId,
|
||||
imageIds: imageIds,
|
||||
instanceInfoList: item.InstanceInfoList,
|
||||
seriesId: item.Id,
|
||||
seriesUid: item.SeriesInstanceUid,
|
||||
seriesNumber: item.SeriesNumber,
|
||||
|
@ -228,77 +288,99 @@ export default {
|
|||
description: item.Description,
|
||||
isReading: item.IsReading,
|
||||
isDeleted: item.IsDeleted,
|
||||
previewImageUrl: item.ImageResizePath ? scope.OSSclientConfig.basePath + item.ImageResizePath : `/api/series/preview/${item.Id}`,
|
||||
previewImageUrl: item.ImageResizePath ? this.OSSclientConfig.basePath + item.ImageResizePath : `/api/series/preview/${item.Id}`,
|
||||
instanceCount: item.InstanceCount,
|
||||
prefetchInstanceCount: 0,
|
||||
hasLabel: item.HasLabel,
|
||||
keySeries: item.KeySeries,
|
||||
tpCode: scope.tpCode,
|
||||
tpCode: this.tpCode,
|
||||
loadStatus: false,
|
||||
imageloadedArr: []
|
||||
})
|
||||
})
|
||||
scope.seriesList = seriesList
|
||||
if (scope.seriesList.length > 0) {
|
||||
scope.$refs.dicomViewer.loadImageStack(scope.seriesList[0], scope.labels[scope.tpCode])
|
||||
scope.firstInstanceId = scope.seriesList[0].imageIds[0]
|
||||
}
|
||||
}
|
||||
})
|
||||
},
|
||||
async loadPatientStudy() {
|
||||
try {
|
||||
let res = await getPatientSeriesList(this.studyId);
|
||||
if (res.IsSuccess && res.Result.length > 0) {
|
||||
console.log(res.Result)
|
||||
this.modality = res.OtherInfo.Modalities
|
||||
this.seriesCount = res.Result.length
|
||||
this.description = res.OtherInfo.Description
|
||||
this.seriesList = []
|
||||
res.Result.map(item=>{
|
||||
var imageIds = []
|
||||
item.InstancePathList.forEach(instance => {
|
||||
imageIds.push(`wadouri:${localStorage.getItem('location') !== 'USA' ? this.OSSclientConfig.basePath : this.OSSclientConfig.basePath}${instance}`)
|
||||
})
|
||||
this.seriesList.push({
|
||||
imageIds: imageIds,
|
||||
seriesId: item.SeriesInstanceUid,
|
||||
seriesUid: item.SeriesInstanceUid,
|
||||
seriesNumber:item.SeriesNumber,
|
||||
sliceThickness: item.SliceThickness,
|
||||
modality: item.Modality,
|
||||
description: item.Description,
|
||||
previewImageUrl: item.ImageResizePath ? this.OSSclientConfig.basePath + item.ImageResizePath : item.ImageResizePath,
|
||||
instanceCount: item.InstanceCount,
|
||||
prefetchInstanceCount: 0,
|
||||
loadStatus: false,
|
||||
imageloadedArr: []
|
||||
imageloadedArr: [],
|
||||
isExistMutiFrames: item.IsExistMutiFrames
|
||||
})
|
||||
})
|
||||
this.seriesList = seriesList
|
||||
if (this.seriesList.length > 0) {
|
||||
this.$nextTick(() => {
|
||||
this.loadAllImages()
|
||||
this.$refs.dicomViewer.loadImageStack(this.seriesList[0])
|
||||
this.firstInstanceId = this.seriesList[0].imageIds[0]
|
||||
})
|
||||
this.loadAllImages()
|
||||
this.$refs.dicomViewer.loadImageStack(this.seriesList[0], this.labels[this.tpCode])
|
||||
this.firstInstanceId = this.seriesList[0].imageIds[0]
|
||||
}
|
||||
}
|
||||
} catch (err) {
|
||||
console.log(err);
|
||||
console.log(err)
|
||||
}
|
||||
},
|
||||
initSeries() {
|
||||
var scope = this
|
||||
this.studyCode = this.$router.currentRoute.query.studyCode
|
||||
this.modality = this.$router.currentRoute.query.modality
|
||||
this.seriesCount = 1
|
||||
this.description = this.$router.currentRoute.query.description
|
||||
var seriesId = this.$router.currentRoute.query.seriesId
|
||||
var seriesNumber = this.$router.currentRoute.query.seriesNumber
|
||||
var subjectVisitId = this.$router.currentRoute.query.subjectVisitId
|
||||
var studyId = this.$router.currentRoute.query.studyId
|
||||
var trialId = this.$router.currentRoute.query.trialId
|
||||
getInstanceList(seriesId).then(res => {
|
||||
async getSeriesList(url) {
|
||||
try {
|
||||
const data = await getSeriesList(url)
|
||||
if (data.IsSuccess) {
|
||||
const { Result } = data
|
||||
var seriesList = []
|
||||
Result.forEach((item, index) => {
|
||||
const imageIds = []
|
||||
item.InstanceInfoList.forEach(i => {
|
||||
if (i.NumberOfFrames && i.NumberOfFrames > 1) {
|
||||
for (let j = 0; j < i.NumberOfFrames; j++) {
|
||||
imageIds.push(`wadouri:${localStorage.getItem('location') !== 'USA' ? this.OSSclientConfig.basePath : this.OSSclientConfig.basePath}${i.Path}?frame=${j}&instanceId=${i.Id}&seriesIndex=${index}`)
|
||||
}
|
||||
i.ImageId = `wadouri:${localStorage.getItem('location') !== 'USA' ? this.OSSclientConfig.basePath : this.OSSclientConfig.basePath}${i.Path}?frame=0&instanceId=${i.Id}&seriesIndex=${index}`
|
||||
} else {
|
||||
const imageId = `wadouri:${localStorage.getItem('location') !== 'USA' ? this.OSSclientConfig.basePath : this.OSSclientConfig.basePath}${i.Path}?instanceId=${i.Id}&seriesIndex=${index}`
|
||||
imageIds.push(imageId)
|
||||
i.ImageId = imageId
|
||||
}
|
||||
})
|
||||
var subjectVisitId = this.$router.currentRoute.query.subjectVisitId
|
||||
var studyId = this.$router.currentRoute.query.studyId
|
||||
var trialId = this.$router.currentRoute.query.trialId
|
||||
seriesList.push({
|
||||
trialId,
|
||||
subjectVisitId,
|
||||
studyId,
|
||||
imageIds: imageIds,
|
||||
instanceInfoList: item.InstanceInfoList,
|
||||
seriesId: item.Id,
|
||||
seriesUid: item.SeriesInstanceUid,
|
||||
seriesNumber: item.SeriesNumber,
|
||||
sliceThickness: item.SliceThickness,
|
||||
modality: item.Modality,
|
||||
description: item.Description,
|
||||
isReading: item.IsReading,
|
||||
isDeleted: item.IsDeleted,
|
||||
previewImageUrl: item.ImageResizePath ? this.OSSclientConfig.basePath + item.ImageResizePath : `/api/series/preview/${item.Id}`,
|
||||
instanceCount: item.InstanceCount,
|
||||
prefetchInstanceCount: 0,
|
||||
hasLabel: item.HasLabel,
|
||||
keySeries: item.KeySeries,
|
||||
tpCode: this.tpCode,
|
||||
loadStatus: false,
|
||||
imageloadedArr: [],
|
||||
isExistMutiFrames: item.IsExistMutiFrames
|
||||
})
|
||||
})
|
||||
this.seriesList = seriesList
|
||||
if (this.seriesList.length > 0) {
|
||||
this.loadAllImages()
|
||||
this.$refs.dicomViewer.loadImageStack(this.seriesList[0], this.labels[this.tpCode])
|
||||
this.firstInstanceId = this.seriesList[0].imageIds[0]
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
console.log(e)
|
||||
}
|
||||
},
|
||||
async initSeries() {
|
||||
try {
|
||||
this.studyCode = this.$router.currentRoute.query.studyCode
|
||||
this.modality = this.$router.currentRoute.query.modality
|
||||
this.seriesCount = 1
|
||||
this.description = this.$router.currentRoute.query.description
|
||||
var seriesId = this.$router.currentRoute.query.seriesId
|
||||
var seriesNumber = this.$router.currentRoute.query.seriesNumber
|
||||
var subjectVisitId = this.$router.currentRoute.query.subjectVisitId
|
||||
var studyId = this.$router.currentRoute.query.studyId
|
||||
var trialId = this.$router.currentRoute.query.trialId
|
||||
const res = await getInstanceList(seriesId)
|
||||
if (!res.Result || (res.Result && res.Result.length === 0)) return
|
||||
var seriesInstanceUid = res.Result[0].SeriesInstanceUid
|
||||
var sliceThickness = res.Result[0].SliceThickness
|
||||
|
@ -306,14 +388,29 @@ export default {
|
|||
var isDeleted = res.Result[0].IsDeleted
|
||||
var seriesList = []
|
||||
var imageIds = []
|
||||
let isExistMutiFrames = false
|
||||
const instanceInfoList = []
|
||||
res.Result.forEach(instance => {
|
||||
imageIds.push(`wadouri:${localStorage.getItem('location') !== 'USA' ? this.OSSclientConfig.basePath : this.OSSclientConfig.basePath}${instance.Path}`)
|
||||
let imageId = ''
|
||||
if (instance.NumberOfFrames > 1) {
|
||||
for (let i = 0; i < instance.NumberOfFrames; i++) {
|
||||
imageIds.push(`wadouri:${localStorage.getItem('location') !== 'USA' ? this.OSSclientConfig.basePath : this.OSSclientConfig.basePath}${instance.Path}?frame=${i}&instanceId=${instance.Id}&seriesIndex=0`)
|
||||
}
|
||||
isExistMutiFrames = true
|
||||
imageId = `wadouri:${localStorage.getItem('location') !== 'USA' ? this.OSSclientConfig.basePath : this.OSSclientConfig.basePath}${instance.Path}?frame=0&instanceId=${instance.Id}&seriesIndex=0`
|
||||
} else {
|
||||
const path = `wadouri:${localStorage.getItem('location') !== 'USA' ? this.OSSclientConfig.basePath : this.OSSclientConfig.basePath}${instance.Path}?instanceId=${instance.Id}&seriesIndex=0`
|
||||
imageIds.push(path)
|
||||
imageId = path
|
||||
}
|
||||
instanceInfoList.push({ Id: instance.Id, InstanceNumber: instance.InstanceNumber, NumberOfFrames: instance.NumberOfFrames, Path: instance.Path, ImageId: imageId })
|
||||
})
|
||||
seriesList.push({
|
||||
trialId,
|
||||
subjectVisitId,
|
||||
studyId,
|
||||
imageIds: imageIds,
|
||||
instanceInfoList,
|
||||
seriesId: seriesId,
|
||||
seriesUid: seriesInstanceUid,
|
||||
seriesNumber: seriesNumber,
|
||||
|
@ -322,11 +419,12 @@ export default {
|
|||
description: this.description,
|
||||
isReading,
|
||||
isDeleted,
|
||||
previewImageUrl: res.OtherInfo.ImageResizePath ? scope.OSSclientConfig.basePath + res.OtherInfo.ImageResizePath : res.OtherInfo.ImageResizePath,
|
||||
previewImageUrl: res.OtherInfo.ImageResizePath ? this.OSSclientConfig.basePath + res.OtherInfo.ImageResizePath : res.OtherInfo.ImageResizePath,
|
||||
instanceCount: res.Result.length,
|
||||
prefetchInstanceCount: 0,
|
||||
loadStatus: false,
|
||||
imageloadedArr: []
|
||||
imageloadedArr: [],
|
||||
isExistMutiFrames: isExistMutiFrames
|
||||
})
|
||||
this.seriesList = seriesList
|
||||
if (this.seriesList.length > 0) {
|
||||
|
@ -336,7 +434,9 @@ export default {
|
|||
this.firstInstanceId = this.seriesList[0].imageIds[0]
|
||||
})
|
||||
}
|
||||
})
|
||||
} catch (e) {
|
||||
console.log(e)
|
||||
}
|
||||
},
|
||||
showSeriesImage(e, seriesIndex, series) {
|
||||
// if (seriesIndex === this.currentSeriesIndex) return
|
||||
|
@ -350,16 +450,101 @@ export default {
|
|||
this.$refs.dicomViewer.loadImageStack(this.seriesList[seriesIndex])
|
||||
if (!series.loadStatus) {
|
||||
series.isLoading = true
|
||||
var p = new Date().getTime()
|
||||
series.imageIds.map((imageId, i) => {
|
||||
var priority = ''
|
||||
if (i === 0) {
|
||||
priority = new Date(new Date().setHours(23, 59, 59, 999)).getTime()
|
||||
var isAddToTakPool = false
|
||||
if (this.showSeriesList.includes(`0_${seriesIndex}`)) {
|
||||
isAddToTakPool = true
|
||||
} else {
|
||||
this.showSeriesList.push(`0_${seriesIndex}`)
|
||||
}
|
||||
if (!isAddToTakPool) {
|
||||
var priority = parseInt(new Date().getTime())
|
||||
// var images = []
|
||||
// if (series.isExistMutiFrames) {
|
||||
// images = series.imageIds.filter(i => i.includes('?frame=0'))
|
||||
// } else {
|
||||
// images = series.imageIds
|
||||
// }
|
||||
// images.map(imageId => {
|
||||
// this.imageList.push({ imageId: imageId, seriesId: series.seriesId, studyIndex: 0, seriesIndex: seriesIndex, priority })
|
||||
// })
|
||||
if (series.isExistMutiFrames) {
|
||||
series.instanceInfoList.map(image => {
|
||||
this.imageList.push({ imageId: image.ImageId, seriesId: series.seriesId, priority })
|
||||
})
|
||||
} else {
|
||||
priority = p - 1
|
||||
series.imageIds.map(imageId => {
|
||||
this.imageList.push({ imageId: imageId, seriesId: series.seriesId, priority })
|
||||
})
|
||||
}
|
||||
this.imageList.push({ imageId: imageId, seriesId: series.seriesId, priority })
|
||||
})
|
||||
if (this.imageList.length > 0) {
|
||||
this.loopLoad()
|
||||
}
|
||||
} else {
|
||||
requestPoolManager.changePriority(series.seriesId)
|
||||
}
|
||||
}
|
||||
},
|
||||
showMultiFrames(series, seriesIndex, instanceInfo) {
|
||||
this.currentSeriesIndex = seriesIndex
|
||||
const imageIds = []
|
||||
if (instanceInfo.NumberOfFrames && instanceInfo.NumberOfFrames > 1) {
|
||||
for (let j = 0; j < instanceInfo.NumberOfFrames; j++) {
|
||||
imageIds.push(`wadouri:${localStorage.getItem('location') !== 'USA' ? this.OSSclientConfig.basePath : this.OSSclientConfig.basePath}${instanceInfo.Path}?frame=${j}&instanceId=${instanceInfo.Id}&seriesIndex=${seriesIndex}`)
|
||||
}
|
||||
} else {
|
||||
imageIds.push(`wadouri:${localStorage.getItem('location') !== 'USA' ? this.OSSclientConfig.basePath : this.OSSclientConfig.basePath}${instanceInfo.Path}?instanceId=${instanceInfo.Id}&seriesIndex=${seriesIndex}`)
|
||||
}
|
||||
const seriesInfo = {
|
||||
trialId: series.trialId,
|
||||
subjectVisitId: series.subjectVisitId,
|
||||
studyId: series.studyId,
|
||||
imageIds: imageIds,
|
||||
seriesId: series.seriesId,
|
||||
seriesUid: series.seriesUid,
|
||||
seriesNumber: series.seriesNumber,
|
||||
sliceThickness: series.sliceThickness,
|
||||
modality: series.modality,
|
||||
description: series.description,
|
||||
isReading: series.isReading,
|
||||
isDeleted: series.isDeleted,
|
||||
previewImageUrl: series.previewImageUrl,
|
||||
instanceCount: series.instanceCount
|
||||
}
|
||||
this.$refs.dicomViewer.loadImageStack(seriesInfo)
|
||||
if (!series.loadStatus) {
|
||||
var isAddToTakPool = false
|
||||
if (this.showSeriesList.includes(`0_${seriesIndex}`)) {
|
||||
isAddToTakPool = true
|
||||
} else {
|
||||
this.showSeriesList.push(`0_${seriesIndex}`)
|
||||
}
|
||||
if (!isAddToTakPool) {
|
||||
var priority = parseInt(new Date().getTime())
|
||||
// if (series.isExistMutiFrames) {
|
||||
// series.instanceInfoList.map(image => {
|
||||
// this.imageList.push({ imageId: image.ImageId, seriesId: series.seriesId, studyIndex: 0, seriesIndex: seriesIndex, priority })
|
||||
// })
|
||||
// } else {
|
||||
// series.imageIds.map((imageId) => {
|
||||
// this.imageList.push({ imageId: imageId, seriesId: series.seriesId, studyIndex: 0, seriesIndex: seriesIndex, priority })
|
||||
// })
|
||||
// }
|
||||
if (series.isExistMutiFrames) {
|
||||
series.instanceInfoList.map(image => {
|
||||
this.imageList.push({ imageId: image.ImageId, seriesId: series.seriesId, priority })
|
||||
})
|
||||
} else {
|
||||
series.imageIds.map(imageId => {
|
||||
this.imageList.push({ imageId: imageId, seriesId: series.seriesId, priority })
|
||||
})
|
||||
}
|
||||
|
||||
if (this.imageList.length > 0) {
|
||||
this.loopLoad()
|
||||
}
|
||||
} else {
|
||||
requestPoolManager.changePriority(series.seriesId)
|
||||
}
|
||||
}
|
||||
},
|
||||
initStudy() {
|
||||
|
@ -371,13 +556,6 @@ export default {
|
|||
const seriesInfo = JSON.parse(this.$router.currentRoute.query.series)
|
||||
var seriesList = []
|
||||
const imageIds = []
|
||||
// const scope = this
|
||||
// seriesInfo.InstanceList.forEach(function(item) {
|
||||
// imageIds.push(`wadouri:/api/instance/content/${item}`)
|
||||
// })
|
||||
// seriesInfo.InstanceList.forEach((id) => {
|
||||
// imageIds.push(`wadouri:http://106.14.89.110:7000/instance/content/${id}`)
|
||||
// })
|
||||
seriesInfo.InstancePathList.forEach((path) => {
|
||||
imageIds.push(`wadouri:${localStorage.getItem('location') !== 'USA' ? this.OSSclientConfig.basePath : this.OSSclientConfig.basePath}${path}`)
|
||||
})
|
||||
|
@ -407,22 +585,25 @@ export default {
|
|||
}
|
||||
}
|
||||
},
|
||||
deleteSeries() {
|
||||
async deleteSeries() {
|
||||
this.loading = true
|
||||
var subjectVisitId = this.$router.currentRoute.query.subjectVisitId
|
||||
var studyId = this.$router.currentRoute.query.studyId
|
||||
var seriesId = this.$router.currentRoute.query.seriesId
|
||||
// trialId, subjectVisitId, studyId, seriesId, state
|
||||
setSeriesStatus(this.trialId, subjectVisitId, studyId, seriesId, 5).then(res => {
|
||||
try {
|
||||
const res = await setSeriesStatus(this.trialId, subjectVisitId, studyId, seriesId, 5)
|
||||
this.loading = false
|
||||
if (res.IsSuccess) {
|
||||
this.$message.success(this.$t('common:message:savedSuccessfully'))
|
||||
|
||||
window.opener.postMessage({ type: 'refreshSeriesList', data: '' }, window.location)
|
||||
}
|
||||
}).catch(() => { this.loading = false })
|
||||
} catch (e) {
|
||||
console.log(e)
|
||||
this.loading = false
|
||||
}
|
||||
},
|
||||
changeReadingStatus(callback, data) {
|
||||
async changeReadingStatus(callback, data) {
|
||||
let statusStr = ''
|
||||
if (callback) {
|
||||
statusStr = this.$t('trials:audit:label:setSeriesReading')
|
||||
|
@ -432,24 +613,31 @@ export default {
|
|||
data.isReading = true
|
||||
}
|
||||
var message = this.$t('trials:audit:message:changeSeriesStatus').replace('xxx', statusStr)
|
||||
this.$confirm(message, {
|
||||
distinguishCancelAndClose: true,
|
||||
type: 'warning'
|
||||
}).then(() => {
|
||||
const state = data.isReading ? 1 : 2
|
||||
this.loading = true
|
||||
|
||||
setSeriesStatus(data.trialId, data.subjectVisitId, data.studyId, data.seriesId, state).then(res => {
|
||||
this.loading = false
|
||||
if (res.IsSuccess) {
|
||||
data.isReading = !data.isReading
|
||||
this.$message.success(this.$t('common:message:savedSuccessfully'))
|
||||
window.opener.postMessage({ type: 'refreshSeriesList', data: '' }, window.location)
|
||||
}
|
||||
}).catch(() => { this.loading = false })
|
||||
}).catch(() => {})
|
||||
message = message.replace('yyy', this.$fd('YesOrNo', !data.isReading))
|
||||
const confirm = await this.$confirm(
|
||||
message,
|
||||
{
|
||||
type: 'warning',
|
||||
distinguishCancelAndClose: true
|
||||
}
|
||||
)
|
||||
if (confirm !== 'confirm') return
|
||||
const state = data.isReading ? 1 : 2
|
||||
this.loading = true
|
||||
try {
|
||||
const res = await setSeriesStatus(data.trialId, data.subjectVisitId, data.studyId, data.seriesId, state)
|
||||
this.loading = false
|
||||
if (res.IsSuccess) {
|
||||
data.isReading = !data.isReading
|
||||
this.$message.success(this.$t('common:message:savedSuccessfully'))
|
||||
window.opener.postMessage({ type: 'refreshSeriesList', data: '' }, window.location)
|
||||
}
|
||||
} catch (e) {
|
||||
console.log(e)
|
||||
this.loading = false
|
||||
}
|
||||
},
|
||||
changeDeleteStatus(callback, data) {
|
||||
async changeDeleteStatus(callback, data) {
|
||||
let statusStr = ''
|
||||
if (callback) {
|
||||
statusStr = this.$t('trials:audit:label:setSeriesDeleted')
|
||||
|
@ -459,88 +647,76 @@ export default {
|
|||
data.isDeleted = true
|
||||
}
|
||||
var message = this.$t('trials:audit:message:changeSeriesStatus').replace('xxx', statusStr)
|
||||
this.$confirm(message, {
|
||||
distinguishCancelAndClose: true,
|
||||
type: 'warning'
|
||||
}).then(() => {
|
||||
const state = data.isDeleted ? 5 : 4
|
||||
this.loading = true
|
||||
// var trialId = this.$router.currentRoute.query.trialId
|
||||
// var subjectVisitId = this.$router.currentRoute.query.subjectVisitId
|
||||
// var studyId = this.$router.currentRoute.query.studyId
|
||||
// var seriesId = this.$router.currentRoute.query.seriesId
|
||||
setSeriesStatus(data.trialId, data.subjectVisitId, data.studyId, data.seriesId, state).then(res => {
|
||||
this.loading = false
|
||||
if (res.IsSuccess) {
|
||||
data.isDeleted = !data.isDeleted
|
||||
this.$message.success(this.$t('common:message:savedSuccessfully'))
|
||||
window.opener.postMessage({ type: 'refreshSeriesList', data: '' }, window.location)
|
||||
}
|
||||
}).catch(() => { this.loading = false })
|
||||
}).catch(() => {})
|
||||
message = message.replace('yyy', this.$fd('YesOrNo', !data.isDeleted))
|
||||
const confirm = await this.$confirm(
|
||||
message,
|
||||
{
|
||||
type: 'warning',
|
||||
distinguishCancelAndClose: true
|
||||
}
|
||||
)
|
||||
if (confirm !== 'confirm') return
|
||||
const state = data.isDeleted ? 5 : 4
|
||||
this.loading = true
|
||||
try {
|
||||
const res = await setSeriesStatus(data.trialId, data.subjectVisitId, data.studyId, data.seriesId, state)
|
||||
this.loading = false
|
||||
if (res.IsSuccess) {
|
||||
data.isDeleted = !data.isDeleted
|
||||
this.$message.success(this.$t('common:message:savedSuccessfully'))
|
||||
window.opener.postMessage({ type: 'refreshSeriesList', data: '' }, window.location)
|
||||
}
|
||||
} catch (e) {
|
||||
console.log(e)
|
||||
this.loading = false
|
||||
}
|
||||
},
|
||||
loadAllImages() {
|
||||
const seriesIndex = this.seriesList.findIndex(i => i.loadStatus === false)
|
||||
if (seriesIndex === -1) return
|
||||
const series = this.seriesList[seriesIndex]
|
||||
var priority = new Date().getTime()
|
||||
this.seriesList.forEach(series => {
|
||||
series.imageIds.forEach(imageId => {
|
||||
priority--
|
||||
// this.load(imageId, series.seriesId, priority)
|
||||
// var images = []
|
||||
// if (series.isExistMutiFrames) {
|
||||
// images = series.imageIds.filter(i => i.includes('?frame=0'))
|
||||
// } else {
|
||||
// images = series.imageIds
|
||||
// }
|
||||
// images.map(imageId => {
|
||||
// this.imageList.push({ imageId: imageId, seriesId: series.seriesId, studyIndex: 0, seriesIndex: seriesIndex, priority })
|
||||
// })
|
||||
if (series.isExistMutiFrames) {
|
||||
series.instanceInfoList.map(image => {
|
||||
this.imageList.push({ imageId: image.ImageId, seriesId: series.seriesId, priority })
|
||||
})
|
||||
} else {
|
||||
series.imageIds.map(imageId => {
|
||||
this.imageList.push({ imageId: imageId, seriesId: series.seriesId, priority })
|
||||
})
|
||||
})
|
||||
}
|
||||
if (this.imageList.length > 0) {
|
||||
this.loopLoad()
|
||||
}
|
||||
},
|
||||
getInstanceInfo(imageId) {
|
||||
const params = {}
|
||||
const searchParams = new URLSearchParams(imageId.split('?')[1])
|
||||
for (const [key, value] of searchParams.entries()) {
|
||||
params[key] = value
|
||||
}
|
||||
return params
|
||||
},
|
||||
loopLoad() {
|
||||
if (this.imageList.length > 0) {
|
||||
requestPoolManager.startTaskTimer()
|
||||
console.log('loopLoad')
|
||||
this.imageList.map(image => {
|
||||
requestPoolManager.loadAndCacheImagePlus(image.imageId, image.seriesId, image.priority).then(res => {
|
||||
this.imageLoaded(image, res.data.string('x0020000e'))
|
||||
})
|
||||
requestPoolManager.loadAndCacheImagePlus(image.imageId, image.seriesId, image.priority)
|
||||
})
|
||||
|
||||
requestPoolManager.sortTaskPool()
|
||||
this.imageList = []
|
||||
}
|
||||
},
|
||||
load(imageId, seriesId, priority = 999) {
|
||||
return new Promise((resolve, reject) => {
|
||||
requestPoolManager.loadAndCacheImagePlus(imageId, seriesId, priority).then(res => {
|
||||
if (!res) return
|
||||
this.imageLoaded(imageId, res.data.string('x0020000e'))
|
||||
resolve(res)
|
||||
}).catch(e => {
|
||||
reject(e)
|
||||
})
|
||||
})
|
||||
},
|
||||
imageLoaded(imageId, seriesUid) {
|
||||
var seriesIndex = -1
|
||||
for (let i = 0; i < this.seriesList.length; ++i) {
|
||||
if (this.seriesList[i].seriesUid === seriesUid) {
|
||||
seriesIndex = i
|
||||
break
|
||||
}
|
||||
}
|
||||
if (seriesIndex < 0) return
|
||||
|
||||
const imageIdIndex = this.seriesList[seriesIndex].imageIds.indexOf(imageId)
|
||||
if (imageIdIndex < 0) return
|
||||
if (this.seriesList[seriesIndex].imageloadedArr.indexOf(imageId) < 0) {
|
||||
++this.seriesList[seriesIndex].prefetchInstanceCount
|
||||
this.seriesList[seriesIndex].imageloadedArr.push(imageId)
|
||||
|
||||
if (this.seriesList[seriesIndex].prefetchInstanceCount >= this.seriesList[seriesIndex].instanceCount) {
|
||||
this.seriesList[seriesIndex].prefetchInstanceCount = this.seriesList[seriesIndex].instanceCount
|
||||
// 设置当前序列状态为已下载完成
|
||||
this.seriesList[seriesIndex].loadStatus = true
|
||||
// if (!this.isLoadedAll) {
|
||||
// this.loadAllImages()
|
||||
// }
|
||||
}
|
||||
}
|
||||
},
|
||||
datasetsCacheChanged(e) {
|
||||
// const uri = e.detail.uri
|
||||
const cacheInfo = e.detail.cacheInfo
|
||||
|
@ -564,48 +740,44 @@ export default {
|
|||
|
||||
return 0
|
||||
},
|
||||
cornerstoneImageLoaded(e) {
|
||||
if (this.firstInstanceId === e.detail.image.imageId && !this.isStartLoad) {
|
||||
// 初始化图像加载完成时,自动下载
|
||||
this.loadAllImages()
|
||||
this.isStartLoad = true
|
||||
// requestPoolManager.executeTask()
|
||||
cornerstoneimageloadprogress(e) {
|
||||
const imageId = e.detail.imageId
|
||||
const percentComplete = e.detail.percentComplete
|
||||
const params = {}
|
||||
const searchParams = new URLSearchParams(imageId.split('?')[1])
|
||||
for (const [key, value] of searchParams.entries()) {
|
||||
params[key] = value
|
||||
}
|
||||
const uri = e.detail.image.sharedCacheKey
|
||||
const index = this.cachedImages.findIndex(item => item.uri === uri)
|
||||
if (index === -1) {
|
||||
this.cachedImages.push({ uri: uri, timestamp: new Date().getTime() })
|
||||
} else {
|
||||
this.cachedImages[index].timestamp = new Date().getTime()
|
||||
}
|
||||
// loadedDataSets[uri].dataSet.byteArray.length
|
||||
// console.log(this.cachedImages.length)
|
||||
// console.log(cornerstoneWADOImageLoader.wadouri.dataSetCacheManager.getInfo().cacheSizeInBytes)
|
||||
// const imageId = e.detail.image.imageId
|
||||
var imageId = e.detail.image.imageId
|
||||
var seriesUid = e.detail.image.data.string('x0020000e')
|
||||
var seriesIndex = -1
|
||||
for (let i = 0; i < this.seriesList.length; ++i) {
|
||||
if (this.seriesList[i].seriesUid === seriesUid) {
|
||||
seriesIndex = i
|
||||
break
|
||||
if (this.visitTaskId === params.visitTaskId) {
|
||||
const seriesIndex = params.seriesIndex
|
||||
var prefetchInstanceCount = this.seriesList[seriesIndex].prefetchInstanceCount
|
||||
var instanceCount = this.seriesList[seriesIndex].instanceCount
|
||||
if (this.seriesList[seriesIndex].imageloadedArr.indexOf(imageId) < 0 && this.seriesList[seriesIndex].imageloadedArr.length < this.seriesList[seriesIndex].instanceCount) {
|
||||
const i = this.currentLoadIns.findIndex(i => i.imageId === imageId)
|
||||
if (i > -1) {
|
||||
prefetchInstanceCount = prefetchInstanceCount - this.currentLoadIns[i].percentComplete + percentComplete
|
||||
this.currentLoadIns[i].percentComplete = percentComplete
|
||||
if (percentComplete === 100) {
|
||||
this.currentLoadIns.splice(i, 1)
|
||||
}
|
||||
} else {
|
||||
if (percentComplete !== 100) {
|
||||
this.currentLoadIns.push({ imageId, percentComplete })
|
||||
}
|
||||
prefetchInstanceCount = prefetchInstanceCount + percentComplete
|
||||
}
|
||||
this.seriesList[seriesIndex].prefetchInstanceCount = prefetchInstanceCount
|
||||
if (percentComplete >= 100) {
|
||||
this.seriesList[seriesIndex].imageloadedArr.push(imageId)
|
||||
}
|
||||
}
|
||||
}
|
||||
if (seriesIndex < 0) return
|
||||
|
||||
const imageIdIndex = this.seriesList[seriesIndex].imageIds.indexOf(imageId)
|
||||
if (imageIdIndex < 0) return
|
||||
if (this.seriesList[seriesIndex].imageloadedArr.indexOf(imageId) < 0) {
|
||||
++this.seriesList[seriesIndex].prefetchInstanceCount
|
||||
this.seriesList[seriesIndex].imageloadedArr.push(imageId)
|
||||
|
||||
if (this.seriesList[seriesIndex].prefetchInstanceCount >= this.seriesList[seriesIndex].instanceCount) {
|
||||
this.seriesList[seriesIndex].prefetchInstanceCount = this.seriesList[seriesIndex].instanceCount
|
||||
if (prefetchInstanceCount >= instanceCount * 100) {
|
||||
this.seriesList[seriesIndex].prefetchInstanceCount = instanceCount * 100
|
||||
// 设置当前序列状态为已下载完成
|
||||
this.seriesList[seriesIndex].loadStatus = true
|
||||
// if (!this.isLoadedAll) {
|
||||
// this.loadAllImages()
|
||||
// }
|
||||
if (!this.isFromCRCUpload) {
|
||||
this.loadAllImages()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -710,7 +882,7 @@ export default {
|
|||
}
|
||||
.viewerContainer .viewerLeftSidePanel .viewernavigatorwrapper {
|
||||
display: flex;
|
||||
width: 210px;
|
||||
width: 200px;
|
||||
height: 84px;
|
||||
padding: 1px 2px 1px 8px;
|
||||
margin: 6px 0 6px 1px;
|
||||
|
@ -757,6 +929,41 @@ export default {
|
|||
color: #D0D0D0;
|
||||
font-size: 13px;
|
||||
}
|
||||
.instance_frame_wrapper{
|
||||
min-width: 120px;
|
||||
background-color: #2c2c2c;
|
||||
border: 1px solid #2c2c2c;
|
||||
padding: 5px;
|
||||
}
|
||||
.frame_list{
|
||||
max-height: 500px;
|
||||
overflow-y: auto;
|
||||
}
|
||||
.instance_frame_wrapper ::-webkit-scrollbar {
|
||||
width: 7px;
|
||||
height: 7px;
|
||||
}
|
||||
.instance_frame_wrapper ::-webkit-scrollbar-thumb {
|
||||
border-radius: 10px;
|
||||
background: #d0d0d0;
|
||||
}
|
||||
.frame_content{
|
||||
height: 50px;
|
||||
padding: 5px;
|
||||
display: flex;
|
||||
justify-content: flex-start;
|
||||
color: #ddd;
|
||||
font-size: 12px;
|
||||
border: 1px solid #404040;
|
||||
}
|
||||
.frame_content:hover {
|
||||
/* font-weight: bold; */
|
||||
/* box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1); */
|
||||
cursor: pointer;
|
||||
/* color: #428bca; */
|
||||
border-color: #213a54 !important;
|
||||
background-color: #213a54;
|
||||
}
|
||||
/* .viewerRightSidePanel {
|
||||
width: 300px;
|
||||
height: 100%;
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,30 +1,43 @@
|
|||
<template>
|
||||
<div class="adReview_wrapper">
|
||||
<el-card v-if="isReadingShowSubjectInfo" shadow="never" :body-style="{ padding: '10px' }" style="margin-bottom:10px">
|
||||
<el-card
|
||||
v-if="isReadingShowSubjectInfo"
|
||||
shadow="never"
|
||||
:body-style="{ padding: '10px' }"
|
||||
style="margin-bottom: 10px"
|
||||
>
|
||||
<h4>
|
||||
<!-- 受试者: -->
|
||||
{{ $t('trials:adReview:title:subject') }}
|
||||
<span style="font-weight:normal">{{ subjectCode }} </span>
|
||||
<span style="font-weight:normal">({{ taskBlindName }})</span>
|
||||
{{ $t("trials:adReview:title:subject") }}
|
||||
<span style="font-weight: normal">{{ subjectCode }} </span>
|
||||
<span style="font-weight: normal">({{ taskBlindName }})</span>
|
||||
</h4>
|
||||
</el-card>
|
||||
<el-card :body-style="{ padding: '10px' }" shadow="never">
|
||||
<!-- <div slot="header" class="clearfix">
|
||||
<span style="font-weight: bold;">评估结果</span>
|
||||
</div> -->
|
||||
<div slot="header" style="display: flex;flex-direction: row;justify-content: space-between;">
|
||||
<div
|
||||
slot="header"
|
||||
style="
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: space-between;
|
||||
"
|
||||
>
|
||||
<!-- 评估结果 -->
|
||||
<div style="font-weight: bold;">{{ $t('trials:adReview:title:result') }}</div>
|
||||
<div style="font-weight: bold">
|
||||
{{ $t("trials:adReview:title:result") }}
|
||||
</div>
|
||||
<div v-if="isExistsClinicalData">
|
||||
<!-- 临床数据 -->
|
||||
<el-button type="text" @click="previewCD">{{ $t('trials:adReview:title:clinicalData') }}</el-button>
|
||||
<el-button type="text" @click="previewCD">{{
|
||||
$t("trials:adReview:title:clinicalData")
|
||||
}}</el-button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<el-table
|
||||
:data="adInfo.VisitInfoList"
|
||||
style="width: 100%"
|
||||
>
|
||||
<el-table :data="adInfo.VisitInfoList" style="width: 100%">
|
||||
<!-- 访视名称 -->
|
||||
<el-table-column
|
||||
prop="VisitName"
|
||||
|
@ -37,13 +50,19 @@
|
|||
<el-table-column
|
||||
v-for="j in judgeQuestion"
|
||||
:key="j.armEnum"
|
||||
:label="j.armEnum===1?$t('trials:adReview:table:viewR1'):j.armEnum===2?$t('trials:adReview:table:viewR2'):$fd('ArmEnum', j.armEnum)"
|
||||
:label="
|
||||
j.armEnum === 1
|
||||
? $t('trials:adReview:table:viewR1')
|
||||
: j.armEnum === 2
|
||||
? $t('trials:adReview:table:viewR2')
|
||||
: $fd('ArmEnum', j.armEnum)
|
||||
"
|
||||
align="center"
|
||||
prop=""
|
||||
>
|
||||
<template>
|
||||
<el-table-column
|
||||
v-for="(qs,i) in j.judgeQuestionList"
|
||||
v-for="(qs, i) in j.judgeQuestionList"
|
||||
:key="i"
|
||||
prop=""
|
||||
:label="qs"
|
||||
|
@ -51,28 +70,49 @@
|
|||
width="150"
|
||||
>
|
||||
<template slot-scope="scope">
|
||||
<div v-if="scope.row.VisitTaskInfoList[j.index].JudgeQuestionList[i].QuestionType===1">
|
||||
<span v-if="scope.row.VisitTaskInfoList[j.index].JudgeQuestionList[i].DictionaryCode">{{ $fd(scope.row.VisitTaskInfoList[j.index].JudgeQuestionList[i].DictionaryCode, parseInt(scope.row.VisitTaskInfoList[j.index].JudgeQuestionList[i].Answer )) }}</span>
|
||||
<span v-else>{{ scope.row.VisitTaskInfoList[j.index].JudgeQuestionList[i].Answer }}</span>
|
||||
<div v-if="scope.row.VisitTaskInfoList[j.index].JudgeQuestionList[i].QuestionType === 1">
|
||||
<span v-if="scope.row.VisitTaskInfoList[j.index].JudgeQuestionList[i].DictionaryCode">
|
||||
{{ $fd(scope.row.VisitTaskInfoList[j.index].JudgeQuestionList[i].DictionaryCode,parseInt(scope.row.VisitTaskInfoList[j.index].JudgeQuestionList[i].Answer))
|
||||
}}
|
||||
</span>
|
||||
<span v-else>
|
||||
{{ scope.row.VisitTaskInfoList[j.index].JudgeQuestionList[i].Answer }}
|
||||
</span>
|
||||
<span v-if="scope.row.VisitTaskInfoList[j.index].JudgeQuestionList[i].Unit && !isNaN(parseFloat(scope.row.VisitTaskInfoList[j.index].JudgeQuestionList[i].Answer))">{{ $fd('ValueUnit', parseInt(scope.row.VisitTaskInfoList[j.index].JudgeQuestionList[i].Unit)) }}</span>
|
||||
</div>
|
||||
<div v-else-if="scope.row.VisitTaskInfoList[j.index].JudgeQuestionList[i].QuestionType===2">
|
||||
<div v-else-if="scope.row.VisitTaskInfoList[j.index].JudgeQuestionList[i].QuestionType === 2">
|
||||
<div v-if="scope.row.VisitTaskInfoList[j.index].JudgeQuestionList[i].Answer">
|
||||
<span>{{ $fd('YesOrNo', scope.row.VisitTaskInfoList[j.index].JudgeQuestionList[i].Answer ) }}</span>
|
||||
<span>
|
||||
{{ $fd("YesOrNo",scope.row.VisitTaskInfoList[j.index].JudgeQuestionList[i].Answer) }}
|
||||
</span>
|
||||
<!-- 查看详情 -->
|
||||
<el-button
|
||||
type="text"
|
||||
style="margin-left:5px;"
|
||||
@click="handleViewDetail(scope.row.VisitTaskInfoList[j.index].GlobalVisitTaskId)"
|
||||
style="margin-left: 5px"
|
||||
@click="
|
||||
handleViewDetail(
|
||||
scope.row.VisitTaskInfoList[j.index].GlobalVisitTaskId
|
||||
)
|
||||
"
|
||||
>
|
||||
{{ $t('trials:adReview:table:view') }}
|
||||
{{ $t("trials:adReview:table:view") }}
|
||||
</el-button>
|
||||
</div>
|
||||
|
||||
<div v-else>
|
||||
{{ $fd('YesOrNo', scope.row.VisitTaskInfoList[j.index].JudgeQuestionList[i].Answer ) }}
|
||||
{{
|
||||
$fd(
|
||||
"YesOrNo",
|
||||
scope.row.VisitTaskInfoList[j.index].JudgeQuestionList[
|
||||
i
|
||||
].Answer
|
||||
)
|
||||
}}
|
||||
</div>
|
||||
</div>
|
||||
<div v-else>{{ scope.row.VisitTaskInfoList[j.index].JudgeQuestionList[i].Answer }}</div>
|
||||
<div v-else>
|
||||
{{ scope.row.VisitTaskInfoList[j.index].JudgeQuestionList[i].Answer }}
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</template>
|
||||
|
@ -80,16 +120,20 @@
|
|||
|
||||
<!-- 查看详情 -->
|
||||
<el-table-column
|
||||
:label="criterionType === 10?$t('trials:adReview:table:visitInfoview'):$t('trials:adReview:table:view')"
|
||||
:label="
|
||||
criterionType === 10
|
||||
? $t('trials:adReview:table:visitInfoview')
|
||||
: $t('trials:adReview:table:view')
|
||||
"
|
||||
width="200"
|
||||
:fixed="isFixed ? 'right' : false"
|
||||
>
|
||||
<template slot-scope="scope">
|
||||
|
||||
<!-- 查看R1详情 -->
|
||||
<el-button
|
||||
type="text"
|
||||
:title="$t('trials:adReview:table:viewR1')"
|
||||
@click="handleView(scope.row,1)"
|
||||
@click="handleView(scope.row, 1)"
|
||||
>
|
||||
R1
|
||||
</el-button>
|
||||
|
@ -97,7 +141,7 @@
|
|||
<el-button
|
||||
type="text"
|
||||
:title="$t('trials:adReview:table:viewR2')"
|
||||
@click="handleView(scope.row,2)"
|
||||
@click="handleView(scope.row, 2)"
|
||||
>
|
||||
R2
|
||||
</el-button>
|
||||
|
@ -115,19 +159,19 @@
|
|||
<template slot-scope="scope">
|
||||
<!-- 查看R1详情 -->
|
||||
<el-button
|
||||
v-if="scope.$index === adInfo.VisitInfoList.length -1"
|
||||
v-if="scope.$index === adInfo.VisitInfoList.length - 1"
|
||||
type="text"
|
||||
:title="$t('trials:adReview:table:viewR1')"
|
||||
@click="handleViewGl(scope.row,1)"
|
||||
@click="handleViewGl(scope.row, 1)"
|
||||
>
|
||||
R1
|
||||
</el-button>
|
||||
<!-- 查看R2详情 -->
|
||||
<el-button
|
||||
v-if="scope.$index === adInfo.VisitInfoList.length -1"
|
||||
v-if="scope.$index === adInfo.VisitInfoList.length - 1"
|
||||
type="text"
|
||||
:title="$t('trials:adReview:table:viewR2')"
|
||||
@click="handleViewGl(scope.row,2)"
|
||||
@click="handleViewGl(scope.row, 2)"
|
||||
>
|
||||
R2
|
||||
</el-button>
|
||||
|
@ -138,13 +182,15 @@
|
|||
<el-card :body-style="{ padding: '10px' }" class="box-mr">
|
||||
<div slot="header" class="clearfix">
|
||||
<!-- 裁判结果 -->
|
||||
<span style="font-weight: bold;">{{ $t('trials:adReview:title:adResult') }}</span>
|
||||
<span style="font-weight: bold">{{
|
||||
$t("trials:adReview:title:adResult")
|
||||
}}</span>
|
||||
</div>
|
||||
<el-form
|
||||
ref="adForm"
|
||||
v-loading="loading"
|
||||
:model="adForm"
|
||||
style="width:800px"
|
||||
style="width: 800px"
|
||||
label-width="100"
|
||||
>
|
||||
<!-- 选择阅片人 -->
|
||||
|
@ -152,7 +198,7 @@
|
|||
:label="$t('trials:adReview:title:choseReader')"
|
||||
prop="judgeResultTaskId"
|
||||
:rules="[
|
||||
{ required: true, message: this.$t('common:ruleMessage:select')},
|
||||
{ required: true, message: this.$t('common:ruleMessage:select') },
|
||||
]"
|
||||
>
|
||||
<el-radio-group
|
||||
|
@ -165,7 +211,7 @@
|
|||
:label="t.VisitTaskId"
|
||||
@change="handleVisitTaskArmChange"
|
||||
>
|
||||
{{ $fd('ArmEnum', t.ArmEnum) }}
|
||||
{{ $fd("ArmEnum", t.ArmEnum) }}
|
||||
</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
|
@ -174,87 +220,121 @@
|
|||
:label="$t('trials:adReview:title:adReason')"
|
||||
prop="judgeResultRemark"
|
||||
:rules="[
|
||||
{ required: true, message: this.$t('common:ruleMessage:specify')},
|
||||
{ max: 500, message: `${this.$t('common:ruleMessage:maxLength')} 500`, trigger: ['blur', 'change'] }
|
||||
{ required: true, message: this.$t('common:ruleMessage:specify') },
|
||||
{
|
||||
max: 500,
|
||||
message: `${this.$t('common:ruleMessage:maxLength')} 500`,
|
||||
trigger: ['blur', 'change'],
|
||||
},
|
||||
]"
|
||||
>
|
||||
<el-input
|
||||
v-model="adForm.judgeResultRemark"
|
||||
type="textarea"
|
||||
:autosize="{ minRows: 4, maxRows: 6}"
|
||||
:disabled="adInfo.ReadingTaskState >= 2"
|
||||
/>
|
||||
<div style="position: relative">
|
||||
<div
|
||||
style="
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 30px;
|
||||
color: #606266;
|
||||
font-size: 13px;
|
||||
"
|
||||
>
|
||||
{{ remark }}
|
||||
</div>
|
||||
<el-input
|
||||
v-model="adForm.judgeResultRemark"
|
||||
type="textarea"
|
||||
:autosize="{ minRows: 4, maxRows: 6 }"
|
||||
:disabled="adInfo.ReadingTaskState >= 2"
|
||||
style="margin-top: 25px"
|
||||
/>
|
||||
</div>
|
||||
</el-form-item>
|
||||
<!-- 截图说明 -->
|
||||
<el-form-item
|
||||
:label="$t('trials:adReview:title:screenShot')"
|
||||
>
|
||||
<el-form-item :label="$t('trials:adReview:title:screenShot')">
|
||||
<el-upload
|
||||
:action="accept"
|
||||
action
|
||||
:accept="accept"
|
||||
:on-preview="handlePictureCardPreview"
|
||||
:before-upload="handleBeforeUpload"
|
||||
:http-request="uploadScreenshot"
|
||||
list-type="picture-card"
|
||||
:on-remove="handleRemove"
|
||||
:file-list="fileList"
|
||||
:class="{disabled:adInfo.ReadingTaskState >= 2}"
|
||||
:class="{ disabled: adInfo.ReadingTaskState >= 2 }"
|
||||
:disabled="adInfo.ReadingTaskState >= 2"
|
||||
>
|
||||
<i slot="default" class="el-icon-plus" />
|
||||
<div slot="file" slot-scope="{file}">
|
||||
<img
|
||||
class="el-upload-list__item-thumbnail"
|
||||
crossOrigin="Anonymous"
|
||||
:src="OSSclientConfig.basePath + file.url"
|
||||
alt=""
|
||||
<div
|
||||
slot="file"
|
||||
slot-scope="{ file }"
|
||||
style="width: 100%; height: 100%"
|
||||
>
|
||||
<viewer
|
||||
:ref="file.url"
|
||||
:images="images"
|
||||
style="
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
"
|
||||
>
|
||||
<span class="el-upload-list__item-actions">
|
||||
<span
|
||||
class="el-upload-list__item-preview"
|
||||
@click="handlePictureCardPreview(file)"
|
||||
<img
|
||||
class="el-upload-list__item-thumbnail"
|
||||
:src="OSSclientConfig.basePath + file.url"
|
||||
alt=""
|
||||
crossorigin="anonymous"
|
||||
style="max-width: 100%; max-height: 100%"
|
||||
>
|
||||
<i class="el-icon-zoom-in" />
|
||||
</span>
|
||||
<span class="el-upload-list__item-actions">
|
||||
<span
|
||||
class="el-upload-list__item-preview"
|
||||
@click="handlePictureCardPreview(file)"
|
||||
>
|
||||
<i class="el-icon-zoom-in" />
|
||||
</span>
|
||||
|
||||
<span
|
||||
v-if="adInfo.ReadingTaskState < 2"
|
||||
class="el-upload-list__item-delete"
|
||||
@click="handleRemove(file)"
|
||||
>
|
||||
<i class="el-icon-delete" />
|
||||
<span
|
||||
v-if="adInfo.ReadingTaskState < 2"
|
||||
class="el-upload-list__item-delete"
|
||||
@click="handleRemove(file)"
|
||||
>
|
||||
<i class="el-icon-delete" />
|
||||
</span>
|
||||
</span>
|
||||
</span>
|
||||
</viewer>
|
||||
</div>
|
||||
</el-upload>
|
||||
<el-dialog
|
||||
append-to-body
|
||||
:visible.sync="imgVisible"
|
||||
width="600px"
|
||||
>
|
||||
<!-- <img width="100%" :src="imageUrl" alt="图片未找到"> -->
|
||||
<el-image :src="imageUrl" width="100%">
|
||||
<div slot="placeholder" class="image-slot">
|
||||
{{ $t('trials:adReview:title:loading') }}<span class="dot">...</span>
|
||||
</div>
|
||||
</el-image>
|
||||
</el-dialog>
|
||||
</el-form-item>
|
||||
<el-form-item v-if="adInfo.ReadingTaskState < 2">
|
||||
<div style="text-align:center;">
|
||||
<div style="text-align: center">
|
||||
<el-button type="primary" @click="skipTask">
|
||||
<!-- 跳过 -->
|
||||
{{ $t("trials:readingReport:button:skip") }}
|
||||
</el-button>
|
||||
<!-- 保存 -->
|
||||
<el-button type="primary" @click="handleSave">{{ $t('common:button:save') }}</el-button>
|
||||
<el-button type="primary" @click="handleSave">{{
|
||||
$t("common:button:save")
|
||||
}}</el-button>
|
||||
<!-- 提交 -->
|
||||
<el-button type="primary" @click="handleSubmit">{{ $t('common:button:submit') }}</el-button>
|
||||
<el-button type="primary" @click="handleSubmit">{{
|
||||
$t("common:button:submit")
|
||||
}}</el-button>
|
||||
</div>
|
||||
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-card>
|
||||
|
||||
<el-card v-if="isReadingShowPreviousResults" :body-style="{ padding: '10px' }">
|
||||
<el-card
|
||||
v-if="isReadingShowPreviousResults"
|
||||
:body-style="{ padding: '10px' }"
|
||||
>
|
||||
<div slot="header" class="clearfix">
|
||||
<!-- 既往裁判评估 -->
|
||||
<span style="font-weight: bold;">{{ $t('trials:adReview:title:previousRes') }}</span>
|
||||
<span style="font-weight: bold">{{
|
||||
$t("trials:adReview:title:previousRes")
|
||||
}}</span>
|
||||
</div>
|
||||
|
||||
<el-table
|
||||
|
@ -276,13 +356,10 @@
|
|||
width="200"
|
||||
>
|
||||
<template slot-scope="scope">
|
||||
{{ $fd('ArmEnum', scope.row.JudgeResultArm) }}
|
||||
{{ $fd("ArmEnum", scope.row.JudgeResultArm) }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
:label="$t('common:action:action')"
|
||||
width="200"
|
||||
>
|
||||
<el-table-column :label="$t('common:action:action')" width="200">
|
||||
<template slot-scope="scope">
|
||||
<!-- 查看详情 -->
|
||||
<el-button
|
||||
|
@ -304,21 +381,34 @@
|
|||
custom-class="base-dialog-wrapper"
|
||||
>
|
||||
<div slot="title">
|
||||
<span style="font-size:18px;">{{ $t('common:dialogTitle:sign') }}</span>
|
||||
<span style="font-size:12px;margin-left:5px">{{ `(${$t('common:label:sign')}${ currentUser })` }}</span>
|
||||
<span style="font-size: 18px">{{ $t("common:dialogTitle:sign") }}</span>
|
||||
<span style="font-size: 12px; margin-left: 5px">{{
|
||||
`(${$t("common:label:sign")}${currentUser})`
|
||||
}}</span>
|
||||
</div>
|
||||
<SignForm ref="signForm" :sign-code-enum="signCode" @closeDialog="closeSignDialog" />
|
||||
<SignForm
|
||||
ref="signForm"
|
||||
:sign-code-enum="signCode"
|
||||
@closeDialog="closeSignDialog"
|
||||
/>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import { getJudgeReadingInfo, uploadJudgeTaskImage, saveJudgeVisitTaskResult, submitJudgeVisitTaskResult, getReadingPastResultList } from '@/api/trials'
|
||||
import {
|
||||
getJudgeReadingInfo,
|
||||
// uploadJudgeTaskImage,
|
||||
saveJudgeVisitTaskResult,
|
||||
submitJudgeVisitTaskResult,
|
||||
getReadingPastResultList
|
||||
} from '@/api/trials'
|
||||
import { getAutoCutNextTask } from '@/api/user'
|
||||
import { setSkipReadingCache } from '@/api/reading'
|
||||
import const_ from '@/const/sign-code'
|
||||
import { getToken } from '@/utils/auth'
|
||||
import SignForm from '@/views/trials/components/newSignForm'
|
||||
import DicomEvent from '@/views/trials/trials-panel/reading/dicoms/components/DicomEvent'
|
||||
import store from '@/store'
|
||||
// import store from '@/store'
|
||||
import { changeURLStatic } from '@/utils/history.js'
|
||||
export default {
|
||||
name: 'AdReview',
|
||||
|
@ -386,7 +476,10 @@ export default {
|
|||
priorLoading: false,
|
||||
judgeResultArmEnum: '',
|
||||
criterionType: null,
|
||||
openWindow: null
|
||||
openWindow: null,
|
||||
isFixed: false,
|
||||
images: [],
|
||||
remark: ''
|
||||
}
|
||||
},
|
||||
// watch: {
|
||||
|
@ -421,51 +514,92 @@ export default {
|
|||
}
|
||||
},
|
||||
methods: {
|
||||
getAdInfo() {
|
||||
async getAdInfo() {
|
||||
this.loading = true
|
||||
getJudgeReadingInfo({ visitTaskId: this.visitTaskId }).then(res => {
|
||||
var judgeQS = []
|
||||
if (res.Result.VisitInfoList.length > 0) {
|
||||
res.Result.VisitInfoList[0].VisitTaskInfoList.map((v, index) => {
|
||||
var qsObj = { armEnum: v.ArmEnum, judgeQuestionList: [], index: index }
|
||||
v.JudgeQuestionList.map(q => {
|
||||
if (q.QuestionType === 1) {
|
||||
qsObj.judgeQuestionList.push(q.QuestionName)
|
||||
} else if (q.QuestionType === 3 && this.criterionType === 10) {
|
||||
qsObj.judgeQuestionList.push(this.$t('trials:globalReview:table:visitRemark'))
|
||||
} else {
|
||||
qsObj.judgeQuestionList.push(this.$fd('JudgeReadingQuestionType', q.QuestionType))
|
||||
try {
|
||||
const res = await getJudgeReadingInfo({
|
||||
visitTaskId: this.visitTaskId
|
||||
})
|
||||
if (res.IsSuccess) {
|
||||
var judgeQS = []
|
||||
if (res.Result.VisitInfoList.length > 0) {
|
||||
res.Result.VisitInfoList[0].VisitTaskInfoList.map((v, index) => {
|
||||
var qsObj = {
|
||||
armEnum: v.ArmEnum,
|
||||
judgeQuestionList: [],
|
||||
index: index
|
||||
}
|
||||
v.JudgeQuestionList.map((q) => {
|
||||
if (q.QuestionType === 1) {
|
||||
qsObj.judgeQuestionList.push(q.QuestionName)
|
||||
} else if (q.QuestionType === 3 && this.criterionType === 10) {
|
||||
qsObj.judgeQuestionList.push(
|
||||
this.$t('trials:globalReview:table:visitRemark')
|
||||
)
|
||||
} else {
|
||||
qsObj.judgeQuestionList.push(
|
||||
this.$fd('JudgeReadingQuestionType', q.QuestionType)
|
||||
)
|
||||
}
|
||||
})
|
||||
judgeQS.push(qsObj)
|
||||
})
|
||||
}
|
||||
this.judgeQuestion = judgeQS
|
||||
this.isFixed =
|
||||
this.judgeQuestion.length > 0 &&
|
||||
this.judgeQuestion[0].judgeQuestionList.length > 4
|
||||
this.adInfo = res.Result
|
||||
this.adForm.judgeResultTaskId = res.Result.JudgeResultTaskId
|
||||
|
||||
this.fileList = []
|
||||
if (res.Result.JudgeResultImagePathList) {
|
||||
res.Result.JudgeResultImagePathList.map((url) => {
|
||||
if (url) {
|
||||
this.fileList.push({ name: '', url: url })
|
||||
}
|
||||
})
|
||||
judgeQS.push(qsObj)
|
||||
})
|
||||
this.adForm.judgeResultImagePathList =
|
||||
res.Result.JudgeResultImagePathList
|
||||
}
|
||||
this.visitTaskArmList = res.Result.VisitTaskArmList
|
||||
var i = this.visitTaskArmList.findIndex(
|
||||
(i) => i.VisitTaskId === this.adForm.judgeResultTaskId
|
||||
)
|
||||
if (i > -1) {
|
||||
// 本人已完整查看两位独立阅片人的全部相关影像和评估数据,经过综合研判,更认同第一阅片人(R1)对该病例的整体评估,原因是:
|
||||
this.judgeResultArmEnum = this.visitTaskArmList[i].ArmEnum
|
||||
var msg = ''
|
||||
if (this.judgeResultArmEnum === 1) {
|
||||
msg = this.$t('trials:adReview:title:msg1')
|
||||
} else if (this.judgeResultArmEnum === 2) {
|
||||
msg = this.$t('trials:adReview:title:msg3')
|
||||
}
|
||||
this.remark = msg
|
||||
this.adForm.judgeResultRemark = res.Result.JudgeResultRemark
|
||||
}
|
||||
}
|
||||
this.judgeQuestion = judgeQS
|
||||
|
||||
this.adInfo = res.Result
|
||||
this.adForm.judgeResultTaskId = res.Result.JudgeResultTaskId
|
||||
|
||||
this.adForm.judgeResultRemark = res.Result.JudgeResultRemark
|
||||
this.fileList = []
|
||||
if (res.Result.JudgeResultImagePathList) {
|
||||
res.Result.JudgeResultImagePathList.map(url => {
|
||||
if (url) { this.fileList.push({ name: '', url: url }) }
|
||||
})
|
||||
this.adForm.judgeResultImagePathList = res.Result.JudgeResultImagePathList
|
||||
}
|
||||
this.visitTaskArmList = res.Result.VisitTaskArmList
|
||||
this.loading = false
|
||||
}).catch(() => { this.loading = false })
|
||||
} catch (e) {
|
||||
this.loading = false
|
||||
}
|
||||
},
|
||||
getPriorAdList() {
|
||||
async getPriorAdList() {
|
||||
this.priorLoading = true
|
||||
getReadingPastResultList({ visitTaskId: this.visitTaskId }).then(res => {
|
||||
this.priorADList = res.Result
|
||||
try {
|
||||
const res = await getReadingPastResultList({
|
||||
visitTaskId: this.visitTaskId
|
||||
})
|
||||
if (res.IsSuccess) {
|
||||
this.priorADList = res.Result
|
||||
}
|
||||
this.priorLoading = false
|
||||
}).catch(() => { this.priorLoading = false })
|
||||
} catch (e) {
|
||||
this.priorLoading = false
|
||||
}
|
||||
},
|
||||
handleVisitTaskArmChange(v) {
|
||||
var i = this.visitTaskArmList.findIndex(i => i.VisitTaskId === v)
|
||||
var i = this.visitTaskArmList.findIndex((i) => i.VisitTaskId === v)
|
||||
if (i > -1) {
|
||||
// 本人已完整查看两位独立阅片人的全部相关影像和评估数据,经过综合研判,更认同第一阅片人(R1)对该病例的整体评估,原因是:
|
||||
this.judgeResultArmEnum = this.visitTaskArmList[i].ArmEnum
|
||||
|
@ -476,9 +610,12 @@ export default {
|
|||
msg = this.$t('trials:adReview:title:msg3')
|
||||
}
|
||||
// this.adForm.judgeResultRemark = `本人已完整查看两位独立阅片人的全部相关影像和评估数据,经过综合研判,更认同${this.$fd('ArmEnum', this.judgeResultArmEnum)}对该病例的整体评估,原因是:`
|
||||
this.adForm.judgeResultRemark = msg
|
||||
this.remark = msg
|
||||
this.adForm.judgeResultRemark = ''
|
||||
} else {
|
||||
this.judgeResultArmEnum = ''
|
||||
this.remark = ''
|
||||
this.adForm.judgeResultRemark = ''
|
||||
}
|
||||
},
|
||||
previewCD() {
|
||||
|
@ -488,33 +625,32 @@ export default {
|
|||
})
|
||||
window.open(routeData.href, '_blank')
|
||||
},
|
||||
handleSave() {
|
||||
this.$refs['adForm'].validate((valid) => {
|
||||
if (!valid) return
|
||||
this.loading = true
|
||||
var paths = []
|
||||
this.fileList.map(file => {
|
||||
if (file.url) {
|
||||
paths.push(file.url)
|
||||
}
|
||||
})
|
||||
this.adForm.judgeResultImagePathList = paths
|
||||
this.adForm.visitTaskId = this.visitTaskId
|
||||
saveJudgeVisitTaskResult(this.adForm).then(res => {
|
||||
this.$message.success(this.$t('common:message:savedSuccessfully'))
|
||||
this.loading = false
|
||||
}).catch(() => {
|
||||
this.loading = false
|
||||
})
|
||||
async handleSave() {
|
||||
const valid = await this.$refs['adForm'].validate()
|
||||
if (!valid) return
|
||||
this.loading = true
|
||||
var paths = []
|
||||
this.fileList.map((file) => {
|
||||
if (file.url) {
|
||||
paths.push(file.url)
|
||||
}
|
||||
})
|
||||
this.adForm.judgeResultImagePathList = paths
|
||||
this.adForm.visitTaskId = this.visitTaskId
|
||||
try {
|
||||
await saveJudgeVisitTaskResult(this.adForm)
|
||||
this.$message.success(this.$t('common:message:savedSuccessfully'))
|
||||
this.loading = false
|
||||
} catch (e) {
|
||||
this.loading = false
|
||||
}
|
||||
},
|
||||
handleSubmit() {
|
||||
this.$refs['adForm'].validate((valid) => {
|
||||
if (!valid) return
|
||||
const { ImageAssessmentReportConfirmation } = const_.processSignature
|
||||
this.signCode = ImageAssessmentReportConfirmation
|
||||
this.signVisible = true
|
||||
})
|
||||
async handleSubmit() {
|
||||
const valid = await this.$refs['adForm'].validate()
|
||||
if (!valid) return
|
||||
const { ImageAssessmentReportConfirmation } = const_.processSignature
|
||||
this.signCode = ImageAssessmentReportConfirmation
|
||||
this.signVisible = true
|
||||
},
|
||||
// 关闭签名框
|
||||
closeSignDialog(isSign, signInfo) {
|
||||
|
@ -525,10 +661,10 @@ export default {
|
|||
}
|
||||
},
|
||||
// 签名并确认
|
||||
signConfirm(signInfo) {
|
||||
async signConfirm(signInfo) {
|
||||
this.loading = true
|
||||
var paths = []
|
||||
this.fileList.map(file => {
|
||||
this.fileList.map((file) => {
|
||||
paths.push(file.url)
|
||||
})
|
||||
var params = {
|
||||
|
@ -540,7 +676,8 @@ export default {
|
|||
},
|
||||
signInfo: signInfo
|
||||
}
|
||||
submitJudgeVisitTaskResult(params).then(async res => {
|
||||
try {
|
||||
const res = await submitJudgeVisitTaskResult(params)
|
||||
if (res.IsSuccess) {
|
||||
this.$message.success(this.$t('common:message:savedSuccessfully'))
|
||||
this.isEdit = false
|
||||
|
@ -550,38 +687,35 @@ export default {
|
|||
// window.opener.postMessage('refreshTaskList', window.location)
|
||||
// 设置当前任务阅片状态为已读
|
||||
this.adInfo.ReadingTaskState = 2
|
||||
var isAutoTask = await this.getAutoTaskVal()
|
||||
const res = await getAutoCutNextTask()
|
||||
var isAutoTask = res.Result.AutoCutNextTask
|
||||
if (isAutoTask) {
|
||||
store.dispatch('reading/resetVisitTasks')
|
||||
DicomEvent.$emit('getNextTask')
|
||||
// store.dispatch('reading/resetVisitTasks')
|
||||
window.location.reload()
|
||||
} else {
|
||||
// '当前阅片任务已完成,是否进入下一个阅片任务?'
|
||||
this.$confirm(this.$t('trials:adReview:title:msg2'), {
|
||||
type: 'warning',
|
||||
distinguishCancelAndClose: true
|
||||
})
|
||||
.then(() => {
|
||||
store.dispatch('reading/resetVisitTasks')
|
||||
DicomEvent.$emit('getNextTask')
|
||||
})
|
||||
.catch(action => {
|
||||
changeURLStatic('visitTaskId', this.visitTaskId)
|
||||
})
|
||||
// '当前阅片任务已完成,是否进入下一个阅片任务?'
|
||||
const confirm = await this.$confirm(
|
||||
this.$t('trials:adReview:title:msg2'),
|
||||
{
|
||||
type: 'warning',
|
||||
distinguishCancelAndClose: true
|
||||
}
|
||||
)
|
||||
if (confirm === 'confirm') {
|
||||
// store.dispatch('reading/resetVisitTasks')
|
||||
// DicomEvent.$emit('getNextTask')
|
||||
window.location.reload()
|
||||
} else {
|
||||
changeURLStatic('visitTaskId', this.visitTaskId)
|
||||
}
|
||||
}
|
||||
window.opener.postMessage('refreshTaskList', window.location)
|
||||
}
|
||||
this.loading = false
|
||||
}).catch(_ => {
|
||||
} catch (e) {
|
||||
this.loading = false
|
||||
this.$refs['signForm'].btnLoading = false
|
||||
})
|
||||
},
|
||||
getAutoTaskVal() {
|
||||
return new Promise((resolve, reject) => {
|
||||
getAutoCutNextTask().then(res => {
|
||||
resolve(res.Result.AutoCutNextTask)
|
||||
}).catch(() => { reject() })
|
||||
})
|
||||
}
|
||||
},
|
||||
handleViewDetail(visitTaskId) {
|
||||
if (this.openWindow) {
|
||||
|
@ -591,14 +725,24 @@ export default {
|
|||
var criterionType = parseInt(localStorage.getItem('CriterionType'))
|
||||
var readingTool = this.$router.currentRoute.query.readingTool
|
||||
readingTool = isNaN(parseInt(readingTool)) ? null : parseInt(readingTool)
|
||||
var isReadingTaskViewInOrder = this.$router.currentRoute.query.isReadingTaskViewInOrder
|
||||
var trialReadingCriterionId = this.$router.currentRoute.query.TrialReadingCriterionId
|
||||
var isReadingTaskViewInOrder =
|
||||
this.$router.currentRoute.query.isReadingTaskViewInOrder
|
||||
var trialReadingCriterionId =
|
||||
this.$router.currentRoute.query.TrialReadingCriterionId
|
||||
|
||||
var path = ''
|
||||
if (readingTool === 0) {
|
||||
path = `/readingDicoms?TrialReadingCriterionId=${trialReadingCriterionId}&trialId=${this.trialId}&subjectCode=${this.subjectCode}&subjectId=${this.subjectId}&visitTaskId=${visitTaskId}&isReadingTaskViewInOrder=${isReadingTaskViewInOrder}&criterionType=${criterionType}&readingTool=${readingTool}&TokenKey=${token}&key=${new Date().getTime()}`
|
||||
path = `/readingDicoms?TrialReadingCriterionId=${trialReadingCriterionId}&trialId=${
|
||||
this.trialId
|
||||
}&subjectCode=${this.subjectCode}&subjectId=${
|
||||
this.subjectId
|
||||
}&visitTaskId=${visitTaskId}&isReadingTaskViewInOrder=${isReadingTaskViewInOrder}&criterionType=${criterionType}&readingTool=${readingTool}&TokenKey=${token}&key=${new Date().getTime()}`
|
||||
} else {
|
||||
path = `/noneDicomReading?TrialReadingCriterionId=${trialReadingCriterionId}&trialId=${this.trialId}&subjectCode=${this.subjectCode}&subjectId=${this.subjectId}&visitTaskId=${visitTaskId}&isReadingTaskViewInOrder=${isReadingTaskViewInOrder}&criterionType=${criterionType}&readingTool=${readingTool}&TokenKey=${token}&key=${new Date().getTime()}`
|
||||
path = `/noneDicomReading?TrialReadingCriterionId=${trialReadingCriterionId}&trialId=${
|
||||
this.trialId
|
||||
}&subjectCode=${this.subjectCode}&subjectId=${
|
||||
this.subjectId
|
||||
}&visitTaskId=${visitTaskId}&isReadingTaskViewInOrder=${isReadingTaskViewInOrder}&criterionType=${criterionType}&readingTool=${readingTool}&TokenKey=${token}&key=${new Date().getTime()}`
|
||||
}
|
||||
var routeData = this.$router.resolve({ path })
|
||||
this.openWindow = window.open(routeData.href, '_blank')
|
||||
|
@ -614,18 +758,32 @@ export default {
|
|||
// })
|
||||
// window.open(routeData.href, '_blank')
|
||||
var token = getToken()
|
||||
var task = row.VisitTaskInfoList.find(item => item.ArmEnum === armEnum)
|
||||
var task = row.VisitTaskInfoList.find((item) => item.ArmEnum === armEnum)
|
||||
var criterionType = this.$router.currentRoute.query.criterionType
|
||||
var readingTool = this.$router.currentRoute.query.readingTool
|
||||
readingTool = isNaN(parseInt(readingTool)) ? null : parseInt(readingTool)
|
||||
var isReadingTaskViewInOrder = this.$router.currentRoute.query.isReadingTaskViewInOrder
|
||||
var trialReadingCriterionId = this.$router.currentRoute.query.TrialReadingCriterionId
|
||||
var isReadingTaskViewInOrder =
|
||||
this.$router.currentRoute.query.isReadingTaskViewInOrder
|
||||
var trialReadingCriterionId =
|
||||
this.$router.currentRoute.query.TrialReadingCriterionId
|
||||
|
||||
var path = ''
|
||||
if (readingTool === 0) {
|
||||
path = `/readingDicoms?TrialReadingCriterionId=${trialReadingCriterionId}&trialId=${this.trialId}&subjectCode=${this.subjectCode}&subjectId=${this.subjectId}&visitTaskId=${task.VisitTaskId}&isReadingTaskViewInOrder=${isReadingTaskViewInOrder}&criterionType=${criterionType}&readingTool=${readingTool}&TokenKey=${token}&key=${new Date().getTime()}`
|
||||
path = `/readingDicoms?TrialReadingCriterionId=${trialReadingCriterionId}&trialId=${
|
||||
this.trialId
|
||||
}&subjectCode=${this.subjectCode}&subjectId=${
|
||||
this.subjectId
|
||||
}&visitTaskId=${
|
||||
task.VisitTaskId
|
||||
}&isReadingTaskViewInOrder=${isReadingTaskViewInOrder}&criterionType=${criterionType}&readingTool=${readingTool}&TokenKey=${token}&key=${new Date().getTime()}`
|
||||
} else {
|
||||
path = `/noneDicomReading?TrialReadingCriterionId=${trialReadingCriterionId}&trialId=${this.trialId}&subjectCode=${this.subjectCode}&subjectId=${this.subjectId}&visitTaskId=${task.VisitTaskId}&isReadingTaskViewInOrder=${isReadingTaskViewInOrder}&criterionType=${criterionType}&readingTool=${readingTool}&TokenKey=${token}&key=${new Date().getTime()}`
|
||||
path = `/noneDicomReading?TrialReadingCriterionId=${trialReadingCriterionId}&trialId=${
|
||||
this.trialId
|
||||
}&subjectCode=${this.subjectCode}&subjectId=${
|
||||
this.subjectId
|
||||
}&visitTaskId=${
|
||||
task.VisitTaskId
|
||||
}&isReadingTaskViewInOrder=${isReadingTaskViewInOrder}&criterionType=${criterionType}&readingTool=${readingTool}&TokenKey=${token}&key=${new Date().getTime()}`
|
||||
}
|
||||
var routeData = this.$router.resolve({ path })
|
||||
this.openWindow = window.open(routeData.href, '_blank')
|
||||
|
@ -635,43 +793,77 @@ export default {
|
|||
this.openWindow.close()
|
||||
}
|
||||
var token = getToken()
|
||||
var task = row.VisitTaskInfoList.find(item => item.ArmEnum === armEnum)
|
||||
var task = row.VisitTaskInfoList.find((item) => item.ArmEnum === armEnum)
|
||||
var criterionType = this.$router.currentRoute.query.criterionType
|
||||
var readingTool = this.$router.currentRoute.query.readingTool
|
||||
readingTool = isNaN(parseInt(readingTool)) ? null : parseInt(readingTool)
|
||||
var isReadingTaskViewInOrder = this.$router.currentRoute.query.isReadingTaskViewInOrder
|
||||
var trialReadingCriterionId = this.$router.currentRoute.query.TrialReadingCriterionId
|
||||
var isReadingTaskViewInOrder =
|
||||
this.$router.currentRoute.query.isReadingTaskViewInOrder
|
||||
var trialReadingCriterionId =
|
||||
this.$router.currentRoute.query.TrialReadingCriterionId
|
||||
|
||||
var path = ''
|
||||
if (readingTool === 0) {
|
||||
path = `/readingDicoms?TrialReadingCriterionId=${trialReadingCriterionId}&trialId=${this.trialId}&subjectCode=${this.subjectCode}&subjectId=${this.subjectId}&visitTaskId=${task.GlobalVisitTaskId}&isReadingTaskViewInOrder=${isReadingTaskViewInOrder}&criterionType=${criterionType}&readingTool=${readingTool}&TokenKey=${token}&key=${new Date().getTime()}`
|
||||
path = `/readingDicoms?TrialReadingCriterionId=${trialReadingCriterionId}&trialId=${
|
||||
this.trialId
|
||||
}&subjectCode=${this.subjectCode}&subjectId=${
|
||||
this.subjectId
|
||||
}&visitTaskId=${
|
||||
task.GlobalVisitTaskId
|
||||
}&isReadingTaskViewInOrder=${isReadingTaskViewInOrder}&criterionType=${criterionType}&readingTool=${readingTool}&TokenKey=${token}&key=${new Date().getTime()}`
|
||||
} else {
|
||||
path = `/noneDicomReading?TrialReadingCriterionId=${trialReadingCriterionId}&trialId=${this.trialId}&subjectCode=${this.subjectCode}&subjectId=${this.subjectId}&visitTaskId=${task.GlobalVisitTaskId}&isReadingTaskViewInOrder=${isReadingTaskViewInOrder}&criterionType=${criterionType}&readingTool=${readingTool}&TokenKey=${token}&key=${new Date().getTime()}`
|
||||
path = `/noneDicomReading?TrialReadingCriterionId=${trialReadingCriterionId}&trialId=${
|
||||
this.trialId
|
||||
}&subjectCode=${this.subjectCode}&subjectId=${
|
||||
this.subjectId
|
||||
}&visitTaskId=${
|
||||
task.GlobalVisitTaskId
|
||||
}&isReadingTaskViewInOrder=${isReadingTaskViewInOrder}&criterionType=${criterionType}&readingTool=${readingTool}&TokenKey=${token}&key=${new Date().getTime()}`
|
||||
}
|
||||
var routeData = this.$router.resolve({ path })
|
||||
this.openWindow = window.open(routeData.href, '_blank')
|
||||
},
|
||||
uploadScreenshot(param) {
|
||||
// uploadScreenshot(param) {
|
||||
// this.loading = true
|
||||
// this.uploadDisabled = false
|
||||
// const formData = new FormData()
|
||||
// formData.append('file', param.file)
|
||||
// uploadJudgeTaskImage(this.$route.query.trialId, this.visitTaskId, formData).then(res => {
|
||||
// this.loading = false
|
||||
// if (res.IsSuccess) {
|
||||
// this.fileList.push({ name: res.Result.FileName, url: `${res.Result.Path}` })
|
||||
// }
|
||||
// this.uploadDisabled = true
|
||||
// }).catch(() => {
|
||||
// this.loading = false
|
||||
// })
|
||||
// },
|
||||
async uploadScreenshot(param) {
|
||||
this.loading = true
|
||||
this.uploadDisabled = false
|
||||
const formData = new FormData()
|
||||
formData.append('file', param.file)
|
||||
uploadJudgeTaskImage(this.$route.query.trialId, this.visitTaskId, formData).then(res => {
|
||||
this.loading = false
|
||||
if (res.IsSuccess) {
|
||||
this.fileList.push({ name: res.Result.FileName, url: `${res.Result.Path}` })
|
||||
}
|
||||
this.uploadDisabled = true
|
||||
}).catch(() => {
|
||||
this.loading = false
|
||||
var trialId = this.$route.query.trialId
|
||||
var file = await this.fileToBlob(param.file)
|
||||
const res = await this.OSSclient.put(
|
||||
`/${trialId}/Read/${this.subjectId}/visit/${param.file.name}`,
|
||||
file
|
||||
)
|
||||
console.log(res)
|
||||
this.fileList.push({
|
||||
name: param.file.name,
|
||||
url: this.$getObjectName(res.url)
|
||||
})
|
||||
this.loading = false
|
||||
this.uploadDisabled = true
|
||||
},
|
||||
handleBeforeUpload(file) {
|
||||
// 检测文件类型是否符合要求
|
||||
if (this.checkFileSuffix(file.name)) {
|
||||
return true
|
||||
} else {
|
||||
const msg = this.$t('trials:adReview:title:msg4').replace('xxx', this.accept)
|
||||
const msg = this.$t('trials:adReview:title:msg4').replace(
|
||||
'xxx',
|
||||
this.accept
|
||||
)
|
||||
this.$alert(msg)
|
||||
return false
|
||||
}
|
||||
|
@ -679,7 +871,10 @@ export default {
|
|||
checkFileSuffix(fileName) {
|
||||
var index = fileName.lastIndexOf('.')
|
||||
var suffix = fileName.substring(index + 1, fileName.length)
|
||||
if (this.accept.toLocaleLowerCase().search(suffix.toLocaleLowerCase()) === -1) {
|
||||
if (
|
||||
this.accept.toLocaleLowerCase().search(suffix.toLocaleLowerCase()) ===
|
||||
-1
|
||||
) {
|
||||
return false
|
||||
} else {
|
||||
return true
|
||||
|
@ -693,39 +888,66 @@ export default {
|
|||
},
|
||||
// 预览图片
|
||||
handlePictureCardPreview(file) {
|
||||
this.imageUrl = file.url
|
||||
this.imgVisible = true
|
||||
this.images = this.fileList.map(
|
||||
(f) => this.OSSclientConfig.basePath + f.url
|
||||
)
|
||||
// this.imageUrl = this.OSSclientConfig.basePath + file.url
|
||||
this.$refs[file.url].$viewer.show()
|
||||
},
|
||||
// 删除图片
|
||||
handleRemove(file, fileList) {
|
||||
var idx = this.fileList.findIndex(i => i.url === file.url)
|
||||
var idx = this.fileList.findIndex((i) => i.url === file.url)
|
||||
if (idx === -1) return
|
||||
this.fileList.splice(idx, 1)
|
||||
},
|
||||
async skipTask() {
|
||||
try {
|
||||
// 是否确认跳过?
|
||||
const confirm = await this.$confirm(
|
||||
this.$t('trials:readingReport:message:skipConfirm'),
|
||||
{
|
||||
type: 'warning',
|
||||
distinguishCancelAndClose: true
|
||||
}
|
||||
)
|
||||
if (confirm !== 'confirm') return
|
||||
this.loading = true
|
||||
const res = await setSkipReadingCache({
|
||||
visitTaskId: this.visitTaskId
|
||||
})
|
||||
this.loading = false
|
||||
if (res.IsSuccess) {
|
||||
window.location.reload()
|
||||
}
|
||||
} catch (e) {
|
||||
this.loading = false
|
||||
console.log(e)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.adReview_wrapper{
|
||||
.adReview_wrapper {
|
||||
flex: 1;
|
||||
padding: 10px;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
overflow-y: auto;
|
||||
.box-mr{
|
||||
margin:10px 0;
|
||||
.box-mr {
|
||||
margin: 10px 0;
|
||||
}
|
||||
.disabled{
|
||||
>>>.el-upload--picture-card {
|
||||
.disabled {
|
||||
/deep/ .el-upload--picture-card {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
>>> .el-upload-list__item {
|
||||
/deep/ .el-upload-list__item {
|
||||
transition: none !important;
|
||||
}
|
||||
>>> .el-upload-list__item-thumbnail {
|
||||
/* 图片在方框内显示长边 */
|
||||
object-fit: scale-down !important;
|
||||
/deep/ .el-upload-list__item-thumbnail {
|
||||
/* 图片在方框内显示长边 */
|
||||
object-fit: scale-down !important;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -111,10 +111,11 @@ export default {
|
|||
this.isRender = true
|
||||
},
|
||||
methods: {
|
||||
handleSave() {
|
||||
this.$refs.assessmentForm.validate(async valid => {
|
||||
if (!valid) return
|
||||
const loading = this.$loading({ fullscreen: true })
|
||||
async handleSave() {
|
||||
const valid = await this.$refs.assessmentForm.validate()
|
||||
if (!valid) return
|
||||
const loading = this.$loading({ fullscreen: true })
|
||||
try {
|
||||
var answers = []
|
||||
for (const k in this.form) {
|
||||
answers.push({ questionId: k, answer: this.form[k] })
|
||||
|
@ -123,13 +124,15 @@ export default {
|
|||
visitTaskId: this.visitTaskId,
|
||||
answerList: answers
|
||||
}
|
||||
submitTaskAdditionalQuestion(params).then(res => {
|
||||
const res = await submitTaskAdditionalQuestion(params)
|
||||
if (res.IsSuccess) {
|
||||
this.$emit('sign')
|
||||
loading.close()
|
||||
}).catch(() => {
|
||||
loading.close()
|
||||
})
|
||||
})
|
||||
}
|
||||
loading.close()
|
||||
} catch (e) {
|
||||
console.log(e)
|
||||
loading.close()
|
||||
}
|
||||
},
|
||||
handleCancel() {
|
||||
this.$emit('close')
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<template>
|
||||
<el-form
|
||||
ref="subjectForm"
|
||||
ref="customWWWC"
|
||||
v-loading="loading"
|
||||
:model="form"
|
||||
:rules="rules"
|
||||
|
@ -67,11 +67,10 @@ export default {
|
|||
}
|
||||
},
|
||||
methods: {
|
||||
handleSave() {
|
||||
this.$refs.subjectForm.validate(valid => {
|
||||
if (!valid) return
|
||||
this.$emit('setWwwc', this.form)
|
||||
})
|
||||
async handleSave() {
|
||||
const valid = await this.$refs.customWWWC.validate()
|
||||
if (!valid) return
|
||||
this.$emit('setWwwc', this.form)
|
||||
},
|
||||
handleCancel() {
|
||||
this.$emit('close')
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
</div>
|
||||
<!-- 切换访视 -->
|
||||
<div
|
||||
v-if="stack.imageRendered && isReadingTaskViewInOrder"
|
||||
v-if="stack.imageRendered && isReadingTaskViewInOrder === 1"
|
||||
class="info-visit"
|
||||
@dblclick.stop="preventDefault($event)"
|
||||
>
|
||||
|
@ -181,7 +181,7 @@ export default {
|
|||
required: true
|
||||
},
|
||||
isReadingTaskViewInOrder: {
|
||||
type: Boolean,
|
||||
type: Number,
|
||||
required: true
|
||||
},
|
||||
customWwcTpl: {
|
||||
|
@ -222,7 +222,8 @@ export default {
|
|||
taskBlindName: '',
|
||||
frame: null,
|
||||
imageRendered: false,
|
||||
isExistsClinicalData: false
|
||||
isExistsClinicalData: false,
|
||||
isExistMutiFrames: false
|
||||
// preventCache: true
|
||||
},
|
||||
dicomInfo: {
|
||||
|
@ -333,7 +334,8 @@ export default {
|
|||
|
||||
mounted() {
|
||||
console.log(cornerstoneTools)
|
||||
this.subjectCode = this.$router.currentRoute.query.subjectCode
|
||||
// this.subjectCode = this.$router.currentRoute.query.subjectCode
|
||||
this.subjectCode = localStorage.getItem('subjectCode')
|
||||
document.addEventListener('mouseup', () => {
|
||||
this.sliderMouseup()
|
||||
})
|
||||
|
@ -477,7 +479,7 @@ export default {
|
|||
},
|
||||
methods: {
|
||||
goViewer(e) {
|
||||
console.log(this.$refs['sliderBox'].clientHeight)
|
||||
// console.log(this.$refs['sliderBox'].clientHeight)
|
||||
var height = e.offsetY * 100 / this.$refs['sliderBox'].clientHeight
|
||||
this.height = height
|
||||
var index = Math.trunc(this.stack.imageIds.length * this.height / 100)
|
||||
|
@ -546,7 +548,7 @@ export default {
|
|||
},
|
||||
|
||||
mouseUp(e) {
|
||||
console.log('mouseUp')
|
||||
// console.log('mouseUp')
|
||||
if (this.readingTaskState >= 2) return
|
||||
this.image = e.detail.image
|
||||
this.getToolStateInfo(e)
|
||||
|
@ -672,7 +674,7 @@ export default {
|
|||
this.sliderInfo.isMove = false
|
||||
},
|
||||
getMeasureData() {
|
||||
console.log('getMeasureData')
|
||||
// console.log('getMeasureData')
|
||||
var idx = this.visitTaskList.findIndex(i => i.VisitTaskId === this.stack.visitTaskId)
|
||||
this.measureData = this.visitTaskList[idx].MeasureData
|
||||
const ToolStateManager = cornerstoneTools.globalImageIdSpecificToolStateManager
|
||||
|
@ -757,7 +759,7 @@ export default {
|
|||
const imageInfo = this.getInstanceInfo(imageId)
|
||||
var instanceId = imageInfo.instanceId
|
||||
var frame = imageInfo.frame
|
||||
this.stack.frame = !isNaN(parseInt(frame)) ? parseInt(frame) : 0
|
||||
this.stack.frame = this.stack.isExistMutiFrames ? parseInt(frame) : null
|
||||
const ToolStateManager = cornerstoneTools.globalImageIdSpecificToolStateManager
|
||||
for (var m = 0; m < this.measuredTools.length; m++) {
|
||||
var toolType = this.measuredTools[m]
|
||||
|
@ -814,7 +816,7 @@ export default {
|
|||
}
|
||||
},
|
||||
stackScrollCallback(e) {
|
||||
console.log('stackScrollCallback')
|
||||
// console.log('stackScrollCallback')
|
||||
const { detail } = e
|
||||
if (this.isScrollSync && this.currentDicomCanvasIndex === this.canvasIndex) {
|
||||
this.scrollSyncInfo.canvasIndex = this.canvasIndex
|
||||
|
@ -879,7 +881,6 @@ export default {
|
|||
return seriesList[seriesIdx].loadStatus ? 1 : 0
|
||||
},
|
||||
renderMeasuredData(e) {
|
||||
this.stack.frame = !isNaN(parseInt(this.stack.frame)) ? parseInt(this.stack.frame) : 0
|
||||
var idx = this.visitTaskList.findIndex(i => i.VisitTaskId === this.stack.visitTaskId)
|
||||
if (idx === -1) return
|
||||
this.measureData = this.visitTaskList[idx].MeasureData
|
||||
|
@ -898,9 +899,7 @@ export default {
|
|||
} else {
|
||||
cornerstoneTools.setToolEnabledForElement(element, data.MeasureData.type, { mouseButtonMask: 1 })
|
||||
}
|
||||
// console.log('renderMeasuredData', this.stack.frame)
|
||||
|
||||
if (this.stack.instanceId.includes(data.InstanceId) && ((data.NumberOfFrames === this.stack.frame) || !data.NumberOfFrames) && data.MeasureData) {
|
||||
if (this.stack.instanceId.includes(data.InstanceId) && ((this.stack.isExistMutiFrames && data.MeasureData.frame === this.stack.frame && data.MeasureData) || (!this.stack.isExistMutiFrames && data.MeasureData))) {
|
||||
const toolState = ToolStateManager.getImageIdToolState(e.detail.image.imageId, data.MeasureData.type)
|
||||
if (toolState && toolState.data.length > 0) {
|
||||
var idx = toolState.data.findIndex(item => item.uuid === data.MeasureData.data.uuid)
|
||||
|
@ -987,7 +986,7 @@ export default {
|
|||
const imageInfo = this.getInstanceInfo(imageId)
|
||||
var instanceId = imageInfo.instanceId
|
||||
var frame = imageInfo.frame
|
||||
this.stack.frame = !isNaN(parseInt(frame)) ? parseInt(frame) : 0
|
||||
this.stack.frame = this.stack.isExistMutiFrames ? parseInt(frame) : null
|
||||
const ToolStateManager = cornerstoneTools.globalImageIdSpecificToolStateManager
|
||||
for (let t = 0; t < this.measuredTools.length; t++) {
|
||||
var toolType = this.measuredTools[t]
|
||||
|
@ -998,7 +997,7 @@ export default {
|
|||
if (i > -1) {
|
||||
var idx = this.measureData.findIndex(item => item.MeasureData && item.MeasureData.data && item.MeasureData.data.uuid === toolState.data[i].uuid)
|
||||
if (idx > -1) {
|
||||
console.log('mouseClick')
|
||||
// console.log('mouseClick')
|
||||
DicomEvent.$emit('setCollapseActive', this.measureData[idx])
|
||||
if (this.readingTaskState < 2) {
|
||||
const measureData = {}
|
||||
|
@ -1040,7 +1039,7 @@ export default {
|
|||
loadImageStack(dicomSeries) {
|
||||
return new Promise(resolve => {
|
||||
this.isCurrentTask = dicomSeries.isCurrentTask
|
||||
this.isBaseline = dicomSeries.isBaseline
|
||||
this.isBaseline = dicomSeries.isBaseLineTask
|
||||
this.readingTaskState = dicomSeries.readingTaskState
|
||||
if (this.isCurrentTask && this.readingTaskState < 2) {
|
||||
this.activeTool = 1
|
||||
|
@ -1055,7 +1054,7 @@ export default {
|
|||
this.stack.studyId = dicomSeries.studyId
|
||||
this.stack.seriesNumber = dicomSeries.seriesNumber
|
||||
this.stack.imageIds = dicomSeries.imageIds
|
||||
this.stack.currentImageIdIndex = dicomSeries.imageIdIndex ? dicomSeries.imageIdIndex : 0
|
||||
this.stack.currentImageIdIndex = dicomSeries.imageIdIndex && dicomSeries.imageIdIndex < dicomSeries.imageIds.length ? dicomSeries.imageIdIndex : 0
|
||||
this.stack.imageIdIndex = dicomSeries.imageIdIndex
|
||||
this.stack.firstImageLoading = true
|
||||
this.stack.visitTaskId = dicomSeries.visitTaskId
|
||||
|
@ -1066,6 +1065,7 @@ export default {
|
|||
this.stack.sliceThickness = dicomSeries.sliceThickness
|
||||
this.stack.instanceCount = dicomSeries.instanceCount
|
||||
this.stack.isExistsClinicalData = dicomSeries.isExistsClinicalData
|
||||
this.stack.isExistMutiFrames = dicomSeries.isExistMutiFrames
|
||||
// this.measuredData = dicomSeries.measuredData
|
||||
var idx = this.visitTaskList.findIndex(i => i.VisitTaskId === dicomSeries.visitTaskId)
|
||||
this.stack.visitTaskNum = this.visitTaskList[idx].VisitTaskNum
|
||||
|
@ -1086,18 +1086,18 @@ export default {
|
|||
const imageInfo = this.getInstanceInfo(imageId)
|
||||
var instanceId = imageInfo.instanceId
|
||||
var frame = imageInfo.frame
|
||||
this.stack.frame = !isNaN(parseInt(frame)) ? parseInt(frame) : 0
|
||||
this.stack.frame = this.stack.isExistMutiFrames ? parseInt(frame) : null
|
||||
this.stack.instanceId = instanceId
|
||||
const ToolStateManager = cornerstoneTools.globalImageIdSpecificToolStateManager
|
||||
ToolStateManager.clearImageIdToolState(dicomSeries.imageIds)
|
||||
if (this.toolState.clipPlaying) this.toggleClipPlay()
|
||||
this.toolState.viewportInvert = false
|
||||
this.toolState.dicomInfoVisible = false
|
||||
|
||||
|
||||
const element = this.$refs.canvas
|
||||
cornerstone.enable(element)
|
||||
element.tabIndex = 0
|
||||
element.focus()
|
||||
const ToolStateManager = cornerstoneTools.globalImageIdSpecificToolStateManager
|
||||
ToolStateManager.clearImageIdToolState(dicomSeries.imageIds)
|
||||
this.toggleClipPlay(false)
|
||||
this.toolState.viewportInvert = false
|
||||
this.toolState.dicomInfoVisible = false
|
||||
var scope = this
|
||||
// var p = parseInt(new Date().getTime())
|
||||
// requestPoolManager.loadAndCacheImagePlus(this.stack.imageIds[this.stack.currentImageIdIndex], this.stack.seriesId, p*100).then(image=>{
|
||||
|
@ -1110,22 +1110,27 @@ export default {
|
|||
// }
|
||||
// resolve()
|
||||
// })
|
||||
this.loading = true
|
||||
cornerstone.loadAndCacheImage(this.stack.imageIds[this.stack.currentImageIdIndex])
|
||||
.then(async image => {
|
||||
await scope.onFirstImageLoaded(image)
|
||||
if (this.stack.imageIds.indexOf(image.imageId) !== -1) {
|
||||
await scope.onFirstImageLoaded(image)
|
||||
}
|
||||
scope.loading = false
|
||||
resolve()
|
||||
})
|
||||
.catch((error) => {
|
||||
if (error.error && error.error.message) {
|
||||
this.$alert(error.error.message)
|
||||
}
|
||||
scope.loading = false
|
||||
resolve()
|
||||
})
|
||||
})
|
||||
},
|
||||
onFirstImageLoaded(image) {
|
||||
console.log('onFirstImageLoaded')
|
||||
return new Promise(resolve => {
|
||||
// console.log('onFirstImageLoaded')
|
||||
return new Promise(async resolve => {
|
||||
const element = this.$refs.canvas
|
||||
var viewport = cornerstone.getDefaultViewportForImage(this.canvas, image)
|
||||
cornerstone.displayImage(this.canvas, image, viewport)
|
||||
|
@ -1195,15 +1200,15 @@ export default {
|
|||
const imageInfo = this.getInstanceInfo(image.imageId)
|
||||
var instanceId = imageInfo.instanceId
|
||||
var frame = imageInfo.frame
|
||||
this.stack.frame = !isNaN(parseInt(frame)) ? parseInt(frame) : 0
|
||||
this.stack.frame = this.stack.isExistMutiFrames ? parseInt(frame) : null
|
||||
this.stack.instanceId = instanceId
|
||||
this.height = (this.stack.currentImageIdIndex) * 100 / (this.stack.imageIds.length - 1)
|
||||
this.resetWwwc()
|
||||
// this.resetWwwc()
|
||||
resolve()
|
||||
})
|
||||
},
|
||||
onNewImage(e) {
|
||||
console.log('cornerstonenewimage')
|
||||
// console.log('cornerstonenewimage')
|
||||
if (this.isCurrentTask && this.readingTaskState < 2) {
|
||||
this.resetHideMeasureArr()
|
||||
}
|
||||
|
@ -1240,6 +1245,12 @@ export default {
|
|||
if (this.dicomInfo.thick) {
|
||||
this.dicomInfo.thick = this.dicomInfo.thick.toFixed(2)
|
||||
}
|
||||
const newImageIdIndex = this.stack.imageIds.findIndex(i => i === imageId)
|
||||
if (newImageIdIndex === -1) return
|
||||
this.stack.currentImageIdIndex = newImageIdIndex
|
||||
this.stack.imageIdIndex = newImageIdIndex
|
||||
this.series.imageIdIndex = newImageIdIndex
|
||||
this.height = (this.stack.currentImageIdIndex) * 100 / (this.stack.imageIds.length - 1)
|
||||
},
|
||||
getScreenshots() {
|
||||
const canvas = this.canvas.querySelector('canvas')
|
||||
|
@ -1264,7 +1275,7 @@ export default {
|
|||
const imageInfo = this.getInstanceInfo(imageId)
|
||||
var instanceId = imageInfo.instanceId
|
||||
var frame = imageInfo.frame
|
||||
this.stack.frame = !isNaN(parseInt(frame)) ? parseInt(frame) : 0
|
||||
this.stack.frame = this.stack.isExistMutiFrames ? parseInt(frame) : null
|
||||
if (this.imageId !== instanceId) {
|
||||
this.getOrientationMarker(e.detail.element)
|
||||
// 初次加载时,如果该影像存在标记,则以标记的窗宽窗位为初始化默认值,否则以序列的窗宽窗位为初始化默认值
|
||||
|
@ -1316,20 +1327,20 @@ export default {
|
|||
var element = cornerstone.getEnabledElement(this.canvas)
|
||||
var viewport = element.viewport
|
||||
// 测量完成
|
||||
console.log('completed')
|
||||
// console.log('completed')
|
||||
this.activeTool = 1
|
||||
this.activeToolName = ''
|
||||
var { imageId } = element.image
|
||||
const imageInfo = this.getInstanceInfo(imageId)
|
||||
var instanceId = imageInfo.instanceId
|
||||
var frame = imageInfo.frame
|
||||
this.stack.frame = !isNaN(parseInt(frame)) ? parseInt(frame) : 0
|
||||
this.stack.frame = this.stack.isExistMutiFrames ? parseInt(frame) : null
|
||||
if (e.detail.toolName === 'Length' || e.detail.toolName === 'ArrowAnnotate' || e.detail.toolName === 'RectangleRoi') {
|
||||
const measureData = {}
|
||||
measureData.studyId = this.stack.studyId
|
||||
measureData.seriesId = this.stack.seriesId
|
||||
measureData.instanceId = instanceId
|
||||
measureData.frame = this.stack.frame ? this.stack.frame : 0
|
||||
measureData.frame = this.stack.frame
|
||||
measureData.data = e.detail.measurementData
|
||||
measureData.type = e.detail.toolName
|
||||
measureData.thick = this.dicomInfo.thick
|
||||
|
@ -1434,7 +1445,7 @@ export default {
|
|||
},
|
||||
onMeasurementmodified(e) {
|
||||
// 移动
|
||||
console.log('modified')
|
||||
// console.log('modified')
|
||||
if (this.readingTaskState >= 2) return
|
||||
const { measurementData, toolType } = e.detail
|
||||
var element = cornerstone.getEnabledElement(this.canvas)
|
||||
|
@ -1443,7 +1454,8 @@ export default {
|
|||
const imageInfo = this.getInstanceInfo(imageId)
|
||||
var instanceId = imageInfo.instanceId
|
||||
var frame = imageInfo.frame
|
||||
this.stack.frame = !isNaN(parseInt(frame)) ? parseInt(frame) : 0
|
||||
this.stack.frame = this.stack.isExistMutiFrames ? parseInt(frame) : null
|
||||
|
||||
var uuid = measurementData.uuid
|
||||
var idx = this.measureData.findIndex(item => item.MeasureData && item.MeasureData.data && item.MeasureData.data.uuid === uuid)
|
||||
if (idx > -1) {
|
||||
|
@ -1559,8 +1571,10 @@ export default {
|
|||
|
||||
resetViewport() {
|
||||
this.toolState.viewportInvert = false
|
||||
this.orientationMarkers = [...this.originalMarkers]
|
||||
this.setMarkers()
|
||||
if (this.originalMarkers.length > 0) {
|
||||
this.orientationMarkers = [...this.originalMarkers]
|
||||
this.setMarkers()
|
||||
}
|
||||
var image = cornerstone.getImage(this.canvas)
|
||||
cornerstone.setViewport(
|
||||
this.canvas,
|
||||
|
@ -1619,18 +1633,19 @@ export default {
|
|||
}
|
||||
},
|
||||
|
||||
toggleClipPlay() {
|
||||
if (this.toolState.clipPlaying) {
|
||||
toggleClipPlay(isPlay) {
|
||||
if (isPlay) {
|
||||
this.toolState.clipPlaying = true
|
||||
cornerstoneTools.playClip(this.canvas, this.dicomInfo.fps)
|
||||
cornerstoneTools.getToolState(
|
||||
this.canvas,
|
||||
'playClip'
|
||||
).data[0].loop = false
|
||||
} else {
|
||||
cornerstoneTools.stopClip(this.canvas)
|
||||
this.toolState.clipPlaying = false
|
||||
return
|
||||
}
|
||||
this.toolState.clipPlaying = true
|
||||
cornerstoneTools.playClip(this.canvas, this.dicomInfo.fps)
|
||||
cornerstoneTools.getToolState(
|
||||
this.canvas,
|
||||
'playClip'
|
||||
).data[0].loop = false
|
||||
},
|
||||
setFps(fps) {
|
||||
this.dicomInfo.fps = fps
|
||||
|
@ -1639,7 +1654,7 @@ export default {
|
|||
resetWwwc() {
|
||||
this.toolState.viewportInvert = false
|
||||
var viewport = cornerstone.getViewport(this.canvas)
|
||||
viewport.invert = false
|
||||
// viewport.invert = false
|
||||
var image = cornerstone.getImage(this.canvas)
|
||||
viewport.voi.windowWidth = image.windowWidth
|
||||
viewport.voi.windowCenter = image.windowCenter
|
||||
|
@ -1675,8 +1690,10 @@ export default {
|
|||
},
|
||||
|
||||
resetRotate() {
|
||||
this.orientationMarkers = [...this.originalMarkers]
|
||||
this.setMarkers()
|
||||
if (this.originalMarkers.length > 0) {
|
||||
this.orientationMarkers = [...this.originalMarkers]
|
||||
this.setMarkers()
|
||||
}
|
||||
var viewport = cornerstone.getViewport(this.canvas)
|
||||
viewport.hflip = false
|
||||
viewport.vflip = false
|
||||
|
@ -1691,23 +1708,25 @@ export default {
|
|||
}
|
||||
},
|
||||
setRotate(hflip, vflip, angle, type) {
|
||||
var markers = [...this.orientationMarkers]
|
||||
if (type === 2) {
|
||||
// 垂直翻转
|
||||
this.orientationMarkers[0] = markers[2]
|
||||
this.orientationMarkers[2] = markers[0]
|
||||
} else if (type === 3) {
|
||||
// 水平翻转
|
||||
this.orientationMarkers[1] = markers[3]
|
||||
this.orientationMarkers[3] = markers[1]
|
||||
} else if (type === 4) {
|
||||
// 左转90度
|
||||
this.orientationMarkers = markers.slice(1, 4).concat(markers[0])
|
||||
} else if (type === 5) {
|
||||
// 右转90度
|
||||
this.orientationMarkers = [markers[3]].concat(markers.slice(0, 3))
|
||||
if (this.orientationMarkers.length > 0) {
|
||||
var markers = [...this.orientationMarkers]
|
||||
if (type === 2) {
|
||||
// 垂直翻转
|
||||
this.orientationMarkers[0] = markers[2]
|
||||
this.orientationMarkers[2] = markers[0]
|
||||
} else if (type === 3) {
|
||||
// 水平翻转
|
||||
this.orientationMarkers[1] = markers[3]
|
||||
this.orientationMarkers[3] = markers[1]
|
||||
} else if (type === 4) {
|
||||
// 左转90度
|
||||
this.orientationMarkers = markers.slice(1, 4).concat(markers[0])
|
||||
} else if (type === 5) {
|
||||
// 右转90度
|
||||
this.orientationMarkers = [markers[3]].concat(markers.slice(0, 3))
|
||||
}
|
||||
this.setMarkers()
|
||||
}
|
||||
this.setMarkers()
|
||||
var viewport = cornerstone.getViewport(this.canvas)
|
||||
if (hflip) viewport.hflip = !viewport.hflip
|
||||
if (vflip) viewport.vflip = !viewport.vflip
|
||||
|
@ -1716,9 +1735,8 @@ export default {
|
|||
},
|
||||
|
||||
saveImage() {
|
||||
let timestamp = Date.now()
|
||||
// var uid = cornerstone.getImage(this.canvas).data.string('x00080018')
|
||||
cornerstoneTools.SaveAs(this.canvas, `${this.subjectCode}_${this.stack.taskBlindName}_${timestamp}.png`)
|
||||
var uid = cornerstone.getImage(this.canvas).data.string('x00080018')
|
||||
cornerstoneTools.SaveAs(this.canvas, `${uid}.png`)
|
||||
},
|
||||
fitToWindow() {
|
||||
if (this.stack.seriesNumber) {
|
||||
|
@ -1917,6 +1935,17 @@ export default {
|
|||
}
|
||||
}
|
||||
},
|
||||
getInstanceInfo(imageId) {
|
||||
const params = {}
|
||||
const searchParams = new URLSearchParams(imageId.split('?')[1])
|
||||
for (const [key, value] of searchParams.entries()) {
|
||||
params[key] = value
|
||||
}
|
||||
if (isNaN(params.frame)) {
|
||||
params.frame = 0
|
||||
}
|
||||
return params
|
||||
},
|
||||
preventDefault(e) {
|
||||
e.stopImmediatePropagation()
|
||||
e.stopPropagation()
|
||||
|
@ -1927,15 +1956,6 @@ export default {
|
|||
e.stopImmediatePropagation()
|
||||
e.stopPropagation()
|
||||
e.preventDefault()
|
||||
},
|
||||
getInstanceInfo(imageId) {
|
||||
const params = {}
|
||||
const searchParams = new URLSearchParams(imageId.split('?')[1])
|
||||
|
||||
for (const [key, value] of searchParams.entries()) {
|
||||
params[key] = value
|
||||
}
|
||||
return params
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -26,7 +26,7 @@
|
|||
A
|
||||
</div>
|
||||
</li>
|
||||
<li v-if="isReadingTaskViewInOrder" class="flex_row" @click.stop="changeLayout('A|B')">
|
||||
<li v-if="isReadingTaskViewInOrder === 1" class="flex_row" @click.stop="changeLayout('A|B')">
|
||||
<div class="layout_box_1_1">
|
||||
A
|
||||
</div>
|
||||
|
@ -280,6 +280,54 @@
|
|||
<div class="text">{{ tool.text }}</div>
|
||||
</div> -->
|
||||
</div>
|
||||
<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">{{ $t('trials:dicom-show:default') }}</option> -->
|
||||
<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">
|
||||
|
@ -292,7 +340,7 @@
|
|||
<div class="text">{{ $t('trials:reading:button:reset') }}</div>
|
||||
</div>
|
||||
</el-tooltip>
|
||||
|
||||
|
||||
<div style="margin-left:auto;">
|
||||
<div style="padding:5px">
|
||||
<!-- 手册 -->
|
||||
|
@ -337,41 +385,63 @@
|
|||
</div>
|
||||
</div>
|
||||
<div ref="form-container" class="form-container">
|
||||
<!-- 激活canvas测量数据 -->
|
||||
<div class="form-wrapper">
|
||||
<RecistBMQuestionList
|
||||
v-if="CriterionType === 17"
|
||||
ref="measurementList"
|
||||
:question-form-change-state="questionFormChangeState"
|
||||
:question-form-change-num="questionFormChangeNum"
|
||||
:is-show="isShow"
|
||||
:is-reading-show-subject-info="isReadingShowSubjectInfo"
|
||||
/>
|
||||
<IRecistQuestionList
|
||||
v-else-if="CriterionType === 3"
|
||||
ref="measurementList"
|
||||
:question-form-change-state="questionFormChangeState"
|
||||
:question-form-change-num="questionFormChangeNum"
|
||||
:is-show="isShow"
|
||||
:is-reading-show-subject-info="isReadingShowSubjectInfo"
|
||||
/>
|
||||
<PCWGQuestionList
|
||||
v-else-if="CriterionType === 10"
|
||||
ref="measurementList"
|
||||
:question-form-change-state="questionFormChangeState"
|
||||
:question-form-change-num="questionFormChangeNum"
|
||||
:is-show="isShow"
|
||||
:is-reading-show-subject-info="isReadingShowSubjectInfo"
|
||||
/>
|
||||
|
||||
<RecistBMQuestionList
|
||||
v-if="CriterionType === 17"
|
||||
ref="measurementList"
|
||||
:question-form-change-state="questionFormChangeState"
|
||||
:question-form-change-num="questionFormChangeNum"
|
||||
:is-show="isShow"
|
||||
:is-reading-show-subject-info="isReadingShowSubjectInfo"
|
||||
/>
|
||||
<IRecistQuestionList
|
||||
v-else-if="CriterionType === 3"
|
||||
ref="measurementList"
|
||||
:question-form-change-state="questionFormChangeState"
|
||||
:question-form-change-num="questionFormChangeNum"
|
||||
:is-show="isShow"
|
||||
:is-reading-show-subject-info="isReadingShowSubjectInfo"
|
||||
/>
|
||||
<PCWGQuestionList
|
||||
v-else-if="CriterionType === 10"
|
||||
ref="measurementList"
|
||||
:question-form-change-state="questionFormChangeState"
|
||||
:question-form-change-num="questionFormChangeNum"
|
||||
:is-show="isShow"
|
||||
:is-reading-show-subject-info="isReadingShowSubjectInfo"
|
||||
/>
|
||||
<RecistQuestionList
|
||||
v-else-if="CriterionType === 1"
|
||||
ref="measurementList"
|
||||
:question-form-change-state="questionFormChangeState"
|
||||
:question-form-change-num="questionFormChangeNum"
|
||||
:is-show="isShow"
|
||||
:is-reading-show-subject-info="isReadingShowSubjectInfo"
|
||||
/>
|
||||
<h2 v-else style="color:#ddd">
|
||||
Developing...
|
||||
</h2>
|
||||
</div>
|
||||
<div v-if="iseCRFShowInDicomReading && currentReadingTaskState < 2" class="form-footer">
|
||||
<el-button
|
||||
type="primary"
|
||||
size="small"
|
||||
@click="skipTask"
|
||||
>
|
||||
<!-- 跳过 -->
|
||||
{{ $t('trials:readingReport:button:skip') }}
|
||||
</el-button>
|
||||
<el-button
|
||||
type="primary"
|
||||
size="small"
|
||||
@click="submit"
|
||||
>
|
||||
<!-- 提交 -->
|
||||
{{ $t('common:button:submit') }}
|
||||
</el-button>
|
||||
</div>
|
||||
|
||||
<RecistQuestionList
|
||||
v-else-if="CriterionType !== 17"
|
||||
ref="measurementList"
|
||||
:question-form-change-state="questionFormChangeState"
|
||||
:question-form-change-num="questionFormChangeNum"
|
||||
:is-show="isShow"
|
||||
:is-reading-show-subject-info="isReadingShowSubjectInfo"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
@ -438,6 +508,21 @@
|
|||
<Manuals :trial-id="trialId" />
|
||||
</div>
|
||||
</el-dialog>
|
||||
|
||||
<!-- 签名框 -->
|
||||
<el-dialog
|
||||
v-if="signVisible"
|
||||
:visible.sync="signVisible"
|
||||
:close-on-click-modal="false"
|
||||
width="600px"
|
||||
custom-class="base-dialog-wrapper"
|
||||
>
|
||||
<div slot="title">
|
||||
<span style="font-size:18px;">{{ $t('common:dialogTitle:sign') }}</span>
|
||||
<span style="font-size:12px;margin-left:5px;user-select: text !important;">{{ `(${$t('common:label:sign')}${ currentUser })` }}</span>
|
||||
</div>
|
||||
<SignForm ref="signForm" :sign-code-enum="signCode" @closeDialog="closeSignDialog" />
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
|
@ -466,6 +551,12 @@ import WL from './WL'
|
|||
import Others from './Others'
|
||||
import DicomEvent from './DicomEvent'
|
||||
import html2canvas from 'html2canvas'
|
||||
import SignForm from '@/views/trials/components/newSignForm'
|
||||
import { getCriterionReadingInfo, verifyVisitTaskQuestions, submitDicomVisitTask } from '@/api/trials'
|
||||
import { setSkipReadingCache } from '@/api/reading'
|
||||
import { getAutoCutNextTask } from '@/api/user'
|
||||
import const_ from '@/const/sign-code'
|
||||
import { changeURLStatic } from '@/utils/history.js'
|
||||
export default {
|
||||
name: 'DicomViewer',
|
||||
components: {
|
||||
|
@ -479,7 +570,8 @@ export default {
|
|||
RecistQuestionList,
|
||||
PCWGQuestionList,
|
||||
RecistBMQuestionList,
|
||||
IRecistQuestionList
|
||||
IRecistQuestionList,
|
||||
SignForm
|
||||
},
|
||||
props: {
|
||||
isShow: {
|
||||
|
@ -499,13 +591,17 @@ export default {
|
|||
required: true
|
||||
},
|
||||
isReadingTaskViewInOrder: {
|
||||
type: Boolean,
|
||||
type: Number,
|
||||
required: true
|
||||
},
|
||||
isExistsManual: {
|
||||
type: Boolean,
|
||||
required: true
|
||||
},
|
||||
iseCRFShowInDicomReading: {
|
||||
type: Boolean,
|
||||
required: true
|
||||
},
|
||||
questionFormChangeState: {
|
||||
type: Boolean,
|
||||
default() {
|
||||
|
@ -603,7 +699,13 @@ export default {
|
|||
digitPlaces: 2,
|
||||
activeCanvasWW: null,
|
||||
activeCanvasWC: null,
|
||||
activeTaskInfo: {}
|
||||
activeTaskInfo: {},
|
||||
clipPlaying: false,
|
||||
fps: 15,
|
||||
taskId: '',
|
||||
signVisible: false,
|
||||
signCode: null,
|
||||
currentUser: zzSessionStorage.getItem('userName')
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -642,22 +744,34 @@ export default {
|
|||
activeSeries: {
|
||||
immediate: true,
|
||||
handler(v) {
|
||||
if (v && v.isCurrentTask && this.studyList.length === 0) {
|
||||
this.activeTaskInfo.taskName = v.taskBlindName
|
||||
this.activeTaskInfo.visitTaskId = v.visitTaskId
|
||||
const i = this.visitTaskList.findIndex(i => i.VisitTaskId === v.visitTaskId)
|
||||
if (i < 0) return
|
||||
this.activeTaskInfo.visitTaskIndex = i
|
||||
var studyList = this.visitTaskList[i].StudyList || []
|
||||
studyList = studyList.filter(i => !i.IsCriticalSequence && i.Modalities.indexOf('CT') !== -1 && i.Modalities.indexOf('PT') !== -1)
|
||||
if (studyList.length === 0) return
|
||||
this.studyList = studyList
|
||||
}
|
||||
// console.log('activeSeries', v)
|
||||
// if (v && v.isCurrentTask && this.studyList.length === 0) {
|
||||
// this.activeTaskInfo.taskName = v.taskBlindName
|
||||
// this.activeTaskInfo.visitTaskId = v.visitTaskId
|
||||
// const i = this.visitTaskList.findIndex(i => i.VisitTaskId === v.visitTaskId)
|
||||
// if (i < 0) return
|
||||
// this.activeTaskInfo.visitTaskIndex = i
|
||||
// var studyList = this.visitTaskList[i].StudyList || []
|
||||
// studyList = studyList.filter(i => !i.IsCriticalSequence && i.Modalities.indexOf('CT') !== -1 && i.Modalities.indexOf('PT') !== -1)
|
||||
// if (studyList.length === 0) return
|
||||
// this.studyList = studyList
|
||||
// }
|
||||
}
|
||||
},
|
||||
imageQualityIssues: {
|
||||
immediate: true,
|
||||
handler(v) {}
|
||||
},
|
||||
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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
},
|
||||
|
@ -675,6 +789,10 @@ export default {
|
|||
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: '' }]
|
||||
} else if (this.CriterionType === 19) {
|
||||
this.measuredTools = []
|
||||
} else if (this.CriterionType === 20) {
|
||||
this.measuredTools = []
|
||||
}
|
||||
this.rotateList[0] = '1'
|
||||
this.colorList[0] = ''
|
||||
|
@ -717,6 +835,7 @@ export default {
|
|||
)
|
||||
var canvas = await html2canvas(divForDownloadViewport)
|
||||
var base64Str = canvas.toDataURL('image/png', 1)
|
||||
console.log('getScreenshots')
|
||||
callback(base64Str)
|
||||
}, 50)
|
||||
}
|
||||
|
@ -772,6 +891,10 @@ export default {
|
|||
if (!this.petctWindow) return
|
||||
this.petctWindow.postMessage({ type: 'readingPageUpdate', data: data }, window.location)
|
||||
})
|
||||
DicomEvent.$on('resetPage', () => {
|
||||
if (!this.petctWindow) return
|
||||
this.petctWindow.postMessage({ type: 'resetPage' }, window.location)
|
||||
})
|
||||
DicomEvent.$on('setReadingState', (data) => {
|
||||
if (!this.petctWindow) return
|
||||
this.petctWindow.postMessage({ type: 'setReadingState', data: data }, window.location)
|
||||
|
@ -809,28 +932,30 @@ export default {
|
|||
})
|
||||
},
|
||||
methods: {
|
||||
getWwcTpl() {
|
||||
const loading = this.$loading({ fullscreen: true })
|
||||
getUserWLTemplateList().then(res => {
|
||||
async getWwcTpl() {
|
||||
// const loading = this.$loading({ fullscreen: true })
|
||||
try {
|
||||
const res = await getUserWLTemplateList()
|
||||
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() })
|
||||
} catch (e) {
|
||||
console.log(e)
|
||||
}
|
||||
},
|
||||
getHotKeys() {
|
||||
const loading = this.$loading({ fullscreen: true })
|
||||
getDoctorShortcutKey({ imageToolType: 0 }).then(res => {
|
||||
async getHotKeys() {
|
||||
// const loading = this.$loading({ fullscreen: true })
|
||||
try {
|
||||
const res = await getDoctorShortcutKey({ imageToolType: 0 })
|
||||
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()
|
||||
})
|
||||
} catch (e) {
|
||||
console.log(e)
|
||||
}
|
||||
},
|
||||
resetHotkeyList(arr) {
|
||||
this.hotKeyList = []
|
||||
|
@ -853,7 +978,7 @@ export default {
|
|||
var container = this.$refs['container']
|
||||
// window.addEventListener
|
||||
container.addEventListener('keydown', event => {
|
||||
console.log(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)
|
||||
|
@ -992,7 +1117,8 @@ export default {
|
|||
store.dispatch('reading/setActiveSeries', series)
|
||||
store.dispatch('reading/setLastCanvasTaskId', series.visitTaskId)
|
||||
}
|
||||
this.$refs[`dicomCanvas${index}`][0].loadImageStack(series)
|
||||
const s = Object.assign({}, series)
|
||||
this.$refs[`dicomCanvas${index}`][0].loadImageStack(s)
|
||||
|
||||
if (this.activeTool) {
|
||||
if (series.isCurrentTask && series.readingTaskState < 2) {
|
||||
|
@ -1010,10 +1136,13 @@ export default {
|
|||
})
|
||||
},
|
||||
loadImageStack(dicomSeries) {
|
||||
this.clipPlaying = false
|
||||
this.fps = 15
|
||||
this.canvasObj[this.currentDicomCanvasIndex] = dicomSeries
|
||||
this.$nextTick(() => {
|
||||
this.activeSeries = dicomSeries
|
||||
this.$refs[`dicomCanvas${this.currentDicomCanvasIndex}`][0].loadImageStack(dicomSeries).then(res => {
|
||||
const s = Object.assign({}, dicomSeries)
|
||||
this.$refs[`dicomCanvas${this.currentDicomCanvasIndex}`][0].loadImageStack(s).then(res => {
|
||||
if (this.activeTool) {
|
||||
if (dicomSeries.isCurrentTask && dicomSeries.readingTaskState < 2) {
|
||||
this.$nextTick(() => {
|
||||
|
@ -1074,7 +1203,8 @@ export default {
|
|||
// }
|
||||
this.$nextTick(() => {
|
||||
this.activeSeries = dicomSeries
|
||||
this.$refs[`dicomCanvas${canvasIndex}`][0].loadImageStack(dicomSeries)
|
||||
const s = Object.assign({}, dicomSeries)
|
||||
this.$refs[`dicomCanvas${canvasIndex}`][0].loadImageStack(s)
|
||||
|
||||
store.dispatch('reading/setActiveSeries', dicomSeries)
|
||||
if (this.currentDicomCanvasIndex === this.maxCanvas - 1) {
|
||||
|
@ -1149,7 +1279,8 @@ export default {
|
|||
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]))
|
||||
const s = Object.assign({}, seriesStack[i])
|
||||
promiseArr.push(this.$refs[`dicomCanvas${i}`][0].loadImageStack(s))
|
||||
}
|
||||
Promise.all(promiseArr).then(() => {
|
||||
// this.activateDicomCanvas(this.currentDicomCanvasIndex)
|
||||
|
@ -1181,7 +1312,7 @@ export default {
|
|||
|
||||
var firstAddSeries = null
|
||||
var currentAddSeries = null
|
||||
if (this.isReadingTaskViewInOrder) {
|
||||
if (this.isReadingTaskViewInOrder === 1) {
|
||||
// 有序
|
||||
// 获取病灶第一次出现的访视序列
|
||||
var firstAddVisitTaskId = null
|
||||
|
@ -1252,12 +1383,14 @@ export default {
|
|||
|
||||
for (let i = 0; i < this.maxCanvas; i++) {
|
||||
if (i === this.maxCanvas - 1) {
|
||||
loadImagePromises.push(this.$refs[`dicomCanvas${i}`][0].loadImageStack(currentAddSeries))
|
||||
const s = Object.assign({}, currentAddSeries)
|
||||
loadImagePromises.push(this.$refs[`dicomCanvas${i}`][0].loadImageStack(s))
|
||||
this.currentDicomCanvasIndex = i
|
||||
this.activeSeries = currentAddSeries
|
||||
store.dispatch('reading/setActiveSeries', currentAddSeries)
|
||||
} else {
|
||||
loadImagePromises.push(this.$refs[`dicomCanvas${i}`][0].loadImageStack(firstAddSeries))
|
||||
const s = Object.assign({}, firstAddSeries)
|
||||
loadImagePromises.push(this.$refs[`dicomCanvas${i}`][0].loadImageStack(s))
|
||||
}
|
||||
}
|
||||
Promise.all(loadImagePromises)
|
||||
|
@ -1331,7 +1464,9 @@ export default {
|
|||
var seriesIdx = studyList[studyIdx].SeriesList.findIndex(s => s.seriesId === seriesId)
|
||||
if (seriesIdx > -1) {
|
||||
var series = studyList[studyIdx].SeriesList[seriesIdx]
|
||||
var instanceIdx = series.instanceList.findIndex(imageId => !!~imageId.indexOf(instanceId))
|
||||
const frame = this.visitTaskList[index].MeasureData[idx].MeasureData.frame
|
||||
const filterStr = series.isExistMutiFrames ? `frame=${frame}&instanceId=${instanceId}` : `instanceId=${instanceId}`
|
||||
var instanceIdx = series.imageIds.findIndex(imageId => imageId.includes(filterStr))
|
||||
if (instanceIdx > -1) {
|
||||
series.imageIdIndex = instanceIdx
|
||||
seriesInfo = series
|
||||
|
@ -1687,6 +1822,31 @@ export default {
|
|||
}
|
||||
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)
|
||||
|
@ -1779,7 +1939,109 @@ export default {
|
|||
previewManuals() {
|
||||
this.isFullscreen = false
|
||||
this.manualsDialog.visible = true
|
||||
}
|
||||
},
|
||||
async skipTask() {
|
||||
// 是否确认跳过?
|
||||
const confirm = await this.$confirm(
|
||||
this.$t('trials:readingReport:message:skipConfirm'),
|
||||
{
|
||||
type: 'warning',
|
||||
distinguishCancelAndClose: true
|
||||
}
|
||||
)
|
||||
if (confirm !== 'confirm') return
|
||||
// const loading = this.$loading({ fullscreen: true })
|
||||
try {
|
||||
const idx = this.visitTaskList.findIndex(i => i.IsCurrentTask)
|
||||
if (idx > -1) {
|
||||
var visitTaskId = this.visitTaskList[idx].VisitTaskId
|
||||
const res = await setSkipReadingCache({ visitTaskId: visitTaskId })
|
||||
if (res.IsSuccess) {
|
||||
window.location.reload()
|
||||
}
|
||||
}
|
||||
// loading.close()
|
||||
} catch (e) {
|
||||
// loading.close()
|
||||
console.log(e)
|
||||
}
|
||||
},
|
||||
async submit() {
|
||||
const loading = this.$loading({ fullscreen: true })
|
||||
try {
|
||||
const idx = this.visitTaskList.findIndex(i => i.IsCurrentTask)
|
||||
if (idx > -1) {
|
||||
var visitTaskId = this.visitTaskList[idx].VisitTaskId
|
||||
this.taskId = visitTaskId
|
||||
await verifyVisitTaskQuestions({ visitTaskId: visitTaskId })
|
||||
const { ImageAssessmentReportConfirmation } = const_.processSignature
|
||||
this.signCode = ImageAssessmentReportConfirmation
|
||||
this.signVisible = true
|
||||
}
|
||||
loading.close()
|
||||
} catch (e) {
|
||||
loading.close()
|
||||
}
|
||||
},
|
||||
// 关闭签名框
|
||||
closeSignDialog(isSign, signInfo) {
|
||||
if (isSign) {
|
||||
this.signConfirm(signInfo)
|
||||
} else {
|
||||
this.signVisible = false
|
||||
}
|
||||
},
|
||||
// 签名并确认
|
||||
async signConfirm(signInfo) {
|
||||
this.loading = true
|
||||
try {
|
||||
var params = {
|
||||
data: {
|
||||
visitTaskId: this.taskId
|
||||
},
|
||||
signInfo: signInfo
|
||||
}
|
||||
const res = await submitDicomVisitTask(params)
|
||||
if (res.IsSuccess) {
|
||||
this.$message.success(this.$t('common:message:savedSuccessfully'))
|
||||
if (this.$refs['signForm']) {
|
||||
this.$refs['signForm'].btnLoading = false
|
||||
}
|
||||
|
||||
this.signVisible = false
|
||||
|
||||
// 设置当前任务阅片状态为已读
|
||||
this.readingTaskState = 2
|
||||
await store.dispatch('reading/setVisitTaskReadingTaskState', { visitTaskId: this.visitTaskId, readingTaskState: 2 })
|
||||
await store.dispatch('reading/setCurrentReadingTaskState', 2)
|
||||
const res = await getAutoCutNextTask()
|
||||
var isAutoTask = res.Result.AutoCutNextTask
|
||||
if (isAutoTask) {
|
||||
window.location.reload()
|
||||
} else {
|
||||
// '当前阅片任务已完成,是否进入下一个阅片任务?'
|
||||
this.$confirm(this.$t('trials:readingReport:message:msg4'), {
|
||||
type: 'warning',
|
||||
distinguishCancelAndClose: true
|
||||
})
|
||||
.then(() => {
|
||||
window.location.reload()
|
||||
})
|
||||
.catch(action => {
|
||||
changeURLStatic('visitTaskId', this.visitTaskId)
|
||||
})
|
||||
}
|
||||
|
||||
window.opener.postMessage('refreshTaskList', window.location)
|
||||
}
|
||||
this.loading = false
|
||||
} catch (e) {
|
||||
this.loading = false
|
||||
if (this.$refs['signForm'] && this.$refs['signForm'].btnLoading) {
|
||||
this.$refs['signForm'].btnLoading = false
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
@ -1832,7 +2094,7 @@ export default {
|
|||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
margin-right: 30px;
|
||||
margin-right: 20px;
|
||||
.icon{
|
||||
padding: 5px;
|
||||
border: 1px solid #404040;
|
||||
|
@ -1851,6 +2113,39 @@ export default {
|
|||
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;
|
||||
}
|
||||
|
@ -1963,9 +2258,22 @@ export default {
|
|||
.form-container{
|
||||
// box-sizing: border-box;
|
||||
width: 350px;
|
||||
height: 100%;
|
||||
// height: 100vh;
|
||||
border: 1px solid #727272;
|
||||
// overflow-y: auto;
|
||||
// position: relative;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
}
|
||||
.form-wrapper{
|
||||
flex-grow: 1;
|
||||
height: 0;
|
||||
overflow: hidden;
|
||||
}
|
||||
.form-footer{
|
||||
background: #000;
|
||||
padding: 10px 0;
|
||||
text-align: center;
|
||||
}
|
||||
.viewer-container{
|
||||
box-sizing: border-box;
|
||||
|
|
|
@ -56,22 +56,25 @@ export default {
|
|||
this.getHotkeys()
|
||||
},
|
||||
methods: {
|
||||
getHotkeys(isReset = false) {
|
||||
async getHotkeys(isReset = false) {
|
||||
this.loading = true
|
||||
this.hotKeyList = []
|
||||
getDoctorShortcutKey({ imageToolType: this.readingTool }).then(res => {
|
||||
res.Result.map(item => {
|
||||
this.hotKeyList.push({ id: item.Id, keys: { controlKey: { altKey: item.AltKey, ctrlKey: item.CtrlKey, shiftKey: item.ShiftKey, metaKey: item.MetaKey, key: item.Keyboardkey, code: item.Code }, text: item.Text }, label: item.ShortcutKeyEnum })
|
||||
})
|
||||
if (isReset) {
|
||||
this.$emit('reset', this.hotKeyList)
|
||||
try {
|
||||
const res = await getDoctorShortcutKey({ imageToolType: this.readingTool })
|
||||
if (res.IsSuccess) {
|
||||
res.Result.map(item => {
|
||||
this.hotKeyList.push({ id: item.Id, keys: { controlKey: { altKey: item.AltKey, ctrlKey: item.CtrlKey, shiftKey: item.ShiftKey, metaKey: item.MetaKey, key: item.Keyboardkey, code: item.Code }, text: item.Text }, label: item.ShortcutKeyEnum })
|
||||
})
|
||||
if (isReset) {
|
||||
this.$emit('reset', this.hotKeyList)
|
||||
}
|
||||
}
|
||||
this.loading = false
|
||||
}).catch(() => {
|
||||
} catch (e) {
|
||||
this.loading = false
|
||||
})
|
||||
}
|
||||
},
|
||||
handleSave() {
|
||||
async handleSave() {
|
||||
var params = {
|
||||
imageToolType: this.readingTool,
|
||||
shortcutKeyList: []
|
||||
|
@ -86,17 +89,15 @@ export default {
|
|||
emptyLabel = item.label
|
||||
break
|
||||
} else {
|
||||
shortcutKeyList.push(
|
||||
{
|
||||
shortcutKeyEnum: item.label,
|
||||
keyboardkey: item.keys.controlKey.key,
|
||||
code: item.keys.controlKey.code,
|
||||
text: item.keys.text,
|
||||
altKey: item.keys.controlKey.altKey,
|
||||
ctrlKey: item.keys.controlKey.ctrlKey,
|
||||
shiftKey: item.keys.controlKey.shiftKey,
|
||||
metaKey: item.keys.controlKey.metaKey }
|
||||
)
|
||||
shortcutKeyList.push({
|
||||
shortcutKeyEnum: item.label,
|
||||
keyboardkey: item.keys.controlKey.key,
|
||||
code: item.keys.controlKey.code,
|
||||
text: item.keys.text,
|
||||
altKey: item.keys.controlKey.altKey,
|
||||
ctrlKey: item.keys.controlKey.ctrlKey,
|
||||
shiftKey: item.keys.controlKey.shiftKey,
|
||||
metaKey: item.keys.controlKey.metaKey })
|
||||
}
|
||||
}
|
||||
if (isExistEmptyText) {
|
||||
|
@ -112,43 +113,40 @@ export default {
|
|||
})
|
||||
} else {
|
||||
this.loading = true
|
||||
// this.hotKeyList.map(item => {
|
||||
// shortcutKeyList.push(
|
||||
// {
|
||||
// shortcutKeyEnum: item.label,
|
||||
// keyboardkey: item.keys.controlKey.key,
|
||||
// code: item.keys.controlKey.code,
|
||||
// text: item.keys.text,
|
||||
// altKey: item.keys.controlKey.altKey,
|
||||
// ctrlKey: item.keys.controlKey.ctrlKey,
|
||||
// shiftKey: item.keys.controlKey.shiftKey,
|
||||
// metaKey: item.keys.controlKey.metaKey }
|
||||
// )
|
||||
// })
|
||||
params.shortcutKeyList = shortcutKeyList
|
||||
setShortcutKey(params).then(res => {
|
||||
this.$emit('reset', this.hotKeyList)
|
||||
// this.$emit('close')
|
||||
try {
|
||||
const res = await setShortcutKey(params)
|
||||
if (res.IsSuccess) {
|
||||
this.$emit('reset', this.hotKeyList)
|
||||
}
|
||||
this.loading = false
|
||||
}).catch(() => {
|
||||
} catch (e) {
|
||||
this.loading = false
|
||||
})
|
||||
}
|
||||
}
|
||||
},
|
||||
handleReset() {
|
||||
async handleReset() {
|
||||
// '是否确认重置?'
|
||||
this.$confirm(this.$t('trials:hotkeys:message:confirmReset'), {
|
||||
type: 'warning',
|
||||
distinguishCancelAndClose: true
|
||||
})
|
||||
.then(() => {
|
||||
this.loading = true
|
||||
restoreDefaultShortcutKey({ imageToolType: this.readingTool }).then(res => {
|
||||
this.$message.success(this.$t('trials:hotkeys:message:resetSuccessfully')) // '重置成功!'
|
||||
this.getHotkeys(true)
|
||||
}).catch(() => { this.loading = false })
|
||||
})
|
||||
.catch(action => {})
|
||||
const confirm = await this.$confirm(
|
||||
this.$t('trials:hotkeys:message:confirmReset'),
|
||||
{
|
||||
type: 'warning',
|
||||
distinguishCancelAndClose: true
|
||||
}
|
||||
)
|
||||
if (confirm !== 'confirm') return
|
||||
|
||||
this.loading = true
|
||||
try {
|
||||
const res = await restoreDefaultShortcutKey({ imageToolType: this.readingTool })
|
||||
if (res.IsSuccess) {
|
||||
this.$message.success(this.$t('trials:hotkeys:message:resetSuccessfully')) // '重置成功!'
|
||||
this.getHotkeys(true)
|
||||
}
|
||||
this.loading = false
|
||||
} catch (e) {
|
||||
this.loading = false
|
||||
}
|
||||
},
|
||||
handleHotkeyVerify(hotkey) {
|
||||
for (const item of this.hotKeyList) {
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,11 +1,21 @@
|
|||
<template>
|
||||
<div class="measurement-wrapper" :style="{'height':height+10+'px'}">
|
||||
<div class="measurement-wrapper">
|
||||
|
||||
<div class="container" :style="{'height':height+'px'}">
|
||||
<h3 v-if="isReadingShowSubjectInfo" style="color: #ddd;padding: 5px 0px;margin: 0;">
|
||||
<span v-if="subjectCode">{{ subjectCode }} </span>
|
||||
<span style="margin-left:5px;">{{ taskBlindName }}</span>
|
||||
</h3>
|
||||
<div class="container">
|
||||
<div class="basic-info">
|
||||
<h3 v-if="isReadingShowSubjectInfo">
|
||||
<span v-if="subjectCode">{{ subjectCode }} </span>
|
||||
<span style="margin-left:5px;">{{ taskBlindName }}</span>
|
||||
</h3>
|
||||
<div v-if="readingTaskState < 2">
|
||||
<el-tooltip class="item" effect="dark" :content="$t('trials:dicomReading:message:confirmReset')" placement="bottom">
|
||||
<i
|
||||
class="el-icon-refresh-left"
|
||||
@click="resetMeasuredData"
|
||||
/>
|
||||
</el-tooltip>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 非测量问题 -->
|
||||
<div class="lesions">
|
||||
<Questions
|
||||
|
@ -29,7 +39,7 @@
|
|||
class="title"
|
||||
>
|
||||
{{ item.QuestionName }}
|
||||
<span v-if="isFirstChangeTask && item.TableQuestions.Answers.length > 0" style="color:red;font-size: 12px;">(请重新评估)</span>
|
||||
<span v-if="isFirstChangeTask && item.TableQuestions.Answers.length > 0" style="color:red;font-size: 12px;">{{ $t("trials:reading:dicom:IRecist:reevaluate") }}</span>
|
||||
</div>
|
||||
<div v-else class="title">
|
||||
{{ item.QuestionName }}
|
||||
|
@ -157,6 +167,7 @@
|
|||
</template>
|
||||
<script>
|
||||
import { splitLesion } from '@/api/trials'
|
||||
import { resetReadingTask } from '@/api/reading'
|
||||
import DicomEvent from './../DicomEvent'
|
||||
import store from '@/store'
|
||||
import { mapGetters } from 'vuex'
|
||||
|
@ -192,7 +203,6 @@ export default {
|
|||
},
|
||||
data() {
|
||||
return {
|
||||
height: window.innerHeight - 140,
|
||||
questions: [],
|
||||
activeName: '',
|
||||
activeItem: {
|
||||
|
@ -237,7 +247,8 @@ export default {
|
|||
}
|
||||
},
|
||||
mounted() {
|
||||
this.subjectCode = this.$router.currentRoute.query.subjectCode
|
||||
// this.subjectCode = this.$router.currentRoute.query.subjectCode
|
||||
this.subjectCode = localStorage.getItem('subjectCode')
|
||||
window.addEventListener('message', this.receiveMsg)
|
||||
this.criterionType = parseInt(localStorage.getItem('CriterionType'))
|
||||
DicomEvent.$on('setCollapseActive', measureData => {
|
||||
|
@ -257,8 +268,6 @@ export default {
|
|||
DicomEvent.$on('split', measureData => {
|
||||
this.handleSplit(measureData.RowId, measureData.QuestionId)
|
||||
})
|
||||
|
||||
window.addEventListener('resize', this.setHeight)
|
||||
},
|
||||
beforeDestroy() {
|
||||
DicomEvent.$off('setCollapseActive')
|
||||
|
@ -445,9 +454,6 @@ export default {
|
|||
} catch (e) { console.log(e) }
|
||||
})
|
||||
},
|
||||
setHeight() {
|
||||
this.height = window.innerHeight - 140
|
||||
},
|
||||
getQuestionAnswer(questions, questionMark, answers) {
|
||||
var idx = questions.findIndex(i => i.QuestionMark === questionMark)
|
||||
if (idx > -1) {
|
||||
|
@ -577,15 +583,15 @@ export default {
|
|||
}
|
||||
}
|
||||
},
|
||||
split(rowId, questionId) {
|
||||
async split(rowId, questionId) {
|
||||
const loading = this.$loading({ fullscreen: true })
|
||||
var params = {
|
||||
visitTaskId: this.visitTaskId,
|
||||
questionId: questionId,
|
||||
rowId: rowId
|
||||
}
|
||||
splitLesion(params).then(async res => {
|
||||
loading.close()
|
||||
try {
|
||||
var params = {
|
||||
visitTaskId: this.visitTaskId,
|
||||
questionId: questionId,
|
||||
rowId: rowId
|
||||
}
|
||||
await splitLesion(params)
|
||||
await this.getReadingQuestionAndAnswer()
|
||||
this.$nextTick(() => {
|
||||
this.tableQuestions.forEach(item => {
|
||||
|
@ -595,7 +601,11 @@ export default {
|
|||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
loading.close()
|
||||
} catch (e) {
|
||||
loading.close()
|
||||
console.log(e)
|
||||
}
|
||||
},
|
||||
isCanActiveTool(toolName) {
|
||||
console.log('isCanActiveTool')
|
||||
|
@ -907,7 +917,6 @@ export default {
|
|||
await store.dispatch('reading/removeMeasuredData', { visitTaskId: this.visitTaskId, measureData: questionsObj.measureData, questionId: questionsObj.questionId, rowIndex: questionsObj.rowIndex })
|
||||
|
||||
questionsObj.measureData.data.remark = lesionMark
|
||||
lesionObj.MarkTool = questionsObj.measureData.type
|
||||
lesionObj.MeasureData = JSON.stringify(questionsObj.measureData)
|
||||
}
|
||||
|
||||
|
@ -1068,6 +1077,39 @@ export default {
|
|||
getECRFQuestions(obj) {
|
||||
this.$refs['ecrf'].getQuestions(obj.visitTaskId)
|
||||
},
|
||||
async resetMeasuredData() {
|
||||
const confirm = await this.$confirm(
|
||||
this.$t('trials:dicomReading:message:confirmReset1'),
|
||||
this.$t('trials:dicomReading:message:confirmReset2'),
|
||||
{
|
||||
type: 'warning',
|
||||
distinguishCancelAndClose: true
|
||||
}
|
||||
)
|
||||
if (confirm !== 'confirm') return
|
||||
const loading = this.$loading({ fullscreen: true })
|
||||
try {
|
||||
const res = await resetReadingTask({ visitTaskId: this.visitTaskId })
|
||||
this.loading = false
|
||||
if (res.IsSuccess) {
|
||||
// 刷新标注、表单、报告页信息
|
||||
this.activeName = ''
|
||||
this.activeItem.activeRowIndex = null
|
||||
this.activeItem.activeCollapseId = null
|
||||
await this.getReadingQuestionAndAnswer(this.visitTaskId)
|
||||
const triald = this.$router.currentRoute.query.trialId
|
||||
await store.dispatch('reading/refreshDicomReadingQuestionAnswer', { trialId: triald, visitTaskId: this.visitTaskId })
|
||||
this.$refs['ecrf'].getQuestions(this.visitTaskId, true)
|
||||
DicomEvent.$emit('getMeasureData')
|
||||
DicomEvent.$emit('getReportInfo', true)
|
||||
DicomEvent.$emit('refreshStudyListMeasureData')
|
||||
}
|
||||
loading.close()
|
||||
} catch (e) {
|
||||
loading.close()
|
||||
console.log(e)
|
||||
}
|
||||
},
|
||||
receiveMsg(event) {
|
||||
if (event.data.type === 'isCanActiveNoneDicomTool') {
|
||||
this.getUnSaveTarget()
|
||||
|
@ -1135,11 +1177,28 @@ export default {
|
|||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.measurement-wrapper{
|
||||
height: 100%;
|
||||
overflow-y: auto;
|
||||
// overflow: hidden;
|
||||
|
||||
.container{
|
||||
padding: 10px;
|
||||
.basic-info{
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
h3{
|
||||
color: #ddd;
|
||||
padding: 5px 0px;
|
||||
margin: 0;
|
||||
}
|
||||
i{
|
||||
color: #fff;
|
||||
font-size: 22px;
|
||||
font-weight: bold;
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
}
|
||||
.title{
|
||||
padding: 5px;
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
</div>
|
||||
<div class="right-wrapper">
|
||||
<div class="right-content">
|
||||
<iframe v-if="selected.filePath" :src="`/static/pdfjs/web/viewer.html?file=${OSSclientConfig.basePath}${selected.filePath}?userName=${currentUser}`" width="100%" height="100%" frameborder="0" />
|
||||
<iframe v-if="selected.filePath" :src="`/static/pdfjs/web/viewer.html?file=${OSSclientConfig.basePath}${selected.filePath}?userName=${currentUser}&COMPANY=${COMPANY}`" width="100%" height="100%" frameborder="0" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -44,26 +44,31 @@ export default {
|
|||
},
|
||||
fileList: [],
|
||||
loading: false,
|
||||
currentUser: zzSessionStorage.getItem('userName')
|
||||
currentUser: zzSessionStorage.getItem('userName'),
|
||||
COMPANY:process.env.VUE_APP_COMPANY_NAME
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.getList()
|
||||
},
|
||||
methods: {
|
||||
getList() {
|
||||
async getList() {
|
||||
this.loading = true
|
||||
var param = {
|
||||
trialId: this.trialId
|
||||
}
|
||||
getManualList(param).then(res => {
|
||||
this.fileList = res.Result
|
||||
|
||||
if (this.fileList.length > 0) {
|
||||
this.preview(this.fileList[0])
|
||||
try {
|
||||
var param = {
|
||||
trialId: this.trialId
|
||||
}
|
||||
const res = await getManualList(param)
|
||||
if (res.IsSuccess) {
|
||||
this.fileList = res.Result
|
||||
if (this.fileList.length > 0) {
|
||||
this.preview(this.fileList[0])
|
||||
}
|
||||
}
|
||||
this.loading = false
|
||||
}).catch(() => { this.loading = false })
|
||||
} catch (e) {
|
||||
this.loading = false
|
||||
}
|
||||
},
|
||||
preview(file) {
|
||||
this.$set(this.selected, 'filePath', file.Path)
|
||||
|
|
|
@ -76,9 +76,10 @@
|
|||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import { getTableAnswerRowInfoList } from '@/api/trials'
|
||||
import { on, off } from 'element-ui/src/utils/dom'
|
||||
import { rafThrottle, isFirefox } from 'element-ui/src/utils/util'
|
||||
import store from '@/store'
|
||||
// import store from '@/store'
|
||||
const mousewheelEventName = isFirefox() ? 'DOMMouseScroll' : 'mousewheel'
|
||||
var ctx = '' // 画布上下文
|
||||
export default {
|
||||
|
@ -223,15 +224,26 @@ export default {
|
|||
return new Promise(async resolve => {
|
||||
this.visitTaskId = this.$router.currentRoute.query.visitTaskId
|
||||
this.canvasData = []
|
||||
await store.dispatch('reading/getMeasuredData', this.visitTaskId)
|
||||
await store.dispatch('reading/getNoneDicomMeasuredData', this.visitTaskId).then(res => {
|
||||
res.forEach(item => {
|
||||
if (item && item.MeasureData) {
|
||||
this.canvasData.push(item.MeasureData)
|
||||
const res = await getTableAnswerRowInfoList(this.visitTaskId)
|
||||
res.Result.forEach(el => {
|
||||
if (!el.IsDicomReading) {
|
||||
if (el.MeasureData) {
|
||||
el.MeasureData = JSON.parse(el.MeasureData)
|
||||
el.MeasureData.data.remark = el.OrderMarkName
|
||||
this.canvasData.push(el.MeasureData)
|
||||
}
|
||||
})
|
||||
sessionStorage.setItem('measureData', this.canvasData)
|
||||
}
|
||||
})
|
||||
sessionStorage.setItem('measureData', this.canvasData)
|
||||
// await store.dispatch('reading/getMeasuredData', this.visitTaskId)
|
||||
// await store.dispatch('reading/getNoneDicomMeasuredData', this.visitTaskId).then(res => {
|
||||
// res.forEach(item => {
|
||||
// if (item && item.MeasureData) {
|
||||
// this.canvasData.push(item.MeasureData)
|
||||
// }
|
||||
// })
|
||||
// sessionStorage.setItem('measureData', this.canvasData)
|
||||
// })
|
||||
resolve()
|
||||
})
|
||||
},
|
||||
|
|
|
@ -31,7 +31,7 @@
|
|||
/>
|
||||
<div ref="imagesWrapper" class="images">
|
||||
<div v-if="noData" class="empty-text">
|
||||
<slot name="empty">暂无数据</slot>
|
||||
<slot name="empty">{{ $t('trial:reading:noneDicoms:noData') }}</slot>
|
||||
</div>
|
||||
<div v-show="!noData" class="items" :style="itemsStyle">
|
||||
<div
|
||||
|
|
|
@ -36,27 +36,31 @@ export default {
|
|||
this.initForm()
|
||||
},
|
||||
methods: {
|
||||
initForm() {
|
||||
async initForm() {
|
||||
this.loading = true
|
||||
getAutoCutNextTask().then(async res => {
|
||||
this.form.AutoCutNextTask = res.Result.AutoCutNextTask
|
||||
this.loading = false
|
||||
}).catch(() => {
|
||||
this.loading = false
|
||||
})
|
||||
},
|
||||
handleSave() {
|
||||
this.$refs.otherForm.validate((valid) => {
|
||||
if (valid) {
|
||||
this.loading = true
|
||||
setAutoCutNextTask(this.form).then((res) => {
|
||||
this.loading = false
|
||||
this.$message.success(this.$t('common:message:savedSuccessfully'))
|
||||
}).catch(() => {
|
||||
this.loading = false
|
||||
})
|
||||
try {
|
||||
const res = await getAutoCutNextTask()
|
||||
if (res.IsSuccess) {
|
||||
this.form.AutoCutNextTask = res.Result.AutoCutNextTask
|
||||
}
|
||||
})
|
||||
this.loading = false
|
||||
} catch (e) {
|
||||
this.loading = false
|
||||
}
|
||||
},
|
||||
async handleSave() {
|
||||
const valid = await this.$refs.otherForm.validate()
|
||||
if (!valid) return
|
||||
this.loading = true
|
||||
try {
|
||||
const res = await setAutoCutNextTask(this.form)
|
||||
if (res.IsSuccess) {
|
||||
this.$message.success(this.$t('common:message:savedSuccessfully'))
|
||||
}
|
||||
this.loading = false
|
||||
} catch (e) {
|
||||
this.loading = false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -69,7 +69,7 @@
|
|||
@focus="focusQs = {...qs}"
|
||||
@change="((val)=>{formItemChange(val, qs)})"
|
||||
>
|
||||
<template v-if="qs.Unit" slot="append">
|
||||
<template v-if="(qs.QuestionMark===0 || qs.QuestionMark===1) && qs.Unit" slot="append">
|
||||
{{ $fd('ValueUnit', parseInt(qs.Unit)) }}
|
||||
</template>
|
||||
</el-input>
|
||||
|
@ -296,7 +296,7 @@ export default {
|
|||
} else if (!reg.test(value) || (parseInt(value) > 99 || parseInt(value) <= 0)) {
|
||||
callback(new Error(this.$t('trials:readingPGWC:warnning:msg1')))
|
||||
} else if (parseInt(value) > parseInt(this.questionForm.BaseLineLesionNumber)) {
|
||||
callback(new Error(this.$t('trials:reading:pcwg:msg6') + this.questionForm.BaseLineLesionNumber + this.$fd('ValueUnit', 3)))
|
||||
callback(new Error(this.$t('trials:reading:pcwg:msg6') + this.questionForm.BaseLineLesionNumber))
|
||||
} else {
|
||||
callback()
|
||||
}
|
||||
|
@ -484,8 +484,8 @@ export default {
|
|||
|
||||
const lesionPart = this.getQuestionVal(8)
|
||||
const lesionOrgan = this.getQuestionVal(6)
|
||||
const lesionState = Number(this.getQuestionVal(7))
|
||||
const lesionNum = Number(this.getQuestionVal(11))
|
||||
const lesionState = this.getQuestionVal(7)
|
||||
const lesionNum = this.getQuestionVal(11)
|
||||
this.$emit('resetQuestions', { lesionPart, lesionOrgan, lesionState, saveTypeEnum: this.questionForm.saveTypeEnum, lesionNum, rowIndex: this.rowIndex, questionId: this.parentQsId, anwsers: this.questionForm })
|
||||
},
|
||||
|
||||
|
@ -547,8 +547,8 @@ export default {
|
|||
this.$set(this.questionForm, 'MeasureData', measureData)
|
||||
const lesionPart = this.getQuestionVal(8)
|
||||
const lesionOrgan = this.getQuestionVal(6)
|
||||
const lesionState = Number(this.getQuestionVal(7))
|
||||
const lesionNum = Number(this.getQuestionVal(11))
|
||||
const lesionState = this.getQuestionVal(7)
|
||||
const lesionNum = this.getQuestionVal(11)
|
||||
|
||||
this.$emit('resetQuestions', { lesionPart, lesionOrgan, lesionState, lesionNum, saveTypeEnum: this.questionForm.saveTypeEnum, rowIndex: this.rowIndex, questionId: this.parentQsId, anwsers: this.questionForm })
|
||||
this.toolType = measureData.type
|
||||
|
@ -572,10 +572,15 @@ export default {
|
|||
}
|
||||
},
|
||||
getQuestionVal(questionMark) {
|
||||
var idx = this.questions.findIndex(i => i.QuestionMark === questionMark)
|
||||
const idx = this.questions.findIndex(i => i.QuestionMark === questionMark)
|
||||
if (idx > -1) {
|
||||
var questionId = this.questions[idx].Id
|
||||
return this.questionForm[questionId]
|
||||
const questionId = this.questions[idx].Id
|
||||
const answer = this.questionForm[questionId]
|
||||
if (isNaN(parseFloat(answer))) {
|
||||
return answer
|
||||
} else {
|
||||
return parseFloat(answer)
|
||||
}
|
||||
} else {
|
||||
return ''
|
||||
}
|
||||
|
@ -619,82 +624,83 @@ export default {
|
|||
// 生成Blob对象(文件对象)
|
||||
return new Blob([bytesCode], { type: imgtype })
|
||||
},
|
||||
handleSave() {
|
||||
this.$refs.measurementForm.validate(async valid => {
|
||||
if (!valid) return
|
||||
var lesionState = this.getQuestionVal(7)
|
||||
var measureData = this.questionForm.MeasureData
|
||||
// 非基线
|
||||
if (!this.isBaseLineTask) {
|
||||
// 新病灶 2
|
||||
// 病灶状态为“存在”的新病灶,请使用箭头工具添加标记2
|
||||
if (this.lesionType === 2 && lesionState === 2) {
|
||||
if (!(measureData && measureData.type === 'ArrowAnnotate')) {
|
||||
this.$confirm(this.$t('trials:readingPGWC:warnning:msg2'), {
|
||||
type: 'warning',
|
||||
showCancelButton: false,
|
||||
callback: action => {}
|
||||
})
|
||||
loading.close()
|
||||
return
|
||||
}
|
||||
}
|
||||
// 既往新病灶 3
|
||||
// 病灶状态为“存在”的既往新病灶,请使用箭头工具添加标记2
|
||||
if (this.lesionType === 3 && lesionState === 2) {
|
||||
if (!(measureData && measureData.type === 'ArrowAnnotate')) {
|
||||
this.$confirm(this.$t('trials:readingPGWC:warnning:msg3'), {
|
||||
type: 'warning',
|
||||
showCancelButton: false,
|
||||
callback: action => {}
|
||||
})
|
||||
loading.close()
|
||||
return
|
||||
}
|
||||
}
|
||||
// 病灶状态为“良性”的既往新病灶,请使用箭头工具添加标记3
|
||||
if (this.lesionType === 3 && lesionState === 3) {
|
||||
if (!(measureData && measureData.type === 'ArrowAnnotate')) {
|
||||
this.$confirm(this.$t('trials:readingPGWC:warnning:msg4'), {
|
||||
type: 'warning',
|
||||
showCancelButton: false,
|
||||
callback: action => {}
|
||||
})
|
||||
loading.close()
|
||||
return
|
||||
}
|
||||
}
|
||||
// 病灶状态为“消失”的既往新病灶,请使用箭头工具添加标记1
|
||||
if (this.lesionType === 3 && lesionState === 1) {
|
||||
if (!(measureData && measureData.type === 'ArrowAnnotate')) {
|
||||
this.$confirm(this.$t('trials:readingPGWC:warnning:msg5'), {
|
||||
type: 'warning',
|
||||
showCancelButton: false,
|
||||
callback: action => {}
|
||||
})
|
||||
loading.close()
|
||||
return
|
||||
}
|
||||
}
|
||||
// 病灶状态为“不可评估”的既往新病灶,不需要添加标记4
|
||||
if (this.lesionType === 3 && lesionState === 4) {
|
||||
if (measureData) {
|
||||
this.$confirm(this.$t('trials:readingPGWC:warnning:msg6'), {
|
||||
type: 'warning',
|
||||
showCancelButton: false,
|
||||
callback: action => {}
|
||||
})
|
||||
loading.close()
|
||||
return
|
||||
}
|
||||
async handleSave() {
|
||||
const valid = await this.$refs.measurementForm.validate()
|
||||
if (!valid) return
|
||||
var lesionState = this.getQuestionVal(7)
|
||||
var measureData = this.questionForm.MeasureData
|
||||
// 非基线
|
||||
if (!this.isBaseLineTask) {
|
||||
// 新病灶 2
|
||||
// 病灶状态为“存在”的新病灶,请使用箭头工具添加标记2
|
||||
if (this.lesionType === 2 && lesionState === 2) {
|
||||
if (!(measureData && measureData.type === 'ArrowAnnotate')) {
|
||||
this.$confirm(this.$t('trials:readingPGWC:warnning:msg2'), {
|
||||
type: 'warning',
|
||||
showCancelButton: false,
|
||||
callback: action => {}
|
||||
})
|
||||
loading.close()
|
||||
return
|
||||
}
|
||||
}
|
||||
const loading = this.$loading({ fullscreen: true })
|
||||
DicomEvent.$emit('getScreenshots', { questionId: this.parentQsId, rowIndex: this.questionForm.RowIndex, visitTaskId: this.visitTaskId, lesionName: this.lesionMark, lesionType: this.lesionType, isMarked: !!measureData }, async val => {
|
||||
// 既往新病灶 3
|
||||
// 病灶状态为“存在”的既往新病灶,请使用箭头工具添加标记2
|
||||
if (this.lesionType === 3 && lesionState === 2) {
|
||||
if (!(measureData && measureData.type === 'ArrowAnnotate')) {
|
||||
this.$confirm(this.$t('trials:readingPGWC:warnning:msg3'), {
|
||||
type: 'warning',
|
||||
showCancelButton: false,
|
||||
callback: action => {}
|
||||
})
|
||||
loading.close()
|
||||
return
|
||||
}
|
||||
}
|
||||
// 病灶状态为“良性”的既往新病灶,请使用箭头工具添加标记3
|
||||
if (this.lesionType === 3 && lesionState === 3) {
|
||||
if (!(measureData && measureData.type === 'ArrowAnnotate')) {
|
||||
this.$confirm(this.$t('trials:readingPGWC:warnning:msg4'), {
|
||||
type: 'warning',
|
||||
showCancelButton: false,
|
||||
callback: action => {}
|
||||
})
|
||||
loading.close()
|
||||
return
|
||||
}
|
||||
}
|
||||
// 病灶状态为“消失”的既往新病灶,请使用箭头工具添加标记1
|
||||
if (this.lesionType === 3 && lesionState === 1) {
|
||||
if (!(measureData && measureData.type === 'ArrowAnnotate')) {
|
||||
this.$confirm(this.$t('trials:readingPGWC:warnning:msg5'), {
|
||||
type: 'warning',
|
||||
showCancelButton: false,
|
||||
callback: action => {}
|
||||
})
|
||||
loading.close()
|
||||
return
|
||||
}
|
||||
}
|
||||
// 病灶状态为“不可评估”的既往新病灶,不需要添加标记4
|
||||
if (this.lesionType === 3 && lesionState === 4) {
|
||||
if (measureData) {
|
||||
this.$confirm(this.$t('trials:readingPGWC:warnning:msg6'), {
|
||||
type: 'warning',
|
||||
showCancelButton: false,
|
||||
callback: action => {}
|
||||
})
|
||||
loading.close()
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
const loading = this.$loading({ fullscreen: true })
|
||||
DicomEvent.$emit('getScreenshots', { questionId: this.parentQsId, rowIndex: this.questionForm.RowIndex, visitTaskId: this.visitTaskId, lesionName: this.lesionMark, lesionType: this.lesionType, isMarked: !!measureData }, async val => {
|
||||
try {
|
||||
var picturePath = ''
|
||||
if (val && measureData) {
|
||||
var pictureObj = await this.uploadScreenshots(`${new Date().getTime()}`, val)
|
||||
picturePath = pictureObj.isSuccess ? pictureObj.result.name : ''
|
||||
picturePath = pictureObj.isSuccess ? this.$getObjectName(pictureObj.result.url) : ''
|
||||
}
|
||||
var answers = []
|
||||
var reg = new RegExp(/^[0-9a-zA-Z]{8}-[0-9a-zA-Z]{4}-[0-9a-zA-Z]{4}-[0-9a-zA-Z]{4}-[0-9a-zA-Z]{12}$/)
|
||||
|
@ -724,106 +730,115 @@ export default {
|
|||
organInfoId: this.questionForm.OrganInfoId,
|
||||
markTool: measureData ? measureData.type : ''
|
||||
}
|
||||
submitTableQuestion(params).then(async res => {
|
||||
try {
|
||||
this.$message.success(this.$t('common:message:savedSuccessfully'))
|
||||
this.currentMarkTool = measureData ? measureData.type : ''
|
||||
this.$set(this.questionForm, 'saveTypeEnum', 2)
|
||||
this.originalQuestionForm = { ...this.questionForm }
|
||||
loading.close()
|
||||
var isLymphLesion = this.getQuestionVal(2)
|
||||
isLymphLesion = isLymphLesion ? parseInt(isLymphLesion) : null
|
||||
var lesionOrgan = this.getQuestionVal(6)
|
||||
this.$set(this.questionForm, 'RowId', res.Result.RowId)
|
||||
const lesionPart = this.getQuestionVal(8)
|
||||
const lesionState = Number(this.getQuestionVal(7))
|
||||
const lesionNum = Number(this.getQuestionVal(11))
|
||||
|
||||
this.$emit('resetQuestions', { isLymphLesion, lesionPart, lesionOrgan, saveTypeEnum: this.questionForm.saveTypeEnum, lesionState, lesionNum, rowIndex: this.rowIndex, questionId: this.parentQsId, anwsers: this.questionForm })
|
||||
DicomEvent.$emit('getMeasureData')
|
||||
this.$emit('close')
|
||||
DicomEvent.$emit('getReportInfo', true)
|
||||
DicomEvent.$emit('setMeasuredToolsPassive')
|
||||
} catch (e) {
|
||||
console.log(e)
|
||||
}
|
||||
}).catch(() => { loading.close() })
|
||||
})
|
||||
})
|
||||
},
|
||||
handleDeleteMeasureData() {
|
||||
this.$confirm(this.$t('trials:reading:warnning:msg47'), {
|
||||
type: 'warning',
|
||||
distinguishCancelAndClose: true
|
||||
})
|
||||
.then(async() => {
|
||||
if (this.questionForm.RowId) {
|
||||
this.$set(this.questionForm, 'saveTypeEnum', 1)
|
||||
} else {
|
||||
this.$set(this.questionForm, 'saveTypeEnum', 0)
|
||||
}
|
||||
var remark = this.getLesionName(this.orderMark, this.questionForm.RowIndex)
|
||||
await store.dispatch('reading/removeMeasuredData', { visitTaskId: this.visitTaskId, measureData: this.questionForm.MeasureData, questionId: this.parentQsId, rowIndex: this.questionForm.RowIndex, orderMarkName: remark })
|
||||
DicomEvent.$emit('getMeasureData')
|
||||
const lesionPart = this.getQuestionVal(8)
|
||||
const lesionOrgan = this.getQuestionVal(6)
|
||||
const lesionState = Number(this.getQuestionVal(7))
|
||||
const lesionNum = Number(this.getQuestionVal(11))
|
||||
const res = await submitTableQuestion(params)
|
||||
if (res.IsSuccess) {
|
||||
this.$message.success(this.$t('common:message:savedSuccessfully'))
|
||||
this.currentMarkTool = measureData ? measureData.type : ''
|
||||
this.$set(this.questionForm, 'saveTypeEnum', 2)
|
||||
this.originalQuestionForm = { ...this.questionForm }
|
||||
|
||||
this.$set(this.questionForm, 'MeasureData', '')
|
||||
let anwsers = null
|
||||
if (this.answers.measureObj) {
|
||||
anwsers = Object.assign({ measureObj: '' }, this.questionForm)
|
||||
} else {
|
||||
anwsers = Object.assign({}, this.questionForm)
|
||||
}
|
||||
this.$emit('resetQuestions', { lesionPart, lesionOrgan, lesionState, lesionNum, saveTypeEnum: this.questionForm.saveTypeEnum, rowIndex: this.rowIndex, questionId: this.parentQsId, anwsers: anwsers })
|
||||
DicomEvent.$emit('refreshStudyListMeasureData')
|
||||
})
|
||||
.catch(() => {})
|
||||
},
|
||||
handleDelete() {
|
||||
this.$confirm(this.$t('trials:reading:warnning:msg48'), {
|
||||
type: 'warning',
|
||||
distinguishCancelAndClose: true
|
||||
})
|
||||
.then(async() => {
|
||||
if (this.questionForm.RowId) {
|
||||
const loading = this.$loading({ fullscreen: true })
|
||||
var param = {
|
||||
visitTaskId: this.visitTaskId,
|
||||
questionId: this.parentQsId,
|
||||
rowId: this.questionForm.RowId
|
||||
}
|
||||
deleteReadingRowAnswer(param)
|
||||
.then(async res => {
|
||||
loading.close()
|
||||
if (res.IsSuccess) {
|
||||
if (this.questionForm.MeasureData) {
|
||||
var remark = this.getLesionName(this.orderMark, this.questionForm.RowIndex)
|
||||
await store.dispatch('reading/removeMeasuredData', { visitTaskId: this.visitTaskId, measureData: this.questionForm.MeasureData, questionId: this.parentQsId, rowIndex: this.questionForm.RowIndex, orderMarkName: remark })
|
||||
}
|
||||
DicomEvent.$emit('getMeasureData')
|
||||
this.$emit('close', { lesionType: this.lesionType, rowIndex: this.rowIndex, visitTaskId: this.visitTaskId })
|
||||
DicomEvent.$emit('getReportInfo', true)
|
||||
this.$message.success(this.$t('common:message:deletedSuccessfully'))
|
||||
loading.close()
|
||||
}
|
||||
}).catch(() => { loading.close() })
|
||||
} else {
|
||||
const loading = this.$loading({ fullscreen: true })
|
||||
// 移除新建病灶并关闭窗口
|
||||
if (this.questionForm.MeasureData) {
|
||||
var remark = this.getLesionName(this.orderMark, this.questionForm.RowIndex)
|
||||
await store.dispatch('reading/removeMeasuredData', { visitTaskId: this.visitTaskId, measureData: this.questionForm.MeasureData, questionId: this.parentQsId, rowIndex: this.questionForm.RowIndex, orderMarkName: remark })
|
||||
}
|
||||
var isLymphLesion = this.getQuestionVal(2)
|
||||
isLymphLesion = isLymphLesion ? parseInt(isLymphLesion) : null
|
||||
var lesionOrgan = this.getQuestionVal(6)
|
||||
this.$set(this.questionForm, 'RowId', res.Result.RowId)
|
||||
const lesionPart = this.getQuestionVal(8)
|
||||
const lesionState = this.getQuestionVal(7)
|
||||
const lesionNum = this.getQuestionVal(11)
|
||||
|
||||
this.$emit('resetQuestions', { isLymphLesion, lesionPart, lesionOrgan, saveTypeEnum: this.questionForm.saveTypeEnum, lesionState, lesionNum, rowIndex: this.rowIndex, questionId: this.parentQsId, anwsers: this.questionForm })
|
||||
DicomEvent.$emit('getMeasureData')
|
||||
this.$emit('close', { lesionType: this.lesionType, rowIndex: this.rowIndex, visitTaskId: this.visitTaskId })
|
||||
DicomEvent.$emit('refreshStudyListMeasureData')
|
||||
this.$emit('close')
|
||||
DicomEvent.$emit('getReportInfo', true)
|
||||
DicomEvent.$emit('setMeasuredToolsPassive')
|
||||
loading.close()
|
||||
}
|
||||
})
|
||||
} catch (e) {
|
||||
console.log(e)
|
||||
loading.close()
|
||||
}
|
||||
})
|
||||
},
|
||||
async handleDeleteMeasureData() {
|
||||
// 是否确认清除标记?
|
||||
const confirm = await this.$confirm(
|
||||
this.$t('trials:reading:warnning:msg47'),
|
||||
{
|
||||
type: 'warning',
|
||||
distinguishCancelAndClose: true
|
||||
}
|
||||
)
|
||||
if (confirm !== 'confirm') return
|
||||
|
||||
if (this.questionForm.RowId) {
|
||||
this.$set(this.questionForm, 'saveTypeEnum', 1)
|
||||
} else {
|
||||
this.$set(this.questionForm, 'saveTypeEnum', 0)
|
||||
}
|
||||
var remark = this.getLesionName(this.orderMark, this.questionForm.RowIndex)
|
||||
await store.dispatch('reading/removeMeasuredData', { visitTaskId: this.visitTaskId, measureData: this.questionForm.MeasureData, questionId: this.parentQsId, rowIndex: this.questionForm.RowIndex, orderMarkName: remark })
|
||||
DicomEvent.$emit('getMeasureData')
|
||||
const lesionPart = this.getQuestionVal(8)
|
||||
const lesionOrgan = this.getQuestionVal(6)
|
||||
const lesionState = this.getQuestionVal(7)
|
||||
const lesionNum = this.getQuestionVal(11)
|
||||
|
||||
this.$set(this.questionForm, 'MeasureData', '')
|
||||
let anwsers = null
|
||||
if (this.answers.measureObj) {
|
||||
anwsers = Object.assign({ measureObj: '' }, this.questionForm)
|
||||
} else {
|
||||
anwsers = Object.assign({}, this.questionForm)
|
||||
}
|
||||
this.$emit('resetQuestions', { lesionPart, lesionOrgan, lesionState, lesionNum, saveTypeEnum: this.questionForm.saveTypeEnum, rowIndex: this.rowIndex, questionId: this.parentQsId, anwsers: anwsers })
|
||||
DicomEvent.$emit('refreshStudyListMeasureData')
|
||||
},
|
||||
async handleDelete() {
|
||||
// 是否确认删除?
|
||||
const loading = this.$loading({ fullscreen: true })
|
||||
try {
|
||||
const confirm = await this.$confirm(
|
||||
this.$t('trials:reading:warnning:msg48'),
|
||||
{
|
||||
type: 'warning',
|
||||
distinguishCancelAndClose: true
|
||||
}
|
||||
)
|
||||
if (confirm !== 'confirm') return
|
||||
if (this.questionForm.RowId) {
|
||||
var param = {
|
||||
visitTaskId: this.visitTaskId,
|
||||
questionId: this.parentQsId,
|
||||
rowId: this.questionForm.RowId
|
||||
}
|
||||
const res = await deleteReadingRowAnswer(param)
|
||||
if (res.IsSuccess) {
|
||||
if (this.questionForm.MeasureData) {
|
||||
const remark = this.getLesionName(this.orderMark, this.questionForm.RowIndex)
|
||||
await store.dispatch('reading/removeMeasuredData', { visitTaskId: this.visitTaskId, measureData: this.questionForm.MeasureData, questionId: this.parentQsId, rowIndex: this.questionForm.RowIndex, orderMarkName: remark })
|
||||
}
|
||||
DicomEvent.$emit('getMeasureData')
|
||||
this.$emit('close', { lesionType: this.lesionType, rowIndex: this.rowIndex, visitTaskId: this.visitTaskId })
|
||||
DicomEvent.$emit('getReportInfo', true)
|
||||
this.$message.success(this.$t('common:message:deletedSuccessfully'))
|
||||
}
|
||||
loading.close()
|
||||
} else {
|
||||
// 移除新建病灶并关闭窗口
|
||||
if (this.questionForm.MeasureData) {
|
||||
const remark = this.getLesionName(this.orderMark, this.questionForm.RowIndex)
|
||||
await store.dispatch('reading/removeMeasuredData', { visitTaskId: this.visitTaskId, measureData: this.questionForm.MeasureData, questionId: this.parentQsId, rowIndex: this.questionForm.RowIndex, orderMarkName: remark })
|
||||
}
|
||||
|
||||
DicomEvent.$emit('getMeasureData')
|
||||
this.$emit('close', { lesionType: this.lesionType, rowIndex: this.rowIndex, visitTaskId: this.visitTaskId })
|
||||
DicomEvent.$emit('refreshStudyListMeasureData')
|
||||
loading.close()
|
||||
}
|
||||
} catch (e) {
|
||||
console.log(e)
|
||||
loading.close()
|
||||
}
|
||||
},
|
||||
handleClose() {
|
||||
if (!this.questionForm.RowId) {
|
||||
|
@ -866,7 +881,7 @@ export default {
|
|||
this.$set(this.questionForm, stateId, 4)
|
||||
const lesionPart = this.getQuestionVal(8)
|
||||
const lesionOrgan = this.getQuestionVal(6)
|
||||
const lesionState = !isNaN(parseInt(this.getQuestionVal(7))) ? parseInt(this.getQuestionVal(7)) : ''
|
||||
const lesionState = this.getQuestionVal(7)
|
||||
this.$emit('resetQuestions', { lesionPart, lesionOrgan, lesionState, saveTypeEnum: this.questionForm.saveTypeEnum, rowIndex: this.rowIndex, questionId: this.parentQsId, anwsers: this.questionForm })
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,11 +1,21 @@
|
|||
<template>
|
||||
<div class="measurement-wrapper" :style="{'height':height+10+'px'}">
|
||||
<div class="measurement-wrapper">
|
||||
|
||||
<div class="container" :style="{'height':height+'px'}">
|
||||
<h3 v-if="isReadingShowSubjectInfo" style="color: #ddd;padding: 5px 0px;margin: 0;">
|
||||
<span v-if="subjectCode">{{ subjectCode }} </span>
|
||||
<span style="margin-left:5px;">{{ taskBlindName }}</span>
|
||||
</h3>
|
||||
<div class="container">
|
||||
<div class="basic-info">
|
||||
<h3 v-if="isReadingShowSubjectInfo">
|
||||
<span v-if="subjectCode">{{ subjectCode }} </span>
|
||||
<span style="margin-left:5px;">{{ taskBlindName }}</span>
|
||||
</h3>
|
||||
<div v-if="readingTaskState < 2">
|
||||
<el-tooltip class="item" effect="dark" :content="$t('trials:dicomReading:message:confirmReset')" placement="bottom">
|
||||
<i
|
||||
class="el-icon-refresh-left"
|
||||
@click="resetMeasuredData"
|
||||
/>
|
||||
</el-tooltip>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 非测量问题 -->
|
||||
<div class="lesions">
|
||||
<Questions
|
||||
|
@ -64,7 +74,7 @@
|
|||
{{ item.TableQuestions.Answers[i].lesionType }}
|
||||
</div>
|
||||
<div v-if="!isNaN(parseInt(item.TableQuestions.Answers[i].lesionNum)) && item.LesionType === 4" style="margin-left:10px;">
|
||||
{{ item.TableQuestions.Answers[i].lesionNum }}{{$fd('ValueUnit', 3)}}
|
||||
{{ item.TableQuestions.Answers[i].lesionNum }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -101,6 +111,7 @@
|
|||
</template>
|
||||
|
||||
<script>
|
||||
import { resetReadingTask } from '@/api/reading'
|
||||
import DicomEvent from './../DicomEvent'
|
||||
import Questions from './../Questions'
|
||||
import QuestionForm from './QuestionForm'
|
||||
|
@ -136,7 +147,6 @@ export default {
|
|||
},
|
||||
data() {
|
||||
return {
|
||||
height: window.innerHeight - 140,
|
||||
questions: [],
|
||||
activeName: '',
|
||||
activeItem: {
|
||||
|
@ -184,7 +194,8 @@ export default {
|
|||
}
|
||||
},
|
||||
mounted() {
|
||||
this.subjectCode = this.$router.currentRoute.query.subjectCode
|
||||
// this.subjectCode = this.$router.currentRoute.query.subjectCode
|
||||
this.subjectCode = localStorage.getItem('subjectCode')
|
||||
window.addEventListener('message', this.receiveMsg)
|
||||
this.criterionType = parseInt(localStorage.getItem('CriterionType'))
|
||||
DicomEvent.$on('setCollapseActive', measureData => {
|
||||
|
@ -200,8 +211,6 @@ export default {
|
|||
callback(list)
|
||||
console.log('getAllUnSaveLesions')
|
||||
})
|
||||
|
||||
window.addEventListener('resize', this.setHeight)
|
||||
},
|
||||
beforeDestroy() {
|
||||
DicomEvent.$off('setCollapseActive')
|
||||
|
@ -687,6 +696,102 @@ export default {
|
|||
this.activeItem.activeRowIndex = null
|
||||
this.activeItem.activeCollapseId = null
|
||||
this.activeName = ''
|
||||
},
|
||||
getECRFQuestions(obj) {
|
||||
this.$refs['ecrf'].getQuestions(obj.visitTaskId)
|
||||
},
|
||||
async resetMeasuredData() {
|
||||
const confirm = await this.$confirm(
|
||||
this.$t('trials:dicomReading:message:confirmReset1'),
|
||||
this.$t('trials:dicomReading:message:confirmReset2'),
|
||||
{
|
||||
type: 'warning',
|
||||
distinguishCancelAndClose: true
|
||||
}
|
||||
)
|
||||
if (confirm !== 'confirm') return
|
||||
const loading = this.$loading({ fullscreen: true })
|
||||
try {
|
||||
const res = await resetReadingTask({ visitTaskId: this.visitTaskId })
|
||||
this.loading = false
|
||||
if (res.IsSuccess) {
|
||||
// 刷新标注、表单、报告页信息
|
||||
this.activeName = ''
|
||||
this.activeItem.activeRowIndex = null
|
||||
this.activeItem.activeCollapseId = null
|
||||
await this.getReadingQuestionAndAnswer(this.visitTaskId)
|
||||
const triald = this.$router.currentRoute.query.trialId
|
||||
await store.dispatch('reading/refreshDicomReadingQuestionAnswer', { trialId: triald, visitTaskId: this.visitTaskId })
|
||||
this.$refs['ecrf'].getQuestions(this.visitTaskId, true)
|
||||
DicomEvent.$emit('getMeasureData')
|
||||
DicomEvent.$emit('getReportInfo', true)
|
||||
DicomEvent.$emit('refreshStudyListMeasureData')
|
||||
}
|
||||
loading.close()
|
||||
} catch (e) {
|
||||
loading.close()
|
||||
console.log(e)
|
||||
}
|
||||
},
|
||||
receiveMsg(event) {
|
||||
if (event.data.type === 'isCanActiveNoneDicomTool') {
|
||||
this.getUnSaveTarget()
|
||||
var obj = {}
|
||||
if (this.unSaveTargets.length > 0) {
|
||||
var rowIndex = String(this.unSaveTargets[0].rowIndex)
|
||||
var questionId = this.unSaveTargets[0].questionId
|
||||
const refName = `${this.activeItem.activeCollapseId}_${this.activeItem.activeRowIndex}`
|
||||
if (rowIndex === this.activeItem.activeRowIndex && questionId === this.activeItem.activeCollapseId && !this.$refs[refName][0].questionForm.MeasureData) {
|
||||
// 判断是否是靶病灶
|
||||
// questions.findIndex(i => i.QuestionMark === questionMark)
|
||||
var lesionType = this.$refs[refName][0].questionForm.LesionType
|
||||
if (lesionType === 0) {
|
||||
// '当前病灶为靶病灶,不允许添加标记!'
|
||||
obj = { isCanActiveTool: false, lesionName: '', reason: this.$t('trials:reading:warnning:msg18') }
|
||||
} else {
|
||||
obj = { isCanActiveTool: true, lesionName: this.$refs[refName][0].lesionMark, reason: '', toolName: event.data.toolName }
|
||||
}
|
||||
} else {
|
||||
let msg = this.$t('trials:reading:warnning:msg5')
|
||||
msg = msg.replace('xxx', this.unSaveTargets[0].lessionName)
|
||||
obj = { isCanActiveTool: false, lesionName: '', reason: msg }
|
||||
}
|
||||
} else {
|
||||
if (this.activeItem.activeCollapseId) {
|
||||
// 判断是否是靶病灶
|
||||
const refName = `${this.activeItem.activeCollapseId}_${this.activeItem.activeRowIndex}`
|
||||
const lesionType = this.$refs[refName][0].questionForm.LesionType
|
||||
if (lesionType === 0) {
|
||||
// 当前病灶为靶病灶,不允许添加标记!
|
||||
obj = { isCanActiveTool: false, lesionName: '', reason: this.$t('trials:reading:warnning:msg18') }
|
||||
} else {
|
||||
obj = { isCanActiveTool: true, lesionName: this.$refs[refName][0].lesionMark, reason: '', toolName: event.data.toolName }
|
||||
}
|
||||
} else {
|
||||
// 获取非靶病灶/新病灶的长度及标识
|
||||
var qsObj = null
|
||||
var lesionName = ''
|
||||
if (this.isBaseLineTask) {
|
||||
const idx = this.tableQuestions.findIndex(item => item.LesionType === 1)
|
||||
if (idx > -1) {
|
||||
qsObj = this.tableQuestions[idx]
|
||||
}
|
||||
} else {
|
||||
const idx = this.tableQuestions.findIndex(item => item.LesionType === 2)
|
||||
if (idx > -1) {
|
||||
qsObj = this.tableQuestions[idx]
|
||||
}
|
||||
}
|
||||
var maxIndex = this.getMaxRowIndex(qsObj.TableQuestions.Answers)
|
||||
lesionName = `${qsObj.OrderMark}${String(maxIndex + 1).padStart(2, '0')}`
|
||||
obj = { isCanActiveTool: true, lesionName: lesionName, reason: '', toolName: event.data.toolName }
|
||||
}
|
||||
}
|
||||
|
||||
DicomEvent.$emit('isCanActiveNoneDicomTool', obj)
|
||||
} else if (event.data.type === 'setMeasurement') {
|
||||
this.setMeasuredData(event.data.data)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -694,11 +799,28 @@ export default {
|
|||
|
||||
<style lang="scss" scoped>
|
||||
.measurement-wrapper{
|
||||
height: 100%;
|
||||
overflow-y: auto;
|
||||
// overflow: hidden;
|
||||
|
||||
.container{
|
||||
padding: 10px;
|
||||
.basic-info{
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
h3{
|
||||
color: #ddd;
|
||||
padding: 5px 0px;
|
||||
margin: 0;
|
||||
}
|
||||
i{
|
||||
color: #fff;
|
||||
font-size: 22px;
|
||||
font-weight: bold;
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
}
|
||||
.title{
|
||||
padding: 5px;
|
||||
|
|
|
@ -13,46 +13,86 @@
|
|||
{{ language==='en'?question.GroupEnName:question.GroupName }}
|
||||
</h4>
|
||||
</div>
|
||||
<template v-else-if="((question.QuestionType === 56 || question.QuestionType === 57) && question.IsBaseLineTask)" />
|
||||
<template v-else>
|
||||
|
||||
<el-form-item
|
||||
v-if="(question.ShowQuestion===1 && String(questionForm[question.ParentId]) === String(question.ParentTriggerValue)) || question.ShowQuestion===0"
|
||||
v-if="(question.ShowQuestion===1 && question.ParentTriggerValueList.includes(String(questionForm[question.ParentId]))) || question.ShowQuestion===0 "
|
||||
:label="`${question.QuestionName}`"
|
||||
:prop="question.Id"
|
||||
:rules="[
|
||||
{ required: (question.IsRequired === 0 || (question.IsRequired ===1 && question.RelevanceId && (questionForm[question.RelevanceId] === question.RelevanceValue))) && question.Type!=='group' && question.Type!=='summary',
|
||||
message: ['radio', 'select', 'checkbox'].includes(question.Type) ? $t('common:ruleMessage:select') : $t('common:ruleMessage:specify'), trigger: ['blur', 'change']},
|
||||
]"
|
||||
:class="[question.Type==='group'?'mb':question.Type==='upload'?'uploadWrapper':'']"
|
||||
:class="[question.Type==='group' ? 'mb' : (question.Type==='upload' || question.QuestionName.length > 15) ?'uploadWrapper' : '']"
|
||||
>
|
||||
<template v-if="question.QuestionType === 60 || question.QuestionType === 61">
|
||||
<div style="display: flex;flex-direction: row;justify-content: flex-start;align-items: center;">
|
||||
|
||||
<el-input
|
||||
v-if="question.Type==='calculation'"
|
||||
v-model="questionForm[question.Id]"
|
||||
disabled
|
||||
style="width: 130px;"
|
||||
>
|
||||
<template v-if="question.Unit" slot="append">
|
||||
{{ $fd('ValueUnit', parseInt(question.Unit)) }}
|
||||
</template>
|
||||
</el-input>
|
||||
<!-- 测量 -->
|
||||
<el-button v-if="!questionForm[question.Id] && readingTaskState!== 2" size="mini" type="text" @click="addAnnotation(question)">{{ $t('trials:lugano:button:addAnnotation') }}</el-button>
|
||||
<!-- 清除标记 -->
|
||||
<el-button v-if="questionForm[question.Id]&& readingTaskState!== 2" size="mini" type="text" @click="removeAnnotation(question)">{{ $t('trials:lugano:button:clearAnnotation') }}</el-button>
|
||||
<!-- 定位 -->
|
||||
<el-button v-if="questionForm[question.Id]" size="mini" type="text" @click="locateAnnotation(question)">{{ $t('trials:lugano:button:locateAnnotation') }}</el-button>
|
||||
<!-- 保存 -->
|
||||
<el-button v-if="readingTaskState!== 2 && question.SaveEnum === 1" size="mini" type="text" @click="saveAnnotation(question)">
|
||||
<!-- 未保存 -->
|
||||
<el-tooltip class="item" effect="dark" :content="$t('trials:reading:button:unsaved')" placement="bottom">
|
||||
<i class="el-icon-warning" style="color:red" />
|
||||
</el-tooltip>
|
||||
{{ $t('common:button:save') }}
|
||||
</el-button>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template v-else-if="question.QuestionType === 48 || question.QuestionType === 51 || question.QuestionType === 52 || question.QuestionType === 53">
|
||||
<el-input
|
||||
v-if="question.Type==='calculation'"
|
||||
v-model="questionForm[question.Id]"
|
||||
disabled
|
||||
>
|
||||
<template v-if="question.Unit" slot="append">
|
||||
{{ $fd('ValueUnit', parseInt(question.Unit)) }}
|
||||
</template>
|
||||
</el-input>
|
||||
</template>
|
||||
|
||||
<!-- 输入框 -->
|
||||
<el-input
|
||||
v-if="question.Type==='input'"
|
||||
v-else-if="question.Type==='input'"
|
||||
v-model="questionForm[question.Id]"
|
||||
:disabled="readingTaskState >= 2 || isFirstChangeTask"
|
||||
@change="((val)=>{formItemChange(val, question)})"
|
||||
/>
|
||||
<!-- 多行文本输入框 -->
|
||||
<el-input
|
||||
v-if="question.Type==='textarea'"
|
||||
v-else-if="question.Type==='textarea'"
|
||||
v-model="questionForm[question.Id]"
|
||||
type="textarea"
|
||||
:autosize="{ minRows: 2, maxRows: 4}"
|
||||
maxlength="500"
|
||||
:disabled="readingTaskState >= 2 || isFirstChangeTask"
|
||||
@change="((val)=>{formItemChange(val, question)})"
|
||||
/>
|
||||
<!-- 下拉框 -->
|
||||
<el-select
|
||||
v-if="question.Type==='select'"
|
||||
v-else-if="question.Type==='select'"
|
||||
v-model="questionForm[question.Id]"
|
||||
:disabled="readingTaskState >= 2 || ((question.TableQuestionType === 2 || question.QuestionGenre === 2) && !!question.DictionaryCode) || isFirstChangeTask"
|
||||
:disabled="readingTaskState >= 2 || ((question.TableQuestionType === 2 || question.QuestionGenre === 2) && !!question.DictionaryCode) || isFirstChangeTask || question.QuestionType === 50 || question.QuestionType === 55"
|
||||
clearable
|
||||
@change="((val)=>{formItemChange(val, question)})"
|
||||
>
|
||||
<!-- <el-option
|
||||
v-for="val in question.TypeValue.split('|')"
|
||||
:key="val"
|
||||
:label="val"
|
||||
:value="val"
|
||||
/> -->
|
||||
<template v-if="question.TableQuestionType === 1">
|
||||
<el-option
|
||||
v-for="item in organList"
|
||||
|
@ -61,6 +101,50 @@
|
|||
:value="item[question.DataTableColumn]"
|
||||
/>
|
||||
</template>
|
||||
<template v-else-if="question.QuestionGenre === 3 && question.QuestionType === 47 && question.IsBaseLineTask">
|
||||
<el-option
|
||||
v-for="item of $d[question.DictionaryCode]"
|
||||
v-show="item.value === 1 ||item.value === 2 || item.value === 5 "
|
||||
:key="item.id"
|
||||
:value="String(item.value)"
|
||||
:label="item.label"
|
||||
/>
|
||||
</template>
|
||||
<template v-else-if="question.QuestionGenre === 3 && question.QuestionType === 47 && !question.IsBaseLineTask">
|
||||
<el-option-group
|
||||
:label="!isNaN(parseFloat(question.LastTaskAnswer)) ? `${$t('trials:dicomReading:tip:lastVisitStatus')} ${$fd(question.DictionaryCode,parseFloat(question.LastTaskAnswer))}` : ''"
|
||||
>
|
||||
<el-option
|
||||
v-for="item of $d[question.DictionaryCode]"
|
||||
v-show="item.value === 1 ||item.value === 3|| item.value === 4 || item.value === 5"
|
||||
:key="item.id"
|
||||
:value="String(item.value)"
|
||||
:label="item.label"
|
||||
/>
|
||||
</el-option-group>
|
||||
</template>
|
||||
<template v-else-if="question.QuestionGenre === 3 && question.QuestionType === 49 && question.IsBaseLineTask">
|
||||
<el-option
|
||||
v-for="item of $d[question.DictionaryCode]"
|
||||
v-show="item.value === 1 ||item.value === 5 || item.value === 6 "
|
||||
:key="item.id"
|
||||
:value="String(item.value)"
|
||||
:label="item.label"
|
||||
/>
|
||||
</template>
|
||||
<template v-else-if="question.QuestionGenre === 3 && question.QuestionType === 49 && !question.IsBaseLineTask">
|
||||
<el-option-group
|
||||
:label="!isNaN(parseFloat(question.LastTaskAnswer)) ? `${$t('trials:dicomReading:tip:lastVisitStatus')} ${$fd(question.DictionaryCode,parseFloat(question.LastTaskAnswer))}` : ''"
|
||||
>
|
||||
<el-option
|
||||
v-for="item of $d[question.DictionaryCode]"
|
||||
v-show="item.value === 1 ||item.value === 2 || item.value === 3 || item.value === 4 || item.value === 5"
|
||||
:key="item.id"
|
||||
:value="String(item.value)"
|
||||
:label="item.label"
|
||||
/>
|
||||
</el-option-group>
|
||||
</template>
|
||||
<template v-else-if="question.TableQuestionType === 3 || question.QuestionGenre === 3">
|
||||
<el-option
|
||||
v-for="item of $d[question.DictionaryCode]"
|
||||
|
@ -88,18 +172,11 @@
|
|||
</el-select>
|
||||
<!-- 单选 -->
|
||||
<el-radio-group
|
||||
v-if="question.Type==='radio'"
|
||||
v-else-if="question.Type==='radio'"
|
||||
v-model="questionForm[question.Id]"
|
||||
:disabled="readingTaskState >= 2 || isFirstChangeTask"
|
||||
@change="((val)=>{formItemChange(val, question)})"
|
||||
>
|
||||
<!-- <el-radio
|
||||
v-for="val in question.TypeValue.split('|')"
|
||||
:key="val"
|
||||
:label="val"
|
||||
>
|
||||
{{ val }}
|
||||
</el-radio> -->
|
||||
<template v-if="question.DictionaryCode">
|
||||
<el-radio
|
||||
v-for="item of $d[question.DictionaryCode]"
|
||||
|
@ -121,7 +198,7 @@
|
|||
</el-radio-group>
|
||||
<!-- 复选框 -->
|
||||
<el-checkbox-group
|
||||
v-if="question.Type==='checkbox'"
|
||||
v-else-if="question.Type==='checkbox'"
|
||||
v-model="questionForm[question.Id]"
|
||||
:disabled="readingTaskState >= 2 || isFirstChangeTask"
|
||||
>
|
||||
|
@ -134,16 +211,45 @@
|
|||
</el-checkbox>
|
||||
</el-checkbox-group>
|
||||
<!-- 数值 -->
|
||||
<!-- :precision="2" :step="0.1" :max="10" -->
|
||||
<el-input-number
|
||||
v-if="question.Type==='number'"
|
||||
<!-- <el-input-number
|
||||
v-else-if="question.Type==='number'"
|
||||
v-model="questionForm[question.Id]"
|
||||
:disabled="readingTaskState >= 2 || isFirstChangeTask"
|
||||
/>
|
||||
:precision="2"
|
||||
/> -->
|
||||
<template v-else-if="question.Type==='number'">
|
||||
<el-input-number
|
||||
v-if="question.ValueType === 0"
|
||||
v-model="questionForm[question.Id]"
|
||||
:precision="0"
|
||||
:disabled="readingTaskState >= 2 || isFirstChangeTask"
|
||||
/>
|
||||
<el-input-number
|
||||
v-else-if="question.ValueType === 3"
|
||||
v-model="questionForm[question.Id]"
|
||||
:disabled="readingTaskState >= 2 || isFirstChangeTask"
|
||||
/>
|
||||
<el-input-number
|
||||
v-else-if="question.ValueType === 1 || question.ValueType === 2"
|
||||
v-model="questionForm[question.Id]"
|
||||
:precision="digitPlaces"
|
||||
:disabled="readingTaskState >= 2 || isFirstChangeTask"
|
||||
/>
|
||||
</template>
|
||||
<el-input
|
||||
v-else-if="question.Type==='calculation'"
|
||||
v-model="questionForm[question.Id]"
|
||||
disabled
|
||||
>
|
||||
<template v-if="question.Unit" slot="append">
|
||||
{{ $fd('ValueUnit', parseInt(question.Unit)) }}
|
||||
</template>
|
||||
</el-input>
|
||||
<!-- 上传图像 -->
|
||||
<el-upload
|
||||
v-if="question.Type==='upload'"
|
||||
:action="accept"
|
||||
v-else-if="question.Type==='upload'"
|
||||
action
|
||||
:accept="accept"
|
||||
:limit="question.ImageCount"
|
||||
:on-preview="handlePictureCardPreview"
|
||||
:before-upload="handleBeforeUpload"
|
||||
|
@ -158,7 +264,6 @@
|
|||
<div slot="file" slot-scope="{file}">
|
||||
<img
|
||||
class="el-upload-list__item-thumbnail"
|
||||
crossOrigin="Anonymous"
|
||||
:src="OSSclientConfig.basePath + file.url"
|
||||
alt=""
|
||||
>
|
||||
|
@ -209,7 +314,8 @@
|
|||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import { uploadReadingAnswerImage } from '@/api/trials'
|
||||
// import { uploadReadingAnswerImage } from '@/api/trials'
|
||||
import DicomEvent from './DicomEvent'
|
||||
import { mapGetters } from 'vuex'
|
||||
export default {
|
||||
name: 'QuestionItem',
|
||||
|
@ -245,7 +351,8 @@ export default {
|
|||
accept: '.png,.jpg,.jpeg',
|
||||
imgVisible: false,
|
||||
imageUrl: '',
|
||||
urls: []
|
||||
urls: [],
|
||||
digitPlaces: 2
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
|
@ -271,11 +378,19 @@ export default {
|
|||
})
|
||||
}
|
||||
}
|
||||
var digitPlaces = Number(localStorage.getItem('digitPlaces'))
|
||||
this.digitPlaces = digitPlaces === -1 ? this.digitPlaces : digitPlaces
|
||||
},
|
||||
methods: {
|
||||
formItemChange(v, question) {
|
||||
// if (parseInt(v) !== 5) {
|
||||
// return
|
||||
// }
|
||||
|
||||
if (question.Childrens.length > 0) {
|
||||
this.resetChild(question.Childrens)
|
||||
} else {
|
||||
this.$emit('setFormItemData', { key: question.Id, val: v })
|
||||
}
|
||||
},
|
||||
resetChild(obj) {
|
||||
|
@ -292,7 +407,28 @@ export default {
|
|||
setFormItemData(obj) {
|
||||
this.$emit('setFormItemData', obj)
|
||||
},
|
||||
uploadScreenshot(param) {
|
||||
addAnnotation(question) {
|
||||
DicomEvent.$emit('addAnnotation', question)
|
||||
},
|
||||
saveAnnotation(question) {
|
||||
DicomEvent.$emit('saveAnnotation', question)
|
||||
},
|
||||
removeAnnotation(question) {
|
||||
DicomEvent.$emit('locateAnnotation', question)
|
||||
// 是否确认清除标记?
|
||||
this.$confirm(this.$t('trials:reading:warnning:msg47'), {
|
||||
type: 'warning',
|
||||
distinguishCancelAndClose: true
|
||||
})
|
||||
.then(() => {
|
||||
DicomEvent.$emit('removeAnnotation', question)
|
||||
})
|
||||
.catch(() => {})
|
||||
},
|
||||
locateAnnotation(question) {
|
||||
DicomEvent.$emit('locateAnnotation', question)
|
||||
},
|
||||
async uploadScreenshot(param) {
|
||||
if (!this.visitTaskId) return
|
||||
const loading = this.$loading({
|
||||
target: document.querySelector('.ecrf-wrapper'),
|
||||
|
@ -301,18 +437,12 @@ export default {
|
|||
text: 'Loading',
|
||||
spinner: 'el-icon-loading'
|
||||
})
|
||||
const formData = new FormData()
|
||||
formData.append('file', param.file)
|
||||
uploadReadingAnswerImage(this.$route.query.trialId, this.visitTaskId, formData).then(res => {
|
||||
if (res.IsSuccess) {
|
||||
this.fileList.push({ url: `${res.Result.Path}` })
|
||||
this.urls.push(res.Result.Path)
|
||||
this.$emit('setFormItemData', { key: this.question.Id, val: this.urls.length > 0 ? this.urls.join('|') : '' })
|
||||
}
|
||||
loading.close()
|
||||
}).catch(() => {
|
||||
loading.close()
|
||||
})
|
||||
var file = await this.fileToBlob(param.file)
|
||||
const res = await this.OSSclient.put(`/${this.trialId}/ReadAttachment/${this.subjectId}/${this.visitTaskId}/${param.file.name}`, file)
|
||||
this.fileList.push({ name: param.file.name, url: this.$getObjectName(res.url) })
|
||||
this.urls.push(this.$getObjectName(res.url))
|
||||
this.$emit('setFormItemData', { key: this.question.Id, val: this.urls.length > 0 ? this.urls.join('|') : '' })
|
||||
loading.close()
|
||||
},
|
||||
handleBeforeUpload(file) {
|
||||
// 检测文件类型是否符合要求
|
||||
|
@ -335,7 +465,7 @@ export default {
|
|||
},
|
||||
// 预览图片
|
||||
handlePictureCardPreview(file) {
|
||||
this.imageUrl = file.url
|
||||
this.imageUrl = this.OSSclientConfig.basePath + file.url
|
||||
this.imgVisible = true
|
||||
},
|
||||
// 删除图片
|
||||
|
@ -353,19 +483,25 @@ export default {
|
|||
margin-bottom: 0px;
|
||||
}
|
||||
.disabled{
|
||||
>>>.el-upload--picture-card {
|
||||
/deep/ .el-upload--picture-card {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
.uploadWrapper{
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
flex-direction: column !important;
|
||||
align-items: flex-start;
|
||||
}
|
||||
>>>.el-input.is-disabled .el-input__inner{
|
||||
/deep/ .el-input.is-disabled .el-input__inner{
|
||||
background-color: #646464a1;
|
||||
}
|
||||
>>>.el-select.is-disabled .el-input__inner{
|
||||
/deep/ .el-input-group__append, .el-input-group__prepend{
|
||||
padding: 0 10px;
|
||||
}
|
||||
/deep/ .el-form-item__content {
|
||||
width: 100%;
|
||||
}
|
||||
/deep/ .el-select.is-disabled .el-input__inner{
|
||||
background-color: #646464a1;
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -19,8 +19,9 @@
|
|||
/>
|
||||
|
||||
<el-form-item v-if="readingTaskState < 2 && !isFirstChangeTask">
|
||||
<div style="text-align:right">
|
||||
<el-button size="mini" :disabled="!questionFormChangeState" :type="questionFormChangeState ? 'primary' : null" @click="handleSave">{{ $t('common:button:save') }}</el-button>
|
||||
<div class="ecrf-footer">
|
||||
<!-- <i v-if="groupClassify === null || groupClassify === 1" class="el-icon-question feedback-icon" @click="openFeedBackTable" /> -->
|
||||
<el-button size="mini" :disabled="!questionFormChangeState || (!formChanged && groupClassify > 0)" :type="questionFormChangeState || (!formChanged && groupClassify > 0) ? 'primary' : null" @click="handleSave">{{ $t('common:button:save') }}</el-button>
|
||||
</div>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
@ -29,8 +30,9 @@
|
|||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
import { saveImageQuality } from '@/api/trials'
|
||||
// import { uploadPrintscreen } from '@/api/reading'
|
||||
import { saveTaskQuestion, getSplenicState, getSplenicVerify, getCanChooseNotMerge, getDicomReadingQuestionAnswer } from '@/api/trials'
|
||||
import { setSkipReadingCache } from '@/api/reading'
|
||||
import QuestionItem from './QuestionItem'
|
||||
import DicomEvent from './DicomEvent'
|
||||
import { mapGetters } from 'vuex'
|
||||
|
@ -52,6 +54,18 @@ export default {
|
|||
isFirstChangeTask: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
groupClassify: {
|
||||
type: Number,
|
||||
default: null
|
||||
},
|
||||
isQulityIssues: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
questionType: {
|
||||
type: Number,
|
||||
default: 0
|
||||
}
|
||||
},
|
||||
data() {
|
||||
|
@ -61,7 +75,20 @@ export default {
|
|||
questionForm: {},
|
||||
readingTaskState: 2,
|
||||
visitTaskId: '',
|
||||
imageQualityId: ''
|
||||
imageQualityId: '',
|
||||
imageQualityIssuesId: '',
|
||||
measurements: [],
|
||||
spleenStatusId: '',
|
||||
spleenLengthId: '',
|
||||
spleenCommentsId: '',
|
||||
spleenTopId: '',
|
||||
spleenBottomId: '',
|
||||
isBaseLineTask: false,
|
||||
criterionType: null,
|
||||
spleenInfo: null,
|
||||
calculateSpleenStatus: '',
|
||||
formChanged: false,
|
||||
digitPlaces: 2
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
|
@ -72,7 +99,9 @@ export default {
|
|||
deep: true,
|
||||
immediate: false,
|
||||
handler(v) {
|
||||
DicomEvent.$emit('questionFormChange', true)
|
||||
if (this.isQulityIssues) {
|
||||
DicomEvent.$emit('questionFormChange', true)
|
||||
}
|
||||
}
|
||||
},
|
||||
currentReadingTaskState: {
|
||||
|
@ -85,45 +114,120 @@ export default {
|
|||
}
|
||||
},
|
||||
mounted() {
|
||||
var digitPlaces = Number(localStorage.getItem('digitPlaces'))
|
||||
this.digitPlaces = digitPlaces === -1 ? this.digitPlaces : digitPlaces
|
||||
this.criterionType = parseInt(localStorage.getItem('CriterionType'))
|
||||
DicomEvent.$on('setReadingState', readingTaskState => {
|
||||
this.readingTaskState = readingTaskState
|
||||
})
|
||||
DicomEvent.$on('handleSaveQuestions', readingTaskState => {
|
||||
this.handleSave()
|
||||
})
|
||||
if (this.groupClassify === 3) {
|
||||
DicomEvent.$on('addAnnotation', obj => {
|
||||
this.$set(obj, 'SaveEnum', 1)
|
||||
this.addAnnotation(obj)
|
||||
})
|
||||
DicomEvent.$on('removeAnnotation', obj => {
|
||||
this.$set(obj, 'SaveEnum', 0)
|
||||
this.removeAnnotation(obj)
|
||||
})
|
||||
DicomEvent.$on('saveAnnotation', obj => {
|
||||
this.saveAnnotation(obj)
|
||||
})
|
||||
|
||||
DicomEvent.$on('locateAnnotation', obj => {
|
||||
this.locateAnnotation(obj)
|
||||
})
|
||||
}
|
||||
},
|
||||
beforeDestroy() {
|
||||
DicomEvent.$off('setReadingState')
|
||||
if (this.groupClassify === 3) {
|
||||
DicomEvent.$off('addAnnotation')
|
||||
DicomEvent.$off('removeAnnotation')
|
||||
DicomEvent.$off('saveAnnotation')
|
||||
DicomEvent.$off('locateAnnotation')
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
async getQuestions(visitTaskId) {
|
||||
async getQuestions(visitTaskId, isRefresh = false) {
|
||||
var isChangeVisitTask = this.visitTaskId !== visitTaskId
|
||||
this.visitTaskId = visitTaskId
|
||||
// const loading = this.$loading({ fullscreen: true })
|
||||
var idx = this.visitTaskList.findIndex(i => i.VisitTaskId === visitTaskId)
|
||||
|
||||
var qs = []
|
||||
if (idx > -1) {
|
||||
this.isBaseLineTask = this.visitTaskList[idx].IsBaseLineTask
|
||||
this.readingTaskState = this.visitTaskList[idx].ReadingTaskState
|
||||
var questions = this.visitTaskList[idx].Questions
|
||||
questions.map((v) => {
|
||||
if (v.Type === 'group' && v.Childrens.length === 0) return
|
||||
if (!v.IsPage && v.Type !== 'group' && v.Type !== 'summary') {
|
||||
if (this.groupClassify === 3) {
|
||||
this.measurements = []
|
||||
this.visitTaskList[idx].QuestionMarkInfoList.forEach(i => {
|
||||
if (this.isJSONString(i.MeasureData)) {
|
||||
i.MeasureData = JSON.parse(i.MeasureData)
|
||||
}
|
||||
this.measurements.push(i)
|
||||
})
|
||||
if (isChangeVisitTask || isRefresh) {
|
||||
const { Result } = await getSplenicVerify(visitTaskId)
|
||||
this.spleenInfo = Result
|
||||
}
|
||||
}
|
||||
|
||||
for (var i = 0; i < questions.length; i++) {
|
||||
var v = questions[i]
|
||||
v.IsBaseLineTask = this.isBaseLineTask
|
||||
if (v.Type === 'group' && v.GroupClassify !== this.groupClassify) continue
|
||||
if (!v.IsPage && v.Type !== 'group' && v.Type !== 'summary' && i.Id) {
|
||||
this.$set(this.questionForm, v.Id, v.Answer ? v.Answer : null)
|
||||
if (v.QuestionType === 44) {
|
||||
// 影响质量评估
|
||||
// 影像质量评估
|
||||
this.imageQualityId = v.Id
|
||||
// store.dispatch('reading/setImageQuality', v.Answer ? v.Answer : null)
|
||||
}
|
||||
if (v.QuestionType === 67) {
|
||||
// 影像质量问题
|
||||
this.imageQualityIssuesId = v.Id
|
||||
}
|
||||
|
||||
if (v.QuestionType === 49) {
|
||||
// 脾脏状态
|
||||
this.spleenStatusId = v.Id
|
||||
}
|
||||
if (v.QuestionType === 48) {
|
||||
// 脾脏垂直径
|
||||
this.spleenLengthId = v.Id
|
||||
}
|
||||
if (v.QuestionType === 58) {
|
||||
// 修改脾脏状态备注
|
||||
this.spleenCommentsId = v.Id
|
||||
}
|
||||
if (v.QuestionType === 60) {
|
||||
// 脾尖位置
|
||||
this.spleenTopId = v.Id
|
||||
}
|
||||
if (v.QuestionType === 61) {
|
||||
// 脾底位置
|
||||
this.spleenBottomId = v.Id
|
||||
}
|
||||
}
|
||||
if (v.Childrens.length > 0) {
|
||||
this.setChild(v.Childrens)
|
||||
}
|
||||
})
|
||||
this.questions = questions
|
||||
qs.push(v)
|
||||
}
|
||||
this.questions = Object.assign([], qs)
|
||||
}
|
||||
if (this.imageQualityIssuesId) {
|
||||
store.dispatch('reading/setImageQualityIssues', this.questionForm[this.imageQualityIssuesId])
|
||||
}
|
||||
if (this.spleenLengthId && this.spleenInfo && this.readingTaskState < 2) {
|
||||
this.calculateSpleenStatus = this.spleenInfo.SplenicStatus
|
||||
this.setSpleenCommentDisplay()
|
||||
}
|
||||
// loading.close()
|
||||
},
|
||||
setChild(obj) {
|
||||
obj.forEach(i => {
|
||||
i.IsBaseLineTask = this.isBaseLineTask
|
||||
if (i.Type !== 'group' && i.Type !== 'summary' && i.Id) {
|
||||
this.$set(this.questionForm, i.Id, i.Answer ? i.Answer : null)
|
||||
if (i.QuestionType === 44) {
|
||||
|
@ -131,95 +235,673 @@ export default {
|
|||
this.imageQualityId = i.Id
|
||||
// store.dispatch('reading/setImageQuality', i.Answer ? i.Answer : null)
|
||||
}
|
||||
if (i.QuestionType === 67) {
|
||||
// 影像质量问题
|
||||
this.imageQualityIssuesId = i.Id
|
||||
}
|
||||
if (i.QuestionType === 49) {
|
||||
// 脾脏状态
|
||||
this.spleenStatusId = i.Id
|
||||
}
|
||||
if (i.QuestionType === 48) {
|
||||
// 脾脏长度
|
||||
this.spleenLengthId = i.Id
|
||||
}
|
||||
if (i.QuestionType === 58) {
|
||||
// 修改脾脏状态备注
|
||||
this.spleenCommentsId = i.Id
|
||||
}
|
||||
if (i.QuestionType === 60) {
|
||||
// 脾尖位置
|
||||
this.spleenTopId = i.Id
|
||||
this.$set(i, 'SaveEnum', 0)
|
||||
}
|
||||
if (i.QuestionType === 61) {
|
||||
// 脾底位置
|
||||
this.spleenBottomId = i.Id
|
||||
this.$set(i, 'SaveEnum', 0)
|
||||
}
|
||||
}
|
||||
if (i.Childrens && i.Childrens.length > 0) {
|
||||
this.setChild(i.Childrens)
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
handleSave() {
|
||||
this.$refs['questions'].validate((valid) => {
|
||||
this.$refs['questions'].validate(async(valid) => {
|
||||
if (!valid) return
|
||||
// lugano标准校验脾脏状态是否符合要求
|
||||
if (this.criterionType === 2 && this.groupClassify === 3) {
|
||||
// 是否有标记未保存
|
||||
var existUnSave = this.checkAnnotationStatus(this.questions)
|
||||
if (existUnSave) {
|
||||
this.$alert(this.$t('trials:lugano:message:saveWarning'), this.$t('trials:lugano:fusionDialog:warning'))
|
||||
return
|
||||
}
|
||||
|
||||
var currentSpleenStatus = this.questionForm[this.spleenStatusId]
|
||||
var currentSpleenLength = this.questionForm[this.spleenLengthId]
|
||||
currentSpleenStatus = isNaN(parseInt(currentSpleenStatus)) ? null : parseInt(currentSpleenStatus)
|
||||
var stIdx = this.measurements.findIndex(i => i.QuestionType === 60)
|
||||
var slIdx = this.measurements.findIndex(i => i.QuestionType === 61)
|
||||
|
||||
if (currentSpleenLength && currentSpleenStatus === 5) {
|
||||
// '脾脏状态为不可评估,不需要添加标记!'
|
||||
this.$alert(this.$t('trials:lugano:message:validSpleen1'), this.$t('trials:lugano:fusionDialog:warning'), {
|
||||
callback: _ => {}
|
||||
})
|
||||
} else if (currentSpleenStatus === 5 && ((stIdx > -1 && this.measurements[stIdx].MeasureData) || (slIdx > -1 && this.measurements[slIdx].MeasureData))) {
|
||||
// 若有标记,状态不可为“无法评估”
|
||||
this.$alert(this.$t('trials:lugano:message:validSpleen1'), this.$t('trials:lugano:fusionDialog:warning'), {
|
||||
callback: _ => {}
|
||||
})
|
||||
} else if (((stIdx > -1 && this.measurements[stIdx].MeasureData) || (slIdx > -1 && this.measurements[slIdx].MeasureData)) && !currentSpleenLength) {
|
||||
this.$alert(this.$t('trials:lugano:message:validSpleen2'), this.$t('trials:lugano:fusionDialog:warning'), {
|
||||
callback: _ => {}
|
||||
})
|
||||
} else {
|
||||
this.saveQuestionsList()
|
||||
}
|
||||
} else if (this.criterionType === 2 && this.groupClassify === 1 && this.questionForm[this.imageQualityIssuesId] && parseInt(this.questionForm[this.imageQualityIssuesId]) === 6) {
|
||||
// 保存影响质量问题分组,如果质量问题为PET-CT影像无法融合则验证是否可以保存
|
||||
const res = await getCanChooseNotMerge({ visitTaskId: this.visitTaskId })
|
||||
if (res.IsSuccess && !res.Result.IsCanChooseNotMerge) {
|
||||
// this.$alert(this.$t('trials:lugano:saveQuestions:warning1'), this.$t('trials:lugano:fusionDialog:warning'), {showCancelButton: false})
|
||||
this.$alert(this.$t('trials:lugano:saveQuestions:warning1'), this.$t('trials:lugano:fusionDialog:warning'), {
|
||||
showCancelButton: false,
|
||||
callback: action => {}
|
||||
})
|
||||
return
|
||||
} else {
|
||||
// 如果设置为PET-CT影像无法融合,则FDG-PET评估会被设置为NE。
|
||||
this.$confirm(this.$t('trials:lugano:saveQuestions:warning2'), {
|
||||
type: 'warning',
|
||||
distinguishCancelAndClose: true
|
||||
})
|
||||
.then(() => {
|
||||
this.saveQuestionsList()
|
||||
})
|
||||
}
|
||||
} else {
|
||||
this.saveQuestionsList()
|
||||
}
|
||||
// this.saveQuestionsList()
|
||||
})
|
||||
},
|
||||
async saveQuestionsList() {
|
||||
this.loading = true
|
||||
var answers = []
|
||||
var imageQuality = null
|
||||
for (const k in this.questionForm) {
|
||||
answers.push({ id: k, answer: this.questionForm[k] })
|
||||
if (k === this.imageQualityId) {
|
||||
imageQuality = this.questionForm[k]
|
||||
}
|
||||
}
|
||||
var params = {
|
||||
visitTaskId: this.visitTaskId,
|
||||
answers: answers
|
||||
|
||||
}
|
||||
// if (this.groupClassify === 3) {
|
||||
// var questionMarkInfoList = []
|
||||
// this.measurements.forEach(item => {
|
||||
// var i = Object.assign({}, item)
|
||||
// if (i.MeasureData) {
|
||||
// i.MeasureData = JSON.stringify(i.MeasureData)
|
||||
// }
|
||||
// questionMarkInfoList.push(i)
|
||||
// })
|
||||
// params.questionMarkInfoList = questionMarkInfoList
|
||||
// }
|
||||
|
||||
saveTaskQuestion(this.questionType, params).then(async res => {
|
||||
if (this.imageQualityIssuesId) {
|
||||
store.dispatch('reading/setImageQualityIssues', this.questionForm[this.imageQualityIssuesId])
|
||||
if (this.questionForm[this.imageQualityIssuesId] && parseInt(this.questionForm[this.imageQualityIssuesId]) === 6) {
|
||||
DicomEvent.$emit('closePetct')
|
||||
}
|
||||
}
|
||||
this.$message.success(this.$t('common:message:savedSuccessfully'))
|
||||
var trialId = this.$route.query.trialId
|
||||
await store.dispatch('reading/refreshDicomReadingQuestionAnswer', { trialId: trialId, visitTaskId: this.visitTaskId })
|
||||
this.getQuestions(this.visitTaskId, true)
|
||||
this.loading = false
|
||||
if (this.isQulityIssues) {
|
||||
DicomEvent.$emit('questionFormChange', false)
|
||||
}
|
||||
DicomEvent.$emit('getReportInfo', true)
|
||||
// DicomEvent.$emit('readingPageUpdate', {})
|
||||
var idx = this.visitTaskList.findIndex(i => i.VisitTaskId === this.visitTaskId)
|
||||
const criterionType = parseInt(localStorage.getItem('CriterionType'))
|
||||
if (idx > -1 && !this.visitTaskList[idx].IsBaseLineTask && (criterionType === 1 || criterionType === 2 || criterionType === 3 || criterionType === 17)) {
|
||||
if (parseInt(imageQuality) === 2) {
|
||||
this.$confirm(this.$t('trials:reading:warnning:unableEvaluate'), '', {
|
||||
type: 'warning'
|
||||
}).then(() => {
|
||||
store.dispatch('reading/setImageQuality', imageQuality)
|
||||
DicomEvent.$emit('handleImageQualityAbnormal')
|
||||
DicomEvent.$emit('readingPageUpdate', {})
|
||||
}).catch(() => {
|
||||
|
||||
})
|
||||
}
|
||||
}
|
||||
this.formChanged = false
|
||||
}).catch(() => {
|
||||
this.loading = false
|
||||
})
|
||||
},
|
||||
checkAnnotationStatus(obj) {
|
||||
for (let i = 0; i < obj.length; i++) {
|
||||
if (obj[i].SaveEnum === 1) {
|
||||
return true
|
||||
}
|
||||
if (obj[i].Childrens && obj[i].Childrens.length > 0) {
|
||||
if (this.checkAnnotationStatus(obj[i].Childrens)) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
checkAnnotationValid(stIdx, slIdx) {
|
||||
var isValid = true
|
||||
if (stIdx > -1 && slIdx > -1 && this.measurements[stIdx].MeasureData && this.measurements[slIdx].MeasureData) {
|
||||
var stSeriesId = this.measurements[stIdx].SeriesId
|
||||
var stInstanceId = this.measurements[stIdx].InstanceId
|
||||
var slSeriesId = this.measurements[slIdx].SeriesId
|
||||
var slInstanceId = this.measurements[slIdx].InstanceId
|
||||
if (!(stSeriesId && stInstanceId && slSeriesId && slInstanceId && stSeriesId === slSeriesId && stInstanceId !== slInstanceId)) {
|
||||
isValid = false
|
||||
}
|
||||
}
|
||||
return isValid
|
||||
},
|
||||
setSpleenCommentDisplay() {
|
||||
if (this.spleenCommentsId && this.spleenStatusId) {
|
||||
for (let i = 0; i < this.questions[0].Childrens.length; i++) {
|
||||
if (this.questions[0].Childrens[i].QuestionType === 58) {
|
||||
if (this.calculateSpleenStatus && this.calculateSpleenStatus !== this.questionForm[this.spleenStatusId]) {
|
||||
this.questions[0].Childrens[i].ShowQuestion = 0
|
||||
this.questions[0].Childrens[i].IsRequired = 0
|
||||
} else {
|
||||
this.questions[0].Childrens[i].ShowQuestion = 2
|
||||
this.questions[0].Childrens[i].IsRequired = 3
|
||||
this.questionForm[this.spleenCommentsId] = ''
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
async getSplenicState() {
|
||||
try {
|
||||
var spleenLength = this.questionForm[this.spleenLengthId]
|
||||
spleenLength = isNaN(parseFloat(spleenLength)) ? -1 : parseFloat(spleenLength)
|
||||
const result = await getSplenicState(this.visitTaskId, spleenLength)
|
||||
return { isSuccess: true, result: result.Result }
|
||||
} catch (e) {
|
||||
return { isSuccess: false, result: e }
|
||||
}
|
||||
},
|
||||
async uploadScreenshots(fileName, file) {
|
||||
try {
|
||||
file = this.convertBase64ToBlob(file)
|
||||
var trialId = this.$route.query.trialId
|
||||
var subjectId = this.$route.query.trialId
|
||||
const result = await this.OSSclient.put(`/${trialId}/Read/${subjectId}/Visit/${fileName}.png`, file)
|
||||
return { isSuccess: true, result: result }
|
||||
} catch (e) {
|
||||
console.log(e)
|
||||
return { isSuccess: false, result: e }
|
||||
}
|
||||
},
|
||||
convertBase64ToBlob(imageEditorBase64) {
|
||||
var base64Arr = imageEditorBase64.split(',')
|
||||
var imgtype = ''
|
||||
var base64String = ''
|
||||
if (base64Arr.length > 1) {
|
||||
// 如果是图片base64,去掉头信息
|
||||
base64String = base64Arr[1]
|
||||
imgtype = base64Arr[0].substring(
|
||||
base64Arr[0].indexOf(':') + 1,
|
||||
base64Arr[0].indexOf(';')
|
||||
)
|
||||
}
|
||||
// 将base64解码
|
||||
var bytes = atob(base64String)
|
||||
// var bytes = base64;
|
||||
var bytesCode = new ArrayBuffer(bytes.length)
|
||||
// 转换为类型化数组
|
||||
var byteArray = new Uint8Array(bytesCode)
|
||||
|
||||
// 将base64转换为ascii码
|
||||
for (var i = 0; i < bytes.length; i++) {
|
||||
byteArray[i] = bytes.charCodeAt(i)
|
||||
}
|
||||
|
||||
// 生成Blob对象(文件对象)
|
||||
return new Blob([bytesCode], { type: imgtype })
|
||||
},
|
||||
addAnnotation(obj) {
|
||||
const { Id, QuestionType } = obj
|
||||
this.currentQsId = Id
|
||||
var idx = this.measurements.findIndex(i => i.QuestionId === Id)
|
||||
var orderMarkName = QuestionType === 60 ? 'Spleen Top' : QuestionType === 61 ? 'Spleen Bottom' : ''
|
||||
if (idx === -1) {
|
||||
this.measurements.push({ QuestionId: Id, QuestionType: QuestionType, StudyId: '', SeriesId: '', InstanceId: '', MarkTool: '', PicturePath: '', NumberOfFrames: '', MeasureData: '', OrderMarkName: orderMarkName })
|
||||
}
|
||||
|
||||
// 脾脏长度 直径测量
|
||||
this.$emit('setNonTargetMeasurementStatus', { status: true })
|
||||
DicomEvent.$emit('imageLocation', { questionId: Id, visitTaskId: this.visitTaskId, lesionName: orderMarkName, markTool: 'ArrowAnnotate', readingTaskState: this.readingTaskState, isMarked: false })
|
||||
},
|
||||
async removeAnnotation(obj) {
|
||||
const { Id } = obj
|
||||
var idx = this.measurements.findIndex(i => i.QuestionId === Id)
|
||||
if (idx === -1) return
|
||||
this.$set(this.questionForm, Id, '')
|
||||
if (!this.questionForm[this.spleenTopId] && !this.questionForm[this.spleenBottomId]) {
|
||||
this.clearSpleenStatus()
|
||||
}
|
||||
// if (obj.QuestionType === 60 || obj.QuestionType === 61) {
|
||||
// this.$set(this.questionForm, this.spleenStatusId, '')
|
||||
// this.$set(this.questionForm, this.spleenLengthId, '')
|
||||
// }
|
||||
await store.dispatch('reading/removeNonTargetMeasuredData', { visitTaskId: this.visitTaskId, measureData: this.measurements[idx].MeasureData, questionId: Id })
|
||||
this.setQuestionStatus(this.questions, this.measurements[idx].QuestionType)
|
||||
this.measurements.splice(idx, 1)
|
||||
DicomEvent.$emit('getMeasureData')
|
||||
// this.calculateSpleenStatus = ''
|
||||
// this.setSpleenCommentDisplay()
|
||||
this.formChanged = true
|
||||
},
|
||||
clearSpleenStatus() {
|
||||
this.$set(this.questionForm, this.spleenStatusId, '')
|
||||
this.$set(this.questionForm, this.spleenLengthId, '')
|
||||
for (let i = 0; i < this.questions[0].Childrens.length; i++) {
|
||||
if (this.questions[0].Childrens[i].QuestionType === 58) {
|
||||
this.questions[0].Childrens[i].ShowQuestion = 2
|
||||
this.questions[0].Childrens[i].IsRequired = 3
|
||||
this.questionForm[this.spleenCommentsId] = ''
|
||||
break
|
||||
}
|
||||
}
|
||||
},
|
||||
saveAnnotation(question) {
|
||||
var stIdx = this.measurements.findIndex(i => i.QuestionType === 60)
|
||||
var slIdx = this.measurements.findIndex(i => i.QuestionType === 61)
|
||||
var chenckVaild = this.checkAnnotationValid(stIdx, slIdx)
|
||||
if (!chenckVaild) {
|
||||
// 校验标记是否在同一序列的不同图像上
|
||||
this.$alert(this.$t('trials:lugano:message:validSpleen3'), this.$t('trials:lugano:fusionDialog:warning'), {
|
||||
callback: _ => {}
|
||||
})
|
||||
return
|
||||
}
|
||||
this.loading = true
|
||||
// 获取截图
|
||||
var annotationObj = this.measurements.find(i => i.QuestionType === question.QuestionType)
|
||||
if (!annotationObj) {
|
||||
this.saveQuestions(question)
|
||||
} else {
|
||||
var obj = Object.assign({}, annotationObj)
|
||||
DicomEvent.$emit('getScreenshots', { questionId: obj.Id, visitTaskId: this.visitTaskId, lesionName: obj.OrderMarkName, markTool: obj.MarkTool, readingTaskState: this.readingTaskState, isMarked: !!obj.MeasureData }, async val => {
|
||||
try {
|
||||
var pictureObj = await this.uploadScreenshots(`${new Date().getTime()}`, val)
|
||||
var picturePath = pictureObj.isSuccess ? this.$getObjectName(pictureObj.result.url) : ''
|
||||
this.saveQuestions(question, obj, picturePath)
|
||||
} catch (e) {
|
||||
console.log(e)
|
||||
this.loading = false
|
||||
}
|
||||
})
|
||||
}
|
||||
},
|
||||
async saveQuestions(question, obj, picturePath) {
|
||||
try {
|
||||
this.loading = true
|
||||
var answers = []
|
||||
var imageQuality = null
|
||||
var questionMarkInfoList = []
|
||||
if (obj && obj.MeasureData) {
|
||||
var annotation = Object.assign({}, obj.MeasureData)
|
||||
obj.MeasureData = JSON.stringify(annotation)
|
||||
obj.PicturePath = picturePath
|
||||
questionMarkInfoList.push(obj)
|
||||
}
|
||||
for (const k in this.questionForm) {
|
||||
answers.push({ id: k, answer: this.questionForm[k] })
|
||||
if (k === this.imageQualityId) {
|
||||
imageQuality = this.questionForm[k]
|
||||
if (k === question.Id) {
|
||||
answers.push({ id: k, answer: this.questionForm[k] })
|
||||
break
|
||||
}
|
||||
}
|
||||
var params = {
|
||||
visitTaskId: this.visitTaskId,
|
||||
answers: answers
|
||||
answers,
|
||||
questionMarkInfoList
|
||||
}
|
||||
saveImageQuality(params).then(async res => {
|
||||
this.$message.success(this.$t('common:message:savedSuccessfully'))
|
||||
var trialId = this.$route.query.trialId
|
||||
await store.dispatch('reading/refreshDicomReadingQuestionAnswer', { trialId: trialId, visitTaskId: this.visitTaskId })
|
||||
this.getQuestions(this.visitTaskId)
|
||||
|
||||
this.loading = false
|
||||
|
||||
DicomEvent.$emit('questionFormChange', false)
|
||||
DicomEvent.$emit('getReportInfo', true)
|
||||
var idx = this.visitTaskList.findIndex(i => i.VisitTaskId === this.visitTaskId)
|
||||
if (idx > -1 && !this.visitTaskList[idx].IsBaseLineTask) {
|
||||
if (parseInt(imageQuality) === 2) {
|
||||
this.$confirm(this.$t('trials:reading:warnning:unableEvaluate'), '', {
|
||||
type: 'warning'
|
||||
}).then(() => {
|
||||
store.dispatch('reading/setImageQuality', imageQuality)
|
||||
DicomEvent.$emit('handleImageQualityAbnormal')
|
||||
}).catch(() => {
|
||||
|
||||
})
|
||||
}
|
||||
const qsType = question.QuestionType === 60 ? 4 : question.QuestionType === 61 ? 5 : null
|
||||
await saveTaskQuestion(qsType, params)
|
||||
this.$message.success(this.$t('common:message:savedSuccessfully'))
|
||||
await this.setQuestions()
|
||||
for (let i = 0; i < this.questions[0].Childrens.length; i++) {
|
||||
if (this.questions[0].Childrens[i].QuestionType === 58) {
|
||||
this.questions[0].Childrens[i].ShowQuestion = 2
|
||||
this.questions[0].Childrens[i].IsRequired = 3
|
||||
this.questionForm[this.spleenCommentsId] = ''
|
||||
break
|
||||
}
|
||||
}).catch(() => {
|
||||
this.loading = false
|
||||
})
|
||||
})
|
||||
}
|
||||
this.loading = false
|
||||
this.$set(question, 'SaveEnum', 0)
|
||||
DicomEvent.$emit('getReportInfo', true)
|
||||
} catch (e) {
|
||||
console.log(e)
|
||||
this.loading = false
|
||||
}
|
||||
},
|
||||
locateAnnotation(obj) {
|
||||
const { Id } = obj
|
||||
var idx = this.measurements.findIndex(i => i.QuestionId === Id)
|
||||
if (idx === -1) return
|
||||
const measureObj = this.measurements[idx]
|
||||
DicomEvent.$emit('imageLocation', { questionId: Id, visitTaskId: this.visitTaskId, lesionName: measureObj.OrderMarkName, markTool: measureObj.MarkTool, readingTaskState: this.readingTaskState, isMarked: !!measureObj.MeasureData })
|
||||
},
|
||||
setMeasuredData(measurement) {
|
||||
var idx = -1
|
||||
if (this.currentQsId) {
|
||||
// 新增
|
||||
idx = this.measurements.findIndex(i => i.QuestionId === this.currentQsId)
|
||||
this.currentQsId = ''
|
||||
} else {
|
||||
// 编辑
|
||||
idx = this.measurements.findIndex(i => i.OrderMarkName === measurement.data.remark)
|
||||
}
|
||||
if (idx === -1) return
|
||||
var remark = this.measurements[idx].QuestionType === 60 ? 'Spleen Top' : this.measurements[idx].QuestionType === 61 ? 'Spleen Bottom' : ''
|
||||
measurement.data.remark = remark
|
||||
this.measurements[idx].StudyId = measurement.studyId
|
||||
this.measurements[idx].SeriesId = measurement.seriesId
|
||||
this.measurements[idx].InstanceId = measurement.instanceId
|
||||
this.measurements[idx].MarkTool = measurement.type
|
||||
this.measurements[idx].NumberOfFrames = isNaN(parseInt(measurement.frame)) ? 0 : measurement.frame
|
||||
this.measurements[idx].MeasureData = measurement
|
||||
this.measurements[idx].pictureBaseStr = measurement.pictureBaseStr
|
||||
measurement.pictureBaseStr = ''
|
||||
// 添加标记
|
||||
var data = {
|
||||
Id: '',
|
||||
IsDicomReading: true,
|
||||
StudyId: measurement.studyId,
|
||||
InstanceId: measurement.instanceId,
|
||||
SeriesId: measurement.seriesId,
|
||||
MeasureData: measurement,
|
||||
QuestionId: this.measurements[idx].QuestionId,
|
||||
RowIndex: null,
|
||||
RowId: null,
|
||||
VisitTaskId: this.visitTaskId,
|
||||
OrderMarkName: measurement.data.remark,
|
||||
frame: isNaN(parseInt(measurement.frame)) ? 0 : measurement.frame
|
||||
}
|
||||
if (measurement.type === 'ArrowAnnotate') {
|
||||
const location = measurement.location ? Number(measurement.location).toFixed(this.digitPlaces) : null
|
||||
this.$set(this.questionForm, this.measurements[idx].QuestionId, location || null)
|
||||
// if (this.measurements[idx].QuestionType === 60 || this.measurements[idx].QuestionType === 61) {
|
||||
// var length = this.getSpleenL()
|
||||
// this.$set(this.questionForm, this.spleenLengthId, length)
|
||||
// var status = this.setSpleenStatus(length)
|
||||
// this.$set(this.questionForm, this.spleenStatusId, status)
|
||||
// this.calculateSpleenStatus = status
|
||||
// }
|
||||
|
||||
// if (this.measurements[idx].QuestionType === 48 && length <= 130 && this.isBaseLineTask) {
|
||||
// // 脾脏状态设置默认值为正常
|
||||
// this.$set(this.questionForm, this.spleenStatusId, '1')
|
||||
// }
|
||||
// if (this.measurements[idx].QuestionType === 48 && length > 130 && this.isBaseLineTask) {
|
||||
// // 脾脏状态设置默认值为肿大
|
||||
// this.$set(this.questionForm, this.spleenStatusId, '6')
|
||||
// }
|
||||
}
|
||||
store.dispatch('reading/addOrUpdateNonTargetMeasuredData', { visitTaskId: this.visitTaskId, data: data })
|
||||
if (this.isQulityIssues) {
|
||||
DicomEvent.$emit('questionFormChange', true)
|
||||
}
|
||||
this.formChanged = true
|
||||
this.setQuestionStatus(this.questions, this.measurements[idx].QuestionType)
|
||||
},
|
||||
setQuestionStatus(obj, questionType) {
|
||||
console.log(obj, questionType)
|
||||
for (let i = 0; i < obj.length; i++) {
|
||||
if (obj[i].QuestionType === questionType) {
|
||||
this.$set(obj[i], 'SaveEnum', 1)
|
||||
return true
|
||||
}
|
||||
if (obj[i].Childrens && obj[i].Childrens.length > 0) {
|
||||
if (this.setQuestionStatus(obj[i].Childrens, questionType)) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
getSpleenL() {
|
||||
var length = null
|
||||
// 脾尖位置
|
||||
var st = this.questionForm[this.spleenTopId]
|
||||
st = isNaN(parseFloat(st)) ? null : parseFloat(st)
|
||||
// 脾底位置
|
||||
var sb = this.questionForm[this.spleenBottomId]
|
||||
sb = isNaN(parseFloat(sb)) ? null : parseFloat(sb)
|
||||
if (st && sb) {
|
||||
length = Math.abs(st - sb).toFixed(this.digitPlaces)
|
||||
}
|
||||
return length
|
||||
},
|
||||
setSpleenStatus(length) {
|
||||
console.log('setSpleenStatus')
|
||||
var status = ''
|
||||
if (length) {
|
||||
if (this.isBaseLineTask) {
|
||||
// 直径≤130mm时,系统默认脾脏状态为“正常”
|
||||
if (length <= 130) {
|
||||
status = '1'
|
||||
}
|
||||
// 直径>130mm时,系统默认脾脏状态为“肿大”
|
||||
if (length > 130) {
|
||||
status = '6'
|
||||
}
|
||||
} else {
|
||||
// 与基线相比脾垂直径变化值
|
||||
var diffFromBaseline = length - this.spleenInfo.BaseLineSpleenLength
|
||||
var percentFormBaseline = 0
|
||||
if (this.spleenInfo.BaseLineSpleenLength) {
|
||||
percentFormBaseline = diffFromBaseline * 100 / (this.spleenInfo.BaseLineSpleenLength - 130)
|
||||
}
|
||||
if (length <= 130) {
|
||||
// 当前访视的垂直径≤130mm
|
||||
// 系统默认脾脏状态为“正常”
|
||||
status = '1'
|
||||
} else if (this.spleenInfo.BaseLineSpleenLength > 130 && diffFromBaseline >= 10 && percentFormBaseline > 50 && length > 130) {
|
||||
// 1、基线 垂直径>130 mm
|
||||
// 2、与基线相比脾垂直径变化值≥10 mm
|
||||
// 3、与基线相比脾肿大增加的百分比>50%
|
||||
// 4、当前垂直径>130 mm
|
||||
// 系统默认脾脏状态为“显著增大”
|
||||
status = '4'
|
||||
} else if (this.spleenInfo.BaseLineSpleenLength <= 130 && diffFromBaseline >= 20 && length > 130) {
|
||||
// 1、基线垂直径≤130mm
|
||||
// 2、与基线相比脾垂直径变化值≥20 mm
|
||||
// 3、当前垂直径>130 mm
|
||||
// 系统默认脾脏状态为“显著增大”
|
||||
status = '4'
|
||||
} else if (this.spleenInfo.BaseLineSpleenLength > 130 && this.spleenInfo.LowSpleenLength <= 130 && length - this.spleenInfo.LowSpleenLength >= 20 && length > 130) {
|
||||
// 1、基线 垂直径>130 mm
|
||||
// 2、当前访视的前面访视中 存在垂直径≤130mm
|
||||
// 3、与最低点相比脾脏垂直径的增加值≥20 mm
|
||||
// 4、当前垂直径>130 mm
|
||||
// 系统默认脾脏状态为“显著增大”
|
||||
status = '4'
|
||||
} else if (this.spleenInfo.BaseLineState === '6' && percentFormBaseline < -50 && length > 130) {
|
||||
// 1、基线期 状态为“肿大”
|
||||
// 2、与基线相比脾肿大增加的百分比小于-50%
|
||||
// 3、当前垂直径>130 mm
|
||||
// 系统默认脾脏状态为“部分缓解”
|
||||
status = '2'
|
||||
} else {
|
||||
// 系统默认脾脏状态为“稳定”
|
||||
status = '3'
|
||||
}
|
||||
}
|
||||
}
|
||||
return status
|
||||
},
|
||||
resetFormItemData(v) {
|
||||
this.questionForm[v] = null
|
||||
// if (v === this.spleenLengthId) {
|
||||
// var spleenStatus = this.questionForm[this.spleenStatusId]
|
||||
// spleenStatus = isNaN(parseInt(spleenStatus)) ? null : parseInt(spleenStatus)
|
||||
// if (spleenStatus === 5) {
|
||||
// this.removeAnnotation({ Id: this.spleenLengthId })
|
||||
// }
|
||||
// }
|
||||
this.formChanged = true
|
||||
},
|
||||
setFormItemData(obj) {
|
||||
this.questionForm[obj.key] = obj.val
|
||||
if (obj.key === this.spleenStatusId) {
|
||||
this.setSpleenCommentDisplay()
|
||||
}
|
||||
this.formChanged = true
|
||||
},
|
||||
setQuestions() {
|
||||
return new Promise(resolve => {
|
||||
var params = {
|
||||
trialId: this.$route.query.trialId,
|
||||
visitTaskId: this.visitTaskId
|
||||
}
|
||||
getDicomReadingQuestionAnswer(params).then(res => {
|
||||
var questions = []
|
||||
for (var i = 0; i < res.Result.length; i++) {
|
||||
var v = res.Result[i]
|
||||
if (v.Type === 'group' && v.GroupClassify !== this.groupClassify) continue
|
||||
questions.push(v)
|
||||
}
|
||||
questions.map((v) => {
|
||||
if (v.Type === 'group' && v.Childrens.length === 0) return
|
||||
if (v.Childrens.length > 0) {
|
||||
this.setQSChild(v.Childrens)
|
||||
}
|
||||
})
|
||||
resolve()
|
||||
})
|
||||
})
|
||||
},
|
||||
setQSChild(obj) {
|
||||
obj.forEach(i => {
|
||||
if (i.QuestionType === 49) {
|
||||
// 脾脏状态;
|
||||
this.$set(this.questionForm, i.Id, i.Answer ? i.Answer : null)
|
||||
this.calculateSpleenStatus = i.Answer
|
||||
}
|
||||
if (i.QuestionType === 48) {
|
||||
// 脾脏长度;
|
||||
this.$set(this.questionForm, i.Id, i.Answer ? i.Answer : null)
|
||||
}
|
||||
if (i.Childrens && i.Childrens.length > 0) {
|
||||
this.setQSChild(i.Childrens)
|
||||
}
|
||||
})
|
||||
},
|
||||
openFeedBackTable() {
|
||||
this.$FB({
|
||||
type: 'imgfail',
|
||||
trialId: this.$route.query.trialId,
|
||||
visitTaskId: this.visitTaskId,
|
||||
callBack: async() => {
|
||||
console.log('callBack')
|
||||
const confirm = await this.$confirm(
|
||||
this.$t('trials:reading:confirm:feedbackmsg'),
|
||||
{
|
||||
type: 'warning',
|
||||
distinguishCancelAndClose: true
|
||||
}
|
||||
)
|
||||
if (confirm !== 'confirm') return
|
||||
this.loading = true
|
||||
try {
|
||||
const res = await setSkipReadingCache({ visitTaskId: this.visitTaskId })
|
||||
this.loading = false
|
||||
if (res.IsSuccess) {
|
||||
window.location.reload()
|
||||
}
|
||||
} catch (e) {
|
||||
this.loading = false
|
||||
console.log(e)
|
||||
}
|
||||
}
|
||||
})
|
||||
},
|
||||
isJSONString(str) {
|
||||
try {
|
||||
JSON.stringify(JSON.parse(str))
|
||||
return true
|
||||
} catch (e) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.ecrf-wrapper{
|
||||
>>>.el-form-item__label{
|
||||
/deep/ .el-form-item__label{
|
||||
color: #c3c3c3;
|
||||
text-align: left;
|
||||
}
|
||||
>>>.el-input__inner{
|
||||
/deep/ .el-input__inner{
|
||||
background-color: transparent;
|
||||
color: #ddd;
|
||||
border: 1px solid #5e5e5e;
|
||||
}
|
||||
>>>.el-textarea__inner{
|
||||
/deep/ .el-textarea__inner{
|
||||
background-color: transparent;
|
||||
color: #ddd;
|
||||
border: 1px solid #5e5e5e;
|
||||
}
|
||||
>>>.el-form-item{
|
||||
|
||||
/deep/ .el-form-item{
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: flex-start;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
>>>.el-form-item__content{
|
||||
/deep/ .el-form-item__content{
|
||||
flex: 1;
|
||||
}
|
||||
>>>.el-button--mini, .el-button--mini.is-round {
|
||||
/deep/ .el-button--mini, .el-button--mini.is-round {
|
||||
padding: 7px 10px;
|
||||
}
|
||||
.el-form-item__content
|
||||
/deep/ .el-form-item__content
|
||||
.el-select{
|
||||
width: 100%;
|
||||
}
|
||||
.ecrf-footer{
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: flex-end;
|
||||
align-items: center;
|
||||
.feedback-icon{
|
||||
padding: 0 10px;
|
||||
color: #fff;
|
||||
font-weight: 400;
|
||||
font-size: 22px;
|
||||
cursor: pointer;
|
||||
&:hover{
|
||||
color: #68a2d5;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
</style>
|
||||
|
|
|
@ -57,6 +57,7 @@
|
|||
:is-reading-show-subject-info="isReadingShowSubjectInfo"
|
||||
:is-reading-task-view-in-order="isReadingTaskViewInOrder"
|
||||
:is-exists-manual="isExistsManual"
|
||||
:iseCRFShowInDicomReading="iseCRFShowInDicomReading"
|
||||
@previewCD="previewCD"
|
||||
/>
|
||||
</div>
|
||||
|
@ -72,6 +73,25 @@ import DicomEvent from './DicomEvent'
|
|||
import store from '@/store'
|
||||
import { getToken } from '@/utils/auth'
|
||||
import { mapGetters } from 'vuex'
|
||||
import * as dicomParser from 'dicom-parser'
|
||||
import * as cornerstone from 'cornerstone-core'
|
||||
import * as cornerstoneWADOImageLoader from 'cornerstone-wado-image-loader'
|
||||
import metaDataProvider from '@/utils/metaDataProvider'
|
||||
cornerstone.metaData.addProvider(metaDataProvider, { priority: 10 });
|
||||
var config = {
|
||||
maxWebWorkers: 4,
|
||||
startWebWorkersOnDemand: true,
|
||||
taskConfiguration: {
|
||||
decodeTask: {
|
||||
initializeCodecsOnStartup: false
|
||||
}
|
||||
}
|
||||
}
|
||||
cornerstoneWADOImageLoader.webWorkerManager.initialize(config)
|
||||
cornerstoneWADOImageLoader.external.dicomParser = dicomParser
|
||||
cornerstoneWADOImageLoader.external.cornerstone = cornerstone
|
||||
const maximumSizeInBytes = 1024 * 1024 * 1024 * 6
|
||||
cornerstone.imageCache.setMaximumSizeBytes(maximumSizeInBytes)
|
||||
export default {
|
||||
name: 'ReadPage',
|
||||
components: {
|
||||
|
@ -112,13 +132,17 @@ export default {
|
|||
required: true
|
||||
},
|
||||
isReadingTaskViewInOrder: {
|
||||
type: Boolean,
|
||||
type: Number,
|
||||
required: true
|
||||
},
|
||||
isExistsManual: {
|
||||
type: Boolean,
|
||||
required: true
|
||||
},
|
||||
iseCRFShowInDicomReading: {
|
||||
type: Boolean,
|
||||
required: true
|
||||
},
|
||||
questionFormChangeState: {
|
||||
type: Boolean,
|
||||
default() {
|
||||
|
@ -210,14 +234,20 @@ export default {
|
|||
this.$refs[this.activeTaskVisitId][0].selectSeries(data)
|
||||
})
|
||||
})
|
||||
cornerstone.events.addEventListener('cornerstoneimageloadprogress', this.cornerstoneimageloadprogress)
|
||||
window.addEventListener('beforeunload', e => {
|
||||
cornerstone.imageCache.purgeCache()
|
||||
})
|
||||
},
|
||||
beforeDestroy() {
|
||||
cornerstone.imageCache.purgeCache()
|
||||
DicomEvent.$off('getNextVisitInfo')
|
||||
DicomEvent.$off('toggleSeries')
|
||||
DicomEvent.$off('isCanActiveNoneDicomTool')
|
||||
DicomEvent.$off('removeNoneDicomMeasureData')
|
||||
DicomEvent.$off('addNoneDicomMeasureData')
|
||||
DicomEvent.$off('selectSeries')
|
||||
window.removeEventListener('beforeunload', e => { cornerstone.imageCache.purgeCache() })
|
||||
},
|
||||
methods: {
|
||||
async getVisitInfo() {
|
||||
|
@ -400,7 +430,7 @@ export default {
|
|||
idx > -1 ? obj = seriesList[idx] : ''
|
||||
}
|
||||
if (obj) {
|
||||
const index = Math.floor(obj.imageIds.length * ((baseSeries.imageIdIndex + 1) / baseSeries.instanceCount))
|
||||
const index = Math.floor(obj.imageIds.length * ((baseSeries.imageIdIndex + 1) / baseSeries.imageIds))
|
||||
obj.imageIdIndex = index > 0 ? index - 1 : 0
|
||||
}
|
||||
return obj
|
||||
|
@ -464,7 +494,10 @@ export default {
|
|||
var seriesIdx = studyList[studyIdx].SeriesList.findIndex(s => s.seriesId === seriesId)
|
||||
if (seriesIdx > -1) {
|
||||
var series = studyList[studyIdx].SeriesList[seriesIdx]
|
||||
var instanceIdx = series.instanceList.findIndex(imageId => !!~imageId.indexOf(instanceId))
|
||||
// var instanceIdx = series.instanceList.findIndex(imageId => !!~imageId.indexOf(instanceId))
|
||||
const frame = this.visitTaskList[index].MeasureData[idx].MeasureData.frame
|
||||
const filterStr = series.isExistMutiFrames ? `frame=${frame}&instanceId=${instanceId}` : `instanceId=${instanceId}`
|
||||
var instanceIdx = series.imageIds.findIndex(imageId => imageId.includes(filterStr))
|
||||
if (instanceIdx > -1) {
|
||||
series.imageIdIndex = instanceIdx
|
||||
// series.studyIndex = studyIdx
|
||||
|
@ -485,6 +518,16 @@ export default {
|
|||
seriesInfo = this.getLinkedSeries(baseSeries, visitTaskId, visitTaskIdx)
|
||||
}
|
||||
return seriesInfo
|
||||
},
|
||||
cornerstoneimageloadprogress(e) {
|
||||
const imageId = e.detail.imageId
|
||||
const params = {}
|
||||
const searchParams = new URLSearchParams(imageId.split('?')[1])
|
||||
for (const [key, value] of searchParams.entries()) {
|
||||
params[key] = value
|
||||
}
|
||||
params.percentComplete = e.detail.percentComplete
|
||||
store.dispatch('reading/setImageLoadedProgress', params)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,11 +1,22 @@
|
|||
<template>
|
||||
<div class="measurement-wrapper" :style="{'height':height+10+'px'}">
|
||||
<div class="measurement-wrapper">
|
||||
|
||||
<div class="container">
|
||||
<div class="basic-info">
|
||||
<h3 v-if="isReadingShowSubjectInfo">
|
||||
<span v-if="subjectCode">{{ subjectCode }} </span>
|
||||
<span style="margin-left:5px;">{{ taskBlindName }}</span>
|
||||
</h3>
|
||||
<div v-if="readingTaskState < 2">
|
||||
<el-tooltip class="item" effect="dark" :content="$t('trials:dicomReading:message:confirmReset')" placement="bottom">
|
||||
<i
|
||||
class="el-icon-refresh-left"
|
||||
@click="resetMeasuredData"
|
||||
/>
|
||||
</el-tooltip>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="container" :style="{'height':height+'px'}">
|
||||
<h3 v-if="isReadingShowSubjectInfo" style="color: #ddd;padding: 5px 0px;margin: 0;">
|
||||
<span v-if="subjectCode">{{ subjectCode }} </span>
|
||||
<span style="margin-left:5px;">{{ taskBlindName }}</span>
|
||||
</h3>
|
||||
<!-- 非测量问题 -->
|
||||
<div class="lesions">
|
||||
<Questions ref="ecrf" :question-form-change-state="questionFormChangeState" :question-form-change-num="questionFormChangeNum" />
|
||||
|
@ -122,6 +133,7 @@
|
|||
</template>
|
||||
<script>
|
||||
import { splitLesion } from '@/api/trials'
|
||||
import { resetReadingTask } from '@/api/reading'
|
||||
import DicomEvent from './../DicomEvent'
|
||||
import store from '@/store'
|
||||
import { mapGetters } from 'vuex'
|
||||
|
@ -157,7 +169,6 @@ export default {
|
|||
},
|
||||
data() {
|
||||
return {
|
||||
height: window.innerHeight - 140,
|
||||
questions: [],
|
||||
activeName: '',
|
||||
activeItem: {
|
||||
|
@ -201,7 +212,8 @@ export default {
|
|||
}
|
||||
},
|
||||
mounted() {
|
||||
this.subjectCode = this.$router.currentRoute.query.subjectCode
|
||||
// this.subjectCode = this.$router.currentRoute.query.subjectCode
|
||||
this.subjectCode = localStorage.getItem('subjectCode')
|
||||
window.addEventListener('message', this.receiveMsg)
|
||||
this.CriterionType = parseInt(localStorage.getItem('CriterionType'))
|
||||
DicomEvent.$on('setCollapseActive', measureData => {
|
||||
|
@ -221,8 +233,6 @@ export default {
|
|||
DicomEvent.$on('split', measureData => {
|
||||
this.handleSplit(measureData.RowId, measureData.QuestionId)
|
||||
})
|
||||
|
||||
window.addEventListener('resize', this.setHeight)
|
||||
},
|
||||
beforeDestroy() {
|
||||
DicomEvent.$off('setCollapseActive')
|
||||
|
@ -403,9 +413,6 @@ export default {
|
|||
} catch (e) { console.log(e) }
|
||||
})
|
||||
},
|
||||
setHeight() {
|
||||
this.height = window.innerHeight - 140
|
||||
},
|
||||
getQuestionAnswer(questions, questionMark, answers) {
|
||||
var idx = questions.findIndex(i => i.QuestionMark === questionMark)
|
||||
if (idx > -1) {
|
||||
|
@ -503,15 +510,15 @@ export default {
|
|||
}
|
||||
}
|
||||
},
|
||||
split(rowId, questionId) {
|
||||
async split(rowId, questionId) {
|
||||
const loading = this.$loading({ fullscreen: true })
|
||||
var params = {
|
||||
visitTaskId: this.visitTaskId,
|
||||
questionId: questionId,
|
||||
rowId: rowId
|
||||
}
|
||||
splitLesion(params).then(async res => {
|
||||
loading.close()
|
||||
try {
|
||||
var params = {
|
||||
visitTaskId: this.visitTaskId,
|
||||
questionId: questionId,
|
||||
rowId: rowId
|
||||
}
|
||||
await splitLesion(params)
|
||||
await this.getReadingQuestionAndAnswer()
|
||||
this.$nextTick(() => {
|
||||
this.tableQuestions.forEach(item => {
|
||||
|
@ -521,7 +528,11 @@ export default {
|
|||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
loading.close()
|
||||
} catch (e) {
|
||||
loading.close()
|
||||
console.log(e)
|
||||
}
|
||||
},
|
||||
isCanActiveTool(toolName) {
|
||||
this.getUnSaveTarget()
|
||||
|
@ -942,6 +953,39 @@ export default {
|
|||
getECRFQuestions(obj) {
|
||||
this.$refs['ecrf'].getQuestions(obj.visitTaskId)
|
||||
},
|
||||
async resetMeasuredData() {
|
||||
const confirm = await this.$confirm(
|
||||
this.$t('trials:dicomReading:message:confirmReset1'),
|
||||
this.$t('trials:dicomReading:message:confirmReset2'),
|
||||
{
|
||||
type: 'warning',
|
||||
distinguishCancelAndClose: true
|
||||
}
|
||||
)
|
||||
if (confirm !== 'confirm') return
|
||||
const loading = this.$loading({ fullscreen: true })
|
||||
try {
|
||||
const res = await resetReadingTask({ visitTaskId: this.visitTaskId })
|
||||
this.loading = false
|
||||
if (res.IsSuccess) {
|
||||
// 刷新标注、表单、报告页信息
|
||||
this.activeName = ''
|
||||
this.activeItem.activeRowIndex = null
|
||||
this.activeItem.activeCollapseId = null
|
||||
await this.getReadingQuestionAndAnswer(this.visitTaskId)
|
||||
const triald = this.$router.currentRoute.query.trialId
|
||||
await store.dispatch('reading/refreshDicomReadingQuestionAnswer', { trialId: triald, visitTaskId: this.visitTaskId })
|
||||
this.$refs['ecrf'].getQuestions(this.visitTaskId, true)
|
||||
DicomEvent.$emit('getMeasureData')
|
||||
DicomEvent.$emit('getReportInfo', true)
|
||||
DicomEvent.$emit('refreshStudyListMeasureData')
|
||||
}
|
||||
loading.close()
|
||||
} catch (e) {
|
||||
loading.close()
|
||||
console.log(e)
|
||||
}
|
||||
},
|
||||
receiveMsg(event) {
|
||||
if (event.data.type === 'isCanActiveNoneDicomTool') {
|
||||
this.getUnSaveTarget()
|
||||
|
@ -1015,11 +1059,28 @@ export default {
|
|||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.measurement-wrapper{
|
||||
height: 100%;
|
||||
overflow-y: auto;
|
||||
// overflow: hidden;
|
||||
|
||||
.container{
|
||||
padding: 10px;
|
||||
.basic-info{
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
h3{
|
||||
color: #ddd;
|
||||
padding: 5px 0px;
|
||||
margin: 0;
|
||||
}
|
||||
i{
|
||||
color: #fff;
|
||||
font-size: 22px;
|
||||
font-weight: bold;
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
}
|
||||
.title{
|
||||
padding: 5px;
|
||||
|
|
|
@ -110,34 +110,38 @@
|
|||
/>
|
||||
</template>
|
||||
<template v-else-if="qs.DictionaryCode && qs.QuestionMark === 7 && !isBaseLineTask">
|
||||
<!-- 首次分裂的病灶只能选择存在 -->
|
||||
<template v-if="answers.IsFristAdd=== 'True' && answers.SplitOrMergeType === '0'">
|
||||
<el-option
|
||||
v-for="item of $d[qs.DictionaryCode]"
|
||||
v-show="item.value === 0"
|
||||
:key="item.id"
|
||||
:value="item.value"
|
||||
:label="item.label"
|
||||
/>
|
||||
</template>
|
||||
<!-- 首次添加的新病灶不能为无法评估和消失 -->
|
||||
<template v-else-if="isCurrentTaskAdd=== 'True' && lesionType === 2">
|
||||
<el-option
|
||||
v-for="item of $d[qs.DictionaryCode]"
|
||||
v-show="item.value === 0 || item.value === 1"
|
||||
:key="item.id"
|
||||
:value="item.value"
|
||||
:label="item.label"
|
||||
/>
|
||||
</template>
|
||||
<template v-else>
|
||||
<el-option
|
||||
v-for="item of filterState($d[qs.DictionaryCode])"
|
||||
:key="item.id"
|
||||
:value="item.value"
|
||||
:label="item.label"
|
||||
/>
|
||||
</template>
|
||||
<el-option-group
|
||||
:label="!isNaN(parseFloat(answers.LastTaskState)) ? `${$t('trials:dicomReading:tip:lastVisitStatus')} ${$fd(qs.DictionaryCode,parseFloat(answers.LastTaskState))}` : ''"
|
||||
>
|
||||
<!-- 首次分裂的病灶只能选择存在 -->
|
||||
<template v-if="answers.IsFristAdd=== 'True' && answers.SplitOrMergeType === '0'">
|
||||
<el-option
|
||||
v-for="item of $d[qs.DictionaryCode]"
|
||||
v-show="item.value === 0"
|
||||
:key="item.id"
|
||||
:value="item.value"
|
||||
:label="item.label"
|
||||
/>
|
||||
</template>
|
||||
<!-- 首次添加的新病灶不能为无法评估和消失 -->
|
||||
<template v-else-if="isCurrentTaskAdd=== 'True' && lesionType === 2">
|
||||
<el-option
|
||||
v-for="item of $d[qs.DictionaryCode]"
|
||||
v-show="item.value === 0 || item.value === 1"
|
||||
:key="item.id"
|
||||
:value="item.value"
|
||||
:label="item.label"
|
||||
/>
|
||||
</template>
|
||||
<template v-else>
|
||||
<el-option
|
||||
v-for="item of filterState($d[qs.DictionaryCode])"
|
||||
:key="item.id"
|
||||
:value="item.value"
|
||||
:label="item.label"
|
||||
/>
|
||||
</template>
|
||||
</el-option-group>
|
||||
</template>
|
||||
<template v-else-if="qs.DictionaryCode && qs.QuestionMark !== 7">
|
||||
<el-option
|
||||
|
@ -340,16 +344,15 @@ export default {
|
|||
await this.getOrganInfoList()
|
||||
|
||||
// 首次分裂的病灶默认状态为空时,设置默认值为存在
|
||||
if (this.answers.IsFristAdd === 'True' && this.answers.SplitOrMergeType === '0' && isNaN(parseInt(this.getQuestionVal(7)))) {
|
||||
if (this.answers.IsFristAdd === 'True' && this.answers.SplitOrMergeType === '0' && lesionState === '') {
|
||||
const stateId = this.getQuestionId(7)
|
||||
this.$set(this.questionForm, stateId, 0)
|
||||
var isLymphLesion = this.getQuestionVal(2)
|
||||
isLymphLesion = !isNaN(parseInt(isLymphLesion)) ? parseInt(isLymphLesion) : null
|
||||
const lesionPart = this.getQuestionVal(8)
|
||||
const lesionOrgan = this.getQuestionVal(6)
|
||||
const lesionLength = !isNaN(parseInt(this.getQuestionVal(0))) ? this.getQuestionVal(0) : ''
|
||||
const lesionShort = !isNaN(parseInt(this.getQuestionVal(1))) ? this.getQuestionVal(1) : ''
|
||||
const lesionState = !isNaN(parseInt(this.getQuestionVal(7))) ? parseInt(this.getQuestionVal(7)) : ''
|
||||
const lesionLength = this.getQuestionVal(0)
|
||||
const lesionShort = this.getQuestionVal(1)
|
||||
const lesionState = this.getQuestionVal(7)
|
||||
this.$emit('resetQuestions', { isLymphLesion, lesionPart, lesionOrgan, lesionShort, lesionState, saveTypeEnum: this.questionForm.saveTypeEnum, lesionLength, rowIndex: this.rowIndex, questionId: this.parentQsId, anwsers: this.questionForm })
|
||||
}
|
||||
this.isRender = true
|
||||
|
@ -515,8 +518,8 @@ export default {
|
|||
}
|
||||
const lesionPart = this.getQuestionVal(8)
|
||||
const lesionOrgan = this.getQuestionVal(6)
|
||||
const lesionLength = !isNaN(parseInt(this.getQuestionVal(0))) ? this.getQuestionVal(0) : ''
|
||||
const lesionState = !isNaN(parseInt(this.getQuestionVal(7))) ? parseInt(this.getQuestionVal(7)) : ''
|
||||
const lesionLength = this.getQuestionVal(0)
|
||||
const lesionState = this.getQuestionVal(7)
|
||||
this.$emit('resetQuestions', { isLymphLesion: 0, lesionPart, lesionOrgan, lesionState, saveTypeEnum: this.questionForm.saveTypeEnum, lesionLength, rowIndex: this.rowIndex, questionId: this.parentQsId, anwsers: this.questionForm })
|
||||
|
||||
if (question.QuestionMark === 7) {
|
||||
|
@ -575,9 +578,8 @@ export default {
|
|||
}
|
||||
|
||||
var isLymphLesion = this.getQuestionVal(2)
|
||||
isLymphLesion = !isNaN(parseInt(isLymphLesion)) ? parseInt(isLymphLesion) : null
|
||||
var lesionLength = !isNaN(parseInt(this.getQuestionVal(0))) ? this.getQuestionVal(0) : ''
|
||||
var lesionShort = !isNaN(parseInt(this.getQuestionVal(1))) ? this.getQuestionVal(1) : ''
|
||||
var lesionLength = this.getQuestionVal(0)
|
||||
var lesionShort = this.getQuestionVal(1)
|
||||
|
||||
// 当前添加的新病灶不做处理
|
||||
if (!(this.isCurrentTaskAdd === 'True')) {
|
||||
|
@ -597,7 +599,7 @@ export default {
|
|||
}
|
||||
}
|
||||
|
||||
const lesionState = !isNaN(parseInt(this.getQuestionVal(7))) ? parseInt(this.getQuestionVal(7)) : ''
|
||||
const lesionState = this.getQuestionVal(7)
|
||||
var status = ''
|
||||
if (lesionState) {
|
||||
if (this.lesionType === 0 && lesionState === 1) {
|
||||
|
@ -646,8 +648,8 @@ export default {
|
|||
|
||||
const lesionPart = this.getQuestionVal(8)
|
||||
const lesionOrgan = this.getQuestionVal(6)
|
||||
const lesionL = !isNaN(parseInt(this.getQuestionVal(0))) ? this.getQuestionVal(0) : ''
|
||||
var lesionState = !isNaN(parseInt(this.getQuestionVal(7))) ? parseInt(this.getQuestionVal(7)) : ''
|
||||
const lesionL = this.getQuestionVal(0)
|
||||
var lesionState = this.getQuestionVal(7)
|
||||
this.$emit('resetQuestions', { isLymphLesion: 0, lesionPart, lesionOrgan, lesionLength: lesionL, lesionState, saveTypeEnum: this.questionForm.saveTypeEnum, rowIndex: this.rowIndex, questionId: this.parentQsId, anwsers: this.questionForm })
|
||||
this.toolType = measureData.type
|
||||
DicomEvent.$emit('refreshStudyListMeasureData')
|
||||
|
@ -670,27 +672,31 @@ export default {
|
|||
}
|
||||
},
|
||||
getQuestionVal(questionMark) {
|
||||
var idx = this.questions.findIndex(i => i.QuestionMark === questionMark)
|
||||
const idx = this.questions.findIndex(i => i.QuestionMark === questionMark)
|
||||
if (idx > -1) {
|
||||
var questionId = this.questions[idx].Id
|
||||
return this.questionForm[questionId]
|
||||
const questionId = this.questions[idx].Id
|
||||
const answer = this.questionForm[questionId]
|
||||
if (isNaN(parseFloat(answer))) {
|
||||
return answer
|
||||
} else {
|
||||
return parseFloat(answer)
|
||||
}
|
||||
} else {
|
||||
return ''
|
||||
}
|
||||
},
|
||||
filterState(arr) {
|
||||
if (!this.isBaseLineTask) {
|
||||
var isLymphLesion = this.getQuestionVal(2)
|
||||
isLymphLesion = !isNaN(parseInt(isLymphLesion)) ? parseInt(isLymphLesion) : null
|
||||
const lesionLength = !isNaN(parseInt(this.getQuestionVal(0))) ? this.getQuestionVal(0) : 0
|
||||
const lesionShort = !isNaN(parseInt(this.getQuestionVal(1))) ? this.getQuestionVal(1) : 0
|
||||
const lastLesionL = !isNaN(parseInt(this.answers.LastTaskMajorAxis)) ? parseInt(this.answers.LastTaskMajorAxis) : 0
|
||||
const lastLesionS = !isNaN(parseInt(this.answers.LastTaskShortAxis)) ? parseInt(this.answers.LastTaskShortAxis) : 0
|
||||
if (this.lesionType === 1 && isLymphLesion === 1 && this.questionForm.MeasureData && (this.questionForm.MeasureData.type === 'Length' || this.questionForm.MeasureData.type === 'Bidirectional') && lesionShort < lastLesionS) {
|
||||
const isLymphLesion = this.getQuestionVal(2)
|
||||
const lesionLength = this.getQuestionVal(0)
|
||||
const lesionShort = this.getQuestionVal(1)
|
||||
const bLesionL = !isNaN(parseInt(this.answers.LastTaskMajorAxis)) ? parseInt(this.answers.LastTaskMajorAxis) : 0
|
||||
const bLesionS = !isNaN(parseInt(this.answers.LastTaskShortAxis)) ? parseInt(this.answers.LastTaskShortAxis) : 0
|
||||
if (this.lesionType === 1 && isLymphLesion === 1 && this.questionForm.MeasureData && this.questionForm.MeasureData.type === 'Bidirectional' && lesionShort < bLesionS) {
|
||||
arr = arr.filter(i => i.value !== 1)
|
||||
} else if (this.lesionType === 1 && isLymphLesion === 1 && this.questionForm.MeasureData && (this.questionForm.MeasureData.type === 'Length' || this.questionForm.MeasureData.type === 'Bidirectional') && lesionShort >= 10 && lesionShort > lastLesionS) {
|
||||
} else if (this.lesionType === 1 && isLymphLesion === 1 && this.questionForm.MeasureData && this.questionForm.MeasureData.type === 'Bidirectional' && lesionShort >= 10 && lesionShort > bLesionS) {
|
||||
arr = arr.filter(i => i.value === 0 || i.value === 1)
|
||||
} else if (this.lesionType === 1 && isLymphLesion === 0 && this.questionForm.MeasureData && (this.questionForm.MeasureData.type === 'Length' || this.questionForm.MeasureData.type === 'Bidirectional') && lesionLength < lastLesionL) {
|
||||
} else if (this.lesionType === 1 && isLymphLesion === 0 && this.questionForm.MeasureData && (this.questionForm.MeasureData.type === 'Length' || this.questionForm.MeasureData.type === 'Bidirectional') && lesionLength < bLesionL) {
|
||||
arr = arr.filter(i => i.value !== 1)
|
||||
}
|
||||
return arr
|
||||
|
@ -754,227 +760,228 @@ export default {
|
|||
// 生成Blob对象(文件对象)
|
||||
return new Blob([bytesCode], { type: imgtype })
|
||||
},
|
||||
handleSave() {
|
||||
this.$refs.measurementForm.validate(async valid => {
|
||||
if (!valid) return
|
||||
const loading = this.$loading({ fullscreen: true })
|
||||
var measureData = this.questionForm.MeasureData
|
||||
var lesionState = this.getQuestionVal(7)
|
||||
var lesionLength = !isNaN(parseInt(this.getQuestionVal(0))) ? this.getQuestionVal(0) : ''
|
||||
async handleSave() {
|
||||
const valid = await this.$refs.measurementForm.validate()
|
||||
if (!valid) return
|
||||
const loading = this.$loading({ fullscreen: true })
|
||||
var measureData = this.questionForm.MeasureData
|
||||
var lesionState = this.getQuestionVal(7)
|
||||
var lesionLength = this.getQuestionVal(0)
|
||||
|
||||
if (this.isBaseLineTask) {
|
||||
// 基线
|
||||
// 靶病灶且状态为存在(0)
|
||||
if (this.lesionType === 0 && lesionState === 0) {
|
||||
// 靶病灶 直径测量工具 长径须大于等于10mm且不小于2倍层厚
|
||||
if (!(measureData && measureData.type === 'Length' && lesionLength >= 10 && (measureData.thick && lesionLength >= 2 * measureData.thick || !measureData.thick))) {
|
||||
// 病灶状态为“存在”的靶病灶,长径应大于10mm且不小于2倍层厚。请使用直径测量工具添加标记。
|
||||
this.$confirm(this.$t('trials:readingBM:warnning:msg06'), {
|
||||
type: 'warning',
|
||||
showCancelButton: false,
|
||||
callback: action => {}
|
||||
})
|
||||
loading.close()
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// 非靶病灶且状态为存在(0)
|
||||
if (this.lesionType === 1 && lesionState === 0) {
|
||||
if (!(measureData && (measureData.type === 'Length' || measureData.type === 'RectangleRoi'))) {
|
||||
// 病灶状态为“存在”的非靶病灶,请使用直径测量工具或矩形工具添加标记。
|
||||
this.$confirm(this.$t('trials:readingBM:warnning:msg07'), {
|
||||
type: 'warning',
|
||||
showCancelButton: false,
|
||||
callback: action => {}
|
||||
})
|
||||
loading.close()
|
||||
return
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// 非基线
|
||||
// 靶病灶且状态为存在(0)
|
||||
if (this.lesionType === 0 && lesionState === 0) {
|
||||
if (!(measureData && measureData.type === 'Length')) {
|
||||
// `病灶状态为“存在”的靶病灶,请使用直径测量工具添加标记。`
|
||||
this.$confirm(this.$t('trials:readingBM:warnning:msg08'), {
|
||||
type: 'warning',
|
||||
showCancelButton: false,
|
||||
callback: action => {}
|
||||
})
|
||||
loading.close()
|
||||
return
|
||||
}
|
||||
}
|
||||
// 靶病灶且状态为太小(1)
|
||||
if (this.lesionType === 0 && lesionState === 1) {
|
||||
if (!(measureData && (measureData.type === 'ArrowAnnotate'))) {
|
||||
// 病灶状态为“太小”的靶病灶,请使用箭头工具添加标记。
|
||||
this.$confirm(this.$t('trials:readingBM:warnning:msg09'), {
|
||||
type: 'warning',
|
||||
showCancelButton: false,
|
||||
callback: action => {}
|
||||
})
|
||||
loading.close()
|
||||
return
|
||||
} else if (measureData && measureData.type === 'ArrowAnnotate') {
|
||||
const lengthId = this.getQuestionId(0)
|
||||
this.$set(this.questionForm, lengthId, 5)
|
||||
lesionLength = 5
|
||||
}
|
||||
}
|
||||
|
||||
// 靶病灶且状态为无法评估(2)
|
||||
if (this.lesionType === 0 && lesionState === 2) {
|
||||
if (measureData) {
|
||||
// 病灶状态为“无法评估”的靶病灶,不需要添加标记。
|
||||
this.$confirm(this.$t('trials:readingBM:warnning:msg10'), {
|
||||
type: 'warning',
|
||||
showCancelButton: false,
|
||||
callback: action => {}
|
||||
})
|
||||
loading.close()
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// 靶病灶且状态为消失(3)
|
||||
if (this.lesionType === 0 && lesionState === 3) {
|
||||
if (!(measureData && measureData.type === 'ArrowAnnotate')) {
|
||||
// 病灶状态为“消失”的靶病灶,请使用箭头工具添加标记。
|
||||
this.$confirm(this.$t('trials:readingBM:warnning:msg11'), {
|
||||
type: 'warning',
|
||||
showCancelButton: false,
|
||||
callback: action => {}
|
||||
})
|
||||
loading.close()
|
||||
return
|
||||
} else if (measureData && measureData.type === 'ArrowAnnotate') {
|
||||
const lId = this.getQuestionId(0)
|
||||
this.$set(this.questionForm, lId, 0)
|
||||
lesionLength = 0
|
||||
}
|
||||
}
|
||||
|
||||
// 非靶病灶且状态为存在(0)
|
||||
if (this.lesionType === 1 && lesionState === 0) {
|
||||
if (!(measureData && (measureData.type === 'Length' || measureData.type === 'RectangleRoi'))) {
|
||||
// 病灶状态为“存在”的非靶病灶,请使用直径测量工具或矩形工具添加标记。
|
||||
this.$confirm(this.$t('trials:readingBM:warnning:msg12'), {
|
||||
type: 'warning',
|
||||
showCancelButton: false,
|
||||
callback: action => {}
|
||||
})
|
||||
loading.close()
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// 非靶病灶且状态为显著增大(1)
|
||||
if (this.lesionType === 1 && lesionState === 1) {
|
||||
if (!(measureData && (measureData.type === 'Length' || measureData.type === 'RectangleRoi'))) {
|
||||
// 病灶状态为“显著增大”的非靶病灶,请使用直径测量工具或矩形工具添加标记。
|
||||
this.$confirm(this.$t('trials:readingBM:warnning:msg13'), {
|
||||
type: 'warning',
|
||||
showCancelButton: false,
|
||||
callback: action => {}
|
||||
})
|
||||
loading.close()
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// 非靶病灶且状态为无法评估(2)
|
||||
if (this.lesionType === 1 && lesionState === 2) {
|
||||
if (measureData) {
|
||||
// 病灶状态为“无法评估”的非靶病灶,不需要添加标记。
|
||||
this.$confirm(this.$t('trials:readingBM:warnning:msg14'), {
|
||||
type: 'warning',
|
||||
showCancelButton: false,
|
||||
callback: action => {}
|
||||
})
|
||||
loading.close()
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// 非靶病灶且状态为消失(3)
|
||||
if (this.lesionType === 1 && lesionState === 3) {
|
||||
if (!(measureData && (measureData.type === 'ArrowAnnotate'))) {
|
||||
// 病灶状态为“消失”的非靶病灶,请使用箭头工具添加标记。
|
||||
this.$confirm(this.$t('trials:readingBM:warnning:msg15'), {
|
||||
type: 'warning',
|
||||
showCancelButton: false,
|
||||
callback: action => {}
|
||||
})
|
||||
loading.close()
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// 新病灶且状态为明确(0)
|
||||
if (this.lesionType === 2 && lesionState === 0) {
|
||||
if (!(measureData && (measureData.type === 'Length' || measureData.type === 'ArrowAnnotate'))) {
|
||||
// 病灶状态为“明确”的新病灶,请使用直径测量工具或箭头工具添加标记。
|
||||
this.$confirm(this.$t('trials:readingBM:warnning:msg16'), {
|
||||
type: 'warning',
|
||||
showCancelButton: false,
|
||||
callback: action => {}
|
||||
})
|
||||
loading.close()
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// 新病灶且状态为疑似(1)
|
||||
if (this.lesionType === 2 && lesionState === 1) {
|
||||
if (!(measureData && (measureData.type === 'Length' || measureData.type === 'ArrowAnnotate'))) {
|
||||
// 病灶状态为“疑似”的新病灶,请使用直径测量工具或箭头工具添加标记。
|
||||
this.$confirm(this.$t('trials:readingBM:warnning:msg17'), {
|
||||
type: 'warning',
|
||||
showCancelButton: false,
|
||||
callback: action => {}
|
||||
})
|
||||
loading.close()
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// 新病灶且状态为无法评估(2)
|
||||
if (this.lesionType === 2 && lesionState === 2) {
|
||||
if (measureData) {
|
||||
// 病灶状态为“无法评估”的新病灶,不需要添加标记。
|
||||
this.$confirm(this.$t('trials:readingBM:warnning:msg18'), {
|
||||
type: 'warning',
|
||||
showCancelButton: false,
|
||||
callback: action => {}
|
||||
})
|
||||
loading.close()
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// 新病灶且状态为消失(3)
|
||||
if (this.lesionType === 2 && lesionState === 3) {
|
||||
if (!(measureData && (measureData.type === 'ArrowAnnotate'))) {
|
||||
// 病灶状态为“消失”的新病灶,请使用箭头工具添加标记。
|
||||
this.$confirm(this.$t('trials:readingBM:warnning:msg19'), {
|
||||
type: 'warning',
|
||||
showCancelButton: false,
|
||||
callback: action => {}
|
||||
})
|
||||
loading.close()
|
||||
return
|
||||
}
|
||||
if (this.isBaseLineTask) {
|
||||
// 基线
|
||||
// 靶病灶且状态为存在(0)
|
||||
if (this.lesionType === 0 && lesionState === 0) {
|
||||
// 靶病灶 直径测量工具 长径须大于等于10mm且不小于2倍层厚
|
||||
if (!(measureData && measureData.type === 'Length' && lesionLength >= 10 && (measureData.thick && lesionLength >= 2 * measureData.thick || !measureData.thick))) {
|
||||
// 病灶状态为“存在”的靶病灶,长径应大于10mm且不小于2倍层厚。请使用直径测量工具添加标记。
|
||||
this.$confirm(this.$t('trials:readingBM:warnning:msg06'), {
|
||||
type: 'warning',
|
||||
showCancelButton: false,
|
||||
callback: action => {}
|
||||
})
|
||||
loading.close()
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
DicomEvent.$emit('getScreenshots', { questionId: this.parentQsId, rowIndex: this.questionForm.RowIndex, visitTaskId: this.visitTaskId, lesionName: this.lesionMark, lesionType: this.lesionType, isMarked: !!measureData }, async val => {
|
||||
// 非靶病灶且状态为存在(0)
|
||||
if (this.lesionType === 1 && lesionState === 0) {
|
||||
if (!(measureData && (measureData.type === 'Length' || measureData.type === 'RectangleRoi'))) {
|
||||
// 病灶状态为“存在”的非靶病灶,请使用直径测量工具或矩形工具添加标记。
|
||||
this.$confirm(this.$t('trials:readingBM:warnning:msg07'), {
|
||||
type: 'warning',
|
||||
showCancelButton: false,
|
||||
callback: action => {}
|
||||
})
|
||||
loading.close()
|
||||
return
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// 非基线
|
||||
// 靶病灶且状态为存在(0)
|
||||
if (this.lesionType === 0 && lesionState === 0) {
|
||||
if (!(measureData && measureData.type === 'Length')) {
|
||||
// `病灶状态为“存在”的靶病灶,请使用直径测量工具添加标记。`
|
||||
this.$confirm(this.$t('trials:readingBM:warnning:msg08'), {
|
||||
type: 'warning',
|
||||
showCancelButton: false,
|
||||
callback: action => {}
|
||||
})
|
||||
loading.close()
|
||||
return
|
||||
}
|
||||
}
|
||||
// 靶病灶且状态为太小(1)
|
||||
if (this.lesionType === 0 && lesionState === 1) {
|
||||
if (!(measureData && (measureData.type === 'ArrowAnnotate'))) {
|
||||
// 病灶状态为“太小”的靶病灶,请使用箭头工具添加标记。
|
||||
this.$confirm(this.$t('trials:readingBM:warnning:msg09'), {
|
||||
type: 'warning',
|
||||
showCancelButton: false,
|
||||
callback: action => {}
|
||||
})
|
||||
loading.close()
|
||||
return
|
||||
} else if (measureData && measureData.type === 'ArrowAnnotate') {
|
||||
const lengthId = this.getQuestionId(0)
|
||||
this.$set(this.questionForm, lengthId, 5)
|
||||
lesionLength = 5
|
||||
}
|
||||
}
|
||||
|
||||
// 靶病灶且状态为无法评估(2)
|
||||
if (this.lesionType === 0 && lesionState === 2) {
|
||||
if (measureData) {
|
||||
// 病灶状态为“无法评估”的靶病灶,不需要添加标记。
|
||||
this.$confirm(this.$t('trials:readingBM:warnning:msg10'), {
|
||||
type: 'warning',
|
||||
showCancelButton: false,
|
||||
callback: action => {}
|
||||
})
|
||||
loading.close()
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// 靶病灶且状态为消失(3)
|
||||
if (this.lesionType === 0 && lesionState === 3) {
|
||||
if (!(measureData && measureData.type === 'ArrowAnnotate')) {
|
||||
// 病灶状态为“消失”的靶病灶,请使用箭头工具添加标记。
|
||||
this.$confirm(this.$t('trials:readingBM:warnning:msg11'), {
|
||||
type: 'warning',
|
||||
showCancelButton: false,
|
||||
callback: action => {}
|
||||
})
|
||||
loading.close()
|
||||
return
|
||||
} else if (measureData && measureData.type === 'ArrowAnnotate') {
|
||||
const lId = this.getQuestionId(0)
|
||||
this.$set(this.questionForm, lId, 0)
|
||||
lesionLength = 0
|
||||
}
|
||||
}
|
||||
|
||||
// 非靶病灶且状态为存在(0)
|
||||
if (this.lesionType === 1 && lesionState === 0) {
|
||||
if (!(measureData && (measureData.type === 'Length' || measureData.type === 'RectangleRoi'))) {
|
||||
// 病灶状态为“存在”的非靶病灶,请使用直径测量工具或矩形工具添加标记。
|
||||
this.$confirm(this.$t('trials:readingBM:warnning:msg12'), {
|
||||
type: 'warning',
|
||||
showCancelButton: false,
|
||||
callback: action => {}
|
||||
})
|
||||
loading.close()
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// 非靶病灶且状态为显著增大(1)
|
||||
if (this.lesionType === 1 && lesionState === 1) {
|
||||
if (!(measureData && (measureData.type === 'Length' || measureData.type === 'RectangleRoi'))) {
|
||||
// 病灶状态为“显著增大”的非靶病灶,请使用直径测量工具或矩形工具添加标记。
|
||||
this.$confirm(this.$t('trials:readingBM:warnning:msg13'), {
|
||||
type: 'warning',
|
||||
showCancelButton: false,
|
||||
callback: action => {}
|
||||
})
|
||||
loading.close()
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// 非靶病灶且状态为无法评估(2)
|
||||
if (this.lesionType === 1 && lesionState === 2) {
|
||||
if (measureData) {
|
||||
// 病灶状态为“无法评估”的非靶病灶,不需要添加标记。
|
||||
this.$confirm(this.$t('trials:readingBM:warnning:msg14'), {
|
||||
type: 'warning',
|
||||
showCancelButton: false,
|
||||
callback: action => {}
|
||||
})
|
||||
loading.close()
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// 非靶病灶且状态为消失(3)
|
||||
if (this.lesionType === 1 && lesionState === 3) {
|
||||
if (!(measureData && (measureData.type === 'ArrowAnnotate'))) {
|
||||
// 病灶状态为“消失”的非靶病灶,请使用箭头工具添加标记。
|
||||
this.$confirm(this.$t('trials:readingBM:warnning:msg15'), {
|
||||
type: 'warning',
|
||||
showCancelButton: false,
|
||||
callback: action => {}
|
||||
})
|
||||
loading.close()
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// 新病灶且状态为明确(0)
|
||||
if (this.lesionType === 2 && lesionState === 0) {
|
||||
if (!(measureData && (measureData.type === 'Length' || measureData.type === 'ArrowAnnotate'))) {
|
||||
// 病灶状态为“明确”的新病灶,请使用直径测量工具或箭头工具添加标记。
|
||||
this.$confirm(this.$t('trials:readingBM:warnning:msg16'), {
|
||||
type: 'warning',
|
||||
showCancelButton: false,
|
||||
callback: action => {}
|
||||
})
|
||||
loading.close()
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// 新病灶且状态为疑似(1)
|
||||
if (this.lesionType === 2 && lesionState === 1) {
|
||||
if (!(measureData && (measureData.type === 'Length' || measureData.type === 'ArrowAnnotate'))) {
|
||||
// 病灶状态为“疑似”的新病灶,请使用直径测量工具或箭头工具添加标记。
|
||||
this.$confirm(this.$t('trials:readingBM:warnning:msg17'), {
|
||||
type: 'warning',
|
||||
showCancelButton: false,
|
||||
callback: action => {}
|
||||
})
|
||||
loading.close()
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// 新病灶且状态为无法评估(2)
|
||||
if (this.lesionType === 2 && lesionState === 2) {
|
||||
if (measureData) {
|
||||
// 病灶状态为“无法评估”的新病灶,不需要添加标记。
|
||||
this.$confirm(this.$t('trials:readingBM:warnning:msg18'), {
|
||||
type: 'warning',
|
||||
showCancelButton: false,
|
||||
callback: action => {}
|
||||
})
|
||||
loading.close()
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// 新病灶且状态为消失(3)
|
||||
if (this.lesionType === 2 && lesionState === 3) {
|
||||
if (!(measureData && (measureData.type === 'ArrowAnnotate'))) {
|
||||
// 病灶状态为“消失”的新病灶,请使用箭头工具添加标记。
|
||||
this.$confirm(this.$t('trials:readingBM:warnning:msg19'), {
|
||||
type: 'warning',
|
||||
showCancelButton: false,
|
||||
callback: action => {}
|
||||
})
|
||||
loading.close()
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DicomEvent.$emit('getScreenshots', { questionId: this.parentQsId, rowIndex: this.questionForm.RowIndex, visitTaskId: this.visitTaskId, lesionName: this.lesionMark, lesionType: this.lesionType, isMarked: !!measureData }, async val => {
|
||||
try {
|
||||
var picturePath = ''
|
||||
if (val && measureData && this.questionForm.IsDicomReading) {
|
||||
var pictureObj = await this.uploadScreenshots(`${new Date().getTime()}`, val)
|
||||
picturePath = pictureObj.isSuccess ? pictureObj.result.name : ''
|
||||
picturePath = pictureObj.isSuccess ? this.$getObjectName(pictureObj.result.url) : ''
|
||||
}
|
||||
var answers = []
|
||||
var reg = new RegExp(/^[0-9a-zA-Z]{8}-[0-9a-zA-Z]{4}-[0-9a-zA-Z]{4}-[0-9a-zA-Z]{4}-[0-9a-zA-Z]{12}$/)
|
||||
|
@ -1010,7 +1017,8 @@ export default {
|
|||
await this.deleteOldLesion(this.deleteInfo.questionId, this.deleteInfo.rowId)
|
||||
this.deleteInfo = null
|
||||
}
|
||||
submitTableQuestion(params).then(async res => {
|
||||
const res = await submitTableQuestion(params)
|
||||
if (res.IsSuccess) {
|
||||
// 保存成功!
|
||||
this.$message.success(this.$t('common:message:savedSuccessfully'))
|
||||
this.currentMarkTool = measureData ? measureData.type : ''
|
||||
|
@ -1018,94 +1026,87 @@ export default {
|
|||
|
||||
this.$set(this.questionForm, 'saveTypeEnum', 2)
|
||||
this.originalQuestionForm = { ...this.questionForm }
|
||||
loading.close()
|
||||
|
||||
var lesionOrgan = this.getQuestionVal(6)
|
||||
this.$set(this.questionForm, 'RowId', res.Result.RowId)
|
||||
const lesionPart = this.getQuestionVal(8)
|
||||
const lesionState = Number(this.getQuestionVal(7))
|
||||
const lesionState = this.getQuestionVal(7)
|
||||
this.$emit('resetQuestions', { isLymphLesion: 0, lesionPart, lesionOrgan, saveTypeEnum: this.questionForm.saveTypeEnum, lesionLength, lesionState, rowIndex: this.rowIndex, questionId: this.parentQsId, anwsers: this.questionForm })
|
||||
this.$emit('close')
|
||||
DicomEvent.$emit('getReportInfo', true)
|
||||
DicomEvent.$emit('setMeasuredToolsPassive')
|
||||
}).catch(() => { loading.close() })
|
||||
})
|
||||
}
|
||||
loading.close()
|
||||
} catch (e) {
|
||||
console.log(e)
|
||||
loading.close()
|
||||
}
|
||||
})
|
||||
},
|
||||
handleDeleteMeasureData() {
|
||||
async handleDeleteMeasureData() {
|
||||
// 是否确认清除标记?
|
||||
this.$confirm(this.$t('trials:reading:warnning:msg47'), {
|
||||
type: 'warning',
|
||||
distinguishCancelAndClose: true
|
||||
})
|
||||
.then(async() => {
|
||||
// 重置长短径 和 状态
|
||||
var lengId = this.getQuestionId(0)
|
||||
this.$set(this.questionForm, lengId, '')
|
||||
const confirm = await this.$confirm(
|
||||
this.$t('trials:reading:warnning:msg47'),
|
||||
{
|
||||
type: 'warning',
|
||||
distinguishCancelAndClose: true
|
||||
}
|
||||
)
|
||||
if (confirm !== 'confirm') return
|
||||
// 重置长短径 和 状态
|
||||
var lengId = this.getQuestionId(0)
|
||||
this.$set(this.questionForm, lengId, '')
|
||||
|
||||
var stateId = this.getQuestionId(7)
|
||||
this.$set(this.questionForm, stateId, '')
|
||||
// saveTypeEnum 0:未保存过(新建病灶);1:已保存,信息不完整(随访初始化病灶/分裂病灶,通过状态判断)
|
||||
if (this.questionForm.RowId) {
|
||||
this.$set(this.questionForm, 'saveTypeEnum', 1)
|
||||
} else {
|
||||
this.$set(this.questionForm, 'saveTypeEnum', 0)
|
||||
}
|
||||
await store.dispatch('reading/removeMeasuredData', { visitTaskId: this.visitTaskId, measureData: this.questionForm.MeasureData, questionId: this.parentQsId, rowIndex: this.questionForm.RowIndex })
|
||||
DicomEvent.$emit('getMeasureData')
|
||||
const lesionPart = this.getQuestionVal(8)
|
||||
const lesionOrgan = this.getQuestionVal(6)
|
||||
const lesionLength = ''
|
||||
const lesionState = !isNaN(parseInt(this.getQuestionVal(7))) ? parseInt(this.getQuestionVal(7)) : ''
|
||||
var stateId = this.getQuestionId(7)
|
||||
this.$set(this.questionForm, stateId, '')
|
||||
// saveTypeEnum 0:未保存过(新建病灶);1:已保存,信息不完整(随访初始化病灶/分裂病灶,通过状态判断)
|
||||
if (this.questionForm.RowId) {
|
||||
this.$set(this.questionForm, 'saveTypeEnum', 1)
|
||||
} else {
|
||||
this.$set(this.questionForm, 'saveTypeEnum', 0)
|
||||
}
|
||||
await store.dispatch('reading/removeMeasuredData', { visitTaskId: this.visitTaskId, measureData: this.questionForm.MeasureData, questionId: this.parentQsId, rowIndex: this.questionForm.RowIndex })
|
||||
DicomEvent.$emit('getMeasureData')
|
||||
const lesionPart = this.getQuestionVal(8)
|
||||
const lesionOrgan = this.getQuestionVal(6)
|
||||
const lesionLength = ''
|
||||
const lesionState = this.getQuestionVal(7)
|
||||
|
||||
if (!this.questionForm.IsDicomReading) {
|
||||
DicomEvent.$emit('removeNoneDicomMeasureData', this.questionForm.MeasureData)
|
||||
}
|
||||
this.$set(this.questionForm, 'IsDicomReading', true)
|
||||
if (!this.questionForm.IsDicomReading) {
|
||||
DicomEvent.$emit('removeNoneDicomMeasureData', this.questionForm.MeasureData)
|
||||
}
|
||||
this.$set(this.questionForm, 'IsDicomReading', true)
|
||||
|
||||
this.$set(this.questionForm, 'MeasureData', '')
|
||||
let anwsers = null
|
||||
if (this.answers.measureObj) {
|
||||
anwsers = Object.assign({ measureObj: '' }, this.questionForm)
|
||||
} else {
|
||||
anwsers = Object.assign({}, this.questionForm)
|
||||
}
|
||||
this.$emit('resetQuestions', { isLymphLesion: 0, lesionPart, lesionOrgan, lesionState, saveTypeEnum: this.questionForm.saveTypeEnum, lesionLength, rowIndex: this.rowIndex, questionId: this.parentQsId, anwsers: anwsers })
|
||||
DicomEvent.$emit('refreshStudyListMeasureData')
|
||||
})
|
||||
.catch(() => {})
|
||||
this.$set(this.questionForm, 'MeasureData', '')
|
||||
let anwsers = null
|
||||
if (this.answers.measureObj) {
|
||||
anwsers = Object.assign({ measureObj: '' }, this.questionForm)
|
||||
} else {
|
||||
anwsers = Object.assign({}, this.questionForm)
|
||||
}
|
||||
this.$emit('resetQuestions', { isLymphLesion: 0, lesionPart, lesionOrgan, lesionState, saveTypeEnum: this.questionForm.saveTypeEnum, lesionLength, rowIndex: this.rowIndex, questionId: this.parentQsId, anwsers: anwsers })
|
||||
DicomEvent.$emit('refreshStudyListMeasureData')
|
||||
},
|
||||
handleDelete() {
|
||||
async handleDelete() {
|
||||
// 是否确认删除?
|
||||
this.$confirm(this.$t('trials:reading:warnning:msg48'), {
|
||||
type: 'warning',
|
||||
distinguishCancelAndClose: true
|
||||
})
|
||||
.then(async() => {
|
||||
if (this.questionForm.RowId) {
|
||||
const loading = this.$loading({ fullscreen: true })
|
||||
var param = {
|
||||
visitTaskId: this.visitTaskId,
|
||||
questionId: this.parentQsId,
|
||||
rowId: this.questionForm.RowId
|
||||
}
|
||||
deleteReadingRowAnswer(param)
|
||||
.then(async res => {
|
||||
loading.close()
|
||||
if (res.IsSuccess) {
|
||||
if (this.questionForm.IsDicomReading && this.questionForm.MeasureData) {
|
||||
await store.dispatch('reading/removeMeasuredData', { visitTaskId: this.visitTaskId, measureData: this.questionForm.MeasureData, questionId: this.parentQsId, rowIndex: this.questionForm.RowIndex })
|
||||
}
|
||||
if (!this.questionForm.IsDicomReading && this.questionForm.MeasureData) {
|
||||
DicomEvent.$emit('removeNoneDicomMeasureData', this.questionForm.MeasureData)
|
||||
}
|
||||
this.$emit('close', { lesionType: this.lesionType, rowIndex: this.rowIndex, visitTaskId: this.visitTaskId })
|
||||
DicomEvent.$emit('getReportInfo', true)
|
||||
this.$message.success(this.$t('common:message:deletedSuccessfully'))
|
||||
loading.close()
|
||||
}
|
||||
}).catch(() => { loading.close() })
|
||||
} else {
|
||||
const loading = this.$loading({ fullscreen: true })
|
||||
try {
|
||||
const confirm = await this.$confirm(
|
||||
this.$t('trials:reading:warnning:msg48'),
|
||||
{
|
||||
type: 'warning',
|
||||
distinguishCancelAndClose: true
|
||||
}
|
||||
)
|
||||
if (confirm !== 'confirm') return
|
||||
if (this.questionForm.RowId) {
|
||||
var param = {
|
||||
visitTaskId: this.visitTaskId,
|
||||
questionId: this.parentQsId,
|
||||
rowId: this.questionForm.RowId
|
||||
}
|
||||
const res = await deleteReadingRowAnswer(param)
|
||||
if (res.IsSuccess) {
|
||||
if (this.questionForm.IsDicomReading && this.questionForm.MeasureData) {
|
||||
await store.dispatch('reading/removeMeasuredData', { visitTaskId: this.visitTaskId, measureData: this.questionForm.MeasureData, questionId: this.parentQsId, rowIndex: this.questionForm.RowIndex })
|
||||
}
|
||||
|
@ -1113,26 +1114,41 @@ export default {
|
|||
DicomEvent.$emit('removeNoneDicomMeasureData', this.questionForm.MeasureData)
|
||||
}
|
||||
this.$emit('close', { lesionType: this.lesionType, rowIndex: this.rowIndex, visitTaskId: this.visitTaskId })
|
||||
DicomEvent.$emit('getReportInfo', true)
|
||||
this.$message.success(this.$t('common:message:deletedSuccessfully'))
|
||||
}
|
||||
DicomEvent.$emit('refreshStudyListMeasureData')
|
||||
})
|
||||
} else {
|
||||
if (this.questionForm.IsDicomReading && this.questionForm.MeasureData) {
|
||||
await store.dispatch('reading/removeMeasuredData', { visitTaskId: this.visitTaskId, measureData: this.questionForm.MeasureData, questionId: this.parentQsId, rowIndex: this.questionForm.RowIndex })
|
||||
}
|
||||
if (!this.questionForm.IsDicomReading && this.questionForm.MeasureData) {
|
||||
DicomEvent.$emit('removeNoneDicomMeasureData', this.questionForm.MeasureData)
|
||||
}
|
||||
this.$emit('close', { lesionType: this.lesionType, rowIndex: this.rowIndex, visitTaskId: this.visitTaskId })
|
||||
}
|
||||
DicomEvent.$emit('refreshStudyListMeasureData')
|
||||
loading.close()
|
||||
} catch (e) {
|
||||
console.log(e)
|
||||
loading.close()
|
||||
}
|
||||
},
|
||||
handleClose() {
|
||||
async handleClose() {
|
||||
if (!this.questionForm.RowId) {
|
||||
// '当前病灶为新建病灶,未保存。如果关闭窗口,将会删除病灶信息,是否继续?'
|
||||
this.$confirm(this.$t('trials:reading:warnning:msg49'), {
|
||||
type: 'warning',
|
||||
distinguishCancelAndClose: true
|
||||
})
|
||||
.then(async() => {
|
||||
// 移除新建病灶并关闭窗口
|
||||
if (this.questionForm.MeasureData) {
|
||||
await store.dispatch('reading/removeMeasuredData', { visitTaskId: this.visitTaskId, measureData: this.questionForm.MeasureData, questionId: this.parentQsId, rowIndex: this.questionForm.RowIndex })
|
||||
}
|
||||
DicomEvent.$emit('getMeasureData')
|
||||
this.$emit('close', { lesionType: this.lesionType, rowIndex: this.rowIndex, visitTaskId: this.visitTaskId })
|
||||
})
|
||||
.catch(() => {})
|
||||
const confirm = await this.$confirm(
|
||||
this.$t('trials:reading:warnning:msg49'),
|
||||
{
|
||||
type: 'warning',
|
||||
distinguishCancelAndClose: true
|
||||
}
|
||||
)
|
||||
if (confirm !== 'confirm') return
|
||||
if (this.questionForm.MeasureData) {
|
||||
await store.dispatch('reading/removeMeasuredData', { visitTaskId: this.visitTaskId, measureData: this.questionForm.MeasureData, questionId: this.parentQsId, rowIndex: this.questionForm.RowIndex })
|
||||
}
|
||||
DicomEvent.$emit('getMeasureData')
|
||||
this.$emit('close', { lesionType: this.lesionType, rowIndex: this.rowIndex, visitTaskId: this.visitTaskId })
|
||||
} else {
|
||||
// saveTypeEnum 0:未保存过(新建病灶);1:已保存,信息不完整(随访初始化病灶/分裂病灶,通过状态判断)
|
||||
|
||||
|
@ -1150,13 +1166,12 @@ export default {
|
|||
if (isNaN(parseInt(lesionState)) && this.answers.IsFristAdd === 'False') {
|
||||
const stateId = this.getQuestionId(7)
|
||||
this.$set(this.questionForm, stateId, 2)
|
||||
var isLymphLesion = this.getQuestionVal(2)
|
||||
isLymphLesion = !isNaN(parseInt(isLymphLesion)) ? parseInt(isLymphLesion) : null
|
||||
const isLymphLesion = this.getQuestionVal(2)
|
||||
const lesionPart = this.getQuestionVal(8)
|
||||
const lesionOrgan = this.getQuestionVal(6)
|
||||
const lesionLength = !isNaN(parseInt(this.getQuestionVal(0))) ? this.getQuestionVal(0) : ''
|
||||
const lesionShort = !isNaN(parseInt(this.getQuestionVal(1))) ? this.getQuestionVal(1) : ''
|
||||
const lesionState = !isNaN(parseInt(this.getQuestionVal(7))) ? parseInt(this.getQuestionVal(7)) : ''
|
||||
const lesionLength = this.getQuestionVal(0)
|
||||
const lesionShort = this.getQuestionVal(1)
|
||||
const lesionState = this.getQuestionVal(7)
|
||||
this.$emit('resetQuestions', { isLymphLesion, lesionPart, lesionOrgan, lesionShort, lesionState, saveTypeEnum: this.questionForm.saveTypeEnum, lesionLength, rowIndex: this.rowIndex, questionId: this.parentQsId, anwsers: this.questionForm })
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,11 +1,21 @@
|
|||
<template>
|
||||
<div class="measurement-wrapper" :style="{'height':height+10+'px'}">
|
||||
<div class="measurement-wrapper">
|
||||
|
||||
<div class="container" :style="{'height':height+'px'}">
|
||||
<h3 v-if="isReadingShowSubjectInfo" style="color: #ddd;padding: 5px 0px;margin: 0;">
|
||||
<span v-if="subjectCode">{{ subjectCode }} </span>
|
||||
<span style="margin-left:5px;">{{ taskBlindName }}</span>
|
||||
</h3>
|
||||
<div class="container">
|
||||
<div class="basic-info">
|
||||
<h3 v-if="isReadingShowSubjectInfo">
|
||||
<span v-if="subjectCode">{{ subjectCode }} </span>
|
||||
<span style="margin-left:5px;">{{ taskBlindName }}</span>
|
||||
</h3>
|
||||
<div v-if="readingTaskState < 2">
|
||||
<el-tooltip class="item" effect="dark" :content="$t('trials:dicomReading:message:confirmReset')" placement="bottom">
|
||||
<i
|
||||
class="el-icon-refresh-left"
|
||||
@click="resetMeasuredData"
|
||||
/>
|
||||
</el-tooltip>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 非测量问题 -->
|
||||
<div class="lesions">
|
||||
<Questions ref="ecrf" :question-form-change-state="questionFormChangeState" :question-form-change-num="questionFormChangeNum" />
|
||||
|
@ -118,6 +128,7 @@
|
|||
</template>
|
||||
<script>
|
||||
import { splitLesion } from '@/api/trials'
|
||||
import { resetReadingTask } from '@/api/reading'
|
||||
import DicomEvent from './../DicomEvent'
|
||||
|
||||
import store from '@/store'
|
||||
|
@ -154,7 +165,6 @@ export default {
|
|||
},
|
||||
data() {
|
||||
return {
|
||||
height: window.innerHeight - 140,
|
||||
questions: [],
|
||||
activeName: '',
|
||||
activeItem: {
|
||||
|
@ -197,7 +207,8 @@ export default {
|
|||
}
|
||||
},
|
||||
mounted() {
|
||||
this.subjectCode = this.$router.currentRoute.query.subjectCode
|
||||
// this.subjectCode = this.$router.currentRoute.query.subjectCode
|
||||
this.subjectCode = localStorage.getItem('subjectCode')
|
||||
window.addEventListener('message', this.receiveMsg)
|
||||
this.CriterionType = parseInt(localStorage.getItem('CriterionType'))
|
||||
DicomEvent.$on('setCollapseActive', measureData => {
|
||||
|
@ -217,8 +228,6 @@ export default {
|
|||
DicomEvent.$on('split', measureData => {
|
||||
this.handleSplit(measureData.RowId, measureData.QuestionId)
|
||||
})
|
||||
|
||||
window.addEventListener('resize', this.setHeight)
|
||||
},
|
||||
beforeDestroy() {
|
||||
DicomEvent.$off('loadMeasurementList')
|
||||
|
@ -397,9 +406,6 @@ export default {
|
|||
} catch (e) { console.log(e) }
|
||||
})
|
||||
},
|
||||
setHeight() {
|
||||
this.height = window.innerHeight - 140
|
||||
},
|
||||
getQuestionAnswer(questions, questionMark, answers) {
|
||||
var idx = questions.findIndex(i => i.QuestionMark === questionMark)
|
||||
if (idx > -1) {
|
||||
|
@ -497,15 +503,15 @@ export default {
|
|||
}
|
||||
}
|
||||
},
|
||||
split(rowId, questionId) {
|
||||
async split(rowId, questionId) {
|
||||
const loading = this.$loading({ fullscreen: true })
|
||||
var params = {
|
||||
visitTaskId: this.visitTaskId,
|
||||
questionId: questionId,
|
||||
rowId: rowId
|
||||
}
|
||||
splitLesion(params).then(async res => {
|
||||
loading.close()
|
||||
try {
|
||||
var params = {
|
||||
visitTaskId: this.visitTaskId,
|
||||
questionId: questionId,
|
||||
rowId: rowId
|
||||
}
|
||||
await splitLesion(params)
|
||||
await this.getReadingQuestionAndAnswer()
|
||||
this.$nextTick(() => {
|
||||
this.tableQuestions.forEach(item => {
|
||||
|
@ -515,7 +521,11 @@ export default {
|
|||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
loading.close()
|
||||
} catch (e) {
|
||||
loading.close()
|
||||
console.log(e)
|
||||
}
|
||||
},
|
||||
isCanActiveTool(toolName) {
|
||||
this.getUnSaveTarget()
|
||||
|
@ -879,6 +889,39 @@ export default {
|
|||
getECRFQuestions(obj) {
|
||||
this.$refs['ecrf'].getQuestions(obj.visitTaskId)
|
||||
},
|
||||
async resetMeasuredData() {
|
||||
const confirm = await this.$confirm(
|
||||
this.$t('trials:dicomReading:message:confirmReset1'),
|
||||
this.$t('trials:dicomReading:message:confirmReset2'),
|
||||
{
|
||||
type: 'warning',
|
||||
distinguishCancelAndClose: true
|
||||
}
|
||||
)
|
||||
if (confirm !== 'confirm') return
|
||||
const loading = this.$loading({ fullscreen: true })
|
||||
try {
|
||||
const res = await resetReadingTask({ visitTaskId: this.visitTaskId })
|
||||
this.loading = false
|
||||
if (res.IsSuccess) {
|
||||
// 刷新标注、表单、报告页信息
|
||||
this.activeName = ''
|
||||
this.activeItem.activeRowIndex = null
|
||||
this.activeItem.activeCollapseId = null
|
||||
await this.getReadingQuestionAndAnswer(this.visitTaskId)
|
||||
const triald = this.$router.currentRoute.query.trialId
|
||||
await store.dispatch('reading/refreshDicomReadingQuestionAnswer', { trialId: triald, visitTaskId: this.visitTaskId })
|
||||
this.$refs['ecrf'].getQuestions(this.visitTaskId, true)
|
||||
DicomEvent.$emit('getMeasureData')
|
||||
DicomEvent.$emit('getReportInfo', true)
|
||||
DicomEvent.$emit('refreshStudyListMeasureData')
|
||||
}
|
||||
loading.close()
|
||||
} catch (e) {
|
||||
loading.close()
|
||||
console.log(e)
|
||||
}
|
||||
},
|
||||
receiveMsg(event) {
|
||||
if (event.data.type === 'isCanActiveNoneDicomTool') {
|
||||
this.getUnSaveTarget()
|
||||
|
@ -945,11 +988,28 @@ export default {
|
|||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.measurement-wrapper{
|
||||
height: 100%;
|
||||
overflow-y: auto;
|
||||
// overflow: hidden;
|
||||
|
||||
.container{
|
||||
padding: 10px;
|
||||
.basic-info{
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
h3{
|
||||
color: #ddd;
|
||||
padding: 5px 0px;
|
||||
margin: 0;
|
||||
}
|
||||
i{
|
||||
color: #fff;
|
||||
font-size: 22px;
|
||||
font-weight: bold;
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
}
|
||||
.title{
|
||||
padding: 5px;
|
||||
|
|
|
@ -12,8 +12,15 @@
|
|||
style="margin-right:5px;"
|
||||
@change="handleShowDetail"
|
||||
/>
|
||||
<!--评估报告-->
|
||||
<el-button :loading="reportBtnLoading" v-if="readingTaskState>=2" type="primary" size="small" @click="showReport">{{$t('trials:dicoms:button:evaluationReport')}}</el-button>
|
||||
<el-button
|
||||
v-if="readingTaskState<2"
|
||||
type="primary"
|
||||
size="small"
|
||||
@click="skipTask"
|
||||
>
|
||||
<!-- 跳过 -->
|
||||
{{ $t('trials:readingReport:button:skip') }}
|
||||
</el-button>
|
||||
<el-button
|
||||
v-if="readingTaskState<2"
|
||||
type="primary"
|
||||
|
@ -24,7 +31,7 @@
|
|||
{{ $t('trials:readingReport:button:refresh') }}
|
||||
</el-button>
|
||||
<el-button
|
||||
v-if="readingTaskState<2"
|
||||
v-if="readingTaskState<2 && CriterionType !== 10"
|
||||
type="primary"
|
||||
size="small"
|
||||
@click="handleSave(true)"
|
||||
|
@ -95,8 +102,8 @@
|
|||
</div>
|
||||
</template>
|
||||
<template slot-scope="scope">
|
||||
<span :style="{color: ((scope.row.isLymphNodes === 1 && scope.row.QuestionMark === 1) || (scope.row.isLymphNodes === 0 && scope.row.QuestionMark === 0)) && (scope.row.LesionType === 0 || scope.row.LesionType === 5) || (scope.row.QuestionMark === 12) ? '#f66' : '#fff'}">
|
||||
<template v-if="task.VisitTaskId === visitTaskId && readingTaskState < 2 && [13,14,15,21,22,42].includes(scope.row.QuestionType)">
|
||||
<span :style="{color: ((scope.row.isLymphNodes === 1 && scope.row.QuestionMark === 1) || (scope.row.isLymphNodes === 0 && scope.row.QuestionMark === 0)) && (scope.row.LesionType === 0 || scope.row.LesionType === 5) || (scope.row.QuestionMark === 12) || scope.row.HighlightAnswerList.includes(`${scope.row.Answers[task.VisitTaskId]}`) ? '#f66' : '#fff'}">
|
||||
<template v-if="task.VisitTaskId === visitTaskId && readingTaskState < 2 && [13,14,15,42].includes(scope.row.QuestionType)">
|
||||
<!-- 是否存在疾病(基线时可修改) -->
|
||||
<template v-if="task.IsBaseLine && scope.row.QuestionType=== 15">
|
||||
<el-select
|
||||
|
@ -150,32 +157,6 @@
|
|||
</template>
|
||||
</el-select>
|
||||
</template>
|
||||
<!-- 访视点肿瘤评估 -->
|
||||
<template v-else-if="!task.IsBaseLine && scope.row.QuestionType=== 21">
|
||||
<el-select
|
||||
v-if="scope.row.Type==='select' && scope.row.DictionaryCode"
|
||||
v-model="currentEvaluateResult"
|
||||
size="mini"
|
||||
@change="handleEvaluateResultChange"
|
||||
>
|
||||
<template>
|
||||
<el-option
|
||||
v-for="item of $d[ scope.row.DictionaryCode]"
|
||||
v-show="task.CrterionDictionaryGroup.indexOf(item.raw.CrterionDictionaryGroup) > -1"
|
||||
:key="item.id"
|
||||
:value="item.value"
|
||||
:label="item.label"
|
||||
/>
|
||||
</template>
|
||||
</el-select>
|
||||
</template>
|
||||
<template v-else-if="!task.IsBaseLine && scope.row.QuestionType=== 22">
|
||||
<el-input v-model="intervalDays" size="mini" @change="handleIntervalDaysChange"
|
||||
@input="handleNumberInput" maxlength="3"></el-input>
|
||||
</template>
|
||||
<template v-else-if="task.IsBaseLine && scope.row.QuestionType=== 22">
|
||||
{{ scope.row.Answers[task.VisitTaskId] }}
|
||||
</template>
|
||||
<!-- <template v-else-if="task.IsBaseLine && scope.row.QuestionType=== 13">
|
||||
{{ $fd(scope.row.DictionaryCode, currentEvaluateResult) }}
|
||||
</template> -->
|
||||
|
@ -200,8 +181,9 @@
|
|||
@change="evaluateReasonChange"
|
||||
/>
|
||||
<!-- 系统评估结果为:xxx,与当前调整的结果不一致,请填写调整原因 -->
|
||||
<p v-if="tumorEvaluate && currentEvaluateResult && parseInt(currentEvaluateResult) !== parseInt(tumorEvaluate)" style="width: 140px;padding:0 2px;white-space: normal;word-break: break-all;word-wrap: break-word;">{{ $t('trials:readingReport:message:msg6').replace('***', $fd('CriterionType', CriterionType)) }}<span v-if="CriterionType === 2" style="color:red">{{ $fd('ImagingOverallAssessment_Lugano',tumorEvaluate) }}</span><span v-else-if="CriterionType === 10" style="color:red">{{ $fd('VisitTumorEvaluation',tumorEvaluate) }}</span><span v-else style="color:red">{{ $fd('OverallAssessment',tumorEvaluate) }}</span>{{ $t('trials:readingReport:message:msg7') }}<span v-if="CriterionType === 2" style="color:red">{{ $fd('ImagingOverallAssessment_Lugano',currentEvaluateResult) }}</span><span v-else-if="CriterionType === 10" style="color:red">{{ $fd('VisitTumorEvaluation',currentEvaluateResult) }}</span><span v-else style="color:red">{{ $fd('OverallAssessment',currentEvaluateResult) }}</span>{{ $t('trials:readingReport:message:msg8') }}</p>
|
||||
<p v-else-if="currentExistDisease !== isExistDisease" style="width: 140px;padding:0 2px;white-space: normal;word-break: break-all;word-wrap: break-word;">{{ $t('trials:readingReport:title:sysEvaluationRes') }}<span style="color:red">{{ $fd('ExistDisease',isExistDisease) }}</span>{{ $t('trials:readingReport:message:msg1') }}</p>
|
||||
<p v-if="currentEvaluateResult !== tumorEvaluate" style="width: 140px;padding:0 2px;white-space: normal;word-break: break-all;word-wrap: break-word;" v-html="getWarningText()" />
|
||||
<p v-else-if="currentExistDisease !== isExistDisease" style="width: 140px;padding:0 2px;white-space: normal;word-break: break-all;word-wrap: break-word;">{{ $t('trials:readingReport:title:sysEvaluationRes') }}<span style="color:red">{{ $fd('ExistDisease',isExistDisease) }}</span>{{ $t('trials:readingReport:message:msg1') }}
|
||||
</p>
|
||||
</template>
|
||||
<!-- <template v-else>
|
||||
<span>{{ currentTaskReason }}</span>
|
||||
|
@ -284,15 +266,11 @@
|
|||
</div>
|
||||
<SignForm ref="signForm" :sign-code-enum="signCode" @closeDialog="closeSignDialog" />
|
||||
</el-dialog>
|
||||
<!--评估报告-->
|
||||
<PreviewFileDialog
|
||||
:visible.sync="previewFileVisible"
|
||||
:fileData="fileData"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import { getReadingReportEvaluation, changeDicomReadingQuestionAnswer, submitDicomVisitTask, verifyVisitTaskQuestions, getTaskAdditionalQuestion } from '@/api/trials'
|
||||
import { setSkipReadingCache } from '@/api/reading'
|
||||
import { getAutoCutNextTask } from '@/api/user'
|
||||
import DicomEvent from './DicomEvent'
|
||||
import const_ from '@/const/sign-code'
|
||||
|
@ -302,11 +280,9 @@ import store from '@/store'
|
|||
import { mapGetters } from 'vuex'
|
||||
import { changeURLStatic } from '@/utils/history.js'
|
||||
import AdditionalAssessment from './AdditionalAssessment'
|
||||
import { showReadReport } from "@/api/export";
|
||||
import PreviewFileDialog from "@/components/PreviewFileDialog/PreviewFileDialog.vue";
|
||||
export default {
|
||||
name: 'ReportPage',
|
||||
components: { SignForm, AdditionalAssessment,PreviewFileDialog },
|
||||
components: { SignForm, AdditionalAssessment },
|
||||
props: {
|
||||
visitTaskId: {
|
||||
type: String,
|
||||
|
@ -343,13 +319,7 @@ export default {
|
|||
assessmentQuestions: [],
|
||||
tLesionCount: null,
|
||||
ntLesionCount: null,
|
||||
openWindow: null,
|
||||
|
||||
// 评估报告
|
||||
previewFileVisible: false,
|
||||
fileData: {},
|
||||
reportBtnLoading:false,
|
||||
intervalDays: null
|
||||
openWindow: null
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
|
@ -390,35 +360,6 @@ export default {
|
|||
}
|
||||
},
|
||||
methods: {
|
||||
// 评估报告
|
||||
async showReport(){
|
||||
if(this.reportBtnLoading) return;
|
||||
let data = {
|
||||
VisitTaskId: this.visitTaskId,
|
||||
};
|
||||
try {
|
||||
this.reportBtnLoading = true;
|
||||
let res = await showReadReport(data);
|
||||
// let urlPdf = window.URL.createObjectURL(new Blob([res]))
|
||||
if(res.IsSuccess){
|
||||
this.viewVisible = true;
|
||||
let href = this.OSSclientConfig.basePath + res.Result;
|
||||
|
||||
// let fileName =
|
||||
// res.Result.split("/")[res.Result.split("/").length - 1];
|
||||
let fileName = '评估报告.pdf';
|
||||
this.fileData = {
|
||||
path:href,
|
||||
name:fileName
|
||||
};
|
||||
}
|
||||
this.reportBtnLoading = false;
|
||||
this.previewFileVisible = true;
|
||||
} catch (err) {
|
||||
this.reportBtnLoading = false;
|
||||
console.log(err);
|
||||
}
|
||||
},
|
||||
myConfirm(msg) {
|
||||
return new Promise(resolve => {
|
||||
this.$confirm(msg, {
|
||||
|
@ -470,32 +411,38 @@ export default {
|
|||
getTableHeight() {
|
||||
this.height = window.innerHeight - 170
|
||||
},
|
||||
getReportInfo(IsCalculate) {
|
||||
async getReportInfo(IsCalculate) {
|
||||
this.loading = true
|
||||
var params = {
|
||||
visitTaskId: this.visitTaskId,
|
||||
trialId: this.$router.currentRoute.query.trialId,
|
||||
IsCalculate: IsCalculate !== false
|
||||
}
|
||||
getReadingReportEvaluation(params).then(res => {
|
||||
this.readingTaskState = res.Result.ReadingTaskState
|
||||
this.tumorEvaluate = res.Result.CalculateResult.TumorEvaluate ? parseInt(res.Result.CalculateResult.TumorEvaluate) : null
|
||||
this.isExistDisease = res.Result.CalculateResult.IsExistDisease ? parseInt(res.Result.CalculateResult.IsExistDisease) : null
|
||||
this.answerArr = []
|
||||
this.questions = res.Result.TaskQuestions.concat()
|
||||
this.visitTaskList = res.Result.VisitTaskList
|
||||
var taskQuestions = this.getQuestions(res.Result.TaskQuestions, !this.isShowDetail, null, null)
|
||||
this.taskQuestions = []
|
||||
taskQuestions.forEach(item => {
|
||||
this.$set(this.taskQuestions, this.taskQuestions.length, item)
|
||||
})
|
||||
const tLesion = res.Result.LesionCountList.find(i => i.LesionType === 0)
|
||||
this.tLesionCount = tLesion ? tLesion.Count : 0
|
||||
const ntLesion = res.Result.LesionCountList.find(i => i.LesionType === 1)
|
||||
this.ntLesionCount = ntLesion ? ntLesion.Count : 0
|
||||
this.setScrollTop()
|
||||
try {
|
||||
var params = {
|
||||
visitTaskId: this.visitTaskId,
|
||||
trialId: this.$router.currentRoute.query.trialId,
|
||||
IsCalculate: IsCalculate !== false
|
||||
}
|
||||
const res = await getReadingReportEvaluation(params)
|
||||
if (res.IsSuccess) {
|
||||
this.readingTaskState = res.Result.ReadingTaskState
|
||||
this.tumorEvaluate = res.Result.CalculateResult.TumorEvaluate ? parseInt(res.Result.CalculateResult.TumorEvaluate) : null
|
||||
this.isExistDisease = res.Result.CalculateResult.IsExistDisease ? parseInt(res.Result.CalculateResult.IsExistDisease) : null
|
||||
this.answerArr = []
|
||||
this.questions = res.Result.TaskQuestions.concat()
|
||||
this.visitTaskList = res.Result.VisitTaskList
|
||||
var taskQuestions = this.getQuestions(res.Result.TaskQuestions, !this.isShowDetail, null, null)
|
||||
this.taskQuestions = []
|
||||
taskQuestions.forEach(item => {
|
||||
this.$set(this.taskQuestions, this.taskQuestions.length, item)
|
||||
})
|
||||
const tLesion = res.Result.LesionCountList.find(i => i.LesionType === 0)
|
||||
this.tLesionCount = tLesion ? tLesion.Count : 0
|
||||
const ntLesion = res.Result.LesionCountList.find(i => i.LesionType === 1)
|
||||
this.ntLesionCount = ntLesion ? ntLesion.Count : 0
|
||||
this.setScrollTop()
|
||||
}
|
||||
this.loading = false
|
||||
}).catch(() => { this.loading = false })
|
||||
} catch (e) {
|
||||
this.loading = false
|
||||
console.log(e)
|
||||
}
|
||||
},
|
||||
setScrollTop(a) {
|
||||
setTimeout(() => {
|
||||
|
@ -503,7 +450,6 @@ export default {
|
|||
if (this.$refs.reportList) {
|
||||
this.getTableHeight()
|
||||
this.$refs.reportList.bodyWrapper.scrollTop = this.$refs.reportList.bodyWrapper.scrollHeight
|
||||
this.$refs.reportList.bodyWrapper.scrollTop = this.$refs.reportList.bodyWrapper.scrollHeight
|
||||
}
|
||||
})
|
||||
}, 50)
|
||||
|
@ -611,7 +557,7 @@ export default {
|
|||
this.currentExistDisease = obj.Answers[this.visitTaskId]
|
||||
this.answerArr.push({ id: item.QuestionId, answer: obj.Answers[this.visitTaskId], questionType: 15 })
|
||||
}
|
||||
if (item.QuestionType === 13 || item.QuestionType === 42 || item.QuestionType === 21) {
|
||||
if (item.QuestionType === 13 || item.QuestionType === 42) {
|
||||
this.currentEvaluateResult = obj.Answers[this.visitTaskId]
|
||||
this.answerArr.push({ id: item.QuestionId, answer: obj.Answers[this.visitTaskId], questionType: item.QuestionType })
|
||||
}
|
||||
|
@ -619,10 +565,6 @@ export default {
|
|||
this.currentTaskReason = obj.Answers[this.visitTaskId]
|
||||
this.answerArr.push({ id: item.QuestionId, answer: obj.Answers[this.visitTaskId], questionType: 14 })
|
||||
}
|
||||
if (item.QuestionType === 22) {
|
||||
this.intervalDays = obj.Answers[this.visitTaskId]
|
||||
this.answerArr.push({ id: item.QuestionId, answer: obj.Answers[this.visitTaskId]?obj.Answers[this.visitTaskId]:null, questionType: 22 })
|
||||
}
|
||||
if (item.Childrens.length >= 1) {
|
||||
obj.Childrens = this.getQuestions(item.Childrens, isNTFilterLength, lesionType, isLymphNodes)
|
||||
}
|
||||
|
@ -657,7 +599,7 @@ export default {
|
|||
}
|
||||
this.currentTaskReason = ''
|
||||
this.evaluateReasonChange('')
|
||||
var idx = this.answerArr.findIndex(i => i.questionType === 13 || i.questionType === 42 || i.questionType === 21)
|
||||
var idx = this.answerArr.findIndex(i => i.questionType === 13 || i.questionType === 42)
|
||||
if (idx > -1) {
|
||||
this.answerArr[idx].answer = val
|
||||
}
|
||||
|
@ -670,39 +612,32 @@ export default {
|
|||
this.answerArr[idx].answer = val
|
||||
}
|
||||
},
|
||||
handleIntervalDaysChange(v) {
|
||||
var idx = this.answerArr.findIndex(i => i.questionType === 22)
|
||||
if (idx > -1) {
|
||||
this.answerArr[idx].answer = v
|
||||
}
|
||||
},
|
||||
handleNumberInput(value) {
|
||||
var reg = /^(?!0)\d{1,3}$/
|
||||
if(reg.test(value)==false){
|
||||
this.intervalDays = ""
|
||||
}else{
|
||||
this.intervalDays = value
|
||||
}
|
||||
},
|
||||
async handleConfirm() {
|
||||
await this.handleSave(false)
|
||||
await this.verifyVisitTaskQuestions()
|
||||
var i = this.visitTaskList.findIndex(i => i.VisitTaskId === this.visitTaskId)
|
||||
var isBaseline = this.visitTaskList[i].IsBaseLine
|
||||
if (isBaseline) {
|
||||
this.assessmentQuestions = await this.getAdditionalAssessments()
|
||||
if (this.assessmentQuestions.length > 0) {
|
||||
this.loading = true
|
||||
try {
|
||||
await this.handleSave(false)
|
||||
await verifyVisitTaskQuestions({ visitTaskId: this.visitTaskId })
|
||||
var i = this.visitTaskList.findIndex(i => i.VisitTaskId === this.visitTaskId)
|
||||
var isBaseline = this.visitTaskList[i].IsBaseLine
|
||||
if (isBaseline) {
|
||||
const res = await getTaskAdditionalQuestion({ visitTaskId: this.visitTaskId })
|
||||
this.assessmentQuestions = res.Result
|
||||
if (this.assessmentQuestions.length > 0) {
|
||||
// 打开附加评估框
|
||||
this.additionalAssessmentsDig.visible = true
|
||||
this.additionalAssessmentsDig.visible = true
|
||||
} else {
|
||||
const { ImageAssessmentReportConfirmation } = const_.processSignature
|
||||
this.signCode = ImageAssessmentReportConfirmation
|
||||
this.signVisible = true
|
||||
}
|
||||
} else {
|
||||
const { ImageAssessmentReportConfirmation } = const_.processSignature
|
||||
this.signCode = ImageAssessmentReportConfirmation
|
||||
this.signVisible = true
|
||||
}
|
||||
} else {
|
||||
const { ImageAssessmentReportConfirmation } = const_.processSignature
|
||||
this.signCode = ImageAssessmentReportConfirmation
|
||||
this.signVisible = true
|
||||
this.loading = false
|
||||
} catch (e) {
|
||||
this.loading = false
|
||||
}
|
||||
},
|
||||
sign() {
|
||||
|
@ -713,31 +648,6 @@ export default {
|
|||
this.signVisible = true
|
||||
})
|
||||
},
|
||||
// 附加评估
|
||||
getAdditionalAssessments() {
|
||||
return new Promise((resolve) => {
|
||||
this.loading = true
|
||||
getTaskAdditionalQuestion({ visitTaskId: this.visitTaskId }).then(res => {
|
||||
this.loading = false
|
||||
resolve(res.Result)
|
||||
}).catch(() => {
|
||||
this.loading = false
|
||||
resolve()
|
||||
})
|
||||
})
|
||||
},
|
||||
verifyVisitTaskQuestions() {
|
||||
return new Promise((resolve, reject) => {
|
||||
this.loading = true
|
||||
verifyVisitTaskQuestions({ visitTaskId: this.visitTaskId }).then(res => {
|
||||
this.loading = false
|
||||
resolve()
|
||||
}).catch(() => {
|
||||
this.loading = false
|
||||
reject()
|
||||
})
|
||||
})
|
||||
},
|
||||
handleResize() {
|
||||
this.$nextTick(() => {
|
||||
this.$refs.reportList && this.$refs.reportList.doLayout()
|
||||
|
@ -752,15 +662,16 @@ export default {
|
|||
}
|
||||
},
|
||||
// 签名并确认
|
||||
signConfirm(signInfo) {
|
||||
async signConfirm(signInfo) {
|
||||
this.loading = true
|
||||
var params = {
|
||||
data: {
|
||||
visitTaskId: this.visitTaskId
|
||||
},
|
||||
signInfo: signInfo
|
||||
}
|
||||
submitDicomVisitTask(params).then(async res => {
|
||||
try {
|
||||
var params = {
|
||||
data: {
|
||||
visitTaskId: this.visitTaskId
|
||||
},
|
||||
signInfo: signInfo
|
||||
}
|
||||
const res = await submitDicomVisitTask(params)
|
||||
if (res.IsSuccess) {
|
||||
this.$message.success(this.$t('common:message:savedSuccessfully'))
|
||||
if (this.$refs['signForm']) {
|
||||
|
@ -776,7 +687,8 @@ export default {
|
|||
await store.dispatch('reading/setVisitTaskReadingTaskState', { visitTaskId: this.visitTaskId, readingTaskState: 2 })
|
||||
// DicomEvent.$emit('setReadingState', 2)
|
||||
await store.dispatch('reading/setCurrentReadingTaskState', 2)
|
||||
var isAutoTask = await this.getAutoTaskVal()
|
||||
const res = await getAutoCutNextTask()
|
||||
var isAutoTask = res.Result.AutoCutNextTask
|
||||
if (isAutoTask) {
|
||||
// DicomEvent.$emit('reload')
|
||||
// DicomEvent.$emit('getNextTask')
|
||||
|
@ -800,19 +712,12 @@ export default {
|
|||
// DicomEvent.$emit('readingPageStateUpdate', { readingTaskState: 2 })
|
||||
}
|
||||
this.loading = false
|
||||
}).catch(() => {
|
||||
} catch (e) {
|
||||
this.loading = false
|
||||
if (this.$refs['signForm'] && this.$refs['signForm'].btnLoading) {
|
||||
this.$refs['signForm'].btnLoading = false
|
||||
}
|
||||
})
|
||||
},
|
||||
getAutoTaskVal() {
|
||||
return new Promise((resolve, reject) => {
|
||||
getAutoCutNextTask().then(res => {
|
||||
resolve(res.Result.AutoCutNextTask)
|
||||
}).catch(() => { reject() })
|
||||
})
|
||||
}
|
||||
},
|
||||
previewDicoms(task) {
|
||||
if (this.openWindow) {
|
||||
|
@ -820,7 +725,8 @@ export default {
|
|||
}
|
||||
var token = getToken()
|
||||
var trialReadingCriterionId = this.$router.currentRoute.query.TrialReadingCriterionId
|
||||
var subjectCode = this.$router.currentRoute.query.subjectCode
|
||||
// var subjectCode = this.$router.currentRoute.query.subjectCode
|
||||
var subjectCode = localStorage.getItem('subjectCode')
|
||||
var subjectId = this.$router.currentRoute.query.subjectId
|
||||
var trialId = this.$router.currentRoute.query.trialId
|
||||
var isReadingTaskViewInOrder = this.$router.currentRoute.query.isReadingTaskViewInOrder
|
||||
|
@ -831,14 +737,14 @@ export default {
|
|||
this.openWindow = window.open(routeData.href, '_blank')
|
||||
},
|
||||
handleSave(isPrompt) {
|
||||
return new Promise((resolve, reject) => {
|
||||
return new Promise(async(resolve, reject) => {
|
||||
var isBeill
|
||||
var evaluateResult = ''
|
||||
var evaluateAjustReason = ''
|
||||
this.answers = []
|
||||
var isExistEvaluateResult = false
|
||||
this.answerArr.map(item => {
|
||||
if (item.questionType === 13 || item.questionType === 42 || item.questionType === 21) {
|
||||
if (item.questionType === 13 || item.questionType === 42) {
|
||||
evaluateResult = item.answer
|
||||
isExistEvaluateResult = true
|
||||
}
|
||||
|
@ -870,7 +776,7 @@ export default {
|
|||
reject()
|
||||
return
|
||||
}
|
||||
if (this.tumorEvaluate !== null && isExistEvaluateResult && (evaluateResult !== this.tumorEvaluate) && !evaluateAjustReason) {
|
||||
if (isExistEvaluateResult && (evaluateResult !== this.tumorEvaluate) && !evaluateAjustReason) {
|
||||
// 请填写整体评估调整原因
|
||||
this.$confirm(this.$t('trials:readingReport:message:msg3'), {
|
||||
type: 'warning',
|
||||
|
@ -881,21 +787,57 @@ export default {
|
|||
return
|
||||
}
|
||||
this.loading = true
|
||||
var params = {
|
||||
visitTaskId: this.visitTaskId,
|
||||
answers: this.answers
|
||||
}
|
||||
changeDicomReadingQuestionAnswer(params).then(res => {
|
||||
if (isPrompt) {
|
||||
try {
|
||||
var params = {
|
||||
visitTaskId: this.visitTaskId,
|
||||
answers: this.answers
|
||||
}
|
||||
const res = await changeDicomReadingQuestionAnswer(params)
|
||||
if (res.IsSuccess && isPrompt) {
|
||||
this.$message.success(this.$t('common:message:savedSuccessfully'))
|
||||
}
|
||||
this.loading = false
|
||||
resolve()
|
||||
}).catch(() => {
|
||||
} catch (e) {
|
||||
this.loading = false
|
||||
reject()
|
||||
})
|
||||
}
|
||||
})
|
||||
},
|
||||
getWarningText() {
|
||||
var sysRes = ''
|
||||
var curRes = ''
|
||||
if (this.CriterionType === 2) {
|
||||
sysRes = this.$fd('ImagingOverallAssessment_Lugano', this.tumorEvaluate)
|
||||
curRes = this.$fd('ImagingOverallAssessment_Lugano', this.currentEvaluateResult)
|
||||
} else {
|
||||
sysRes = this.$fd('OverallAssessment', this.tumorEvaluate)
|
||||
curRes = this.$fd('OverallAssessment', this.currentEvaluateResult)
|
||||
}
|
||||
const msg = this.$t('trials:readingReport:message:msg9').replace('xxx', '<font color="red">' + sysRes + '</font>').replace('yyy', '<font color="red">' + curRes + '</font>')
|
||||
return msg
|
||||
},
|
||||
async skipTask() {
|
||||
try {
|
||||
// 是否确认跳过?
|
||||
const confirm = await this.$confirm(
|
||||
this.$t('trials:readingReport:message:skipConfirm'),
|
||||
{
|
||||
type: 'warning',
|
||||
distinguishCancelAndClose: true
|
||||
}
|
||||
)
|
||||
if (confirm !== 'confirm') return
|
||||
this.loading = true
|
||||
const res = await setSkipReadingCache({ visitTaskId: this.visitTaskId })
|
||||
this.loading = false
|
||||
if (res.IsSuccess) {
|
||||
window.location.reload()
|
||||
}
|
||||
} catch (e) {
|
||||
this.loading = false
|
||||
console.log(e)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -976,4 +918,7 @@ export default {
|
|||
/deep/ .el-switch__label.is-active{
|
||||
color: #428bca;
|
||||
}
|
||||
.colorOfRed{
|
||||
color: #f66;
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -49,20 +49,42 @@
|
|||
/>
|
||||
<div class="image-desc">
|
||||
<div class="flex-div">
|
||||
<div v-if="!study.IsCriticalSequence">#{{ series.seriesNumber }} </div>
|
||||
<div v-if="series.isDicom && series.prefetchInstanceCount<series.instanceCount && series.modality!== 'SR'">
|
||||
<!-- 下载 -->
|
||||
<el-tooltip v-if="!series.isLoading" class="item" effect="dark" :content="$t('trials:reading:button:download')" placement="bottom">
|
||||
<div style="width: 40px;display: flex;flex-direction: row;justify-content: space-between;">
|
||||
<div v-if="!study.IsCriticalSequence">#{{ series.seriesNumber }}</div>
|
||||
<div v-if="series.isDicom && series.prefetchInstanceCount<series.instanceCount * 100 && series.modality!== 'SR'">
|
||||
<!-- 下载 -->
|
||||
<el-tooltip v-if="!series.isLoading" class="item" effect="dark" :content="$t('trials:reading:button:download')" placement="bottom">
|
||||
<i class="el-icon-video-play" style="font-size: 18px;margin-right: 5px;color: #ffeb3b;cursor: pointer;" @click.stop="loadSeries(series,index,i)" />
|
||||
</el-tooltip>
|
||||
</div>
|
||||
<el-tooltip v-else-if="series.isDicom && series.prefetchInstanceCount === 0 &&series.modality!== 'SR'" class="item" effect="dark" :content="$t('trials:reading:button:download')" placement="bottom">
|
||||
<i class="el-icon-video-play" style="font-size: 18px;margin-right: 5px;color: #ffeb3b;cursor: pointer;" @click.stop="loadSeries(series,index,i)" />
|
||||
</el-tooltip>
|
||||
<!-- 暂停 -->
|
||||
<!-- <el-tooltip v-else class="item" effect="dark" :content="$t('trials:reading:button:pause')" placement="bottom">
|
||||
<i class="el-icon-video-pause" style="font-size: 18px;margin-right: 5px;color: #ffeb3b;cursor: pointer;" @click.stop="stopLoadSeries(series,index,i)" />
|
||||
</el-tooltip> -->
|
||||
</div>
|
||||
<el-tooltip v-else-if="series.isDicom && series.prefetchInstanceCount === 0 &&series.modality!== 'SR'" class="item" effect="dark" :content="$t('trials:reading:button:download')" placement="bottom">
|
||||
<i class="el-icon-video-play" style="font-size: 18px;margin-right: 5px;color: #ffeb3b;cursor: pointer;" @click.stop="loadSeries(series,index,i)" />
|
||||
</el-tooltip>
|
||||
<div v-if="series.isExistMutiFrames && series.instanceCount > 1">
|
||||
<el-popover
|
||||
placement="right"
|
||||
trigger="hover"
|
||||
popper-class="instance_frame_wrapper"
|
||||
>
|
||||
<div class="frame_list">
|
||||
<div
|
||||
v-for="(instance, idx) in series.instanceInfoList"
|
||||
:key="instance.Id"
|
||||
class="frame_content"
|
||||
:style="{'margin-bottom':idx<series.instanceInfoList.length-1? '5px':'0px'}"
|
||||
@click.stop="showMultiFrames(index,series, i, instance)"
|
||||
>
|
||||
<div>
|
||||
<div>{{ instance.InstanceNumber }}</div>
|
||||
<div>{{ `${instance.NumberOfFrames > 0 ? instance.KeyFramesList.length > 0 ? instance.KeyFramesList.length : instance.NumberOfFrames : 1} frame` }}</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<i slot="reference" class="el-icon-connection" style="font-size: 15px;cursor: pointer;color: #ffeb3b;" />
|
||||
</el-popover>
|
||||
</div>
|
||||
</div>
|
||||
<p v-show="series.description">
|
||||
<el-tooltip class="item" effect="dark" :content="series.description" placement="right">
|
||||
|
@ -73,7 +95,10 @@
|
|||
<p v-show="series.sliceThickness && !study.IsCriticalSequence">
|
||||
T: {{ parseFloat(series.sliceThickness).toFixed(digitPlaces) }}
|
||||
</p>
|
||||
<p v-show="series.instanceCount">
|
||||
<p v-show="series.instanceCount && series.imageloadedArr.length < series.instanceCount">
|
||||
{{ series.modality }}: {{ series.imageloadedArr.length }}/{{ series.instanceCount }} image
|
||||
</p>
|
||||
<p v-show="series.instanceCount && series.imageloadedArr.length >= series.instanceCount">
|
||||
{{ series.modality }}: {{ series.instanceCount }} image
|
||||
</p>
|
||||
|
||||
|
@ -88,9 +113,9 @@
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="series.isDicom && series.prefetchInstanceCount>0 && series.prefetchInstanceCount<series.instanceCount" style="width: 100%;">
|
||||
<div v-if="series.isDicom && series.prefetchInstanceCount>0 && series.prefetchInstanceCount<series.instanceCount * 100" style="width: 100%;">
|
||||
<el-progress
|
||||
:percentage="parseInt(((series.prefetchInstanceCount/series.instanceCount)*100).toFixed(2))"
|
||||
:percentage="parseInt((series.prefetchInstanceCount / series.instanceCount).toFixed(2))"
|
||||
/>
|
||||
</div>
|
||||
|
||||
|
@ -125,18 +150,13 @@
|
|||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import * as dicomParser from 'dicom-parser'
|
||||
import * as cornerstone from 'cornerstone-core'
|
||||
import * as cornerstoneWADOImageLoader from 'cornerstone-wado-image-loader'
|
||||
// import * as cornerstone from 'cornerstone-core'
|
||||
import requestPoolManager from '@/utils/request-pool'
|
||||
import DicomEvent from './DicomEvent'
|
||||
import { mapGetters } from 'vuex'
|
||||
import store from '@/store'
|
||||
import SrList from './SrList'
|
||||
cornerstoneWADOImageLoader.external.dicomParser = dicomParser
|
||||
cornerstoneWADOImageLoader.external.cornerstone = cornerstone
|
||||
const maximumSizeInBytes = 1024 * 1024 * 1024 // 1 GB
|
||||
cornerstone.imageCache.setMaximumSizeBytes(maximumSizeInBytes)
|
||||
|
||||
export default {
|
||||
name: 'StudyList',
|
||||
components: { SrList },
|
||||
|
@ -219,7 +239,8 @@ export default {
|
|||
// }
|
||||
},
|
||||
mounted() {
|
||||
this.subjectCode = this.$router.currentRoute.query.subjectCode
|
||||
// this.subjectCode = this.$router.currentRoute.query.subjectCode
|
||||
this.subjectCode = localStorage.getItem('subjectCode')
|
||||
var digitPlaces = Number(localStorage.getItem('digitPlaces'))
|
||||
this.digitPlaces = digitPlaces === -1 ? this.digitPlaces : digitPlaces
|
||||
DicomEvent.$on('refreshStudyListMeasureData', () => {
|
||||
|
@ -233,99 +254,72 @@ export default {
|
|||
// this.studyList = this.visitTaskList[idx].StudyList
|
||||
// }
|
||||
// })
|
||||
cornerstone.events.addEventListener('cornerstoneimageloaded', this.cornerstoneImageLoaded)
|
||||
// const debouncedInputHandler = this.debounce(this.cornerstoneimageloadprogress, 100)
|
||||
// cornerstone.events.addEventListener('cornerstoneimageloadprogress', this.cornerstoneimageloadprogress)
|
||||
// cornerstone.events.addEventListener('cornerstoneimageloaded', this.cornerstoneImageLoaded)
|
||||
// cornerstone.events.addEventListener('cornerstoneimagecachefull', this.cornerstoneimagecachefull)
|
||||
// cornerstone.events.addEventListener('cornerstoneimagecachechanged', this.cornerstoneimagecachechanged)
|
||||
window.addEventListener('beforeunload', e => {
|
||||
cornerstone.imageCache.purgeCache()
|
||||
})
|
||||
// window.addEventListener('beforeunload', e => {
|
||||
// cornerstone.imageCache.purgeCache()
|
||||
// })
|
||||
},
|
||||
beforeDestroy() {
|
||||
cornerstone.imageCache.purgeCache()
|
||||
// cornerstone.imageCache.purgeCache()
|
||||
DicomEvent.$off('refreshStudyListMeasureData')
|
||||
window.removeEventListener('beforeunload', e => { cornerstone.imageCache.purgeCache() })
|
||||
// window.removeEventListener('beforeunload', e => { cornerstone.imageCache.purgeCache() })
|
||||
},
|
||||
methods: {
|
||||
debounce(fn, delay) {
|
||||
let timer = null
|
||||
return function() {
|
||||
const context = this
|
||||
const args = arguments
|
||||
clearTimeout(timer)
|
||||
timer = setTimeout(() => {
|
||||
fn.apply(context, args)
|
||||
}, delay)
|
||||
}
|
||||
},
|
||||
initStudyInfo() {
|
||||
const loading = this.$loading({ fullscreen: true })
|
||||
// 初始化待渲染序列
|
||||
this.getInitSeries().then((res) => {
|
||||
requestPoolManager.startTaskTimer()
|
||||
res.map((item) => {
|
||||
this.loadInitialImage(item)
|
||||
res.map(async(item) => {
|
||||
// this.loadInitialImage(item)
|
||||
const imageId = item.imageIds[item.imageIdIndex]
|
||||
const p = parseInt(new Date().getTime())
|
||||
await requestPoolManager.loadAndCacheImagePlus(imageId, item.seriesId, p * 100)
|
||||
if (!item.isCurrentTask) {
|
||||
store.dispatch('reading/setImageloadedInfo', item)
|
||||
}
|
||||
})
|
||||
var i = res.findIndex(s => s.isCurrentTask)
|
||||
var i = -1
|
||||
var isReadingTaskViewInOrder = parseInt(this.$router.currentRoute.query.isReadingTaskViewInOrder)
|
||||
if (isReadingTaskViewInOrder === 2) {
|
||||
// 受试者内随机
|
||||
i = res.length === 2 ? 1 : -1
|
||||
} else {
|
||||
i = res.findIndex(s => s.isCurrentTask)
|
||||
}
|
||||
if (i > -1) {
|
||||
var idx = this.visitTaskList.findIndex(i => i.VisitTaskId === this.visitTaskId)
|
||||
if (idx > -1) {
|
||||
this.measureData = this.visitTaskList[idx].MeasureData
|
||||
this.studyList = this.visitTaskList[idx].StudyList
|
||||
var priority = parseInt(new Date().getTime())
|
||||
res[i].imageIds.map(image => {
|
||||
priority--
|
||||
this.imageList.push({ imageId: image, seriesId: res[i].seriesId, studyIndex: res[i].studyIndex, seriesIndex: res[i].seriesIndex, visitTaskId: res[i].visitTaskId, priority })
|
||||
})
|
||||
|
||||
// this.studyList.map((study, studyIndex) => {
|
||||
// study.SeriesList.map((series, seriesIndex) => {
|
||||
// if (series.modality !== 'SR') {
|
||||
// series.imageIds.map(image => {
|
||||
// var p = priority - seriesIndex
|
||||
// if (series.seriesId === res[i].seriesId) {
|
||||
// p = priority
|
||||
// } else {
|
||||
// --p
|
||||
// }
|
||||
// this.imageList.push({ imageId: image, seriesId: series.seriesId, studyIndex: studyIndex, seriesIndex: seriesIndex, visitTaskId: series.visitTaskId, priority: p })
|
||||
// })
|
||||
// }
|
||||
// })
|
||||
// })
|
||||
this.loopLoad()
|
||||
}
|
||||
}
|
||||
DicomEvent.$emit('loadImageStacks', res)
|
||||
loading.close()
|
||||
this.isRender = true
|
||||
}).catch(() => {
|
||||
loading.close()
|
||||
})
|
||||
},
|
||||
initStudyInfo2() {
|
||||
console.log('initStudyInfo')
|
||||
const loading = this.$loading({ fullscreen: true })
|
||||
// 初始化待渲染序列
|
||||
this.getInitSeries().then((res) => {
|
||||
requestPoolManager.startTaskTimer()
|
||||
res.map((item) => {
|
||||
this.loadInitialImage(item)
|
||||
})
|
||||
var i = res.findIndex(s => s.isCurrentTask)
|
||||
if (i > -1) {
|
||||
var p = parseInt(new Date().getTime())
|
||||
// var p = this.visitTaskId === this.currentTaskId ? parseInt(new Date().getTime()) : 999 // 非当前任务,符合自动下载的权重次之
|
||||
var idx = this.visitTaskList.findIndex(i => i.VisitTaskId === this.visitTaskId)
|
||||
if (idx > -1) {
|
||||
this.measureData = this.visitTaskList[idx].MeasureData
|
||||
this.studyList = this.visitTaskList[idx].StudyList
|
||||
|
||||
this.studyList.map((study, studyIndex) => {
|
||||
study.SeriesList.map((series, seriesIndex) => {
|
||||
if (series.modality !== 'SR') {
|
||||
// var sliceThickness = isNaN(parseInt(series.sliceThickness)) ? null : parseInt(series.sliceThickness)
|
||||
// if (sliceThickness === 5 || series.instanceCount <= 100) {
|
||||
series.imageIds.map(image => {
|
||||
let priority = 0
|
||||
if (series.seriesId === res[i].seriesId) {
|
||||
priority = parseInt(new Date().getTime()) * 10
|
||||
} else {
|
||||
priority = --p
|
||||
}
|
||||
this.imageList.push({ imageId: image, seriesId: series.seriesId, studyIndex: studyIndex, seriesIndex: seriesIndex, visitTaskId: series.visitTaskId, priority })
|
||||
})
|
||||
}
|
||||
if (res[i].isExistMutiFrames) {
|
||||
res[i].instanceInfoList.map(image => {
|
||||
priority--
|
||||
this.imageList.push({ imageId: image.ImageId, seriesId: res[i].seriesId, studyIndex: res[i].studyIndex, seriesIndex: res[i].seriesIndex, visitTaskId: res[i].visitTaskId, priority })
|
||||
})
|
||||
})
|
||||
} else {
|
||||
res[i].imageIds.map(image => {
|
||||
priority--
|
||||
this.imageList.push({ imageId: image, seriesId: res[i].seriesId, studyIndex: res[i].studyIndex, seriesIndex: res[i].seriesIndex, visitTaskId: res[i].visitTaskId, priority })
|
||||
})
|
||||
}
|
||||
|
||||
this.loopLoad()
|
||||
}
|
||||
}
|
||||
|
@ -341,9 +335,9 @@ export default {
|
|||
var p = parseInt(new Date().getTime())
|
||||
var imageId = seriesInfo.imageIds[seriesInfo.imageIdIndex]
|
||||
requestPoolManager.loadAndCacheImagePlus(imageId, seriesInfo.seriesId, p * 100).then(res => {
|
||||
if (seriesInfo.isCurrentTask) {
|
||||
this.imageLoaded({ studyIndex: seriesInfo.studyIndex, seriesIndex: seriesInfo.seriesIndex, imageId: res.imageId }, res.data.string('x0020000e'))
|
||||
}
|
||||
// if (seriesInfo.isCurrentTask) {
|
||||
// this.imageLoaded({ studyIndex: seriesInfo.studyIndex, seriesIndex: seriesInfo.seriesIndex, imageId: res.imageId }, res.data.string('x0020000e'))
|
||||
// }
|
||||
})
|
||||
},
|
||||
getStudyList() {
|
||||
|
@ -355,11 +349,31 @@ export default {
|
|||
this.studyList = this.visitTaskList[idx].StudyList
|
||||
var sIdx = this.studyList.findIndex(s => s.IsDicom)
|
||||
if (sIdx > -1) {
|
||||
this.studyIndex = sIdx
|
||||
this.seriesIndex = 0
|
||||
console.log(this.studyIndex, this.studyIndex)
|
||||
// this.studyIndex = sIdx
|
||||
// c = 0
|
||||
this.activeNames = [`${this.studyList[sIdx].StudyId}`]
|
||||
|
||||
this.loadImages(this.visitTaskList[idx])
|
||||
// 下载关键序列
|
||||
const i = this.studyList.findIndex(i => i.IsCriticalSequence)
|
||||
if (i > -1 && this.studyList[i].SeriesList[0].length > 0) {
|
||||
const series = this.studyList[i].SeriesList[0]
|
||||
if (!series.loadStatus) {
|
||||
let priority = parseInt(new Date().getTime())
|
||||
if (series.isExistMutiFrames) {
|
||||
series.instanceInfoList.map(image => {
|
||||
priority = priority - 1
|
||||
this.imageList.push({ imageId: image.ImageId, seriesId: series.seriesId, studyIndex: i, seriesIndex: 0, visitTaskId: series.visitTaskId, priority })
|
||||
})
|
||||
} else {
|
||||
series.imageIds.map(imageId => {
|
||||
priority = priority - 1
|
||||
this.imageList.push({ imageId: imageId, seriesId: series.seriesId, studyIndex: i, seriesIndex: 0, visitTaskId: series.visitTaskId, priority })
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
this.loopLoad()
|
||||
// this.loadImages(this.visitTaskList[idx])
|
||||
}
|
||||
}
|
||||
this.isRender = true
|
||||
|
@ -368,11 +382,26 @@ export default {
|
|||
|
||||
async getInitSeries() {
|
||||
var seriesList = []
|
||||
var isReadingTaskViewInOrder = JSON.parse(this.$router.currentRoute.query.isReadingTaskViewInOrder)
|
||||
var isReadingTaskViewInOrder = parseInt(this.$router.currentRoute.query.isReadingTaskViewInOrder)
|
||||
var idx = this.visitTaskList.findIndex(i => i.VisitTaskId === this.visitTaskId)
|
||||
this.studyList = this.visitTaskList[idx].StudyList
|
||||
if (this.visitTaskList[idx].IsBaseLineTask || !isReadingTaskViewInOrder) {
|
||||
// 基线
|
||||
const studyList = this.visitTaskList[idx].StudyList.filter(i => i.IsDicom)
|
||||
const seriesArr = studyList.map(s => s.SeriesList).flat()
|
||||
if (isReadingTaskViewInOrder === 2) {
|
||||
// 受试者内随机
|
||||
if (seriesArr.length === 1) {
|
||||
seriesList.push(seriesArr[0], seriesArr[0])
|
||||
this.studyIndex = seriesArr[0].studyIndex
|
||||
this.seriesIndex = seriesArr[0].seriesIndex
|
||||
this.activeNames = [`${seriesArr[0].studyId}`]
|
||||
} else if (seriesArr.length > 1) {
|
||||
seriesList.push(seriesArr[0], seriesArr[1])
|
||||
this.studyIndex = seriesArr[1].studyIndex
|
||||
this.seriesIndex = seriesArr[1].seriesIndex
|
||||
this.activeNames = [`${seriesArr[1].studyId}`]
|
||||
}
|
||||
} else if (this.visitTaskList[idx].IsBaseLineTask || isReadingTaskViewInOrder === 0) {
|
||||
// 基线任务或完全随机
|
||||
const obj = this.getFirstMarkedSeries(this.visitTaskList[idx].MeasureData, [...this.visitTaskList[idx].StudyList])
|
||||
if (Object.keys(obj).length !== 0) {
|
||||
this.studyIndex = obj.studyIndex
|
||||
|
@ -381,9 +410,13 @@ export default {
|
|||
this.activeNames = [`${this.studyList[ this.studyIndex].StudyId}`]
|
||||
this.studyList[ obj.studyIndex].SeriesList[obj.seriesIndex].isFirstRender = true
|
||||
} else {
|
||||
// 初始化问题表单
|
||||
if (this.studyList.length > 0) {
|
||||
this.activeNames = [`${this.studyList[0].StudyId}`]
|
||||
// 初始化问题表单
|
||||
this.studyIndex = seriesArr[0].studyIndex
|
||||
this.seriesIndex = seriesArr[0].seriesIndex
|
||||
this.activeNames = [`${seriesArr[0].studyId}`]
|
||||
seriesList.push(seriesArr[0])
|
||||
// this.activeNames = [`${this.studyList[0].StudyId}`]
|
||||
}
|
||||
|
||||
// DicomEvent.$emit('loadMeasurementList', { visitTaskId: this.visitTaskList[idx].VisitTaskId, taskBlindName: this.visitTaskList[idx].TaskBlindName })
|
||||
|
@ -407,6 +440,7 @@ export default {
|
|||
|
||||
const firstObj = this.getFirstMarkedSeries(this.visitTaskList[bsIdx].MeasureData, [...this.visitTaskList[bsIdx].StudyList])
|
||||
seriesList.push(firstObj.series)
|
||||
|
||||
const secondObj = this.getSecondMarkedSeries(firstObj, { ...this.visitTaskList[idx] })
|
||||
this.studyIndex = secondObj.studyIndex
|
||||
this.seriesIndex = secondObj.seriesIndex
|
||||
|
@ -441,9 +475,10 @@ export default {
|
|||
const sdIndx = studyList.findIndex(sd => sd.StudyId === measureDatas[i].StudyId)
|
||||
const seriesList = studyList[sdIndx].SeriesList
|
||||
const srIdx = seriesList.findIndex(sr => sr.seriesId === measureDatas[i].SeriesId)
|
||||
// const instanceList = seriesList[srIdx].imageIds
|
||||
const instanceList = seriesList[srIdx].instanceList
|
||||
const isIdx = instanceList.findIndex(is => is.includes(measureDatas[i].InstanceId))
|
||||
// const instanceList = seriesList[srIdx].instanceList
|
||||
const imageIds = seriesList[srIdx].imageIds
|
||||
const filterStr = seriesList[srIdx].isExistMutiFrames ? `frame=${measureDatas[i].MeasureData.frame}&instanceId=${measureDatas[i].InstanceId}` : `instanceId=${measureDatas[i].InstanceId}`
|
||||
const isIdx = imageIds.findIndex(is => is.includes(filterStr))
|
||||
const series = seriesList[srIdx]
|
||||
series.imageIdIndex = isIdx
|
||||
|
||||
|
@ -514,8 +549,9 @@ export default {
|
|||
const seriesList = studyList[sdIndx].SeriesList
|
||||
const srIdx = seriesList.findIndex(sr => sr.seriesId === measureDatas[mIdx].SeriesId)
|
||||
// const instanceList = seriesList[srIdx].imageIds
|
||||
const instanceList = seriesList[srIdx].instanceList
|
||||
const isIdx = instanceList.findIndex(is => is.includes(measureDatas[mIdx].InstanceId))
|
||||
const imageIds = seriesList[srIdx].imageIds
|
||||
const filterStr = seriesList[srIdx].isExistMutiFrames ? `frame=${measureDatas[mIdx].MeasureData.frame}&instanceId=${measureDatas[mIdx].InstanceId}` : `instanceId=${measureDatas[mIdx].InstanceId}`
|
||||
const isIdx = imageIds.findIndex(is => is.includes(filterStr))
|
||||
const series = seriesList[srIdx]
|
||||
series.imageIdIndex = isIdx
|
||||
|
||||
|
@ -544,22 +580,20 @@ export default {
|
|||
obj.series = seriesObj.series
|
||||
obj.seriesId = seriesObj.series.seriesId
|
||||
obj.isMarked = false
|
||||
} else {
|
||||
const sIdx = studyList.findIndex(s => s.IsDicom)
|
||||
if (sIdx > -1) {
|
||||
// 判断是否存在层厚为5的序列,否则显示第一个检查的第一个序列
|
||||
const series = studyList[sIdx].SeriesList[0]
|
||||
var imageIdIndex = series.imageIds.length > 1 ? Math.floor(series.imageIds.length / 2) - 1 : 0
|
||||
obj.studyIndex = sIdx
|
||||
obj.seriesIndex = 0
|
||||
obj.series = series
|
||||
obj.series.imageIdIndex = imageIdIndex >= 0 ? imageIdIndex : 0
|
||||
obj.seriesId = series.seriesId
|
||||
obj.isMarked = false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (Object.keys(obj).length === 0) {
|
||||
const sIdx = studyList.findIndex(s => s.IsDicom)
|
||||
if (sIdx > -1) {
|
||||
obj.studyIndex = sIdx
|
||||
obj.seriesIndex = 0
|
||||
obj.series = studyList[obj.studyIndex].SeriesList[obj.seriesIndex]
|
||||
const imageIdIndex = Math.floor(obj.series.imageIds.length / 2)
|
||||
obj.series.imageIdIndex = imageIdIndex >= 0 ? imageIdIndex : 0
|
||||
// obj.seriesId = series.seriesId
|
||||
obj.isMarked = false
|
||||
}
|
||||
}
|
||||
return obj
|
||||
},
|
||||
strSimilarity2Number(s, t) {
|
||||
|
@ -613,7 +647,10 @@ export default {
|
|||
this.studyIndex = studyIndex
|
||||
this.seriesIndex = seriesIndex
|
||||
this.studyList[studyIndex].SeriesList[seriesIndex].measureData = this.measureData
|
||||
var dicomStatck = this.studyList[studyIndex].SeriesList[seriesIndex]
|
||||
// var dicomStatck = this.studyList[studyIndex].SeriesList[seriesIndex]
|
||||
var dicomStatck = Object.assign({}, this.studyList[studyIndex].SeriesList[seriesIndex])
|
||||
|
||||
dicomStatck.imageIdIndex = 0
|
||||
this.$emit('loadImageStack', dicomStatck)
|
||||
if (!series.loadStatus && series.modality !== 'SR') {
|
||||
this.loopLoadStatus = -1
|
||||
|
@ -626,9 +663,15 @@ export default {
|
|||
}
|
||||
if (!isAddToTakPool) {
|
||||
var priority = parseInt(new Date().getTime())
|
||||
series.imageIds.map((imageId) => {
|
||||
this.imageList.push({ imageId: imageId, seriesId: series.seriesId, studyIndex: studyIndex, seriesIndex: seriesIndex, visitTaskId: series.visitTaskId, priority })
|
||||
})
|
||||
if (series.isExistMutiFrames) {
|
||||
series.instanceInfoList.map(image => {
|
||||
this.imageList.push({ imageId: image.ImageId, seriesId: series.seriesId, studyIndex: studyIndex, seriesIndex: seriesIndex, visitTaskId: series.visitTaskId, priority })
|
||||
})
|
||||
} else {
|
||||
series.imageIds.map(imageId => {
|
||||
this.imageList.push({ imageId: imageId, seriesId: series.seriesId, studyIndex: studyIndex, seriesIndex: seriesIndex, visitTaskId: series.visitTaskId, priority })
|
||||
})
|
||||
}
|
||||
if (this.imageList.length > 0) {
|
||||
this.loopLoadStatus = 0
|
||||
this.loopLoad()
|
||||
|
@ -647,6 +690,59 @@ export default {
|
|||
|
||||
store.dispatch('reading/setActiveSeries', series)
|
||||
},
|
||||
showMultiFrames(studyIndex, series, seriesIndex, instanceInfo) {
|
||||
this.currentSeriesIndex = seriesIndex
|
||||
var idx = this.visitTaskIdx
|
||||
const imageIds = []
|
||||
if (instanceInfo.KeyFramesList.length > 0) {
|
||||
instanceInfo.KeyFramesList.map(i => {
|
||||
imageIds.push(`wadouri:${localStorage.getItem('location') !== 'USA' ? this.OSSclientConfig.basePath : this.OSSclientConfig.basePath}${instanceInfo.Path}?frame=${i}&instanceId=${instanceInfo.Id}&visitTaskId=${this.visitTaskId}&idx=${studyIndex}|${seriesIndex}|${idx}`)
|
||||
})
|
||||
} else if (instanceInfo.NumberOfFrames && instanceInfo.NumberOfFrames > 1) {
|
||||
for (let j = 0; j < instanceInfo.NumberOfFrames; j++) {
|
||||
imageIds.push(`wadouri:${localStorage.getItem('location') !== 'USA' ? this.OSSclientConfig.basePath : this.OSSclientConfig.basePath}${instanceInfo.Path}?frame=${j}&instanceId=${instanceInfo.Id}&visitTaskId=${this.visitTaskId}&idx=${studyIndex}|${seriesIndex}|${idx}`)
|
||||
}
|
||||
} else {
|
||||
imageIds.push(`wadouri:${localStorage.getItem('location') !== 'USA' ? this.OSSclientConfig.basePath : this.OSSclientConfig.basePath}${instanceInfo.Path}?instanceId=${instanceInfo.Id}&visitTaskId=${this.visitTaskId}&idx=${studyIndex}|${seriesIndex}|${idx}`)
|
||||
}
|
||||
this.studyIndex = studyIndex
|
||||
this.seriesIndex = seriesIndex
|
||||
this.studyList[studyIndex].SeriesList[seriesIndex].measureData = this.measureData
|
||||
// var dicomStatck = this.studyList[studyIndex].SeriesList[seriesIndex]
|
||||
var dicomStatck = Object.assign({}, this.studyList[studyIndex].SeriesList[seriesIndex])
|
||||
dicomStatck.imageIds = imageIds
|
||||
dicomStatck.imageIdIndex = 0
|
||||
this.$emit('loadImageStack', dicomStatck)
|
||||
this.loopLoadStatus = -1
|
||||
series.isLoading = true
|
||||
var isAddToTakPool = false
|
||||
if (this.showSeriesList.includes(`${studyIndex}_${seriesIndex}`)) {
|
||||
isAddToTakPool = true
|
||||
} else {
|
||||
this.showSeriesList.push(`${studyIndex}_${seriesIndex}`)
|
||||
}
|
||||
if (!isAddToTakPool) {
|
||||
var priority = parseInt(new Date().getTime())
|
||||
if (series.isExistMutiFrames) {
|
||||
series.instanceInfoList.map(image => {
|
||||
this.imageList.push({ imageId: image.ImageId, seriesId: series.seriesId, studyIndex: studyIndex, seriesIndex: seriesIndex, visitTaskId: series.visitTaskId, priority })
|
||||
})
|
||||
} else {
|
||||
series.imageIds.map((imageId) => {
|
||||
this.imageList.push({ imageId: imageId, seriesId: series.seriesId, studyIndex: studyIndex, seriesIndex: seriesIndex, visitTaskId: series.visitTaskId, priority })
|
||||
})
|
||||
}
|
||||
|
||||
if (this.imageList.length > 0) {
|
||||
this.loopLoadStatus = 0
|
||||
this.loopLoad()
|
||||
}
|
||||
} else {
|
||||
requestPoolManager.changePriority(series.seriesId)
|
||||
}
|
||||
|
||||
DicomEvent.$emit('loadMeasurementList', { visitTaskId: this.visitTaskId, taskBlindName: this.taskBlindName })
|
||||
},
|
||||
setSeriesActive(obj) {
|
||||
var idx = this.visitTaskList.findIndex(i => i.VisitTaskId === this.visitTaskId)
|
||||
if (idx === -1) return
|
||||
|
@ -656,7 +752,8 @@ export default {
|
|||
var activeNames = `${this.studyList[obj.studyIndex].StudyId}`
|
||||
if (this.activeNames.includes(activeNames)) return
|
||||
this.activeNames.push(activeNames)
|
||||
this.loadImages(this.visitTaskList[idx])
|
||||
// console.log('setSeriesActive', obj)
|
||||
this.loadImages(obj)
|
||||
},
|
||||
selectSeries(obj) {
|
||||
var seriseList = this.studyList.map(s => s.SeriesList).flat()
|
||||
|
@ -681,10 +778,27 @@ export default {
|
|||
var activeNames = `${this.studyList[series.studyIndex].StudyId}`
|
||||
if (this.activeNames.includes(activeNames)) return
|
||||
this.activeNames.push(activeNames)
|
||||
this.loadImages(this.visitTaskList[idx])
|
||||
this.loadImages(series)
|
||||
store.dispatch('reading/setActiveSeries', series)
|
||||
},
|
||||
loadImages(taskInfo) {
|
||||
loadImages(series) {
|
||||
var priority = parseInt(new Date().getTime())
|
||||
if (!series.loadStatus && series.isDicom && series.modality !== 'SR') {
|
||||
if (series.isExistMutiFrames) {
|
||||
series.instanceInfoList.map(image => {
|
||||
priority = priority - 1
|
||||
this.imageList.push({ imageId: image.ImageId, seriesId: series.seriesId, studyIndex: series.studyIndex, seriesIndex: series.seriesIndex, visitTaskId: series.visitTaskId, priority })
|
||||
})
|
||||
} else {
|
||||
series.imageIds.map(imageId => {
|
||||
priority = priority - 1
|
||||
this.imageList.push({ imageId: imageId, seriesId: series.seriesId, studyIndex: series.studyIndex, seriesIndex: series.seriesIndex, visitTaskId: series.visitTaskId, priority })
|
||||
})
|
||||
}
|
||||
}
|
||||
this.loopLoad()
|
||||
},
|
||||
loadImages1(taskInfo) {
|
||||
// const isBaseLineTask = taskInfo.IsBaseLineTask
|
||||
const isCurrentTask = taskInfo.IsCurrentTask
|
||||
// var priority = isCurrentTask ? parseInt(new Date().getTime()) : 999
|
||||
|
@ -705,10 +819,17 @@ export default {
|
|||
// }
|
||||
// 均只下载关键序列
|
||||
if (!isCurrentTask && study.IsCriticalSequence) {
|
||||
series.imageIds.map(image => {
|
||||
priority = priority - 1
|
||||
this.imageList.push({ imageId: image, seriesId: series.seriesId, studyIndex: studyIndex, seriesIndex: seriesIndex, visitTaskId: series.visitTaskId, priority })
|
||||
})
|
||||
if (series.isExistMutiFrames) {
|
||||
series.instanceInfoList.map(image => {
|
||||
priority = priority - 1
|
||||
this.imageList.push({ imageId: image.ImageId, seriesId: series.seriesId, studyIndex: studyIndex, seriesIndex: seriesIndex, visitTaskId: series.visitTaskId, priority })
|
||||
})
|
||||
} else {
|
||||
series.imageIds.map(imageId => {
|
||||
priority = priority - 1
|
||||
this.imageList.push({ imageId: imageId, seriesId: series.seriesId, studyIndex: studyIndex, seriesIndex: seriesIndex, visitTaskId: series.visitTaskId, priority })
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
@ -720,11 +841,7 @@ export default {
|
|||
if (this.imageList.length > 0) {
|
||||
// requestPoolManager.startTaskTimer()
|
||||
this.imageList.map(image => {
|
||||
requestPoolManager.loadAndCacheImagePlus(image.imageId, image.seriesId, image.priority).then(res => {
|
||||
if (res) {
|
||||
this.imageLoaded(image, res.data.string('x0020000e'))
|
||||
}
|
||||
})
|
||||
requestPoolManager.loadAndCacheImagePlus(image.imageId, image.seriesId, image.priority)
|
||||
})
|
||||
requestPoolManager.sortTaskPool()
|
||||
|
||||
|
@ -744,12 +861,22 @@ export default {
|
|||
}
|
||||
if (!isAddToTakPool) {
|
||||
const priority = parseInt(new Date().getTime())
|
||||
series.imageIds.map(image => {
|
||||
const index = this.cachedImages.findIndex(item => item.uri === image)
|
||||
if (index === -1) {
|
||||
this.imageList.push({ imageId: image, seriesId: series.seriesId, studyIndex: studyIndex, seriesIndex: seriesIndex, visitTaskId: series.visitTaskId, priority })
|
||||
}
|
||||
})
|
||||
if (series.isExistMutiFrames) {
|
||||
series.instanceInfoList.map(image => {
|
||||
const index = this.cachedImages.findIndex(item => item.uri === image)
|
||||
if (index === -1) {
|
||||
this.imageList.push({ imageId: image.ImageId, seriesId: series.seriesId, studyIndex: studyIndex, seriesIndex: seriesIndex, visitTaskId: series.visitTaskId, priority })
|
||||
}
|
||||
})
|
||||
} else {
|
||||
series.imageIds.map(image => {
|
||||
const index = this.cachedImages.findIndex(item => item.uri === image)
|
||||
if (index === -1) {
|
||||
this.imageList.push({ imageId: image, seriesId: series.seriesId, studyIndex: studyIndex, seriesIndex: seriesIndex, visitTaskId: series.visitTaskId, priority })
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
if (this.imageList.length > 0) {
|
||||
this.loopLoadStatus = 0
|
||||
this.loopLoad()
|
||||
|
@ -763,83 +890,6 @@ export default {
|
|||
console.log('stopLoadSeries')
|
||||
requestPoolManager.removeTask(series.seriesId)
|
||||
this.$set(this.studyList[studyIndex].SeriesList[seriesIndex], 'isLoading', false)
|
||||
},
|
||||
async imageLoaded(image, seriesUid) {
|
||||
// await store.dispatch('reading/updateStudyList', { visitTaskId: image.visitTaskId, imageId: image.imageId, seriesUid })
|
||||
// console.log(this.studyList[image.studyIndex].SeriesList[image.seriesIndex])
|
||||
if (image.studyIndex > -1 && image.seriesIndex > -1) {
|
||||
var prefetchInstanceCount = this.studyList[image.studyIndex].SeriesList[image.seriesIndex].prefetchInstanceCount
|
||||
var instanceCount = this.studyList[image.studyIndex].SeriesList[image.seriesIndex].instanceCount
|
||||
if (this.studyList[image.studyIndex].SeriesList[image.seriesIndex].imageloadedArr.indexOf(image.imageId) < 0) {
|
||||
this.studyList[image.studyIndex].SeriesList[image.seriesIndex].imageloadedArr.push(image.imageId)
|
||||
prefetchInstanceCount = prefetchInstanceCount + 1
|
||||
this.studyList[image.studyIndex].SeriesList[image.seriesIndex].prefetchInstanceCount = prefetchInstanceCount
|
||||
}
|
||||
if (prefetchInstanceCount >= instanceCount) {
|
||||
this.studyList[image.studyIndex].SeriesList[image.seriesIndex].prefetchInstanceCount = this.studyList[image.studyIndex].SeriesList[image.seriesIndex].instanceCount
|
||||
// 设置当前序列状态为已下载完成
|
||||
this.studyList[image.studyIndex].SeriesList[image.seriesIndex].loadStatus = true
|
||||
}
|
||||
}
|
||||
|
||||
// store.dispatch('reading/updateSeriesList', { visitTaskindex: this.visitTaskIdx, studyIndex: image.studyIndex, seriesIndex: image.seriesIndex, imageId: image.imageId })
|
||||
},
|
||||
// instance下载成功回调
|
||||
async cornerstoneImageLoaded(e) {
|
||||
// var idx = this.visitTaskList.findIndex(i => i.VisitTaskId === this.visitTaskId)
|
||||
// if (idx === -1) return
|
||||
// this.studyList = this.visitTaskList[idx].StudyList
|
||||
// if (!this.studyList || this.studyList.length === 0) {
|
||||
// return
|
||||
// }
|
||||
// if (!this.visitTaskList[idx].IsInit) {
|
||||
// const loading = this.$loading({ fullscreen: true })
|
||||
// await store.dispatch('reading/getMeasuredData', this.visitTaskList[idx].VisitTaskId)
|
||||
// await store.dispatch('reading/getStudyInfo', { trialId: this.trialId, subjectVisitId: this.visitTaskList[idx].VisitId, visitTaskId: this.visitTaskList[idx].VisitTaskId, taskBlindName: this.visitTaskList[idx].TaskBlindName })
|
||||
// await store.dispatch('reading/getReadingQuestionAndAnswer', { trialId: this.trialId, visitTaskId: this.visitTaskList[idx].VisitTaskId })
|
||||
// await store.dispatch('reading/getDicomReadingQuestionAnswer', { trialId: this.trialId, visitTaskId: this.visitTaskList[idx].VisitTaskId })
|
||||
// await store.dispatch('reading/setStatus', { visitTaskId: this.visitTaskList[idx].VisitTaskId })
|
||||
// loading.close()
|
||||
// }
|
||||
// await store.dispatch('reading/updateStudyList', { visitTaskId: this.visitTaskId, imageId: e.detail.image.imageId, seriesUid: e.detail.image.data.string('x0020000e') })
|
||||
// const uri = e.detail.image.sharedCacheKey
|
||||
// const index = this.cachedImages.findIndex(item => item.uri === uri)
|
||||
// if (index === -1) {
|
||||
// this.cachedImages.push({ uri: uri, timestamp: new Date().getTime() })
|
||||
// } else {
|
||||
// this.cachedImages[index].timestamp = new Date().getTime()
|
||||
// }
|
||||
// var imageId = e.detail.image.imageId
|
||||
// var seriesUid = e.detail.image.data.string('x0020000e')
|
||||
// var studyIndex = -1
|
||||
// var seriesIndex = -1
|
||||
// for (let i = 0; i < this.studyList.length; ++i) {
|
||||
// for (let j = 0; j < this.studyList[i].SeriesList.length; ++j) {
|
||||
// if (this.studyList[i].SeriesList[j].seriesUid === seriesUid) {
|
||||
// studyIndex = i
|
||||
// seriesIndex = j
|
||||
// break
|
||||
// }
|
||||
// }
|
||||
// if (studyIndex > 0) break
|
||||
// }
|
||||
// if (seriesIndex < 0) return
|
||||
|
||||
// const imageIdIndex = this.studyList[studyIndex].SeriesList[seriesIndex].imageIds.indexOf(imageId)
|
||||
// if (imageIdIndex < 0) return
|
||||
// if (this.studyList[studyIndex].SeriesList[seriesIndex].imageloadedArr.indexOf(imageId) < 0) {
|
||||
// if (this.studyList[studyIndex].SeriesList[seriesIndex].prefetchInstanceCount >= this.studyList[studyIndex].SeriesList[seriesIndex].instanceCount) {
|
||||
// // 设置当前序列状态为已下载完成
|
||||
// this.studyList[studyIndex].SeriesList[seriesIndex].loadStatus = true
|
||||
// }
|
||||
// }
|
||||
},
|
||||
cornerstoneimagecachechanged(e) {
|
||||
const cacheInfo = cornerstone.imageCache.getCacheInfo()
|
||||
console.log(cacheInfo)
|
||||
},
|
||||
cornerstoneimagecachefull(e) {
|
||||
console.log('超过内存了')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -936,6 +986,7 @@ export default {
|
|||
padding: 1px;
|
||||
margin: 0px;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
/deep/.el-collapse{
|
||||
|
@ -986,5 +1037,41 @@ export default {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
</style>
|
||||
<style>
|
||||
.instance_frame_wrapper{
|
||||
min-width: 120px;
|
||||
background-color: #2c2c2c;
|
||||
border: 1px solid #2c2c2c;
|
||||
padding: 5px;
|
||||
}
|
||||
.frame_list{
|
||||
max-height: 500px;
|
||||
overflow-y: auto;
|
||||
}
|
||||
.instance_frame_wrapper ::-webkit-scrollbar {
|
||||
width: 7px;
|
||||
height: 7px;
|
||||
}
|
||||
.instance_frame_wrapper ::-webkit-scrollbar-thumb {
|
||||
border-radius: 10px;
|
||||
background: #d0d0d0;
|
||||
}
|
||||
.frame_content{
|
||||
height: 50px;
|
||||
padding: 5px;
|
||||
display: flex;
|
||||
justify-content: flex-start;
|
||||
color: #ddd;
|
||||
font-size: 12px;
|
||||
border: 1px solid #404040;
|
||||
}
|
||||
.frame_content:hover {
|
||||
/* font-weight: bold; */
|
||||
/* box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1); */
|
||||
cursor: pointer;
|
||||
/* color: #428bca; */
|
||||
border-color: #213a54 !important;
|
||||
background-color: #213a54;
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -83,13 +83,16 @@ export default {
|
|||
this.getWL()
|
||||
},
|
||||
methods: {
|
||||
getWL() {
|
||||
async getWL() {
|
||||
this.loading = true
|
||||
getUserWLTemplateList().then(res => {
|
||||
try {
|
||||
const res = await getUserWLTemplateList()
|
||||
this.tableData = res.Result
|
||||
this.loading = false
|
||||
this.$emit('getWwcTpl')
|
||||
}).catch(() => { this.loading = false })
|
||||
} catch (e) {
|
||||
this.loading = false
|
||||
}
|
||||
},
|
||||
handleAdd() {
|
||||
this.customWwc.title = this.$t('common:button:new')
|
||||
|
@ -101,22 +104,27 @@ export default {
|
|||
this.row = Object.assign({}, row)
|
||||
this.customWwc.visible = true
|
||||
},
|
||||
handleDelete(row) {
|
||||
async handleDelete(row) {
|
||||
// '是否确认删除?'
|
||||
var msg = this.$t('trials:reading:wlTemplate:delete')
|
||||
|
||||
this.$confirm(msg, {
|
||||
type: 'warning',
|
||||
distinguishCancelAndClose: true
|
||||
}).then(() => {
|
||||
this.loading = true
|
||||
deleteUserWLTemplate(row.Id).then(res => {
|
||||
this.loading = false
|
||||
// 删除成功
|
||||
this.$message.success(this.$t('common:message:deletedSuccessfully'))
|
||||
this.getWL()
|
||||
}).catch(() => { this.loading = false })
|
||||
})
|
||||
const confirm = await this.$confirm(
|
||||
msg,
|
||||
{
|
||||
type: 'warning',
|
||||
distinguishCancelAndClose: true
|
||||
}
|
||||
)
|
||||
if (confirm !== 'confirm') return
|
||||
this.loading = true
|
||||
try {
|
||||
await deleteUserWLTemplate(row.Id)
|
||||
this.loading = false
|
||||
// 删除成功
|
||||
this.$message.success(this.$t('common:message:deletedSuccessfully'))
|
||||
this.getWL()
|
||||
} catch (e) {
|
||||
this.loading = false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -83,24 +83,23 @@ export default {
|
|||
}
|
||||
},
|
||||
methods: {
|
||||
handleSave() {
|
||||
this.$refs.wlForm.validate((valid) => {
|
||||
if (valid) {
|
||||
this.loading = true
|
||||
addOrUpdateUserWLTemplate(this.form).then((res) => {
|
||||
this.loading = false
|
||||
this.$emit('getWL')
|
||||
this.$emit('close')
|
||||
if (this.form.Id) {
|
||||
this.$message.success(this.$t('common:message:savedSuccessfully'))
|
||||
} else {
|
||||
this.$message.success(this.$t('common:message:addedSuccessfully'))
|
||||
}
|
||||
}).catch(() => {
|
||||
this.loading = false
|
||||
})
|
||||
async handleSave() {
|
||||
const valid = await this.$refs.wlForm.validate()
|
||||
if (!valid) return
|
||||
this.loading = true
|
||||
try {
|
||||
await addOrUpdateUserWLTemplate(this.form)
|
||||
this.loading = false
|
||||
this.$emit('getWL')
|
||||
this.$emit('close')
|
||||
if (this.form.Id) {
|
||||
this.$message.success(this.$t('common:message:savedSuccessfully'))
|
||||
} else {
|
||||
this.$message.success(this.$t('common:message:addedSuccessfully'))
|
||||
}
|
||||
})
|
||||
} catch (e) {
|
||||
this.loading = false
|
||||
}
|
||||
},
|
||||
handleCancel() {
|
||||
this.$emit('close')
|
||||
|
|
Binary file not shown.
Binary file not shown.
|
@ -19,7 +19,7 @@
|
|||
</div>
|
||||
<!-- 切换访视 -->
|
||||
<div
|
||||
v-if="stack.imageRendered && isReadingTaskViewInOrder"
|
||||
v-if="stack.imageRendered && isReadingTaskViewInOrder === 1"
|
||||
class="info-visit"
|
||||
@dblclick.stop="preventDefault($event)"
|
||||
>
|
||||
|
@ -43,7 +43,7 @@
|
|||
<i class="el-icon-caret-right" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="info-series">
|
||||
<div class="info-series">
|
||||
<h2 v-if="isReadingShowSubjectInfo" style="color:#f44336;padding: 5px 0px;margin: 0;">{{ subjectCode }} {{ stack.taskBlindName }}</h2>
|
||||
<div v-show="dicomInfo.series">Series: #{{ dicomInfo.series }}</div>
|
||||
<div>Image: #{{ dicomInfo.frame }}</div>
|
||||
|
@ -99,8 +99,8 @@
|
|||
</div>
|
||||
|
||||
<div class="info-instance">
|
||||
<div v-show="dicomInfo.location">Location: {{ dicomInfo.location }}</div>
|
||||
<div v-show="dicomInfo.thick">Slice Thickness: {{ dicomInfo.thick }}mm</div>
|
||||
<div v-if="dicomInfo.location">Location: {{ `${Number(dicomInfo.location).toFixed(digitPlaces)} mm` }}</div>
|
||||
<div v-show="dicomInfo.thick">Slice Thickness: {{ `${dicomInfo.thick} mm` }}</div>
|
||||
<div v-show="dicomInfo.wwwc">WW/WL: {{ dicomInfo.wwwc }}</div>
|
||||
</div>
|
||||
|
||||
|
@ -146,6 +146,7 @@ import LengthTool from '@/views/trials/trials-panel/reading/dicoms/tools/Length/
|
|||
import BidirectionalTool from '@/views/trials/trials-panel/reading/dicoms/tools/Bidirectional/BidirectionalTool'
|
||||
import ArrowAnnotateTool from '@/views/trials/trials-panel/reading/dicoms/tools/ArrowAnnotate/ArrowAnnotateTool'
|
||||
import RectangleRoiTool from '@/views/trials/trials-panel/reading/dicoms/tools/RectangleRoi/RectangleRoiTool'
|
||||
import CircleRoiTool from '@/views/trials/trials-panel/reading/dicoms/tools/CircleRoi/CircleRoiTool'
|
||||
// import OrientationMarkersTool from '@/views/trials/trials-panel/reading/dicoms/tools/OrientationMarkers/OrientationMarkersTool'
|
||||
import ScaleOverlayTool from '@/views/trials/trials-panel/reading/dicoms/tools/ScaleOverlay/ScaleOverlayTool'
|
||||
import getOrientationString from '@/views/trials/trials-panel/reading/dicoms/tools/OrientationMarkers/getOrientationString'
|
||||
|
@ -180,7 +181,7 @@ export default {
|
|||
required: true
|
||||
},
|
||||
isReadingTaskViewInOrder: {
|
||||
type: Boolean,
|
||||
type: Number,
|
||||
required: true
|
||||
},
|
||||
customWwcTpl: {
|
||||
|
@ -220,7 +221,9 @@ export default {
|
|||
visitTaskId: '',
|
||||
taskBlindName: '',
|
||||
frame: null,
|
||||
imageRendered: false
|
||||
imageRendered: false,
|
||||
isExistsClinicalData: false,
|
||||
isExistMutiFrames: false
|
||||
// preventCache: true
|
||||
},
|
||||
dicomInfo: {
|
||||
|
@ -256,7 +259,7 @@ export default {
|
|||
series: '',
|
||||
ToolStateManager: null,
|
||||
renderedMeasured: [],
|
||||
measuredTools: ['Length', 'Bidirectional', 'ArrowAnnotate', 'RectangleRoi'],
|
||||
measuredTools: ['Length', 'Bidirectional', 'ArrowAnnotate', 'RectangleRoi', 'CircleRoi'],
|
||||
measureData: [],
|
||||
selectedLesion: null,
|
||||
activeTool: 0, // 0:enable 1:passive 2:active
|
||||
|
@ -296,8 +299,8 @@ export default {
|
|||
|
||||
],
|
||||
scrollSyncInfo: { offset: 0 },
|
||||
hideMeasureArr: []
|
||||
|
||||
hideMeasureArr: [],
|
||||
enabledElement: null
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
|
@ -330,7 +333,9 @@ export default {
|
|||
},
|
||||
|
||||
mounted() {
|
||||
this.subjectCode = this.$router.currentRoute.query.subjectCode
|
||||
console.log(cornerstoneTools)
|
||||
// this.subjectCode = this.$router.currentRoute.query.subjectCode
|
||||
this.subjectCode = localStorage.getItem('subjectCode')
|
||||
document.addEventListener('mouseup', () => {
|
||||
this.sliderMouseup()
|
||||
})
|
||||
|
@ -373,10 +378,10 @@ export default {
|
|||
}
|
||||
)
|
||||
|
||||
// this.canvas.addEventListener(
|
||||
// 'cornerstonetoolsmeasurementremoved',
|
||||
// this.onMeasurementremoved
|
||||
// )
|
||||
this.canvas.addEventListener(
|
||||
'cornerstonetoolsmeasurementremoved',
|
||||
this.onMeasurementremoved
|
||||
)
|
||||
// EVENTS.MOUSE_UP
|
||||
this.canvas.addEventListener('cornerstonetoolsmouseup', this.mouseUp)
|
||||
this.canvas.addEventListener('cornerstonetoolsmousedown', this.mouseDown)
|
||||
|
@ -395,7 +400,8 @@ export default {
|
|||
cornerstone.updateImage(this.canvas, true)
|
||||
})
|
||||
DicomEvent.$on('updateImage', () => {
|
||||
cornerstone.updateImage(this.canvas)
|
||||
if (!this.canvas) return
|
||||
this.updateImage()
|
||||
})
|
||||
// this.canvas.addEventListener('keydown', event => {
|
||||
// event.preventDefault()
|
||||
|
@ -477,7 +483,6 @@ export default {
|
|||
},
|
||||
methods: {
|
||||
goViewer(e) {
|
||||
console.log('goViewer')
|
||||
console.log(this.$refs['sliderBox'].clientHeight)
|
||||
var height = e.offsetY * 100 / this.$refs['sliderBox'].clientHeight
|
||||
this.height = height
|
||||
|
@ -539,7 +544,7 @@ export default {
|
|||
this.mousePosition.y = currentPoints.image.y + 1
|
||||
this.mousePosition.mo = stats.mo
|
||||
this.mousePosition.suv = stats.suv
|
||||
if (this.isFirstChangeTask && this.pointNearTool(e)) {
|
||||
if (this.pointNearTool(e)) {
|
||||
e.stopImmediatePropagation()
|
||||
e.stopPropagation()
|
||||
e.preventDefault()
|
||||
|
@ -548,24 +553,25 @@ export default {
|
|||
|
||||
mouseUp(e) {
|
||||
console.log('mouseUp')
|
||||
if (this.readingTaskState >= 2) return
|
||||
// if (this.readingTaskState >= 2) return
|
||||
this.image = e.detail.image
|
||||
this.getToolStateInfo(e)
|
||||
},
|
||||
mouseDown(e) {
|
||||
this.image = e.detail.image
|
||||
var pointNearTool = this.pointNearTool(e)
|
||||
if (this.isFirstChangeTask && pointNearTool) {
|
||||
if (pointNearTool) {
|
||||
e.stopImmediatePropagation()
|
||||
e.stopPropagation()
|
||||
e.preventDefault()
|
||||
} else if (this.activeToolName === 'Length' || this.activeToolName === 'Bidirectional' && this.readingTaskState < 2) {
|
||||
} else if (this.activeToolName === 'Length' || this.activeToolName === 'Bidirectional') {
|
||||
if (!e.detail.image.columnPixelSpacing || !e.detail.image.rowPixelSpacing) {
|
||||
// '该影像不具备测量长度所需的必要数据,不能进行长度测量。请选择其他工具进行标注。'
|
||||
this.$confirm(this.$t('trials:reading:warnning:msg56'), '', {
|
||||
showCancelButton: false,
|
||||
type: 'warning'
|
||||
}).then(() => {
|
||||
|
||||
}).catch(() => {})
|
||||
e.stopImmediatePropagation()
|
||||
e.stopPropagation()
|
||||
|
@ -597,10 +603,11 @@ export default {
|
|||
getDisabledMarks(measureDatas) {
|
||||
var arr = []
|
||||
measureDatas.map(i => {
|
||||
if ((i.LesionType === 0 || i.LesionType === 1 || i.LesionType === 7) && i.IsFirstChangeTask) {
|
||||
arr.push(i.OrderMarkName)
|
||||
if (i.Id && this.readingTaskState >= 2) {
|
||||
arr.push(i.MeasureData.data.remark)
|
||||
}
|
||||
})
|
||||
console.log(arr)
|
||||
return arr
|
||||
},
|
||||
getRGBPixels(element, x, y, width, height) {
|
||||
|
@ -651,7 +658,7 @@ export default {
|
|||
if (PX < 0) return
|
||||
if (PX > boxHeight) return
|
||||
var height = PX * 100 / boxHeight
|
||||
var index = Math.trunc(this.stack.imageIds.length * this.height / 100)
|
||||
var index = Math.trunc(this.stack.imageIds.length * height / 100)
|
||||
index = index > this.stack.imageIds.length ? this.stack.imageIds.length : index < 0 ? 0 : index
|
||||
// if (!cornerstone.imageCache.getImageLoadObject(this.stack.imageIds[index])) return
|
||||
this.height = height
|
||||
|
@ -663,6 +670,7 @@ export default {
|
|||
this.sliderInfo.isMove = false
|
||||
},
|
||||
getMeasureData() {
|
||||
console.log('getMeasureData')
|
||||
var idx = this.visitTaskList.findIndex(i => i.VisitTaskId === this.stack.visitTaskId)
|
||||
this.measureData = this.visitTaskList[idx].MeasureData
|
||||
const ToolStateManager = cornerstoneTools.globalImageIdSpecificToolStateManager
|
||||
|
@ -736,14 +744,10 @@ export default {
|
|||
getToolStateInfo(e) {
|
||||
const { element, currentPoints, image, viewport } = e.detail
|
||||
var imageId = image.imageId
|
||||
var instanceId = imageId.split('/')[imageId.split('/').length - 1]
|
||||
var frame = null
|
||||
if (instanceId.includes('?frame=')) {
|
||||
frame = instanceId.split('?frame=')[1]
|
||||
instanceId = instanceId.split('?frame=')[0]
|
||||
}
|
||||
this.stack.frame = !isNaN(parseInt(frame)) ? parseInt(frame) : 0
|
||||
instanceId = instanceId.split('.')[0]
|
||||
const imageInfo = this.getInstanceInfo(imageId)
|
||||
var instanceId = imageInfo.instanceId
|
||||
var frame = imageInfo.frame
|
||||
this.stack.frame = this.stack.isExistMutiFrames ? parseInt(frame) : null
|
||||
const ToolStateManager = cornerstoneTools.globalImageIdSpecificToolStateManager
|
||||
for (var m = 0; m < this.measuredTools.length; m++) {
|
||||
var toolType = this.measuredTools[m]
|
||||
|
@ -771,10 +775,11 @@ export default {
|
|||
measureData.data = toolState.data[i]
|
||||
measureData.type = toolType
|
||||
measureData.thick = this.dicomInfo.thick
|
||||
measureData.location = this.dicomInfo.location
|
||||
var uuid = toolState.data[i].uuid
|
||||
var idx = this.measureData.findIndex(item => item.MeasureData && item.MeasureData.data && item.MeasureData.data.uuid === uuid)
|
||||
if (idx > -1) {
|
||||
var markName = this.measureData[idx].OrderMarkName
|
||||
var markName = this.measureData[idx].MeasureData.data.remark
|
||||
if (this.disabledMarks.indexOf(markName) === -1 || !this.disabledMarks) {
|
||||
measureData.ww = Math.round(viewport.voi.windowWidth)
|
||||
measureData.wc = Math.round(viewport.voi.windowCenter)
|
||||
|
@ -799,7 +804,7 @@ export default {
|
|||
}
|
||||
},
|
||||
stackScrollCallback(e) {
|
||||
console.log('stackScrollCallback')
|
||||
// console.log('stackScrollCallback')
|
||||
const { detail } = e
|
||||
if (this.isScrollSync && this.currentDicomCanvasIndex === this.canvasIndex) {
|
||||
this.scrollSyncInfo.canvasIndex = this.canvasIndex
|
||||
|
@ -864,8 +869,8 @@ export default {
|
|||
return seriesList[seriesIdx].loadStatus ? 1 : 0
|
||||
},
|
||||
renderMeasuredData(e) {
|
||||
this.stack.frame = !isNaN(parseInt(this.stack.frame)) ? parseInt(this.stack.frame) : 0
|
||||
var idx = this.visitTaskList.findIndex(i => i.VisitTaskId === this.stack.visitTaskId)
|
||||
if (idx === -1) return
|
||||
this.measureData = this.visitTaskList[idx].MeasureData
|
||||
const { element } = e.detail
|
||||
const ToolStateManager = cornerstoneTools.globalImageIdSpecificToolStateManager
|
||||
|
@ -880,11 +885,12 @@ export default {
|
|||
} else if (this.activeTool === 1 && this.readingTaskState < 2) {
|
||||
cornerstoneTools.setToolPassiveForElement(element, data.MeasureData.type, { mouseButtonMask: 1 })
|
||||
} else {
|
||||
cornerstoneTools.setToolEnabledForElement(element, data.MeasureData.type, { mouseButtonMask: 1 })
|
||||
// cornerstoneTools.setToolEnabledForElement(element, data.MeasureData.type, { mouseButtonMask: 1 })
|
||||
cornerstoneTools.setToolPassiveForElement(element, data.MeasureData.type, { mouseButtonMask: 1 })
|
||||
|
||||
}
|
||||
// console.log('renderMeasuredData', this.stack.frame)
|
||||
|
||||
if (this.stack.instanceId.includes(data.InstanceId) && ((data.NumberOfFrames === this.stack.frame) || !data.NumberOfFrames) && data.MeasureData) {
|
||||
if (this.stack.instanceId.includes(data.InstanceId) && ((this.stack.isExistMutiFrames && (data.MeasureData.frame === this.stack.frame) && data.MeasureData) || (!this.stack.isExistMutiFrames && data.MeasureData))) {
|
||||
// console.log('renderMeasuredData', this.stack.frame,data.MeasureData.frame,this.stack.isExistMutiFrames)
|
||||
const toolState = ToolStateManager.getImageIdToolState(e.detail.image.imageId, data.MeasureData.type)
|
||||
if (toolState && toolState.data.length > 0) {
|
||||
var idx = toolState.data.findIndex(item => item.uuid === data.MeasureData.data.uuid)
|
||||
|
@ -904,11 +910,8 @@ export default {
|
|||
if (this.readingTaskState >= 2) return
|
||||
var element = cornerstone.getEnabledElement(this.canvas)
|
||||
var { imageId } = element.image
|
||||
var instanceId = imageId.split('/')[imageId.split('/').length - 1]
|
||||
if (instanceId.includes('?frame=')) {
|
||||
instanceId = instanceId.split('?frame=')[0]
|
||||
}
|
||||
instanceId = instanceId.split('.')[0]
|
||||
const imageInfo = this.getInstanceInfo(imageId)
|
||||
var instanceId = imageInfo.instanceId
|
||||
var idx = this.visitTaskList.findIndex(i => i.VisitTaskId === this.stack.visitTaskId && i.IsCurrentTask && i.ReadingTaskState < 2)
|
||||
if (idx === -1) return
|
||||
this.measureData = this.visitTaskList[idx].MeasureData
|
||||
|
@ -968,18 +971,13 @@ export default {
|
|||
}
|
||||
}
|
||||
},
|
||||
async mouseClick(e) {
|
||||
mouseClick(e) {
|
||||
const { element, currentPoints, image, viewport } = e.detail
|
||||
var imageId = image.imageId
|
||||
var instanceId = imageId.split('/')[imageId.split('/').length - 1]
|
||||
var frame = null
|
||||
if (instanceId.includes('?frame=')) {
|
||||
frame = instanceId.split('?frame=')[1]
|
||||
instanceId = instanceId.split('?frame=')[0]
|
||||
}
|
||||
this.stack.frame = !isNaN(parseInt(frame)) ? parseInt(frame) : 0
|
||||
instanceId = instanceId.split('.')[0]
|
||||
|
||||
const imageInfo = this.getInstanceInfo(imageId)
|
||||
var instanceId = imageInfo.instanceId
|
||||
var frame = imageInfo.frame
|
||||
this.stack.frame = this.stack.isExistMutiFrames ? parseInt(frame) : null
|
||||
const ToolStateManager = cornerstoneTools.globalImageIdSpecificToolStateManager
|
||||
for (let t = 0; t < this.measuredTools.length; t++) {
|
||||
var toolType = this.measuredTools[t]
|
||||
|
@ -990,17 +988,17 @@ export default {
|
|||
if (i > -1) {
|
||||
var idx = this.measureData.findIndex(item => item.MeasureData && item.MeasureData.data && item.MeasureData.data.uuid === toolState.data[i].uuid)
|
||||
if (idx > -1) {
|
||||
console.log('mouseClick')
|
||||
DicomEvent.$emit('setCollapseActive', this.measureData[idx])
|
||||
if (this.readingTaskState < 2) {
|
||||
const measureData = {}
|
||||
var markName = this.measureData[idx].OrderMarkName
|
||||
if (this.activeToolName === 'Eraser') {
|
||||
var questionInfo = this.measureData[idx]
|
||||
this.$emit('moveMeasureData', { measureData, questionInfo })
|
||||
// var markName = this.measureData[idx].OrderMarkName
|
||||
var markName = this.measureData[idx].MeasureData.data.remark
|
||||
if (this.activeToolName === 'Eraser' && this.disabledMarks.indexOf(markName) === -1) {
|
||||
const questionInfo = this.measureData[idx]
|
||||
measureData.orderMarkName = markName
|
||||
this.$emit('moveMeasureData', { measureData, questionInfo, orderMarkName: markName})
|
||||
}
|
||||
if ((this.disabledMarks.indexOf(markName) === -1 || !this.disabledMarks) && this.activeToolName !== 'Eraser') {
|
||||
var questionInfo = this.measureData[idx]
|
||||
const questionInfo = this.measureData[idx]
|
||||
const canvas = this.canvas.querySelector('canvas')
|
||||
measureData.pictureBaseStr = canvas.toDataURL('image/png', 1)
|
||||
measureData.studyId = this.stack.studyId
|
||||
|
@ -1010,12 +1008,13 @@ export default {
|
|||
measureData.data = toolState.data[i]
|
||||
measureData.type = toolType
|
||||
measureData.thick = this.dicomInfo.thick
|
||||
measureData.location = this.dicomInfo.location
|
||||
measureData.ww = Math.round(viewport.voi.windowWidth)
|
||||
measureData.wc = Math.round(viewport.voi.windowCenter)
|
||||
measureData.data.active = false
|
||||
this.$emit('modifyMeasureData', { measureData, questionInfo })
|
||||
}
|
||||
}
|
||||
|
||||
break
|
||||
}
|
||||
}
|
||||
|
@ -1039,7 +1038,7 @@ export default {
|
|||
this.stack.studyId = dicomSeries.studyId
|
||||
this.stack.seriesNumber = dicomSeries.seriesNumber
|
||||
this.stack.imageIds = dicomSeries.imageIds
|
||||
this.stack.currentImageIdIndex = dicomSeries.imageIdIndex ? dicomSeries.imageIdIndex : 0
|
||||
this.stack.currentImageIdIndex = dicomSeries.imageIdIndex && dicomSeries.imageIdIndex < dicomSeries.imageIds.length ? dicomSeries.imageIdIndex : 0
|
||||
this.stack.imageIdIndex = dicomSeries.imageIdIndex
|
||||
this.stack.firstImageLoading = true
|
||||
this.stack.visitTaskId = dicomSeries.visitTaskId
|
||||
|
@ -1049,38 +1048,31 @@ export default {
|
|||
this.stack.seriesIndex = dicomSeries.seriesIndex
|
||||
this.stack.sliceThickness = dicomSeries.sliceThickness
|
||||
this.stack.instanceCount = dicomSeries.instanceCount
|
||||
this.stack.isExistsClinicalData = dicomSeries.isExistsClinicalData
|
||||
// this.measuredData = dicomSeries.measuredData
|
||||
var idx = this.visitTaskList.findIndex(i => i.VisitTaskId === dicomSeries.visitTaskId)
|
||||
this.stack.visitTaskNum = this.visitTaskList[idx].VisitTaskNum
|
||||
this.isFirstChangeTask = this.visitTaskList[idx].IsFirstChangeTask
|
||||
if (this.isFirstChangeTask) {
|
||||
this.disabledMarks = this.getDisabledMarks(this.visitTaskList[idx].MeasureData)
|
||||
} else {
|
||||
this.disabledMarks = []
|
||||
}
|
||||
this.disabledMarks = this.getDisabledMarks(this.visitTaskList[idx].MeasureData)
|
||||
|
||||
this.maxVistNum = this.visitTaskList[this.visitTaskList.length - 1].VisitTaskNum
|
||||
this.minVistNum = this.visitTaskList[0].VisitTaskNum
|
||||
this.measureData = this.visitTaskList[idx].MeasureData
|
||||
const imageId = this.stack.imageIds[this.stack.currentImageIdIndex]
|
||||
var instanceId = imageId.split('/')[imageId.split('/').length - 1]
|
||||
var frame = null
|
||||
if (instanceId.includes('?frame=')) {
|
||||
frame = instanceId.split('?frame=')[1]
|
||||
instanceId = instanceId.split('?frame=')[0]
|
||||
}
|
||||
this.stack.frame = !isNaN(parseInt(frame)) ? parseInt(frame) : 0
|
||||
instanceId = instanceId.split('.')[0]
|
||||
const imageInfo = this.getInstanceInfo(imageId)
|
||||
var instanceId = imageInfo.instanceId
|
||||
var frame = imageInfo.frame
|
||||
this.stack.frame = this.stack.isExistMutiFrames ? parseInt(frame) : null
|
||||
this.stack.instanceId = instanceId
|
||||
const ToolStateManager = cornerstoneTools.globalImageIdSpecificToolStateManager
|
||||
ToolStateManager.clearImageIdToolState(dicomSeries.imageIds)
|
||||
if (this.toolState.clipPlaying) this.toggleClipPlay()
|
||||
this.toolState.viewportInvert = false
|
||||
this.toolState.dicomInfoVisible = false
|
||||
|
||||
const element = this.$refs.canvas
|
||||
cornerstone.enable(element)
|
||||
element.tabIndex = 0
|
||||
element.focus()
|
||||
const ToolStateManager = cornerstoneTools.globalImageIdSpecificToolStateManager
|
||||
ToolStateManager.clearImageIdToolState(dicomSeries.imageIds)
|
||||
this.toggleClipPlay(false)
|
||||
this.toolState.viewportInvert = false
|
||||
this.toolState.dicomInfoVisible = false
|
||||
var scope = this
|
||||
// var p = parseInt(new Date().getTime())
|
||||
// requestPoolManager.loadAndCacheImagePlus(this.stack.imageIds[this.stack.currentImageIdIndex], this.stack.seriesId, p*100).then(image=>{
|
||||
|
@ -1093,102 +1085,106 @@ export default {
|
|||
// }
|
||||
// resolve()
|
||||
// })
|
||||
this.loading = true
|
||||
cornerstone.loadAndCacheImage(this.stack.imageIds[this.stack.currentImageIdIndex])
|
||||
.then(image => {
|
||||
scope.onFirstImageLoaded(image)
|
||||
.then(async image => {
|
||||
if (this.stack.imageIds.indexOf(image.imageId) !== -1) {
|
||||
await scope.onFirstImageLoaded(image)
|
||||
}
|
||||
scope.loading = false
|
||||
resolve()
|
||||
})
|
||||
.catch((error) => {
|
||||
if (error.error && error.error.message) {
|
||||
this.$alert(error.error.message)
|
||||
}
|
||||
scope.loading = false
|
||||
resolve()
|
||||
})
|
||||
})
|
||||
},
|
||||
onFirstImageLoaded(image) {
|
||||
console.log('onFirstImageLoaded')
|
||||
return new Promise(async resolve => {
|
||||
const element = this.$refs.canvas
|
||||
var viewport = cornerstone.getDefaultViewportForImage(this.canvas, image)
|
||||
cornerstone.displayImage(this.canvas, image, viewport)
|
||||
|
||||
const element = this.$refs.canvas
|
||||
var viewport = cornerstone.getDefaultViewportForImage(this.canvas, image)
|
||||
cornerstone.displayImage(this.canvas, image, viewport)
|
||||
|
||||
if (!this.toolState.initialized) {
|
||||
this.toolState.initialized = true
|
||||
const toolButtons = document.querySelectorAll('[data-tool]')
|
||||
|
||||
// const scope = this
|
||||
Array.from(toolButtons).forEach((toolBtn) => {
|
||||
if (!this.toolState.initialized) {
|
||||
this.toolState.initialized = true
|
||||
const toolButtons = document.querySelectorAll('[data-tool]')
|
||||
// const scope = this
|
||||
Array.from(toolButtons).forEach((toolBtn) => {
|
||||
// Add the tool
|
||||
const toolName = toolBtn.getAttribute('data-tool')
|
||||
const apiTool = cornerstoneTools[`${toolName}Tool`]
|
||||
if (apiTool) {
|
||||
const toolAlreadyAddedToElement = cornerstoneTools.getToolForElement(element, apiTool)
|
||||
const toolName = toolBtn.getAttribute('data-tool')
|
||||
const apiTool = cornerstoneTools[`${toolName}Tool`]
|
||||
if (apiTool) {
|
||||
const toolAlreadyAddedToElement = cornerstoneTools.getToolForElement(element, apiTool)
|
||||
|
||||
if (!toolAlreadyAddedToElement) {
|
||||
if (toolName === 'Length') {
|
||||
cornerstoneTools.addToolForElement(element, LengthTool, { configuration: { handleRadius: false, drawHandlesOnHover: true, hideHandlesIfMoving: true, digits: this.digitPlaces, drawHandles: true }})
|
||||
} else if (toolName === 'Bidirectional') {
|
||||
if (!toolAlreadyAddedToElement) {
|
||||
if (toolName === 'Length') {
|
||||
cornerstoneTools.addToolForElement(element, LengthTool, { configuration: { handleRadius: false, drawHandlesOnHover: true, hideHandlesIfMoving: true, digits: this.digitPlaces, drawHandles: true }})
|
||||
} else if (toolName === 'Bidirectional') {
|
||||
// cornerstoneTools.addToolForElement(element, BidirectionalTool, { digits: this.digitPlaces })
|
||||
// , handleRadius: false, drawHandlesOnHover: true, hideHandlesIfMoving: true
|
||||
cornerstoneTools.addToolForElement(element, BidirectionalTool, { configuration: { digits: this.digitPlaces, hideHandlesIfMoving: true }})
|
||||
} else if (toolName === 'ArrowAnnotate') {
|
||||
cornerstoneTools.addToolForElement(element, ArrowAnnotateTool, { configuration: { allowEmptyLabel: true, handleRadius: false, drawHandlesOnHover: true, hideHandlesIfMoving: true }})
|
||||
} else if (toolName === 'RectangleRoi') {
|
||||
cornerstoneTools.addToolForElement(element, RectangleRoiTool, { configuration: { allowEmptyLabel: true, handleRadius: false, drawHandlesOnHover: true, hideHandlesIfMoving: true }})
|
||||
} else {
|
||||
cornerstoneTools.addToolForElement(element, apiTool)
|
||||
cornerstoneTools.addToolForElement(element, BidirectionalTool, { configuration: { digits: this.digitPlaces, hideHandlesIfMoving: true }})
|
||||
} else if (toolName === 'ArrowAnnotate') {
|
||||
cornerstoneTools.addToolForElement(element, ArrowAnnotateTool, { configuration: { allowEmptyLabel: true, handleRadius: false, drawHandlesOnHover: true, hideHandlesIfMoving: true }})
|
||||
} else if (toolName === 'RectangleRoi') {
|
||||
cornerstoneTools.addToolForElement(element, RectangleRoiTool, { configuration: { allowEmptyLabel: true, handleRadius: false, drawHandlesOnHover: true, hideHandlesIfMoving: true }})
|
||||
} else if (toolName === 'CircleRoi') {
|
||||
cornerstoneTools.addToolForElement(element, CircleRoiTool, { configuration: { handleRadius: false, drawHandlesOnHover: true, hideHandlesIfMoving: true, digits: this.digitPlaces, drawHandles: true, showMinMax: true }})
|
||||
} else {
|
||||
cornerstoneTools.addToolForElement(element, apiTool)
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
if (!cornerstoneTools.getToolForElement(element, cornerstoneTools.WwwcRegionTool)) {
|
||||
cornerstoneTools.addToolForElement(element, cornerstoneTools.WwwcRegionTool)
|
||||
}
|
||||
})
|
||||
if (!cornerstoneTools.getToolForElement(element, cornerstoneTools.WwwcRegionTool)) {
|
||||
cornerstoneTools.addToolForElement(element, cornerstoneTools.WwwcRegionTool)
|
||||
}
|
||||
if (!cornerstoneTools.getToolForElement(element, cornerstoneTools.StackScrollMouseWheelTool)) {
|
||||
cornerstoneTools.addToolForElement(element, cornerstoneTools.StackScrollMouseWheelTool)
|
||||
}
|
||||
cornerstoneTools.setToolActiveForElement(element, 'StackScrollMouseWheel', {})
|
||||
if (!cornerstoneTools.getToolForElement(element, cornerstoneTools.StackScrollMouseWheelTool)) {
|
||||
cornerstoneTools.addToolForElement(element, cornerstoneTools.StackScrollMouseWheelTool)
|
||||
}
|
||||
cornerstoneTools.setToolActiveForElement(element, 'StackScrollMouseWheel', {})
|
||||
|
||||
if (!cornerstoneTools.getToolForElement(element, ScaleOverlayTool)) {
|
||||
cornerstoneTools.addToolForElement(element, ScaleOverlayTool)
|
||||
}
|
||||
cornerstoneTools.setToolActiveForElement(element, 'ScaleOverlay', {})
|
||||
cornerstoneTools.setToolActiveForElement(this.canvas, 'Zoom', {
|
||||
mouseButtonMask: 2
|
||||
})
|
||||
cornerstoneTools.setToolActiveForElement(this.canvas, 'Pan', {
|
||||
mouseButtonMask: 4
|
||||
})
|
||||
if (!cornerstoneTools.getToolForElement(element, ScaleOverlayTool)) {
|
||||
cornerstoneTools.addToolForElement(element, ScaleOverlayTool)
|
||||
}
|
||||
cornerstoneTools.setToolActiveForElement(element, 'ScaleOverlay', {})
|
||||
cornerstoneTools.setToolActiveForElement(this.canvas, 'Zoom', {
|
||||
mouseButtonMask: 2
|
||||
})
|
||||
cornerstoneTools.setToolActiveForElement(this.canvas, 'Pan', {
|
||||
mouseButtonMask: 4
|
||||
})
|
||||
|
||||
// if (!cornerstoneTools.getToolForElement(element, OrientationMarkersTool)) {
|
||||
// cornerstoneTools.addToolForElement(element, OrientationMarkersTool)
|
||||
// }
|
||||
// cornerstoneTools.setToolActiveForElement(element, 'OrientationMarkers', { })
|
||||
}
|
||||
}
|
||||
|
||||
// cornerstoneTools.addStackStateManager(this.canvas, ['stack', 'stackPrefetch', 'playClip'])
|
||||
cornerstoneTools.addStackStateManager(this.canvas, ['stack', 'playClip'])
|
||||
cornerstoneTools.addToolState(this.canvas, 'stack', this.stack)
|
||||
// cornerstoneTools.stackPrefetch.enable(this.canvas)
|
||||
cornerstone.updateImage(element, true)
|
||||
// cornerstoneTools.addStackStateManager(this.canvas, ['stack', 'stackPrefetch', 'playClip'])
|
||||
cornerstoneTools.addStackStateManager(this.canvas, ['stack', 'playClip'])
|
||||
cornerstoneTools.addToolState(this.canvas, 'stack', this.stack)
|
||||
// cornerstoneTools.stackPrefetch.enable(this.canvas)
|
||||
cornerstone.updateImage(element, true)
|
||||
|
||||
this.stack.firstImageLoading = false
|
||||
this.toolState.dicomInfoVisible = true
|
||||
var instanceId = image.imageId.split('/')[image.imageId.split('/').length - 1]
|
||||
var frame = null
|
||||
if (instanceId.includes('?frame=')) {
|
||||
frame = instanceId.split('?frame=')[1]
|
||||
instanceId = instanceId.split('?frame=')[0]
|
||||
}
|
||||
this.stack.frame = !isNaN(parseInt(frame)) ? parseInt(frame) : 0
|
||||
instanceId = instanceId.split('.')[0]
|
||||
this.stack.instanceId = instanceId
|
||||
this.height = (this.stack.currentImageIdIndex) * 100 / (this.stack.imageIds.length - 1)
|
||||
this.resetWwwc()
|
||||
this.stack.firstImageLoading = false
|
||||
this.toolState.dicomInfoVisible = true
|
||||
const imageInfo = this.getInstanceInfo(image.imageId)
|
||||
var instanceId = imageInfo.instanceId
|
||||
var frame = imageInfo.frame
|
||||
this.stack.frame = this.stack.isExistMutiFrames ? parseInt(frame) : null
|
||||
this.stack.instanceId = instanceId
|
||||
this.height = (this.stack.currentImageIdIndex) * 100 / (this.stack.imageIds.length - 1)
|
||||
// this.resetWwwc()
|
||||
resolve()
|
||||
})
|
||||
},
|
||||
onNewImage(e) {
|
||||
console.log('cornerstonenewimage')
|
||||
// console.log('cornerstonenewimage')
|
||||
if (this.isCurrentTask && this.readingTaskState < 2) {
|
||||
this.resetHideMeasureArr()
|
||||
}
|
||||
|
@ -1225,6 +1221,12 @@ export default {
|
|||
if (this.dicomInfo.thick) {
|
||||
this.dicomInfo.thick = this.dicomInfo.thick.toFixed(2)
|
||||
}
|
||||
const newImageIdIndex = this.stack.imageIds.findIndex(i => i === imageId)
|
||||
if (newImageIdIndex === -1) return
|
||||
this.stack.currentImageIdIndex = newImageIdIndex
|
||||
this.stack.imageIdIndex = newImageIdIndex
|
||||
this.series.imageIdIndex = newImageIdIndex
|
||||
this.height = (this.stack.currentImageIdIndex) * 100 / (this.stack.imageIds.length - 1)
|
||||
},
|
||||
getScreenshots() {
|
||||
const canvas = this.canvas.querySelector('canvas')
|
||||
|
@ -1242,18 +1244,13 @@ export default {
|
|||
// console.log('onImageLoaded')
|
||||
},
|
||||
onImageRendered(e) {
|
||||
// console.log('onImageRendered')
|
||||
this.stack.imageRendered = true
|
||||
// const { element } = e.detail
|
||||
var imageId = e.detail.image.imageId
|
||||
var instanceId = imageId.split('/')[imageId.split('/').length - 1]
|
||||
var frame = null
|
||||
if (instanceId.includes('?frame=')) {
|
||||
frame = instanceId.split('?frame=')[1]
|
||||
instanceId = instanceId.split('?frame=')[0]
|
||||
}
|
||||
this.stack.frame = !isNaN(parseInt(frame)) ? parseInt(frame) : 0
|
||||
instanceId = instanceId.split('.')[0]
|
||||
const imageInfo = this.getInstanceInfo(imageId)
|
||||
var instanceId = imageInfo.instanceId
|
||||
var frame = imageInfo.frame
|
||||
this.stack.frame = this.stack.isExistMutiFrames ? parseInt(frame) : null
|
||||
if (this.imageId !== instanceId) {
|
||||
this.getOrientationMarker(e.detail.element)
|
||||
// 初次加载时,如果该影像存在标记,则以标记的窗宽窗位为初始化默认值,否则以序列的窗宽窗位为初始化默认值
|
||||
|
@ -1290,26 +1287,17 @@ export default {
|
|||
if (!imagePlane || !imagePlane.rowCosines || !imagePlane.columnCosines) {
|
||||
return
|
||||
}
|
||||
|
||||
const row = getOrientationString(imagePlane.rowCosines)
|
||||
const column = getOrientationString(imagePlane.columnCosines)
|
||||
const oppositeRow = invertOrientationString(row)
|
||||
const oppositeColumn = invertOrientationString(column)
|
||||
const markers = {
|
||||
top: oppositeColumn,
|
||||
bottom: column,
|
||||
left: oppositeRow,
|
||||
right: row
|
||||
}
|
||||
if (!markers) {
|
||||
return
|
||||
}
|
||||
|
||||
this.orientationMarkers = [oppositeColumn, row, column, oppositeRow]
|
||||
this.originalMarkers = [oppositeColumn, row, column, oppositeRow]
|
||||
this.setMarkers()
|
||||
},
|
||||
onMeasurementcompleted(e) {
|
||||
if (this.readingTaskState >= 2) return
|
||||
// if (this.readingTaskState >= 2) return
|
||||
|
||||
var element = cornerstone.getEnabledElement(this.canvas)
|
||||
var viewport = element.viewport
|
||||
|
@ -1318,15 +1306,11 @@ export default {
|
|||
this.activeTool = 1
|
||||
this.activeToolName = ''
|
||||
var { imageId } = element.image
|
||||
var instanceId = imageId.split('/')[imageId.split('/').length - 1]
|
||||
var frame = null
|
||||
if (instanceId.includes('?frame=')) {
|
||||
frame = instanceId.split('?frame=')[1]
|
||||
instanceId = instanceId.split('?frame=')[0]
|
||||
}
|
||||
const imageInfo = this.getInstanceInfo(imageId)
|
||||
var instanceId = imageInfo.instanceId
|
||||
var frame = imageInfo.frame
|
||||
this.stack.frame = !isNaN(parseInt(frame)) ? parseInt(frame) : 0
|
||||
instanceId = instanceId.split('.')[0]
|
||||
if (e.detail.toolName === 'Length' || e.detail.toolName === 'ArrowAnnotate' || e.detail.toolName === 'RectangleRoi') {
|
||||
if (e.detail.toolName === 'Length' || e.detail.toolName === 'ArrowAnnotate' || e.detail.toolName === 'RectangleRoi' || e.detail.toolName === 'CircleRoi') {
|
||||
const measureData = {}
|
||||
measureData.studyId = this.stack.studyId
|
||||
measureData.seriesId = this.stack.seriesId
|
||||
|
@ -1335,11 +1319,13 @@ export default {
|
|||
measureData.data = e.detail.measurementData
|
||||
measureData.type = e.detail.toolName
|
||||
measureData.thick = this.dicomInfo.thick
|
||||
measureData.location = this.dicomInfo.location
|
||||
measureData.ww = Math.round(viewport.voi.windowWidth)
|
||||
measureData.wc = Math.round(viewport.voi.windowCenter)
|
||||
|
||||
const canvas = this.canvas.querySelector('canvas')
|
||||
measureData.pictureBaseStr = canvas.toDataURL('image/png', 1)
|
||||
measureData.temporary = this.readingTaskState >= 2
|
||||
this.$emit('setMeasureData', measureData)
|
||||
cornerstoneTools.setToolPassiveForElement(this.canvas, e.detail.toolName)
|
||||
} else if (e.detail.toolName === 'Bidirectional') {
|
||||
|
@ -1351,10 +1337,12 @@ export default {
|
|||
measureData.data = e.detail.measurementData
|
||||
measureData.type = e.detail.toolName
|
||||
measureData.thick = this.dicomInfo.thick
|
||||
measureData.location = this.dicomInfo.location
|
||||
measureData.ww = Math.round(viewport.voi.windowWidth)
|
||||
measureData.wc = Math.round(viewport.voi.windowCenter)
|
||||
const canvas = this.canvas.querySelector('canvas')
|
||||
measureData.pictureBaseStr = canvas.toDataURL('image/png', 1)
|
||||
measureData.temporary = this.readingTaskState >= 2
|
||||
this.$emit('setMeasureData', measureData)
|
||||
cornerstoneTools.setToolPassiveForElement(this.canvas, e.detail.toolName)
|
||||
} else if (!e.detail.toolName) {
|
||||
|
@ -1402,9 +1390,9 @@ export default {
|
|||
var element = cornerstone.getEnabledElement(this.canvas)
|
||||
const { rowPixelSpacing, colPixelSpacing } = this.getPixelSpacing(element.image)
|
||||
const dx =
|
||||
(data.handles.end.x - data.handles.start.x) * (colPixelSpacing || 1)
|
||||
(data.handles.end.x - data.handles.start.x) * (colPixelSpacing || 1)
|
||||
const dy =
|
||||
(data.handles.end.y - data.handles.start.y) * (rowPixelSpacing || 1)
|
||||
(data.handles.end.y - data.handles.start.y) * (rowPixelSpacing || 1)
|
||||
const length = Math.sqrt(dx * dx + dy * dy)
|
||||
|
||||
return length.toFixed(this.digitPlaces)
|
||||
|
@ -1418,9 +1406,9 @@ export default {
|
|||
if (imagePlane) {
|
||||
return {
|
||||
rowPixelSpacing:
|
||||
imagePlane.rowPixelSpacing || imagePlane.rowImagePixelSpacing,
|
||||
imagePlane.rowPixelSpacing || imagePlane.rowImagePixelSpacing,
|
||||
colPixelSpacing:
|
||||
imagePlane.columnPixelSpacing || imagePlane.colImagePixelSpacing
|
||||
imagePlane.columnPixelSpacing || imagePlane.colImagePixelSpacing
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1430,30 +1418,27 @@ export default {
|
|||
}
|
||||
},
|
||||
onMeasurementremoved(e) {
|
||||
|
||||
console.log('================移除病灶=================', e)
|
||||
},
|
||||
onMeasurementmodified(e) {
|
||||
// 移动
|
||||
console.log('modified')
|
||||
if (this.readingTaskState >= 2) return
|
||||
// if (this.readingTaskState >= 2) return
|
||||
const { measurementData, toolType } = e.detail
|
||||
var element = cornerstone.getEnabledElement(this.canvas)
|
||||
var viewport = element.viewport
|
||||
var { imageId } = element.image
|
||||
var instanceId = imageId.split('/')[imageId.split('/').length - 1]
|
||||
var frame = null
|
||||
if (instanceId.includes('?frame=')) {
|
||||
frame = instanceId.split('?frame=')[1]
|
||||
instanceId = instanceId.split('?frame=')[0]
|
||||
}
|
||||
this.stack.frame = !isNaN(parseInt(frame)) ? parseInt(frame) : 0
|
||||
instanceId = instanceId.split('.')[0]
|
||||
const imageInfo = this.getInstanceInfo(imageId)
|
||||
var instanceId = imageInfo.instanceId
|
||||
var frame = imageInfo.frame
|
||||
this.stack.frame = this.stack.isExistMutiFrames ? parseInt(frame) : null
|
||||
|
||||
var uuid = measurementData.uuid
|
||||
var idx = this.measureData.findIndex(item => item.MeasureData && item.MeasureData.data && item.MeasureData.data.uuid === uuid)
|
||||
if (idx > -1) {
|
||||
const measureData = {}
|
||||
var markName = this.measureData[idx].OrderMarkName
|
||||
// var markName = this.measureData[idx].OrderMarkName
|
||||
var markName = this.measureData[idx].MeasureData.data.remark
|
||||
if (this.disabledMarks.indexOf(markName) === -1 || !this.disabledMarks) {
|
||||
var questionInfo = this.measureData[idx]
|
||||
const canvas = this.canvas.querySelector('canvas')
|
||||
|
@ -1465,6 +1450,7 @@ export default {
|
|||
measureData.data = measurementData
|
||||
measureData.type = toolType
|
||||
measureData.thick = this.dicomInfo.thick
|
||||
measureData.location = this.dicomInfo.location
|
||||
measureData.ww = Math.round(viewport.voi.windowWidth)
|
||||
measureData.wc = Math.round(viewport.voi.windowCenter)
|
||||
measureData.data.active = false
|
||||
|
@ -1482,15 +1468,21 @@ export default {
|
|||
}
|
||||
},
|
||||
updateImage(instanceId) {
|
||||
if (!this.canvas) return
|
||||
var i = this.visitTaskList.findIndex(i => i.VisitTaskId === this.stack.visitTaskId)
|
||||
this.measureData = this.visitTaskList[i].MeasureData
|
||||
|
||||
const ToolStateManager = cornerstoneTools.globalImageIdSpecificToolStateManager
|
||||
|
||||
var element = cornerstone.getEnabledElement(this.canvas)
|
||||
if (!element) return
|
||||
var { imageId } = element.image
|
||||
ToolStateManager.clearImageIdToolState(imageId)
|
||||
cornerstone.updateImage(element, true)
|
||||
if (imageId) {
|
||||
ToolStateManager.clearImageIdToolState(imageId)
|
||||
let elements = cornerstone.getEnabledElementsByImageId(imageId)
|
||||
elements.map(el=>{
|
||||
cornerstone.updateImage(el.element)
|
||||
})
|
||||
}
|
||||
// cornerstone.updateImage(element)
|
||||
},
|
||||
toggleSeries(evt, type) {
|
||||
evt.stopImmediatePropagation()
|
||||
|
@ -1504,11 +1496,8 @@ export default {
|
|||
// 判断有没有标记 获取第一个标记
|
||||
var element = cornerstone.getEnabledElement(this.canvas)
|
||||
var { imageId } = element.image
|
||||
var instanceId = imageId.split('/')[imageId.split('/').length - 1]
|
||||
if (instanceId.includes('?frame=')) {
|
||||
instanceId = instanceId.split('?frame=')[0]
|
||||
}
|
||||
instanceId = instanceId.split('.')[0]
|
||||
const imageInfo = this.getInstanceInfo(imageId)
|
||||
var instanceId = imageInfo.instanceId
|
||||
var idx = this.measureData.findIndex(item => item.InstanceId === instanceId)
|
||||
var measureData = null
|
||||
if (idx > -1) {
|
||||
|
@ -1626,18 +1615,19 @@ export default {
|
|||
}
|
||||
},
|
||||
|
||||
toggleClipPlay() {
|
||||
if (this.toolState.clipPlaying) {
|
||||
toggleClipPlay(isPlay) {
|
||||
if (isPlay) {
|
||||
this.toolState.clipPlaying = true
|
||||
cornerstoneTools.playClip(this.canvas, this.dicomInfo.fps)
|
||||
cornerstoneTools.getToolState(
|
||||
this.canvas,
|
||||
'playClip'
|
||||
).data[0].loop = false
|
||||
} else {
|
||||
cornerstoneTools.stopClip(this.canvas)
|
||||
this.toolState.clipPlaying = false
|
||||
return
|
||||
}
|
||||
this.toolState.clipPlaying = true
|
||||
cornerstoneTools.playClip(this.canvas, this.dicomInfo.fps)
|
||||
cornerstoneTools.getToolState(
|
||||
this.canvas,
|
||||
'playClip'
|
||||
).data[0].loop = false
|
||||
},
|
||||
setFps(fps) {
|
||||
this.dicomInfo.fps = fps
|
||||
|
@ -1646,7 +1636,7 @@ export default {
|
|||
resetWwwc() {
|
||||
this.toolState.viewportInvert = false
|
||||
var viewport = cornerstone.getViewport(this.canvas)
|
||||
viewport.invert = false
|
||||
// viewport.invert = false
|
||||
var image = cornerstone.getImage(this.canvas)
|
||||
viewport.voi.windowWidth = image.windowWidth
|
||||
viewport.voi.windowCenter = image.windowCenter
|
||||
|
@ -1774,20 +1764,19 @@ export default {
|
|||
this.activeToolName = toolName
|
||||
this.$nextTick(() => {
|
||||
// console.log(cornerstoneTools.isToolActiveForElement(this.canvas, 'Bidirectional'))
|
||||
if (!cornerstoneTools.isToolActiveForElement(this.canvas, toolName)) {
|
||||
cornerstoneTools.setToolActiveForElement(this.canvas, toolName, {
|
||||
mouseButtonMask: 1
|
||||
})
|
||||
}
|
||||
|
||||
if (toolName === 'Zoom') {
|
||||
cornerstoneTools.setToolActiveForElement(this.canvas, 'Zoom', {
|
||||
mouseButtonMask: [1, 2]
|
||||
})
|
||||
}
|
||||
if (toolName === 'Pan') {
|
||||
} else if (toolName === 'Pan') {
|
||||
cornerstoneTools.setToolActiveForElement(this.canvas, 'Pan', {
|
||||
mouseButtonMask: [1, 4]
|
||||
})
|
||||
} else {
|
||||
cornerstoneTools.setToolActiveForElement(this.canvas, toolName, {
|
||||
mouseButtonMask: 1
|
||||
})
|
||||
}
|
||||
})
|
||||
},
|
||||
|
@ -1923,6 +1912,17 @@ export default {
|
|||
}
|
||||
}
|
||||
},
|
||||
getInstanceInfo(imageId) {
|
||||
const params = {}
|
||||
const searchParams = new URLSearchParams(imageId.split('?')[1])
|
||||
for (const [key, value] of searchParams.entries()) {
|
||||
params[key] = value
|
||||
}
|
||||
if (isNaN(params.frame)){
|
||||
params.frame = 0
|
||||
}
|
||||
return params
|
||||
},
|
||||
preventDefault(e) {
|
||||
e.stopImmediatePropagation()
|
||||
e.stopPropagation()
|
||||
|
@ -1940,87 +1940,87 @@ export default {
|
|||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.context-menu-wrapper{
|
||||
position: absolute;
|
||||
ul{
|
||||
list-style: none;
|
||||
margin: 0px;
|
||||
padding: 0px;
|
||||
background: #343333;
|
||||
color: #fff;
|
||||
margin: 0;
|
||||
border: 1px solid #2a2a2a;
|
||||
border-radius: 3px;
|
||||
height: auto;
|
||||
min-height: 50px;
|
||||
line-height: 1.5em;
|
||||
width:80px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
.menu{
|
||||
li {
|
||||
padding: 2px 5px;
|
||||
position: relative;
|
||||
border-bottom: 1px solid #666;
|
||||
div{
|
||||
padding: 5px;
|
||||
}
|
||||
}
|
||||
.submenu{
|
||||
position: absolute;
|
||||
left: 77px;
|
||||
top: -1px;
|
||||
.context-menu-wrapper{
|
||||
position: absolute;
|
||||
ul{
|
||||
list-style: none;
|
||||
margin: 0px;
|
||||
padding: 0px;
|
||||
background: #343333;
|
||||
color: #fff;
|
||||
display: none;
|
||||
margin: 0;
|
||||
border: 1px solid #2a2a2a;
|
||||
border-radius: 3px;
|
||||
height: auto;
|
||||
min-height: 50px;
|
||||
line-height: 1.5em;
|
||||
width:80px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
.menu{
|
||||
li {
|
||||
padding: 2px 5px;
|
||||
position: relative;
|
||||
border-bottom: 1px solid #666;
|
||||
div{
|
||||
padding: 5px;
|
||||
}
|
||||
}
|
||||
.submenu{
|
||||
position: absolute;
|
||||
left: 77px;
|
||||
top: -1px;
|
||||
background: #343333;
|
||||
color: #fff;
|
||||
display: none;
|
||||
li {
|
||||
padding: 2px 5px;
|
||||
border-bottom: 1px solid #666;
|
||||
div{
|
||||
padding: 5px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
.menu li:hover{
|
||||
background-color: #ff5722;
|
||||
.submenu{
|
||||
display:block;
|
||||
}
|
||||
}
|
||||
.menu_active{
|
||||
cursor: pointer;
|
||||
}
|
||||
.menu_disabled{
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
}
|
||||
.menu li:hover{
|
||||
background-color: #ff5722;
|
||||
.submenu{
|
||||
display:block;
|
||||
.info-visit{
|
||||
position: absolute;
|
||||
left:50%;
|
||||
top: 5px;
|
||||
transform: translateX(-50%);
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
.arrw_div_wrapper{
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
background-color: #3f3f3f;
|
||||
text-align: center;
|
||||
line-height: 20px;
|
||||
border-radius: 10%;
|
||||
}
|
||||
.blind_name_wrapper{
|
||||
height: 20px;
|
||||
line-height: 20px;
|
||||
background-color: #00000057;
|
||||
color: #fff;
|
||||
padding:0 10px;
|
||||
font-size: 14px;
|
||||
}
|
||||
}
|
||||
.menu_active{
|
||||
cursor: pointer;
|
||||
}
|
||||
.menu_disabled{
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
}
|
||||
.info-visit{
|
||||
position: absolute;
|
||||
left:50%;
|
||||
top: 5px;
|
||||
transform: translateX(-50%);
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
.arrw_div_wrapper{
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
background-color: #3f3f3f;
|
||||
text-align: center;
|
||||
line-height: 20px;
|
||||
border-radius: 10%;
|
||||
}
|
||||
.blind_name_wrapper{
|
||||
height: 20px;
|
||||
line-height: 20px;
|
||||
background-color: #00000057;
|
||||
color: #fff;
|
||||
padding:0 10px;
|
||||
font-size: 14px;
|
||||
}
|
||||
}
|
||||
.info-cd{
|
||||
position: absolute;
|
||||
left: 10px;
|
||||
|
@ -2110,10 +2110,10 @@ li:hover {
|
|||
color: white;
|
||||
}
|
||||
.msg-div {
|
||||
position: absolute;
|
||||
z-index: 10;
|
||||
background-color: rgba(255, 255, 255, 0.5);
|
||||
color: #000;
|
||||
padding: 5px 20px;
|
||||
}
|
||||
position: absolute;
|
||||
z-index: 10;
|
||||
background-color: rgba(255, 255, 255, 0.5);
|
||||
color: #000;
|
||||
padding: 5px 20px;
|
||||
}
|
||||
</style>
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -2,22 +2,37 @@
|
|||
<div class="measurement-wrapper" :style="{'height':height+10+'px'}" style="position: relative">
|
||||
|
||||
<div class="container" :style="{'height':height+'px'}" style="padding-bottom: 50px;overflow-y: auto;">
|
||||
<h3 style="color: #ddd;padding: 5px 0px;margin: 0;" v-if="isReadingShowSubjectInfo">
|
||||
<span v-if="subjectCode">{{ subjectCode }} </span>
|
||||
<span style="margin-left:5px;">{{ taskBlindName }}</span>
|
||||
</h3>
|
||||
<div class="basic-info">
|
||||
<div v-if="readingTaskState < 2">
|
||||
<el-tooltip class="item" effect="dark" :content="$t('trials:dicomReading:message:confirmReset')" placement="bottom">
|
||||
<i
|
||||
class="el-icon-refresh-left"
|
||||
@click="resetMeasuredData"
|
||||
/>
|
||||
</el-tooltip>
|
||||
</div>
|
||||
<h3 v-if="isReadingShowSubjectInfo">
|
||||
<span v-if="subjectCode">{{ subjectCode }} </span>
|
||||
<span style="margin-left:5px;">{{ taskBlindName }}</span>
|
||||
</h3>
|
||||
</div>
|
||||
<QuestionsPreview
|
||||
ref="QuestionsPreview"
|
||||
v-if="ecrfShow"
|
||||
v-if="ecrfShow && TrialReadingCriterionId"
|
||||
:visitTaskId="visitTaskId"
|
||||
:criterionId="TrialReadingCriterionId">
|
||||
</QuestionsPreview>
|
||||
</div>
|
||||
<div style="position: absolute;bottom:0;left: 0;z-index: 10;background: #000;width: 100%;display: flex;justify-content: right;align-items: center;height: 50px">
|
||||
<el-button size="mini" v-if="readingTaskState<2" style="margin-right: 10px" @click="handleSave(true)">
|
||||
<div class="questions-footer">
|
||||
<!-- <i class="el-icon-question feedback-icon" @click="openFeedBackTable" /> -->
|
||||
<el-button v-if="readingTaskState<2" style="margin-right: 10px" type="primary" size="small" @click="handleSave(true)">
|
||||
{{$t('common:button:save')}}
|
||||
</el-button>
|
||||
<el-button size="mini" style="margin-right: 10px" v-if="readingTaskState<2 && IseCRFShowInDicomReading" @click="handleConfirm">
|
||||
<el-button v-if="readingTaskState<2 && IseCRFShowInDicomReading" type="primary" style="margin-right: 10px" size="small" @click="skipTask">
|
||||
<!-- 跳过 -->
|
||||
{{ $t('trials:readingReport:button:skip') }}
|
||||
</el-button>
|
||||
<el-button style="margin-right: 10px" type="primary" size="small" v-if="readingTaskState<2 && IseCRFShowInDicomReading" @click="handleConfirm">
|
||||
{{ $t('common:button:submit') }}</el-button>
|
||||
</div>
|
||||
<!-- 签名框 -->
|
||||
|
@ -77,7 +92,8 @@
|
|||
</template>
|
||||
<script>
|
||||
import { submitDicomVisitTask } from '@/api/trials'
|
||||
import { getCustomTag, submitCustomTag, deleteCustomTag } from '@/api/reading'
|
||||
import { getCustomTag, submitCustomTag, resetReadingTask } from '@/api/reading'
|
||||
import { setSkipReadingCache } from '@/api/reading'
|
||||
import DicomEvent from './../components/DicomEvent'
|
||||
import SignForm from '@/views/trials/components/newSignForm'
|
||||
import QuestionsPreview from './CustomizeQuestionsPreview'
|
||||
|
@ -144,7 +160,8 @@ export default {
|
|||
}
|
||||
},
|
||||
mounted() {
|
||||
this.subjectCode = this.$router.currentRoute.query.subjectCode
|
||||
// this.subjectCode = this.$router.currentRoute.query.subjectCode
|
||||
this.subjectCode = localStorage.getItem('subjectCode')
|
||||
this.CriterionType = parseInt(localStorage.getItem('CriterionType'))
|
||||
this.TrialReadingCriterionId = this.$router.currentRoute.query.TrialReadingCriterionId
|
||||
DicomEvent.$on('getCustomTableQuestionAnswer', (visitTaskId) => {
|
||||
|
@ -168,7 +185,6 @@ export default {
|
|||
methods: {
|
||||
async initList(){
|
||||
if (this.visitTaskId !== this.lastCanvasTaskId) {
|
||||
this.activeName = ''
|
||||
this.ecrfShow = true
|
||||
var i = this.visitTaskList.findIndex(i => i.VisitTaskId === this.lastCanvasTaskId)
|
||||
console.log(i)
|
||||
|
@ -216,19 +232,26 @@ export default {
|
|||
this.measureData = measureData
|
||||
},
|
||||
modifyMeasuredData(measureData) {
|
||||
console.log(measureData)
|
||||
measureData.visitTaskId = this.visitTaskId
|
||||
measureData.measureData.pictureBaseStr = ''
|
||||
let params = JSON.parse(JSON.stringify(measureData))
|
||||
params.measureData = JSON.stringify(measureData.measureData)
|
||||
params.Id = params.questionInfo.Id
|
||||
params.StudyId = params.questionInfo.StudyId
|
||||
params.SeriesId = params.questionInfo.SeriesId
|
||||
params.InstanceId = params.questionInfo.InstanceId
|
||||
submitCustomTag(params).then(() => {
|
||||
if (this.readingTaskState >=2) {
|
||||
this.measuredDataVisible = false
|
||||
DicomEvent.$emit('updateImage')
|
||||
})
|
||||
store.dispatch('reading/addCustomizeMeasuredData', { visitTaskId: this.visitTaskId, measureData: measureData.measureData })
|
||||
}else{
|
||||
let params = JSON.parse(JSON.stringify(measureData))
|
||||
params.measureData = JSON.stringify(measureData.measureData)
|
||||
params.Id = params.questionInfo.Id
|
||||
params.StudyId = params.questionInfo.StudyId
|
||||
params.SeriesId = params.questionInfo.SeriesId
|
||||
params.InstanceId = params.questionInfo.InstanceId
|
||||
params.NumberOfFrames = measureData.frame
|
||||
submitCustomTag(params).then(() => {
|
||||
this.measuredDataVisible = false
|
||||
DicomEvent.$emit('updateImage')
|
||||
// this.$message.success(this.$t('common:message:savedSuccessfully'))
|
||||
})
|
||||
}
|
||||
|
||||
},
|
||||
async moveMeasureData(measureData) {
|
||||
console.log('measureData', measureData)
|
||||
|
@ -237,24 +260,47 @@ export default {
|
|||
},
|
||||
handleMeasuredDataCancel() {
|
||||
this.measuredDataVisible = false
|
||||
// DicomEvent.$emit('updateImage')
|
||||
},
|
||||
handleMeasuredDataSave() {
|
||||
this.$refs.measuredDataForm.validate(valid => {
|
||||
if (!valid) return
|
||||
// 是否同名验证
|
||||
let isValid = this.validateRemarkName(this.form.measuredDataName)
|
||||
if (!isValid) {
|
||||
// '存在同名标记,不允许保存!'
|
||||
this.$message.error(this.$t('trials:customReading:error:validMarkName'))
|
||||
return
|
||||
}
|
||||
this.measureData.data.remark = this.form.measuredDataName
|
||||
this.measureData.pictureBaseStr = ''
|
||||
let params = JSON.parse(JSON.stringify(this.measureData))
|
||||
params.measureData = JSON.stringify(this.measureData)
|
||||
submitCustomTag(params).then(async (res) => {
|
||||
this.measuredDataVisible = false
|
||||
this.form.measuredDataName = ''
|
||||
this.measureData.Id = res.Result
|
||||
await store.dispatch('reading/addCustomizeMeasuredData', { visitTaskId: this.visitTaskId, ...this.measureData })
|
||||
await store.dispatch('reading/getCustomizeMeasuredData', this.visitTaskId)
|
||||
DicomEvent.$emit('updateImage')
|
||||
})
|
||||
if (this.readingTaskState >=2) {
|
||||
this.measuredDataVisible = false
|
||||
this.form.measuredDataName = ''
|
||||
store.dispatch('reading/addCustomizeMeasuredData', { visitTaskId: this.visitTaskId, measureData: this.measureData })
|
||||
DicomEvent.$emit('updateImage')
|
||||
this.$message.success(this.$t('common:message:savedSuccessfully'))
|
||||
} else {
|
||||
let params = JSON.parse(JSON.stringify(this.measureData))
|
||||
params.measureData = JSON.stringify(this.measureData)
|
||||
params.NumberOfFrames = this.measureData.frame
|
||||
submitCustomTag(params).then(async (res) => {
|
||||
this.measuredDataVisible = false
|
||||
this.form.measuredDataName = ''
|
||||
await store.dispatch('reading/addCustomizeMeasuredData', { visitTaskId: this.visitTaskId, measureData: this.measureData, id: res.Result })
|
||||
await store.dispatch('reading/getCustomizeMeasuredData', this.visitTaskId)
|
||||
DicomEvent.$emit('updateImage')
|
||||
this.$message.success(this.$t('common:message:savedSuccessfully'))
|
||||
})
|
||||
}
|
||||
})
|
||||
},
|
||||
validateRemarkName(remark) {
|
||||
var idx = this.visitTaskList.findIndex(i => i.VisitTaskId === this.visitTaskId)
|
||||
var measureData = this.visitTaskList[idx].MeasureData
|
||||
let i = measureData.findIndex(i=>i.MeasureData.data.remark === remark)
|
||||
return i === -1
|
||||
},
|
||||
// 关闭签名框
|
||||
closeSignDialog(isSign, signInfo) {
|
||||
if (isSign) {
|
||||
|
@ -291,7 +337,7 @@ export default {
|
|||
distinguishCancelAndClose: true
|
||||
})
|
||||
.then(() => {
|
||||
try {DicomEvent.$emit('getNextTask')} catch (e) {console.log(e)}
|
||||
window.location.reload()
|
||||
})
|
||||
.catch(action => {
|
||||
})
|
||||
|
@ -325,9 +371,87 @@ export default {
|
|||
if (this.visitTaskId !== obj.visitTaskId) {
|
||||
this.visitTaskId = obj.visitTaskId
|
||||
this.taskBlindName = obj.taskBlindName
|
||||
this.activeName = ''
|
||||
this.ecrfShow = true
|
||||
}
|
||||
},
|
||||
async resetMeasuredData() {
|
||||
const confirm = await this.$confirm(
|
||||
this.$t('trials:dicomReading:message:confirmReset1'),
|
||||
this.$t('trials:dicomReading:message:confirmReset2'),
|
||||
{
|
||||
type: 'warning',
|
||||
distinguishCancelAndClose: true
|
||||
}
|
||||
)
|
||||
if (confirm !== 'confirm') return
|
||||
const loading = this.$loading({ fullscreen: true })
|
||||
try {
|
||||
const res = await resetReadingTask({ visitTaskId: this.visitTaskId })
|
||||
this.loading = false
|
||||
if (res.IsSuccess) {
|
||||
// 刷新标注、表单、报告页信息
|
||||
this.$refs['QuestionsPreview'].getCustomTableQuestionAnswer(this.visitTaskId )
|
||||
await store.dispatch('reading/refreshCustomizeMeasuredData', this.visitTaskId)
|
||||
DicomEvent.$emit('getMeasureData')
|
||||
DicomEvent.$emit('getReportInfo', true)
|
||||
DicomEvent.$emit('refreshStudyListMeasureData')
|
||||
}
|
||||
loading.close()
|
||||
} catch (e) {
|
||||
loading.close()
|
||||
console.log(e)
|
||||
}
|
||||
},
|
||||
async skipTask() {
|
||||
try {
|
||||
// 是否确认跳过?
|
||||
const confirm = await this.$confirm(
|
||||
this.$t('trials:readingReport:message:skipConfirm'),
|
||||
{
|
||||
type: 'warning',
|
||||
distinguishCancelAndClose: true
|
||||
}
|
||||
)
|
||||
if (confirm !== 'confirm') return
|
||||
this.loading = true
|
||||
const res = await setSkipReadingCache({ visitTaskId: this.visitTaskId })
|
||||
this.loading = false
|
||||
if (res.IsSuccess) {
|
||||
window.location.reload()
|
||||
}
|
||||
} catch (e) {
|
||||
this.loading = false
|
||||
console.log(e)
|
||||
}
|
||||
},
|
||||
openFeedBackTable() {
|
||||
this.$FB({
|
||||
type: 'imgfail',
|
||||
trialId: this.$route.query.trialId,
|
||||
visitTaskId: this.visitTaskId,
|
||||
callBack: async() => {
|
||||
console.log('callBack')
|
||||
const confirm = await this.$confirm(
|
||||
this.$t('trials:reading:confirm:feedbackmsg'),
|
||||
{
|
||||
type: 'warning',
|
||||
distinguishCancelAndClose: true
|
||||
}
|
||||
)
|
||||
if (confirm !== 'confirm') return
|
||||
this.loading = true
|
||||
try {
|
||||
const res = await setSkipReadingCache({ visitTaskId: this.visitTaskId })
|
||||
this.loading = false
|
||||
if (res.IsSuccess) {
|
||||
window.location.reload()
|
||||
}
|
||||
} catch (e) {
|
||||
this.loading = false
|
||||
console.log(e)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -339,6 +463,23 @@ export default {
|
|||
|
||||
.container{
|
||||
padding: 10px;
|
||||
.basic-info{
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
flex-direction: row-reverse;
|
||||
h3{
|
||||
color: #ddd;
|
||||
padding: 5px 0px;
|
||||
margin: 0;
|
||||
}
|
||||
i{
|
||||
color: #fff;
|
||||
font-size: 22px;
|
||||
font-weight: bold;
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
}
|
||||
.title{
|
||||
padding: 5px;
|
||||
|
@ -403,5 +544,27 @@ export default {
|
|||
}
|
||||
|
||||
}
|
||||
.questions-footer{
|
||||
position: absolute;
|
||||
bottom:0;
|
||||
left: 0;
|
||||
z-index: 10;
|
||||
background: #000;
|
||||
width: 100%;
|
||||
display: flex;
|
||||
justify-content: right;
|
||||
align-items: center;
|
||||
height: 50px;
|
||||
.feedback-icon{
|
||||
padding: 0 10px;
|
||||
color: #fff;
|
||||
font-weight: 400;
|
||||
font-size: 24px;
|
||||
cursor: pointer;
|
||||
&:hover{
|
||||
color: #68a2d5;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
{{ question.GroupName }}
|
||||
</div>
|
||||
<div
|
||||
v-if=" question.Type==='table'"
|
||||
v-if="question.Type==='table' || question.Type==='basicTable'"
|
||||
style="font-weight: bold;font-size: 14px;margin: 5px 0px;"
|
||||
>
|
||||
<div style="display: flex;justify-content: space-between;align-items: center;color:#fff;margin: 10px 0 5px">
|
||||
|
@ -33,7 +33,7 @@
|
|||
>
|
||||
<template slot-scope="scope">
|
||||
<span v-if="item.Type === 'upload'">
|
||||
{{scope.row[item.Id] === '' ? '' : scope.row[item.Id].split('|').length}}
|
||||
{{scope.row[item.Id] === '' ? '' : scope.row[item.Id] ? scope.row[item.Id].split('|').length : ''}}
|
||||
</span>
|
||||
<span v-else-if="item.Type === 'number'">
|
||||
{{scope.row[item.Id] ? parseFloat(scope.row[item.Id]).toFixed(digitPlaces) : null}}
|
||||
|
@ -67,7 +67,7 @@
|
|||
:label="`${question.QuestionName}`"
|
||||
:prop="question.Id"
|
||||
:rules="[
|
||||
{ required: (question.IsRequired === 0 || (question.IsRequired ===1 && question.RelevanceId && (question.RelevanceValueList.includes(questionForm[question.RelevanceId])))) && question.Type!=='group' && question.Type!=='summary',
|
||||
{ required: (question.IsRequired === 0 || (question.IsRequired ===1 && question.RelevanceId && (question.RelevanceValueList.includes(isNaN(parseFloat(questionForm[question.RelevanceId])) ? questionForm[question.RelevanceId] : questionForm[question.RelevanceId].toString())))) && question.Type!=='group' && question.Type!=='summary',
|
||||
message: $t('common:ruleMessage:specify'), trigger: ['blur', 'change']},
|
||||
]"
|
||||
:class="[question.Type==='group'?'mb':question.Type==='upload'?'uploadWrapper':'']"
|
||||
|
@ -120,9 +120,9 @@
|
|||
<template v-else>
|
||||
<el-option
|
||||
v-for="val in question.TypeValue.split('|')"
|
||||
:key="val"
|
||||
:label="val"
|
||||
:value="val"
|
||||
:key="val.trim()"
|
||||
:label="val.trim()"
|
||||
:value="val.trim()"
|
||||
/>
|
||||
</template>
|
||||
|
||||
|
@ -135,10 +135,10 @@
|
|||
>
|
||||
<el-radio
|
||||
v-for="val in question.TypeValue.split('|')"
|
||||
:key="val"
|
||||
:label="val"
|
||||
:key="val.trim()"
|
||||
:label="val.trim()"
|
||||
>
|
||||
{{ val }}
|
||||
{{ val.trim() }}
|
||||
</el-radio>
|
||||
</el-radio-group>
|
||||
<!-- 复选框 -->
|
||||
|
@ -149,16 +149,50 @@
|
|||
<el-checkbox
|
||||
v-for="val in question.TypeValue.split('|')"
|
||||
:key="val"
|
||||
:label="val"
|
||||
:label="val.trim()"
|
||||
>
|
||||
{{ val }}
|
||||
{{ val.trim() }}
|
||||
</el-checkbox>
|
||||
</el-checkbox-group>
|
||||
<!-- 自动分类 -->
|
||||
<el-input
|
||||
v-if="question.Type === 'class'"
|
||||
v-if="question.Type === 'class' && question.ClassifyShowType === 1"
|
||||
v-model="questionForm[question.Id]"
|
||||
disabled
|
||||
:disabled="!question.ClassifyEditType"
|
||||
/>
|
||||
<el-select
|
||||
v-if="question.Type === 'class' && question.ClassifyShowType === 2"
|
||||
v-model="questionForm[question.Id]"
|
||||
:disabled="!question.ClassifyEditType"
|
||||
@change="(val) => { formItemChange(val, question) }"
|
||||
>
|
||||
<el-option
|
||||
v-for="val in question.TypeValue.split('|')"
|
||||
:key="val"
|
||||
:label="val.trim()"
|
||||
:value="val.trim()"
|
||||
/>
|
||||
</el-select>
|
||||
<el-radio-group
|
||||
v-if="question.Type === 'class' && question.ClassifyShowType === 3"
|
||||
v-model="questionForm[question.Id]"
|
||||
:disabled="!question.ClassifyEditType"
|
||||
@change="(val) => { formItemChange(val, question) }"
|
||||
>
|
||||
<el-radio
|
||||
v-for="item of question.TypeValue.split('|')"
|
||||
:key="item.trim()"
|
||||
:label="item.trim()"
|
||||
>
|
||||
{{ item.trim() }}
|
||||
</el-radio>
|
||||
</el-radio-group>
|
||||
<el-input
|
||||
v-if="question.Type === 'class' && question.ClassifyShowType === 4"
|
||||
type="number"
|
||||
:disabled="!question.ClassifyEditType"
|
||||
v-model="questionForm[question.Id]"
|
||||
@change="(val) => { formItemNumberChange(val, question) }"
|
||||
/>
|
||||
<!-- 自动计算 -->
|
||||
<!-- :precision="2" :step="0.1" :max="10" -->
|
||||
|
@ -176,12 +210,24 @@
|
|||
/>
|
||||
<!-- 数值 -->
|
||||
<!-- :precision="2" :step="0.1" :max="10" -->
|
||||
|
||||
<el-select
|
||||
v-if="question.Type === 'number' && question.TypeValue"
|
||||
v-model="questionForm[question.Id]"
|
||||
clearable
|
||||
@change="(val) => { formItemNumberChange(val, question) }"
|
||||
>
|
||||
<el-option
|
||||
v-for="val in question.TypeValue.split('|')"
|
||||
:key="val"
|
||||
:label="val.trim()"
|
||||
:value="val.trim()"
|
||||
/>
|
||||
</el-select>
|
||||
<el-input
|
||||
type="number"
|
||||
v-if="question.Type === 'number' && question.DataSource !== 1"
|
||||
@change="((val)=>{formItemNumberChange(val, question)})"
|
||||
onblur="value=parseFloat(value).toFixed(parseInt(localStorage.getItem('digitPlaces')));console.log(localStorage.getItem('digitPlaces'))"
|
||||
@change="(val) => { formItemNumberChange(val, question) }"
|
||||
onblur="value=parseFloat(value).toFixed(parseInt(localStorage.getItem('digitPlaces')));"
|
||||
@input="limitInput($event, questionForm, question.Id)"
|
||||
v-model="questionForm[question.Id]"
|
||||
>
|
||||
|
@ -191,7 +237,7 @@
|
|||
<el-input
|
||||
type="number"
|
||||
v-if="question.Type === 'number' && question.DataSource === 1"
|
||||
onblur="value=parseFloat(value).toFixed(parseInt(localStorage.getItem('digitPlaces')));console.log(localStorage.getItem('digitPlaces'))"
|
||||
onblur="value=parseFloat(value).toFixed(parseInt(localStorage.getItem('digitPlaces')));"
|
||||
@input="limitInput($event, questionForm, question.Id)"
|
||||
:disabled="question.DataSource === 1"
|
||||
v-model="questionForm[question.Id]"
|
||||
|
@ -202,59 +248,37 @@
|
|||
<!-- 上传图像 -->
|
||||
<el-upload
|
||||
v-if="question.Type==='upload'"
|
||||
:action="question.FileType"
|
||||
:limit="question.ImageCount"
|
||||
action
|
||||
:accept="question.FileType"
|
||||
:limit="question.ImageCount === 0 ? 100 : question.ImageCount"
|
||||
:on-preview="handlePictureCardPreview"
|
||||
:before-upload="(file) => {return handleBeforeUpload(file, question.FileType)}"
|
||||
:http-request="uploadScreenshot"
|
||||
:on-remove="handleRemove"
|
||||
:file-list="fileList"
|
||||
:class="{disabled:fileList.length >= question.ImageCount}"
|
||||
:class="{disabled:question.ImageCount === 0 ? false : fileList.length >= question.ImageCount}"
|
||||
>
|
||||
<el-button slot="default" class="el-icon-plus">
|
||||
{{this.$t('common:button:upload')}}
|
||||
</el-button>
|
||||
<!-- <div slot="file" slot-scope="{file}">-->
|
||||
<!-- <div class="el-upload-list__item-name"></div>-->
|
||||
<!--<!– <img–>-->
|
||||
<!--<!– class="el-upload-list__item-thumbnail"–>-->
|
||||
<!--<!– :src="OSSclientConfig.basePath + file.url"–>-->
|
||||
<!--<!– alt=""–>-->
|
||||
<!--<!– >–>-->
|
||||
<!-- <span class="el-upload-list__item-actions">-->
|
||||
<!-- <span-->
|
||||
<!-- class="el-upload-list__item-preview"-->
|
||||
<!-- @click="handlePictureCardPreview(file)"-->
|
||||
<!-- >-->
|
||||
<!-- <i class="el-icon-zoom-in" />-->
|
||||
<!-- </span>-->
|
||||
|
||||
<!-- <span-->
|
||||
<!-- v-if="readingTaskState < 2"-->
|
||||
<!-- class="el-upload-list__item-delete"-->
|
||||
<!-- @click="handleRemove(file)"-->
|
||||
<!-- >-->
|
||||
<!-- <i class="el-icon-delete" />-->
|
||||
<!-- </span>-->
|
||||
<!-- </span>-->
|
||||
<!-- </div>-->
|
||||
</el-upload>
|
||||
<el-dialog
|
||||
v-if="question.Type==='upload'"
|
||||
append-to-body
|
||||
:visible.sync="imgVisible"
|
||||
width="600px"
|
||||
<viewer
|
||||
v-if="question.Type==='upload' && imgVisible"
|
||||
:ref="imageUrl"
|
||||
style="margin:0 10px;"
|
||||
:images="[imageUrl]"
|
||||
>
|
||||
<el-image :src="imageUrl" width="100%">
|
||||
<div slot="placeholder" class="image-slot">
|
||||
加载中<span class="dot">...</span>
|
||||
</div>
|
||||
</el-image>
|
||||
</el-dialog>
|
||||
<img
|
||||
v-show="false"
|
||||
crossorigin="anonymous"
|
||||
:src="imageUrl"
|
||||
alt="Image"
|
||||
>
|
||||
</viewer>
|
||||
</el-form-item>
|
||||
</template>
|
||||
|
||||
<template v-if="question.Childrens && question.Childrens.length>0 && question.Type !== 'table'">
|
||||
<template v-if="question.Childrens && question.Childrens.length>0 && question.Type !== 'table' && question.Type !== 'basicTable'">
|
||||
<CustomizeQuestionFormItem
|
||||
v-for="(item) in question.Childrens"
|
||||
:key="item.Id"
|
||||
|
@ -295,9 +319,8 @@
|
|||
:type="addOrEdit.type"
|
||||
:CalculationList="CalculationTabelList"
|
||||
@formItemTableNumberChange="formItemTableNumberChange"
|
||||
@setFormItemData="setFormItemData"
|
||||
@resetFormItemData="resetFormItemData"
|
||||
@setFormTableItemData="setFormTableItemData"
|
||||
@resetFormItemData="resetTableFormItemData"
|
||||
@setFormItemData="setFormTableItemData"
|
||||
/>
|
||||
</el-form>
|
||||
</template>
|
||||
|
@ -374,7 +397,8 @@ export default {
|
|||
RowIndex: 0,
|
||||
RowId: null,
|
||||
digitPlaces: 0,
|
||||
CalculationTabelList: []
|
||||
CalculationTabelList: [],
|
||||
classArr: []
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
|
@ -382,9 +406,18 @@ export default {
|
|||
deep: true,
|
||||
immediate: true,
|
||||
handler(v, oldv) {
|
||||
// try {
|
||||
// if (!v[this.question.Id] || !oldv[this.question.Id]) return
|
||||
// } catch (e) {
|
||||
// }
|
||||
try {
|
||||
if (!v[this.question.Id] || !oldv[this.question.Id]) return
|
||||
if (!v || !v[this.question.Id] || !oldv || !oldv[this.question.Id])
|
||||
return
|
||||
} catch (e) {
|
||||
console.log(e, v)
|
||||
}
|
||||
if (this.question.Type === 'class') {
|
||||
this.$emit("setFormItemData", { key: this.question.Id, val: v[this.question.Id], question: v })
|
||||
}
|
||||
this.formItemNumberChange(this.question.Id, false)
|
||||
}
|
||||
|
@ -392,21 +425,21 @@ export default {
|
|||
},
|
||||
mounted() {
|
||||
this.digitPlaces = localStorage.getItem('digitPlaces') ? parseInt(localStorage.getItem('digitPlaces')) : 0
|
||||
if (this.question.Type === 'class') {
|
||||
this.ClassifyAlgorithmsList = JSON.parse(this.question.ClassifyAlgorithms)
|
||||
}
|
||||
setInterval(()=> {
|
||||
if (this.question.Type === 'class') {
|
||||
let o = this.ClassifyAlgorithmsList.find(v => {
|
||||
return this.questionForm[this.question.ClassifyQuestionId] >= v.gt && this.questionForm[this.question.ClassifyQuestionId] < v.lt
|
||||
})
|
||||
if (this.questionForm[this.question.ClassifyQuestionId]) {
|
||||
this.questionForm[this.question.Id] = o ? o.label : null
|
||||
} else {
|
||||
this.questionForm[this.question.Id] = null
|
||||
}
|
||||
}
|
||||
}, 300)
|
||||
// if (this.question.Type === 'class') {
|
||||
// this.ClassifyAlgorithmsList = JSON.parse(this.question.ClassifyAlgorithms)
|
||||
// }
|
||||
// setInterval(()=> {
|
||||
// if (this.question.Type === 'class') {
|
||||
// let o = this.ClassifyAlgorithmsList.find(v => {
|
||||
// return this.questionForm[this.question.ClassifyQuestionId] >= v.gt && this.questionForm[this.question.ClassifyQuestionId] < v.lt
|
||||
// })
|
||||
// if (this.questionForm[this.question.ClassifyQuestionId]) {
|
||||
// this.questionForm[this.question.Id] = o ? o.label : null
|
||||
// } else {
|
||||
// this.questionForm[this.question.Id] = null
|
||||
// }
|
||||
// }
|
||||
// }, 300)
|
||||
if (this.question.Type === 'upload') {
|
||||
if (this.questionForm[this.question.Id]) {
|
||||
this.urls = this.questionForm[this.question.Id].split('|')
|
||||
|
@ -416,7 +449,7 @@ export default {
|
|||
})
|
||||
}
|
||||
}
|
||||
if (this.question.Type === 'table') {
|
||||
if (this.question.Type === 'table' || this.question.Type === 'baiscTable') {
|
||||
this.getQuestionCalculateRelation()
|
||||
if (this.questionForm[this.question.Id]) {
|
||||
this.QuestionsForm = {}
|
||||
|
@ -436,11 +469,9 @@ export default {
|
|||
if (value.split('.')[1].length >= this.digitPlaces) {
|
||||
this.$set(a, b, parseFloat(value).toFixed(this.digitPlaces))
|
||||
}
|
||||
} else {
|
||||
}
|
||||
},
|
||||
deleteTableCol(row, index) {
|
||||
console.log(row)
|
||||
this.$confirm(this.$t('trials:uploadNonDicoms:message:msg1')).then(() => {
|
||||
const loading = this.$loading({ fullscreen: true })
|
||||
var param = {
|
||||
|
@ -451,7 +482,7 @@ export default {
|
|||
deleteReadingRowAnswer(param)
|
||||
.then(async res => {
|
||||
if (res.IsSuccess) {
|
||||
this.$message.success('删除成功')
|
||||
this.$message.success(this.$t('common:message:deletedSuccessfully'))
|
||||
DicomEvent.$emit('reGetQuestionAnswer')
|
||||
}
|
||||
loading.close()
|
||||
|
@ -461,11 +492,57 @@ export default {
|
|||
})
|
||||
|
||||
},
|
||||
setFormTableItemData(id, url) {
|
||||
this.$set(this.QuestionsForm, id, url)
|
||||
setFormTableItemData(obj) {
|
||||
this.$set(this.QuestionsForm, obj.key, obj.val)
|
||||
this.classArr.map(i=>{
|
||||
if (i.triggerId === obj.key) {
|
||||
let answer = null
|
||||
let list = JSON.parse(i.classifyAlgorithms)
|
||||
if (i.classifyType === 0) {
|
||||
let o = list.find(v => {
|
||||
return (
|
||||
parseFloat(obj.val) >= parseFloat(v.gt) &&
|
||||
parseFloat(obj.val) < parseFloat(v.lt)
|
||||
)
|
||||
})
|
||||
answer = o ? o.label : null
|
||||
} else if (i.classifyType === 1) {
|
||||
let o = list.find(v => {
|
||||
return v.val.includes(obj.val)
|
||||
})
|
||||
answer = o ? o.label : null
|
||||
}
|
||||
this.$set(this.QuestionsForm, i.classId, answer)
|
||||
}
|
||||
})
|
||||
// if (this.classArr.length > 0) {
|
||||
// let qs = this.classArr.find(i=>i.triggerId === obj.key)
|
||||
// if (!qs) return
|
||||
// let answer = null
|
||||
// let list = JSON.parse(qs.classifyAlgorithms)
|
||||
// if (qs.classifyType === 0) {
|
||||
// let o = list.find(v => {
|
||||
// return (
|
||||
// parseFloat(obj.val) >= parseFloat(v.gt) &&
|
||||
// parseFloat(obj.val) < parseFloat(v.lt)
|
||||
// )
|
||||
// })
|
||||
// answer = o ? o.label : null
|
||||
// } else if (qs.classifyType === 1) {
|
||||
// let o = list.find(v => {
|
||||
// return v.val.includes(obj.val)
|
||||
// })
|
||||
// answer = o ? o.label : null
|
||||
// }
|
||||
// if (answer !== null) {
|
||||
// this.$set(this.QuestionsForm, qs.classId, answer)
|
||||
// }
|
||||
// }
|
||||
},
|
||||
resetTableFormItemData(obj) {
|
||||
this.$set(this.QuestionsForm, obj.key, null)
|
||||
},
|
||||
handleSave() {
|
||||
console.log(this.QuestionsForm)
|
||||
this.$refs.tableQsForm.validate(valid => {
|
||||
if (!valid) return
|
||||
const loading = this.$loading({ fullscreen: true })
|
||||
|
@ -474,7 +551,6 @@ export default {
|
|||
for (const k in this.QuestionsForm) {
|
||||
if (reg.test(k)) {
|
||||
if (answers.findIndex(i => i.tableQuestionId === k) === -1) {
|
||||
console.log(this.QuestionsForm)
|
||||
answers.push({ tableQuestionId: k, answer: this.QuestionsForm[k] })
|
||||
}
|
||||
}
|
||||
|
@ -501,6 +577,7 @@ export default {
|
|||
submitTableQuestion(params).then(async res => {
|
||||
this.$message.success(this.$t('common:message:savedSuccessfully'))
|
||||
this.QuestionsForm.RowId = res.Result.RowId
|
||||
// DicomEvent.$emit('reGetQuestionAnswer')
|
||||
this.save()
|
||||
loading.close()
|
||||
}).catch(() => { loading.close() })
|
||||
|
@ -523,9 +600,7 @@ export default {
|
|||
})
|
||||
},
|
||||
save() {
|
||||
console.log(this.$refs.tableQsForm, this.QuestionsForm)
|
||||
this.$refs['tableQsForm'].validate((valid) => {
|
||||
console.log(valid)
|
||||
if (!valid) return
|
||||
if (this.addOrEdit.type === 'add') {
|
||||
this.AnswersList.push(this.QuestionsForm)
|
||||
|
@ -533,7 +608,7 @@ export default {
|
|||
var index = this.AnswersList.findIndex(v => v.RowId === this.QuestionsForm.RowId)
|
||||
this.AnswersList.splice(index, 1, this.QuestionsForm)
|
||||
}
|
||||
this.$emit('setFormItemData', {key: this.question.Id, val: this.AnswersList})
|
||||
this.$emit('setFormItemData', {key: this.question.Id, val: this.AnswersList, question: this.question})
|
||||
this.formItemNumberChange(this.question.Id, true)
|
||||
this.addOrEdit.visible = false
|
||||
})
|
||||
|
@ -543,9 +618,10 @@ export default {
|
|||
if (rules.CalculateQuestionList.length === 0) {
|
||||
return false
|
||||
}
|
||||
let dataArr = []
|
||||
rules.CalculateQuestionList.forEach((o, i) => {
|
||||
if (i === 0) {
|
||||
if (rules.CustomCalculateMark > 4) {
|
||||
if (rules.CustomCalculateMark > 4 && rules.CustomCalculateMark < 10) {
|
||||
switch (rules.CustomCalculateMark) {
|
||||
case 5:
|
||||
this.questionForm[o.QuestionId].forEach((q, qi) => {
|
||||
|
@ -592,6 +668,9 @@ export default {
|
|||
}
|
||||
} else {
|
||||
num = parseFloat(this.questionForm[o.TableQuestionId])
|
||||
if (!isNaN(num)) {
|
||||
dataArr.push(num)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
switch (rules.CustomCalculateMark) {
|
||||
|
@ -611,6 +690,38 @@ export default {
|
|||
num /= parseFloat(this.questionForm[o.TableQuestionId])
|
||||
}
|
||||
break;
|
||||
case 10:
|
||||
if (!isNaN(parseFloat(this.questionForm[o.TableQuestionId]))) {
|
||||
dataArr.push(parseFloat(this.questionForm[o.TableQuestionId]))
|
||||
}
|
||||
num = dataArr.length === 0 ? 0 : dataArr.reduce((acc, curr) => {
|
||||
return acc + (typeof curr === "number" ? curr : 0);
|
||||
}, 0) / dataArr.length;
|
||||
break;
|
||||
case 11:
|
||||
if (!isNaN(parseFloat(this.questionForm[o.TableQuestionId]))) {
|
||||
dataArr.push(parseFloat(this.questionForm[o.TableQuestionId]))
|
||||
}
|
||||
num = Math.max(...dataArr);
|
||||
break;
|
||||
case 12:
|
||||
if (!isNaN(parseFloat(this.questionForm[o.TableQuestionId]))) {
|
||||
dataArr.push(parseFloat(this.questionForm[o.TableQuestionId]))
|
||||
}
|
||||
num = Math.min(...dataArr);
|
||||
break;
|
||||
case 13:
|
||||
if (!isNaN(parseFloat(this.questionForm[o.TableQuestionId]))) {
|
||||
dataArr.push(parseFloat(this.questionForm[o.TableQuestionId]))
|
||||
}
|
||||
num = dataArr.length === 0 ? 0 : dataArr.reduce((acc, curr) => acc && curr) ? 1 : 0
|
||||
break;
|
||||
case 14:
|
||||
if (!isNaN(parseFloat(this.questionForm[o.TableQuestionId]))) {
|
||||
dataArr.push(parseFloat(this.questionForm[o.TableQuestionId]))
|
||||
}
|
||||
num = dataArr.length === 0 ? 0 : dataArr.reduce((acc, curr) => acc || curr, 0) ? 1 : 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
})
|
||||
|
@ -621,7 +732,12 @@ export default {
|
|||
if (rules.ValueType === 2) {
|
||||
num = num * 100
|
||||
}
|
||||
return num.toFixed(digitPlaces)
|
||||
if (rules.CustomCalculateMark === 13 || rules.CustomCalculateMark === 14) {
|
||||
return num
|
||||
} else {
|
||||
return num.toFixed(digitPlaces)
|
||||
}
|
||||
|
||||
},
|
||||
formItemNumberChange(questionId, isTable) {
|
||||
if (isTable) {
|
||||
|
@ -633,7 +749,7 @@ export default {
|
|||
if (find) {
|
||||
var num = this.logic(v)
|
||||
if (num !== false) {
|
||||
this.$emit('setFormItemData', { key: v.QuestionId, val: num })
|
||||
this.$emit('setFormItemData', { key: v.QuestionId, val: num, question: v })
|
||||
}
|
||||
}
|
||||
})
|
||||
|
@ -646,54 +762,107 @@ export default {
|
|||
if (find) {
|
||||
var num = this.logic(v)
|
||||
if (num !== false) {
|
||||
this.$emit('setFormItemData', { key: v.QuestionId, val: num })
|
||||
this.$emit('setFormItemData', { key: v.QuestionId, val: num, question: v })
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
// this.$emit('formItemNumberChange')
|
||||
},
|
||||
// formItemTableNumberChange() {
|
||||
// this.question.TableQuestions.Questions.forEach(v => {
|
||||
// if (v.Type === 'number' && v.DataSource === 1) {
|
||||
// var CalculateQuestions = JSON.parse(v.CalculateQuestions)
|
||||
// var num
|
||||
// CalculateQuestions.forEach((o, i) => {
|
||||
// if (i === 0) {
|
||||
// num = this.QuestionsForm[o.TableQuestionId]
|
||||
// } else {
|
||||
// switch (v.CustomCalculateMark) {
|
||||
// case 1:
|
||||
// num += this.QuestionsForm[o.TableQuestionId]
|
||||
// break;
|
||||
// case 2:
|
||||
// num -= this.QuestionsForm[o.TableQuestionId]
|
||||
// break;
|
||||
// case 3:
|
||||
// num *= this.QuestionsForm[o.TableQuestionId]
|
||||
// break;
|
||||
// case 4:
|
||||
// num /= this.QuestionsForm[o.TableQuestionId]
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
// })
|
||||
// this.$set(this.QuestionsForm, v.Id, num.toString())
|
||||
// }
|
||||
// })
|
||||
|
||||
// },
|
||||
formItemTableNumberChange() {
|
||||
this.question.TableQuestions.Questions.forEach(v => {
|
||||
if (v.Type === 'number' && v.DataSource === 1) {
|
||||
var CalculateQuestions = JSON.parse(v.CalculateQuestions)
|
||||
var num
|
||||
this.question.TableQuestions.Questions.forEach((v) => {
|
||||
if (v.Type === "number" && v.DataSource === 1) {
|
||||
var CalculateQuestions = JSON.parse(v.CalculateQuestions);
|
||||
var num,
|
||||
arr = [];
|
||||
CalculateQuestions.forEach((o, i) => {
|
||||
if (i === 0) {
|
||||
num = this.QuestionsForm[o.TableQuestionId]
|
||||
num = parseFloat(this.QuestionsForm[o.TableQuestionId]);
|
||||
arr = [num];
|
||||
} else {
|
||||
switch (v.CustomCalculateMark) {
|
||||
case 1:
|
||||
num += this.QuestionsForm[o.TableQuestionId]
|
||||
num += parseFloat(this.QuestionsForm[o.TableQuestionId]);
|
||||
break;
|
||||
case 2:
|
||||
num -= this.QuestionsForm[o.TableQuestionId]
|
||||
num -= parseFloat(this.QuestionsForm[o.TableQuestionId]);
|
||||
break;
|
||||
case 3:
|
||||
num *= this.QuestionsForm[o.TableQuestionId]
|
||||
num *= parseFloat(this.QuestionsForm[o.TableQuestionId]);
|
||||
break;
|
||||
case 4:
|
||||
num /= this.QuestionsForm[o.TableQuestionId]
|
||||
num /= parseFloat(this.QuestionsForm[o.TableQuestionId]);
|
||||
break;
|
||||
case 7:
|
||||
arr.push(parseFloat(this.QuestionsForm[o.TableQuestionId]));
|
||||
num =
|
||||
arr.length === 0
|
||||
? 0
|
||||
: arr.reduce((acc, curr) => {
|
||||
return acc + (typeof curr === "number" ? curr : 0);
|
||||
}, 0) / arr.length;
|
||||
break;
|
||||
case 8:
|
||||
arr.push(parseFloat(this.QuestionsForm[o.TableQuestionId]));
|
||||
num = arr.length === 0 ? 0 : Math.max(...arr);
|
||||
break;
|
||||
case 9:
|
||||
arr.push(parseFloat(this.QuestionsForm[o.TableQuestionId]));
|
||||
num = arr.length === 0 ? 0 : Math.min(...arr);
|
||||
// console.log('min', this.questionForm[o.QuestionId], arr, num)
|
||||
break;
|
||||
}
|
||||
}
|
||||
})
|
||||
this.$set(this.QuestionsForm, v.Id, num.toString())
|
||||
});
|
||||
this.$set(this.QuestionsForm, v.Id, num.toString());
|
||||
}
|
||||
})
|
||||
|
||||
});
|
||||
},
|
||||
openAddTableCol(row, index) {
|
||||
this.addOrEdit.visible = true
|
||||
this.addOrEdit.title = row.QuestionName + this.$t('trials:readingUnit:qsList:title:tableQs')
|
||||
this.QuestionsList = row.TableQuestions.Questions
|
||||
row.TableQuestions.Questions.map(v=>{
|
||||
if (v.Type === 'class') {
|
||||
this.classArr.push({triggerId: v.ClassifyTableQuestionId, classId: v.Id, classifyAlgorithms: v.ClassifyAlgorithms, classifyType: v.ClassifyType})
|
||||
}
|
||||
})
|
||||
this.AnswersList = row.TableQuestions.Answers
|
||||
if (!index && index !== 0) {
|
||||
this.addOrEdit.type = 'add'
|
||||
this.QuestionsForm = {}
|
||||
} else {
|
||||
this.addOrEdit.type = 'edit'
|
||||
console.log(this.questionForm)
|
||||
this.QuestionsForm = Object.assign({}, this.questionForm[row.Id][index])
|
||||
}
|
||||
},
|
||||
|
@ -709,7 +878,7 @@ export default {
|
|||
})
|
||||
},
|
||||
formNumberItemChange(v) {
|
||||
this.$emit('setFormItemData', { key: v.QuestionId, val: num })
|
||||
this.$emit('setFormItemData', { key: v.QuestionId, val: num, question: v })
|
||||
},
|
||||
formItemChange(v, question) {
|
||||
if (question.Childrens.length > 0) {
|
||||
|
@ -724,8 +893,10 @@ export default {
|
|||
// if (typeof val === 'boolean') {
|
||||
// // val = String(val)
|
||||
// }
|
||||
this.$emit('setFormItemData', { key: qs.Id, val: val })
|
||||
this.$emit('setFormItemData', { key: qs.Id, val: val, question: qs })
|
||||
})
|
||||
} else {
|
||||
this.$emit('setFormItemData', { key: question.Id, val: v, question: question })
|
||||
}
|
||||
},
|
||||
resetChild(obj) {
|
||||
|
@ -741,9 +912,9 @@ export default {
|
|||
},
|
||||
setFormItemData(obj) {
|
||||
this.$emit('setFormItemData', obj)
|
||||
|
||||
},
|
||||
async uploadScreenshot(param) {
|
||||
console.log('uploadScreenshot')
|
||||
if (!this.visitTaskId) return
|
||||
const loading = this.$loading({
|
||||
target: document.querySelector('.ecrf-wrapper'),
|
||||
|
@ -756,9 +927,8 @@ export default {
|
|||
let file = await this.fileToBlob(param.file)
|
||||
let res = await this.OSSclient.put(`/${this.$route.query.trialId}/Customize/${this.visitTaskId}/${fileName}`, file)
|
||||
this.fileList.push({ name: `${this.$t('trials:emailManageCfg:title:fileName')}${this.fileList.length + 1}`, url: this.$getObjectName(res.url) })
|
||||
console.log('fileList', this.fileList)
|
||||
this.urls.push(this.$getObjectName(res.url))
|
||||
this.$emit('setFormItemData', { key: this.question.Id, val: this.urls.length > 0 ? this.urls.join('|') : '' })
|
||||
this.$emit('setFormItemData', { key: this.question.Id, val: this.urls.length > 0 ? this.urls.join('|') : '', question: this.question })
|
||||
loading.close()
|
||||
// uploadReadingAnswerImage(this.$route.query.trialId, this.visitTaskId, formData).then(res => {
|
||||
// if (res.IsSuccess) {
|
||||
|
@ -773,7 +943,6 @@ export default {
|
|||
},
|
||||
handleBeforeUpload(file, accept) {
|
||||
// 检测文件类型是否符合要求
|
||||
console.log('handleBeforeUpload', file)
|
||||
if (this.checkFileSuffix(file.name, accept) || accept === '-1') {
|
||||
return true
|
||||
} else {
|
||||
|
@ -781,7 +950,6 @@ export default {
|
|||
this.$alert(msg)
|
||||
return false
|
||||
}
|
||||
console.log(file)
|
||||
},
|
||||
checkFileSuffix(fileName, accept) {
|
||||
var index = fileName.lastIndexOf('.')
|
||||
|
@ -794,17 +962,25 @@ export default {
|
|||
},
|
||||
// 预览图片
|
||||
handlePictureCardPreview(file) {
|
||||
this.imageUrl = this.OSSclientConfig.basePath + file.url
|
||||
this.imgVisible = true
|
||||
var suffix = file.url.substring(file.url.lastIndexOf(".")+1)
|
||||
suffix = suffix ? suffix.toLowerCase() : ''
|
||||
if (suffix === 'doc' || suffix === 'docx' || suffix === 'pdf'){
|
||||
window.open(this.OSSclientConfig.basePath + file.url,'_blank')
|
||||
}else{
|
||||
this.imageUrl = this.OSSclientConfig.basePath + file.url
|
||||
this.imgVisible = true
|
||||
this.$nextTick(()=>{
|
||||
this.$refs[this.imageUrl].$viewer.show()
|
||||
})
|
||||
}
|
||||
},
|
||||
// 删除图片
|
||||
handleRemove(file, fileList) {
|
||||
console.log('handleRemove')
|
||||
if (file && file.status === "success") {
|
||||
this.imageUrl = ''
|
||||
this.fileList.splice(this.fileList.findIndex(f => f.url === file.url), 1)
|
||||
this.urls.splice(this.fileList.findIndex(f => f === file.url), 1)
|
||||
this.$emit('setFormItemData', { key: this.question.Id, val: this.urls.length > 0 ? this.urls.join('|') : '' })
|
||||
this.$emit('setFormItemData', { key: this.question.Id, val: this.urls.length > 0 ? this.urls.join('|') : '', question: this.question })
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -125,7 +125,8 @@
|
|||
<!-- 上传图像 -->
|
||||
<el-upload
|
||||
v-if="question.Type==='upload'"
|
||||
:action="accept"
|
||||
action
|
||||
:accept="accept"
|
||||
:limit="question.ImageCount"
|
||||
:on-preview="handlePictureCardPreview"
|
||||
:before-upload="handleBeforeUpload"
|
||||
|
@ -138,27 +139,41 @@
|
|||
>
|
||||
<i slot="default" class="el-icon-plus" />
|
||||
<div slot="file" slot-scope="{file}">
|
||||
<img
|
||||
class="el-upload-list__item-thumbnail"
|
||||
:src="OSSclientConfig.basePath + file.url"
|
||||
alt=""
|
||||
<viewer
|
||||
:ref="file.url"
|
||||
:images="[imageUrl]"
|
||||
style="
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
"
|
||||
>
|
||||
<span class="el-upload-list__item-actions">
|
||||
<span
|
||||
class="el-upload-list__item-preview"
|
||||
@click="handlePictureCardPreview(file)"
|
||||
>
|
||||
<i class="el-icon-zoom-in" />
|
||||
</span>
|
||||
<img
|
||||
class="el-upload-list__item-thumbnail"
|
||||
:src="OSSclientConfig.basePath + file.url"
|
||||
crossOrigin="anonymous"
|
||||
alt=""
|
||||
style="max-width: 100%; max-height: 100%"
|
||||
/>
|
||||
<span class="el-upload-list__item-actions">
|
||||
<span
|
||||
class="el-upload-list__item-preview"
|
||||
@click="handlePictureCardPreview(file)"
|
||||
>
|
||||
<i class="el-icon-zoom-in" />
|
||||
</span>
|
||||
|
||||
<span
|
||||
v-if="readingTaskState < 2"
|
||||
class="el-upload-list__item-delete"
|
||||
@click="handleRemove(file)"
|
||||
>
|
||||
<i class="el-icon-delete" />
|
||||
<span
|
||||
v-if="readingTaskState < 2"
|
||||
class="el-upload-list__item-delete"
|
||||
@click="handleRemove(file)"
|
||||
>
|
||||
<i class="el-icon-delete" />
|
||||
</span>
|
||||
</span>
|
||||
</span>
|
||||
</viewer>
|
||||
</div>
|
||||
</el-upload>
|
||||
<el-dialog
|
||||
|
@ -276,7 +291,7 @@ export default {
|
|||
const res = await this.OSSclient.put(`/${this.trialId}/ReadAttachment/${this.subjectId}/${this.visitTaskId}/${param.file.name}`, file)
|
||||
this.fileList.push({ name: param.file.name, url: this.$getObjectName(res.url) })
|
||||
this.urls.push(this.$getObjectName(res.url))
|
||||
this.$emit('setFormItemData', { key: this.question.Id, val: this.urls.length > 0 ? this.urls.join('|') : '' })
|
||||
this.$emit('setFormItemData', { key: this.question.Id, val: this.urls.length > 0 ? this.urls.join('|') : '', question: this.question })
|
||||
loading.close()
|
||||
},
|
||||
handleBeforeUpload(file) {
|
||||
|
@ -302,15 +317,21 @@ export default {
|
|||
},
|
||||
// 预览图片
|
||||
handlePictureCardPreview(file) {
|
||||
this.imageUrl = this.OSSclientConfig.basePath + file.url
|
||||
this.imgVisible = true
|
||||
var suffix = file.url.substring(file.url.lastIndexOf(".")+1)
|
||||
suffix = suffix ? suffix.toLowerCase() : ''
|
||||
if (suffix === 'doc' || suffix === 'docx' || suffix === 'pdf'){
|
||||
window.open(this.OSSclientConfig.basePath + file.url,'_blank')
|
||||
}else{
|
||||
this.imageUrl = this.OSSclientConfig.basePath + file.url
|
||||
this.$refs[file.url].$viewer.show();
|
||||
}
|
||||
},
|
||||
// 删除图片
|
||||
handleRemove(file, fileList) {
|
||||
this.imageUrl = ''
|
||||
this.fileList.splice(this.fileList.findIndex(f => f.url === file.url), 1)
|
||||
this.urls.splice(this.fileList.findIndex(f => f === file.url), 1)
|
||||
this.$emit('setFormItemData', { key: this.question.Id, val: this.urls.length > 0 ? this.urls.join('|') : '' })
|
||||
this.$emit('setFormItemData', { key: this.question.Id, val: this.urls.length > 0 ? this.urls.join('|') : '', question: this.question })
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -95,7 +95,38 @@
|
|||
{{ val }}
|
||||
</el-checkbox>
|
||||
</el-checkbox-group>
|
||||
|
||||
<!-- 自动分类 -->
|
||||
<el-input
|
||||
v-if="question.Type === 'class' && question.ClassifyShowType === 1"
|
||||
v-model="questionForm[question.Id]"
|
||||
/>
|
||||
<el-select
|
||||
v-if="question.Type === 'class' && question.ClassifyShowType === 2"
|
||||
v-model="questionForm[question.Id]"
|
||||
:disabled="!question.ClassifyEditType"
|
||||
@change="(val) => { formItemChange(val, question) }"
|
||||
>
|
||||
<el-option
|
||||
v-for="val in question.TypeValue.split('|')"
|
||||
:key="val"
|
||||
:label="val.trim()"
|
||||
:value="val.trim()"
|
||||
/>
|
||||
</el-select>
|
||||
<el-radio-group
|
||||
v-if="question.Type === 'class' && question.ClassifyShowType === 3"
|
||||
v-model="questionForm[question.Id]"
|
||||
:disabled="!question.ClassifyEditType"
|
||||
@change="(val) => { formItemChange(val, question) }"
|
||||
>
|
||||
<el-radio
|
||||
v-for="item of question.TypeValue.split('|')"
|
||||
:key="item.trim()"
|
||||
:label="item.trim()"
|
||||
>
|
||||
{{ item.trim() }}
|
||||
</el-radio>
|
||||
</el-radio-group>
|
||||
<!-- 自动计算 -->
|
||||
<!-- :precision="2" :step="0.1" :max="10" -->
|
||||
<el-input
|
||||
|
@ -136,39 +167,54 @@
|
|||
<!-- 上传图像 -->
|
||||
<el-upload
|
||||
v-if="question.Type==='upload'"
|
||||
:action="accept"
|
||||
:limit="question.ImageCount"
|
||||
action
|
||||
:accept="question.FileType"
|
||||
:limit="question.ImageCount === 0 ? 100 : question.ImageCount"
|
||||
:on-preview="handlePictureCardPreview"
|
||||
:before-upload="handleBeforeUpload"
|
||||
:http-request="uploadScreenshot"
|
||||
list-type="picture-card"
|
||||
:on-remove="handleRemove"
|
||||
:file-list="fileList"
|
||||
:class="{disabled:fileList.length >= question.ImageCount}"
|
||||
:class="{disabled: question.ImageCount === 0 ? false : fileList.length >= question.ImageCount}"
|
||||
>
|
||||
<i slot="default" class="el-icon-plus" />
|
||||
<div slot="file" slot-scope="{file}">
|
||||
<img
|
||||
class="el-upload-list__item-thumbnail"
|
||||
:src="OSSclientConfig.basePath + file.url"
|
||||
alt=""
|
||||
<viewer
|
||||
:ref="file.url"
|
||||
:images="[imageUrl]"
|
||||
style="
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
"
|
||||
>
|
||||
<span class="el-upload-list__item-actions">
|
||||
<span
|
||||
class="el-upload-list__item-preview"
|
||||
@click="handlePictureCardPreview(file)"
|
||||
>
|
||||
<i class="el-icon-zoom-in" />
|
||||
</span>
|
||||
<img
|
||||
class="el-upload-list__item-thumbnail"
|
||||
:src="OSSclientConfig.basePath + file.url"
|
||||
crossOrigin="anonymous"
|
||||
alt=""
|
||||
style="max-width: 100%; max-height: 100%"
|
||||
/>
|
||||
<span class="el-upload-list__item-actions">
|
||||
<span
|
||||
class="el-upload-list__item-preview"
|
||||
@click="handlePictureCardPreview(file)"
|
||||
>
|
||||
<i class="el-icon-zoom-in" />
|
||||
</span>
|
||||
|
||||
<span
|
||||
v-if="readingTaskState < 2"
|
||||
class="el-upload-list__item-delete"
|
||||
@click="handleRemove(file)"
|
||||
>
|
||||
<i class="el-icon-delete" />
|
||||
<span
|
||||
v-if="readingTaskState < 2"
|
||||
class="el-upload-list__item-delete"
|
||||
@click="handleRemove(file)"
|
||||
>
|
||||
<i class="el-icon-delete" />
|
||||
</span>
|
||||
</span>
|
||||
</span>
|
||||
</viewer>
|
||||
</div>
|
||||
</el-upload>
|
||||
<el-dialog
|
||||
|
@ -268,11 +314,11 @@ export default {
|
|||
deep: true,
|
||||
immediate: true,
|
||||
handler(v, oldv) {
|
||||
try {
|
||||
if (!v[this.question.Id] || !oldv[this.question.Id]) return
|
||||
} catch (e) {
|
||||
}
|
||||
this.formItemNumberChange(this.question.Id, false)
|
||||
// try {
|
||||
// if (!v[this.question.Id] || !oldv[this.question.Id]) return
|
||||
// } catch (e) {
|
||||
// }
|
||||
// this.formItemNumberChange(this.question.Id, false)
|
||||
}
|
||||
},
|
||||
},
|
||||
|
@ -286,14 +332,15 @@ export default {
|
|||
this.fileList.push({ name: '', url: `${url}` })
|
||||
})
|
||||
}
|
||||
console.log('11')
|
||||
}
|
||||
if (this.type === 'edit') return
|
||||
if (this.question.Type === 'number') {
|
||||
console.log(this.questionForm)
|
||||
this.$set(this.questionForm, this.question.Id, null)
|
||||
} else {
|
||||
this.$set(this.questionForm, this.question.Id, '')
|
||||
}
|
||||
// if (this.question.Type === 'number') {
|
||||
// console.log(this.questionForm)
|
||||
// this.$set(this.questionForm, this.question.Id, null)
|
||||
// } else {
|
||||
// this.$set(this.questionForm, this.question.Id, '')
|
||||
// }
|
||||
},
|
||||
methods: {
|
||||
save() {
|
||||
|
@ -329,8 +376,10 @@ export default {
|
|||
// if (typeof val === 'boolean') {
|
||||
// // val = String(val)
|
||||
// }
|
||||
this.$emit('setFormItemData', { key: qs.Id, val: val })
|
||||
this.$emit('setFormItemData', { key: qs.Id, val: val, question: qs })
|
||||
})
|
||||
} else {
|
||||
this.$emit('setFormItemData', { key: question.Id, val: v, question: question })
|
||||
}
|
||||
},
|
||||
limitInput(value, q) {
|
||||
|
@ -347,10 +396,11 @@ export default {
|
|||
if (rules.CalculateQuestionList.length === 0) {
|
||||
return false
|
||||
}
|
||||
let dataArr = []
|
||||
var count = 0
|
||||
var maxList = [], minList = []
|
||||
rules.CalculateQuestionList.forEach((o, i) => {
|
||||
if (rules.CustomCalculateMark > 4) {
|
||||
if (rules.CustomCalculateMark > 4 && rules.CustomCalculateMark < 10) {
|
||||
if (i !== 0) {
|
||||
switch (rules.CustomCalculateMark) {
|
||||
case 7:
|
||||
|
@ -377,6 +427,7 @@ export default {
|
|||
minList.push(this.questionForm[o.TableQuestionId])
|
||||
count = parseFloat(this.questionForm[o.TableQuestionId])
|
||||
num = parseFloat(this.questionForm[o.TableQuestionId])
|
||||
dataArr.push(num)
|
||||
}
|
||||
} else {
|
||||
if (i !== 0) {
|
||||
|
@ -397,6 +448,26 @@ export default {
|
|||
num /= parseFloat(this.questionForm[o.TableQuestionId])
|
||||
}
|
||||
break;
|
||||
case 10:
|
||||
if (!isNaN(parseFloat(this.questionForm[o.TableQuestionId]))) {
|
||||
dataArr.push(parseFloat(this.questionForm[o.TableQuestionId]))
|
||||
}
|
||||
num = dataArr.length === 0 ? 0 : dataArr.reduce((acc, curr) => {
|
||||
return acc + (typeof curr === "number" ? curr : 0);
|
||||
}, 0) / dataArr.length;
|
||||
break;
|
||||
case 11:
|
||||
if (!isNaN(parseFloat(this.questionForm[o.TableQuestionId]))) {
|
||||
dataArr.push(parseFloat(this.questionForm[o.TableQuestionId]))
|
||||
}
|
||||
num = Math.max(...dataArr);
|
||||
break;
|
||||
case 12:
|
||||
if (!isNaN(parseFloat(this.questionForm[o.TableQuestionId]))) {
|
||||
dataArr.push(parseFloat(this.questionForm[o.TableQuestionId]))
|
||||
}
|
||||
num = Math.min(...dataArr);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
num = parseFloat(this.questionForm[o.TableQuestionId])
|
||||
|
@ -413,23 +484,7 @@ export default {
|
|||
return num.toFixed(digitPlaces)
|
||||
},
|
||||
formItemNumberChange(v, question) {
|
||||
console.log(this.CalculationList)
|
||||
this.CalculationList.forEach((v, i) => {
|
||||
console.log('v', v)
|
||||
var find = v.CalculateQuestionList.filter(o => {
|
||||
return o.QuestionId === question.Id
|
||||
})
|
||||
console.log('find', find)
|
||||
// find的自动计算值number
|
||||
if (find) {
|
||||
var num = this.logic(v)
|
||||
console.log(num)
|
||||
if (num !== false) {
|
||||
this.$set(this.questionForm, v.QuestionId, num)
|
||||
// this.$emit('setFormItemData', { key: v.QuestionId, val: num })
|
||||
}
|
||||
}
|
||||
})
|
||||
this.$emit('formItemTableNumberChange', v, question)
|
||||
// this.$emit('formItemTableNumberChange', v, question)
|
||||
},
|
||||
resetChild(obj) {
|
||||
|
@ -462,7 +517,7 @@ export default {
|
|||
console.log(res)
|
||||
this.fileList.push({ name: param.file.name, path: this.$getObjectName(res.url), url: this.$getObjectName(res.url)})
|
||||
this.urls.push(this.$getObjectName(res.url))
|
||||
this.$emit('setFormTableItemData', this.question.Id, this.urls.length > 0 ? this.urls.join('|') : '')
|
||||
this.$emit('setFormItemData', { key:this.question.Id, val: this.urls.length > 0 ? this.urls.join('|') : '', question: this.question })
|
||||
loading.close()
|
||||
},
|
||||
handleBeforeUpload(file) {
|
||||
|
@ -471,14 +526,17 @@ export default {
|
|||
// this.fileList = []
|
||||
return true
|
||||
} else {
|
||||
this.$alert(`必须是 ${this.accept} 格式`)
|
||||
let msg = this.$t(
|
||||
"trials:readingUnit:qsList:message:imageFormat"
|
||||
).replace("xxx", this.question.FileType)
|
||||
this.$alert(msg)
|
||||
return false
|
||||
}
|
||||
},
|
||||
checkFileSuffix(fileName) {
|
||||
var index = fileName.lastIndexOf('.')
|
||||
var suffix = fileName.substring(index + 1, fileName.length)
|
||||
if (this.accept.toLocaleLowerCase().search(suffix.toLocaleLowerCase()) === -1) {
|
||||
if (this.question.FileType.toLocaleLowerCase().search(suffix.toLocaleLowerCase()) === -1) {
|
||||
return false
|
||||
} else {
|
||||
return true
|
||||
|
@ -486,15 +544,23 @@ export default {
|
|||
},
|
||||
// 预览图片
|
||||
handlePictureCardPreview(file) {
|
||||
this.imageUrl = this.OSSclientConfig.basePath + file.url
|
||||
this.imgVisible = true
|
||||
var suffix = file.url.substring(file.url.lastIndexOf(".")+1)
|
||||
suffix = suffix ? suffix.toLowerCase() : ''
|
||||
if (suffix === 'doc' || suffix === 'docx' || suffix === 'pdf'){
|
||||
window.open(this.OSSclientConfig.basePath + file.url,'_blank')
|
||||
}else{
|
||||
this.imageUrl = this.OSSclientConfig.basePath + file.url
|
||||
// this.imgVisible = true
|
||||
this.$refs[file.url].$viewer.show()
|
||||
}
|
||||
|
||||
},
|
||||
// 删除图片
|
||||
handleRemove(file, fileList) {
|
||||
this.imageUrl = ''
|
||||
this.fileList.splice(this.fileList.findIndex(f => f.url === file.url), 1)
|
||||
this.urls.splice(this.fileList.findIndex(f => f === file.url), 1)
|
||||
this.$emit('setFormTableItemData', this.question.Id, this.urls.length > 0 ? this.urls.join('|') : '')
|
||||
this.$emit('setFormItemData', { key:this.question.Id, val: this.urls.length > 0 ? this.urls.join('|') : '', question: this.question })
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -57,7 +57,8 @@ export default {
|
|||
readingTaskState: 0,
|
||||
activeName: 0,
|
||||
CalculationList: [],
|
||||
IsBaseline: true
|
||||
IsBaseline: true,
|
||||
classArr: []
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
|
@ -82,7 +83,7 @@ export default {
|
|||
var answers = []
|
||||
for (const k in this.questionForm) {
|
||||
if (this.questionForm[k] instanceof Array) {} else {
|
||||
answers.push({ id: k, answer: this.questionForm[k].toString() })
|
||||
answers.push({ id: k, answer: this.questionForm[k] })
|
||||
}
|
||||
}
|
||||
var params = {
|
||||
|
@ -122,12 +123,15 @@ export default {
|
|||
DicomEvent.$emit('setReadingState', res.OtherInfo.ReadingTaskState)
|
||||
res.Result.SinglePage.map((v) => {
|
||||
if (v.Type === 'group' && v.Childrens.length === 0) return
|
||||
if (!v.IsPage && v.Type !== 'group' && v.Type !== 'summary' && v.Type !== 'table' && v.Type !== 'number') {
|
||||
if (!v.IsPage && v.Type !== 'group' && v.Type !== 'summary' && v.Type !== 'table' && v.Type !== 'basicTable' && v.Type !== 'number') {
|
||||
this.$set(this.questionForm, v.Id, v.Answer)
|
||||
}
|
||||
if (v.Type === 'table') {
|
||||
if (v.Type === 'table' || v.Type === 'basicTable') {
|
||||
this.$set(this.questionForm, v.Id, v.TableQuestions.Answers)
|
||||
}
|
||||
if (v.Type === 'class') {
|
||||
this.classArr.push({triggerId: v.ClassifyQuestionId, classId: v.Id, classifyAlgorithms: v.ClassifyAlgorithms, classifyType: v.ClassifyType})
|
||||
}
|
||||
if (v.Type === 'number') {
|
||||
this.$set(this.questionForm, v.Id, v.Answer === '' ? '' : parseFloat(v.Answer).toFixed(localStorage.getItem('digitPlaces')))
|
||||
}
|
||||
|
@ -136,7 +140,6 @@ export default {
|
|||
}
|
||||
})
|
||||
this.questions = res.Result.SinglePage
|
||||
console.log(this.questions)
|
||||
this.isRender = true
|
||||
this.loading = false
|
||||
})
|
||||
|
@ -151,8 +154,8 @@ export default {
|
|||
if (res.OtherInfo.FormType === 2) {
|
||||
if (res.Result.MultiPage.length > 0) {
|
||||
res.Result.MultiPage.map((v) => {
|
||||
if (v.Type === 'group' && v.Childrens.length === 0 && i.Type !== 'table') return
|
||||
if (!v.IsPage && v.Type !== 'group' && v.Type !== 'summary' && i.Type !== 'table') {
|
||||
if (v.Type === 'group' && v.Childrens.length === 0 && i.Type !== 'table' && i.Type !== 'basicTable') return
|
||||
if (!v.IsPage && v.Type !== 'group' && v.Type !== 'summary' && i.Type !== 'table' && i.Type !== 'basicTable') {
|
||||
this.$set(this.questionForm, v.Id, '')
|
||||
}
|
||||
if (v.Childrens.length > 0) {
|
||||
|
@ -164,8 +167,8 @@ export default {
|
|||
}
|
||||
if (res.Result.PublicPage.length > 0) {
|
||||
res.Result.PublicPage.map((v) => {
|
||||
if (v.Type === 'group' && v.Childrens.length === 0 && i.Type !== 'table') return
|
||||
if (!v.IsPage && v.Type !== 'group' && v.Type !== 'summary' && i.Type !== 'table') {
|
||||
if (v.Type === 'group' && v.Childrens.length === 0 && i.Type !== 'table' && i.Type !== 'basicTable') return
|
||||
if (!v.IsPage && v.Type !== 'group' && v.Type !== 'summary' && i.Type !== 'table' && i.Type !== 'basicTable') {
|
||||
this.$set(this.questionForm, v.Id, '')
|
||||
}
|
||||
if (v.Childrens.length > 0) {
|
||||
|
@ -176,11 +179,11 @@ export default {
|
|||
}
|
||||
} else {
|
||||
res.Result.SinglePage.map((v) => {
|
||||
if (v.Type === 'group' && v.Childrens.length === 0 && v.Type !== 'table') return
|
||||
if (!v.IsPage && v.Type !== 'group' && v.Type !== 'summary' && v.Type !== 'table' && v.Type !== 'number') {
|
||||
if (v.Type === 'group' && v.Childrens.length === 0 && v.Type !== 'table' && v.Type !== 'basicTable') return
|
||||
if (!v.IsPage && v.Type !== 'group' && v.Type !== 'summary' && v.Type !== 'table' && v.Type !== 'basicTable' && v.Type !== 'number') {
|
||||
this.$set(this.questionForm, v.Id, v.Answer)
|
||||
}
|
||||
if (v.Type === 'table') {
|
||||
if (v.Type === 'table' || v.Type === 'basicTable') {
|
||||
this.$set(this.questionForm, v.Id, v.TableQuestions.Answers)
|
||||
}
|
||||
if (v.Type === 'number') {
|
||||
|
@ -198,10 +201,10 @@ export default {
|
|||
},
|
||||
setChild(obj) {
|
||||
obj.forEach(i => {
|
||||
if (i.Type !== 'group' && i.Type !== 'summary' && i.Id && i.Type !== 'table') {
|
||||
if (i.Type !== 'group' && i.Type !== 'summary' && i.Id && i.Type !== 'table' && i.Type !== 'basicTable') {
|
||||
this.$set(this.questionForm, i.Id, i.Answer)
|
||||
}
|
||||
if (i.Type === 'table') {
|
||||
if (i.Type === 'table' || i.Type === 'basicTable') {
|
||||
i.TableQuestions.Questions.forEach(o => {
|
||||
if (o.Type === 'number') {
|
||||
i.TableQuestions.Answers.forEach((ite, index) => {
|
||||
|
@ -211,6 +214,9 @@ export default {
|
|||
})
|
||||
this.$set(this.questionForm, i.Id, i.TableQuestions.Answers)
|
||||
}
|
||||
if (i.Type === 'class') {
|
||||
this.classArr.push({triggerId: i.ClassifyQuestionId, classId: i.Id, classifyAlgorithms: i.ClassifyAlgorithms, classifyType: i.ClassifyType})
|
||||
}
|
||||
if (i.Type === 'number') {
|
||||
this.$set(this.questionForm, i.Id, i.Answer === '' ? '' : parseFloat(i.Answer).toFixed(localStorage.getItem('digitPlaces')))
|
||||
}
|
||||
|
@ -224,6 +230,50 @@ export default {
|
|||
},
|
||||
setFormItemData(obj) {
|
||||
this.$set(this.questionForm, obj.key, JSON.parse(JSON.stringify(obj.val)))
|
||||
this.classArr.map(i=>{
|
||||
if (i.triggerId === obj.key) {
|
||||
let answer = null
|
||||
let list = JSON.parse(i.classifyAlgorithms)
|
||||
if (i.classifyType === 0) {
|
||||
let o = list.find(v => {
|
||||
return (
|
||||
parseFloat(obj.val) >= parseFloat(v.gt) &&
|
||||
parseFloat(obj.val) < parseFloat(v.lt)
|
||||
)
|
||||
})
|
||||
answer = o ? o.label : null
|
||||
} else if (i.classifyType === 1) {
|
||||
let o = list.find(v => {
|
||||
return v.val.includes(obj.val)
|
||||
})
|
||||
answer = o ? o.label.trim() : null
|
||||
}
|
||||
this.$set(this.questionForm, i.classId, answer)
|
||||
}
|
||||
})
|
||||
// if (this.classArr.length > 0) {
|
||||
// let qs = this.classArr.find(i=>i.triggerId === obj.key)
|
||||
// if (!qs) return
|
||||
// let answer = null
|
||||
// let list = JSON.parse(qs.classifyAlgorithms)
|
||||
// if (qs.classifyType === 0) {
|
||||
// let o = list.find(v => {
|
||||
// return (
|
||||
// parseFloat(obj.val) >= parseFloat(v.gt) &&
|
||||
// parseFloat(obj.val) < parseFloat(v.lt)
|
||||
// )
|
||||
// })
|
||||
// answer = o ? o.label : null
|
||||
// } else if (qs.classifyType === 1) {
|
||||
// let o = list.find(v => {
|
||||
// return v.val.includes(obj.val)
|
||||
// })
|
||||
// answer = o ? o.label.trim() : null
|
||||
// }
|
||||
// if (answer !== null) {
|
||||
// this.$set(this.questionForm, qs.classId, answer)
|
||||
// }
|
||||
// }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -11,6 +11,15 @@
|
|||
style="margin-right:5px"
|
||||
@change="handleShowDetail"
|
||||
/>
|
||||
<el-button
|
||||
v-if="readingTaskState<2"
|
||||
type="primary"
|
||||
size="small"
|
||||
@click="skipTask"
|
||||
>
|
||||
<!-- 跳过 -->
|
||||
{{ $t('trials:readingReport:button:skip') }}
|
||||
</el-button>
|
||||
<el-button v-if="readingTaskState<2" type="primary" size="small" @click="getReportInfo">{{$t('trials:readingReport:button:refresh')}}</el-button>
|
||||
<el-button v-if="readingTaskState<2" type="primary" size="small" @click="handleSave(true)">{{$t('common:button:save')}}</el-button>
|
||||
<el-button v-if="readingTaskState<2" type="primary" size="small" @click="handleConfirm">{{$t('common:button:submit')}}</el-button>
|
||||
|
@ -71,7 +80,7 @@
|
|||
</div>
|
||||
</template>
|
||||
<template slot-scope="scope">
|
||||
<template v-if="readingTaskState<2 && task.VisitTaskId === visitTaskId && (scope.row.Type==='input' || scope.row.Type==='number' || scope.row.Type==='select' || scope.row.Type==='textarea' || scope.row.Type==='radio')">
|
||||
<template v-if="readingTaskState<2 && task.VisitTaskId === visitTaskId && (scope.row.Type==='input' || scope.row.Type==='number' || scope.row.Type==='select' || scope.row.Type==='textarea' || scope.row.Type==='radio' || scope.row.Type === 'class')">
|
||||
<template>
|
||||
<!-- 输入框 -->
|
||||
<div>
|
||||
|
@ -103,12 +112,12 @@
|
|||
<el-option
|
||||
v-for="val in scope.row.TypeValue.split('|')"
|
||||
:key="val"
|
||||
:label="val"
|
||||
:value="val"
|
||||
:label="val.trim()"
|
||||
:value="val.trim()"
|
||||
/>
|
||||
</template>
|
||||
</el-select>
|
||||
<span v-else-if="questionForm[scope.row.QuestionId] instanceof Array && scope.row.Type==='select'">
|
||||
<span v-else-if="questionForm[scope.row.QuestionId] instanceof Array && scope.row.Type==='select' || scope.row.Type==='radio'">
|
||||
{{questionForm[scope.row.QuestionId][scope.row.xfIndex][scope.row.TableQuestionId]}}
|
||||
</span>
|
||||
<el-select
|
||||
|
@ -121,14 +130,20 @@
|
|||
<el-option
|
||||
v-for="val in scope.row.TypeValue.split('|')"
|
||||
:key="val"
|
||||
:label="val"
|
||||
:value="val"
|
||||
:label="val.trim()"
|
||||
:value="val.trim()"
|
||||
/>
|
||||
</template>
|
||||
</el-select>
|
||||
<span v-else-if="scope.row.Type==='select' || scope.row.Type==='radio'">
|
||||
{{questionForm[scope.row.QuestionId]}}
|
||||
</span>
|
||||
<span v-else-if="questionForm[scope.row.QuestionId] instanceof Array && scope.row.Type==='class'">
|
||||
{{questionForm[scope.row.QuestionId][scope.row.xfIndex][scope.row.TableQuestionId]}}
|
||||
</span>
|
||||
<span v-else-if="scope.row.Type==='class'">
|
||||
{{questionForm[scope.row.QuestionId]}}
|
||||
</span>
|
||||
<el-input
|
||||
v-else-if="scope.row.DataSource !== 1 && questionForm[scope.row.QuestionId] instanceof Array && scope.row.Type==='number' && (scope.row.xfIndex || scope.row.xfIndex === 0) && !scope.row.IsShowInDicom && ((task.IsBaseLine && scope.row.LimitEdit === 1) || (!task.IsBaseLine && scope.row.LimitEdit === 2) || scope.row.LimitEdit === 0)"
|
||||
v-model="questionForm[scope.row.QuestionId][scope.row.xfIndex][scope.row.TableQuestionId]"
|
||||
|
@ -260,6 +275,7 @@
|
|||
</template>
|
||||
<script>
|
||||
import { changeCalculationAnswer, getReadingReportEvaluation, changeDicomReadingQuestionAnswer, submitDicomVisitTask, verifyVisitTaskQuestions, getQuestionCalculateRelation } from '@/api/trials'
|
||||
import { setSkipReadingCache } from '@/api/reading'
|
||||
import DicomEvent from './../components/DicomEvent'
|
||||
import CustomizeReportPageUpload from './CustomizeReportPageUpload'
|
||||
import const_ from '@/const/sign-code'
|
||||
|
@ -415,11 +431,11 @@ export default {
|
|||
},
|
||||
InitVisitTaskQuestionForm() {
|
||||
this.taskQuestions.map((v, i) => {
|
||||
if (v.Type === 'group' && v.Childrens.length === 0 && v.Type !== 'table') return
|
||||
if (!v.IsPage && v.Type !== 'group' && v.Type !== 'summary' && v.Type !== 'table' && v.Type !== 'number') {
|
||||
if (v.Type === 'group' && v.Childrens.length === 0 && v.Type !== 'table' && v.Type !== 'basicTable') return
|
||||
if (!v.IsPage && v.Type !== 'group' && v.Type !== 'summary' && v.Type !== 'table' && v.Type !== 'basicTable' && v.Type !== 'number') {
|
||||
this.$set(this.questionForm, v.QuestionId, v.Answers[this.visitTaskId])
|
||||
}
|
||||
if (v.Type === 'table') {
|
||||
if (v.Type === 'table' || v.Type === 'basicTable') {
|
||||
var tableAnswers = this.getTableAnswers(v.QuestionId, v.Childrens, i)
|
||||
this.$set(this.questionForm, v.QuestionId, tableAnswers)
|
||||
// this.$set(v, 'xfIndex', i)
|
||||
|
@ -435,17 +451,17 @@ export default {
|
|||
},
|
||||
setChild(obj) {
|
||||
obj.forEach((i, index) => {
|
||||
if (i.Type !== 'group' && i.Type !== 'summary' && i.Id && i.Type !== 'table') {
|
||||
if (i.Type !== 'group' && i.Type !== 'summary' && i.Id && i.Type !== 'table' && i.Type !== 'basicTable') {
|
||||
this.$set(this.questionForm, i.QuestionId, i.Answers[this.visitTaskId])
|
||||
}
|
||||
if (i.Type === 'table') {
|
||||
if (i.Type === 'table' || i.Type === 'basicTable') {
|
||||
var tableAnswers = this.getTableAnswers(i.QuestionId, i.Childrens, index)
|
||||
this.$set(this.questionForm, i.QuestionId, tableAnswers)
|
||||
}
|
||||
if (i.Type === 'number') {
|
||||
this.$set(this.questionForm, i.QuestionId, i.Answers[this.visitTaskId] === '' ? parseFloat(0).toFixed(this.digitPlaces) : i.Answers[this.visitTaskId])
|
||||
}
|
||||
if (i.Childrens && i.Childrens.length > 0 && i.Type !== 'table') {
|
||||
if (i.Childrens && i.Childrens.length > 0 && i.Type !== 'table' && i.Type !== 'basicTable') {
|
||||
this.setChild(i.Childrens)
|
||||
}
|
||||
})
|
||||
|
@ -775,13 +791,15 @@ export default {
|
|||
},
|
||||
previewDicoms(task) {
|
||||
var token = getToken()
|
||||
var subjectCode = this.$router.currentRoute.query.subjectCode
|
||||
// var subjectCode = this.$router.currentRoute.query.subjectCode
|
||||
var subjectCode = localStorage.getItem('subjectCode')
|
||||
var subjectId = this.$router.currentRoute.query.subjectId
|
||||
var trialId = this.$router.currentRoute.query.trialId
|
||||
var isReadingTaskViewInOrder = this.$router.currentRoute.query.isReadingTaskViewInOrder
|
||||
var criterionType = this.$router.currentRoute.query.criterionType
|
||||
var readingTool = this.$router.currentRoute.query.readingTool
|
||||
var path = `/readingDicoms?trialId=${trialId}&subjectCode=${subjectCode}&subjectId=${subjectId}&visitTaskId=${task.VisitTaskId}&isReadingTaskViewInOrder=${isReadingTaskViewInOrder}&criterionType=${criterionType}&readingTool=${readingTool}&TokenKey=${token}`
|
||||
var trialReadingCriterionId = this.$router.currentRoute.query.TrialReadingCriterionId
|
||||
var path = `/readingDicoms?TrialReadingCriterionId=${trialReadingCriterionId}&trialId=${trialId}&subjectCode=${subjectCode}&subjectId=${subjectId}&visitTaskId=${task.VisitTaskId}&isReadingTaskViewInOrder=${isReadingTaskViewInOrder}&criterionType=${criterionType}&readingTool=${readingTool}&TokenKey=${token}`
|
||||
const routeData = this.$router.resolve({ path })
|
||||
window.open(routeData.href, '_blank')
|
||||
},
|
||||
|
@ -826,6 +844,28 @@ export default {
|
|||
reject()
|
||||
})
|
||||
})
|
||||
},
|
||||
async skipTask() {
|
||||
try {
|
||||
// 是否确认跳过?
|
||||
const confirm = await this.$confirm(
|
||||
this.$t('trials:readingReport:message:skipConfirm'),
|
||||
{
|
||||
type: 'warning',
|
||||
distinguishCancelAndClose: true
|
||||
}
|
||||
)
|
||||
if (confirm !== 'confirm') return
|
||||
this.loading = true
|
||||
const res = await setSkipReadingCache({ visitTaskId: this.visitTaskId })
|
||||
this.loading = false
|
||||
if (res.IsSuccess) {
|
||||
window.location.reload()
|
||||
}
|
||||
} catch (e) {
|
||||
this.loading = false
|
||||
console.log(e)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,54 +1,57 @@
|
|||
<template>
|
||||
<div>
|
||||
<el-upload
|
||||
:action="accept"
|
||||
:limit="question.ImageCount"
|
||||
action
|
||||
:accept="question.FileType"
|
||||
:limit="question.ImageCount === 0 ? 100 : question.ImageCount"
|
||||
:on-preview="handlePictureCardPreview"
|
||||
:before-upload="handleBeforeUpload"
|
||||
:http-request="uploadScreenshot"
|
||||
list-type="picture-card"
|
||||
:on-remove="handleRemove"
|
||||
:file-list="fileList"
|
||||
:class="{disabled:readingTaskState >= 2 || (fileList.length >= question.ImageCount) || (task.VisitTaskId !== visitTaskId) || question.IsShowInDicom || ((task.IsBaseLine && question.LimitEdit === 2) || (!task.IsBaseLine && question.LimitEdit === 1))}"
|
||||
:class="{disabled:readingTaskState >= 2 || (question.ImageCount === 0 ? false : fileList.length >= question.ImageCount) || (task.VisitTaskId !== visitTaskId) || question.IsShowInDicom || ((task.IsBaseLine && question.LimitEdit === 2) || (!task.IsBaseLine && question.LimitEdit === 1))}"
|
||||
:disabled="readingTaskState >= 2 || task.VisitTaskId !== visitTaskId || question.IsShowInDicom || ((task.IsBaseLine && question.LimitEdit === 2) || (!task.IsBaseLine && question.LimitEdit === 1))"
|
||||
>
|
||||
<i slot="default" class="el-icon-plus" />
|
||||
<div slot="file" slot-scope="{file}">
|
||||
<img
|
||||
class="el-upload-list__item-thumbnail"
|
||||
crossOrigin="Anonymous"
|
||||
:src="OSSclientConfig.basePath + file.url"
|
||||
alt=""
|
||||
<viewer
|
||||
:ref="file.url"
|
||||
:images="[imageUrl]"
|
||||
style="
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
"
|
||||
>
|
||||
<span class="el-upload-list__item-actions">
|
||||
<span
|
||||
class="el-upload-list__item-preview"
|
||||
@click="handlePictureCardPreview(file)"
|
||||
>
|
||||
<i class="el-icon-zoom-in" />
|
||||
</span>
|
||||
<img
|
||||
class="el-upload-list__item-thumbnail"
|
||||
:src="OSSclientConfig.basePath + file.url"
|
||||
crossOrigin="anonymous"
|
||||
alt=""
|
||||
style="max-width: 100%; max-height: 100%"
|
||||
/>
|
||||
<span class="el-upload-list__item-actions">
|
||||
<span
|
||||
class="el-upload-list__item-preview"
|
||||
@click="handlePictureCardPreview(file)"
|
||||
>
|
||||
<i class="el-icon-zoom-in" />
|
||||
</span>
|
||||
|
||||
<span
|
||||
v-if="readingTaskState < 2"
|
||||
class="el-upload-list__item-delete"
|
||||
@click="handleRemove(file)"
|
||||
>
|
||||
<i class="el-icon-delete" />
|
||||
</span>
|
||||
</span>
|
||||
<span
|
||||
v-if="readingTaskState < 2"
|
||||
class="el-upload-list__item-delete"
|
||||
@click="handleRemove(file)"
|
||||
>
|
||||
<i class="el-icon-delete" />
|
||||
</span>
|
||||
</span>
|
||||
</viewer>
|
||||
</div>
|
||||
</el-upload>
|
||||
<el-dialog
|
||||
append-to-body
|
||||
:visible.sync="imgVisible"
|
||||
width="600px"
|
||||
>
|
||||
<el-image :src="imageUrl" width="100%" crossOrigin="Anonymous">
|
||||
<div slot="placeholder" class="image-slot">
|
||||
加载中<span class="dot">...</span>
|
||||
</div>
|
||||
</el-image>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
@ -93,13 +96,13 @@ name: "CustomizeReportPageUpload",
|
|||
this.urls.map(url => {
|
||||
this.fileList.push({ name: '', url: `${url}` })
|
||||
})
|
||||
console.log(this.fileList)
|
||||
// console.log(this.fileList)
|
||||
},
|
||||
methods: {
|
||||
checkFileSuffix(fileName) {
|
||||
var index = fileName.lastIndexOf('.')
|
||||
var suffix = fileName.substring(index + 1, fileName.length)
|
||||
if (this.accept.toLocaleLowerCase().search(suffix.toLocaleLowerCase()) === -1) {
|
||||
if (this.question.FileType.toLocaleLowerCase().search(suffix.toLocaleLowerCase()) === -1) {
|
||||
return false
|
||||
} else {
|
||||
return true
|
||||
|
@ -130,14 +133,25 @@ name: "CustomizeReportPageUpload",
|
|||
// this.fileList = []
|
||||
return true
|
||||
} else {
|
||||
this.$alert(`必须是 ${this.accept} 格式`)
|
||||
// this.$alert(`必须是 ${this.accept} 格式`)
|
||||
let msg = this.$t(
|
||||
"trials:readingUnit:qsList:message:imageFormat"
|
||||
).replace("xxx", this.question.FileType)
|
||||
this.$alert(msg)
|
||||
return false
|
||||
}
|
||||
},
|
||||
// 预览图片
|
||||
handlePictureCardPreview(file) {
|
||||
this.imageUrl = this.OSSclientConfig.basePath + file.url
|
||||
this.imgVisible = true
|
||||
var suffix = file.url.substring(file.url.lastIndexOf(".")+1)
|
||||
suffix = suffix ? suffix.toLowerCase() : ''
|
||||
if (suffix === 'doc' || suffix === 'docx' || suffix === 'pdf'){
|
||||
window.open(this.OSSclientConfig.basePath + file.url,'_blank')
|
||||
}else{
|
||||
this.imageUrl = this.OSSclientConfig.basePath + file.url
|
||||
// this.imgVisible = true
|
||||
this.$refs[file.url].$viewer.show()
|
||||
}
|
||||
},
|
||||
// 删除图片
|
||||
handleRemove(file, fileList) {
|
||||
|
|
|
@ -49,20 +49,52 @@
|
|||
/>
|
||||
<div class="image-desc">
|
||||
<div class="flex-div">
|
||||
<div v-if="!study.IsCriticalSequence">#{{ series.seriesNumber }} </div>
|
||||
<div v-if="series.isDicom && series.prefetchInstanceCount<series.instanceCount && series.modality!== 'SR'">
|
||||
<!-- 下载 -->
|
||||
<el-tooltip v-if="!series.isLoading" class="item" effect="dark" :content="$t('trials:reading:button:download')" placement="bottom">
|
||||
<div style="width: 40px;display: flex;flex-direction: row;justify-content: space-between;">
|
||||
<div v-if="!study.IsCriticalSequence">#{{ series.seriesNumber }}</div>
|
||||
<div v-if="series.isDicom && series.prefetchInstanceCount<series.instanceCount * 100 && series.modality!== 'SR'">
|
||||
<!-- 下载 -->
|
||||
<el-tooltip v-if="!series.isLoading" class="item" effect="dark" :content="$t('trials:reading:button:download')" placement="bottom">
|
||||
<i class="el-icon-video-play" style="font-size: 18px;margin-right: 5px;color: #ffeb3b;cursor: pointer;" @click.stop="loadSeries(series,index,i)" />
|
||||
</el-tooltip>
|
||||
</div>
|
||||
<el-tooltip v-else-if="series.isDicom && series.prefetchInstanceCount === 0 &&series.modality!== 'SR'" class="item" effect="dark" :content="$t('trials:reading:button:download')" placement="bottom">
|
||||
<i class="el-icon-video-play" style="font-size: 18px;margin-right: 5px;color: #ffeb3b;cursor: pointer;" @click.stop="loadSeries(series,index,i)" />
|
||||
</el-tooltip>
|
||||
<!-- 暂停 -->
|
||||
<!-- <el-tooltip v-else class="item" effect="dark" :content="$t('trials:reading:button:pause')" placement="bottom">
|
||||
<i class="el-icon-video-pause" style="font-size: 18px;margin-right: 5px;color: #ffeb3b;cursor: pointer;" @click.stop="stopLoadSeries(series,index,i)" />
|
||||
</el-tooltip> -->
|
||||
</div>
|
||||
<el-tooltip v-else-if="series.isDicom && series.prefetchInstanceCount === 0 &&series.modality!== 'SR'" class="item" effect="dark" :content="$t('trials:reading:button:download')" placement="bottom">
|
||||
<i class="el-icon-video-play" style="font-size: 18px;margin-right: 5px;color: #ffeb3b;cursor: pointer;" @click.stop="loadSeries(series,index,i)" />
|
||||
</el-tooltip>
|
||||
<div v-if="series.isExistMutiFrames && series.instanceCount > 1">
|
||||
<el-popover
|
||||
placement="right"
|
||||
trigger="hover"
|
||||
popper-class="instance_frame_wrapper"
|
||||
>
|
||||
<div class="frame_list">
|
||||
<div
|
||||
v-for="(instance, idx) in series.instanceInfoList"
|
||||
:key="instance.Id"
|
||||
class="frame_content"
|
||||
:style="{'margin-bottom':idx<series.instanceInfoList.length-1? '5px':'0px'}"
|
||||
@click.stop="showMultiFrames(index,series, i, instance)"
|
||||
>
|
||||
<!-- <div>
|
||||
<img
|
||||
class="image-preview"
|
||||
:src="series.previewImageUrl"
|
||||
crossorigin="anonymous"
|
||||
alt=""
|
||||
style="width: 40px;height:40px;"
|
||||
fit="fill"
|
||||
>
|
||||
</div> -->
|
||||
<div>
|
||||
<div>{{ instance.InstanceNumber }}</div>
|
||||
<div>{{ `${instance.NumberOfFrames > 0 ? instance.KeyFramesList.length > 0 ? instance.KeyFramesList.length : instance.NumberOfFrames : 1} frame` }}</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<i slot="reference" class="el-icon-connection" style="font-size: 15px;cursor: pointer;color: #ffeb3b;" />
|
||||
</el-popover>
|
||||
</div>
|
||||
</div>
|
||||
<p v-show="series.description">
|
||||
<el-tooltip class="item" effect="dark" :content="series.description" placement="right">
|
||||
|
@ -73,10 +105,12 @@
|
|||
<p v-show="series.sliceThickness && !study.IsCriticalSequence">
|
||||
T: {{ parseFloat(series.sliceThickness).toFixed(digitPlaces) }}
|
||||
</p>
|
||||
<p v-show="series.instanceCount">
|
||||
<p v-show="series.instanceCount && series.imageloadedArr.length < series.instanceCount">
|
||||
{{ series.modality }}: {{ series.imageloadedArr.length }}/{{ series.instanceCount }} image
|
||||
</p>
|
||||
<p v-show="series.instanceCount && series.imageloadedArr.length >= series.instanceCount">
|
||||
{{ series.modality }}: {{ series.instanceCount }} image
|
||||
</p>
|
||||
|
||||
<div class="flex-div">
|
||||
<div v-if="measureData && measureData.findIndex(v=>v.SeriesId === series.seriesId && v.MeasureData) > -1">
|
||||
<!-- 有标注 -->
|
||||
|
@ -88,9 +122,9 @@
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="series.isDicom && series.prefetchInstanceCount>0 && series.prefetchInstanceCount<series.instanceCount" style="width: 100%;">
|
||||
<div v-if="series.isDicom && series.prefetchInstanceCount>0 && series.prefetchInstanceCount<series.instanceCount * 100" style="width: 100%;">
|
||||
<el-progress
|
||||
:percentage="parseInt(((series.prefetchInstanceCount/series.instanceCount)*100).toFixed(2))"
|
||||
:percentage="parseInt((series.prefetchInstanceCount / series.instanceCount).toFixed(2))"
|
||||
/>
|
||||
</div>
|
||||
|
||||
|
@ -125,18 +159,11 @@
|
|||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import * as dicomParser from 'dicom-parser'
|
||||
import * as cornerstone from 'cornerstone-core'
|
||||
import * as cornerstoneWADOImageLoader from 'cornerstone-wado-image-loader'
|
||||
import requestPoolManager from '@/utils/request-pool'
|
||||
import DicomEvent from './../components/DicomEvent'
|
||||
import { mapGetters } from 'vuex'
|
||||
import store from '@/store'
|
||||
import SrList from './../components/SrList'
|
||||
cornerstoneWADOImageLoader.external.dicomParser = dicomParser
|
||||
cornerstoneWADOImageLoader.external.cornerstone = cornerstone
|
||||
const maximumSizeInBytes = 1024 * 1024 * 1024 // 1 GB
|
||||
cornerstone.imageCache.setMaximumSizeBytes(maximumSizeInBytes)
|
||||
export default {
|
||||
name: 'StudyList',
|
||||
components: { SrList },
|
||||
|
@ -219,22 +246,23 @@ export default {
|
|||
// }
|
||||
},
|
||||
mounted() {
|
||||
this.subjectCode = this.$router.currentRoute.query.subjectCode
|
||||
// this.subjectCode = this.$router.currentRoute.query.subjectCode
|
||||
this.subjectCode = localStorage.getItem('subjectCode')
|
||||
var digitPlaces = Number(localStorage.getItem('digitPlaces'))
|
||||
this.digitPlaces = digitPlaces === -1 ? this.digitPlaces : digitPlaces
|
||||
|
||||
DicomEvent.$on('refreshStudyListMeasureData', () => {
|
||||
var idx = this.visitTaskList.findIndex(i => i.VisitTaskId === this.visitTaskId)
|
||||
this.measureData = this.visitTaskList[idx].MeasureData
|
||||
})
|
||||
// DicomEvent.$on('setReadingState', readingTaskState => {
|
||||
// var idx = this.visitTaskList.findIndex(i => i.VisitTaskId === this.visitTaskId)
|
||||
// if (idx > -1) {
|
||||
// this.studyList = this.visitTaskList[idx].StudyList
|
||||
// }
|
||||
// })
|
||||
cornerstone.events.addEventListener('cornerstoneimageloaded', this.cornerstoneImageLoaded)
|
||||
// cornerstone.events.addEventListener('cornerstoneimagecachefull', this.cornerstoneimagecachefull)
|
||||
// cornerstone.events.addEventListener('cornerstoneimagecachechanged', this.cornerstoneimagecachechanged)
|
||||
|
||||
},
|
||||
beforeDestroy() {
|
||||
cornerstone.imageCache.purgeCache()
|
||||
},
|
||||
methods: {
|
||||
initStudyInfo() {
|
||||
|
@ -242,81 +270,40 @@ export default {
|
|||
// 初始化待渲染序列
|
||||
this.getInitSeries().then((res) => {
|
||||
requestPoolManager.startTaskTimer()
|
||||
res.map((item) => {
|
||||
this.loadInitialImage(item)
|
||||
res.map(async(item) => {
|
||||
let imageId = item.imageIds[item.imageIdIndex]
|
||||
const p = parseInt(new Date().getTime())
|
||||
// requestPoolManager.loadAndCacheImagePlus(imageId, item.seriesId, p * 100)
|
||||
await requestPoolManager.loadAndCacheImagePlus(imageId, item.seriesId, p * 100)
|
||||
if (!item.isCurrentTask) {
|
||||
store.dispatch('reading/setImageloadedInfo', item)
|
||||
}
|
||||
})
|
||||
var i = res.findIndex(s => s.isCurrentTask)
|
||||
var i = -1
|
||||
var isReadingTaskViewInOrder = parseInt(this.$router.currentRoute.query.isReadingTaskViewInOrder)
|
||||
if (isReadingTaskViewInOrder === 2) {
|
||||
// 受试者内随机
|
||||
i = res.length === 2 ? 1 : -1
|
||||
} else {
|
||||
i = res.findIndex(s => s.isCurrentTask)
|
||||
}
|
||||
if (i > -1) {
|
||||
var idx = this.visitTaskList.findIndex(i => i.VisitTaskId === this.visitTaskId)
|
||||
if (idx > -1) {
|
||||
this.measureData = this.visitTaskList[idx].MeasureData
|
||||
this.studyList = this.visitTaskList[idx].StudyList
|
||||
var priority = parseInt(new Date().getTime())
|
||||
res[i].imageIds.map(image => {
|
||||
priority--
|
||||
this.imageList.push({ imageId: image, seriesId: res[i].seriesId, studyIndex: res[i].studyIndex, seriesIndex: res[i].seriesIndex, visitTaskId: res[i].visitTaskId, priority })
|
||||
})
|
||||
|
||||
// this.studyList.map((study, studyIndex) => {
|
||||
// study.SeriesList.map((series, seriesIndex) => {
|
||||
// if (series.modality !== 'SR') {
|
||||
// series.imageIds.map(image => {
|
||||
// var p = priority - seriesIndex
|
||||
// if (series.seriesId === res[i].seriesId) {
|
||||
// p = priority
|
||||
// } else {
|
||||
// --p
|
||||
// }
|
||||
// this.imageList.push({ imageId: image, seriesId: series.seriesId, studyIndex: studyIndex, seriesIndex: seriesIndex, visitTaskId: series.visitTaskId, priority: p })
|
||||
// })
|
||||
// }
|
||||
// })
|
||||
// })
|
||||
this.loopLoad()
|
||||
}
|
||||
}
|
||||
DicomEvent.$emit('loadImageStacks', res)
|
||||
loading.close()
|
||||
this.isRender = true
|
||||
}).catch(() => {
|
||||
loading.close()
|
||||
})
|
||||
},
|
||||
initStudyInfo2() {
|
||||
console.log('initStudyInfo')
|
||||
const loading = this.$loading({ fullscreen: true })
|
||||
// 初始化待渲染序列
|
||||
this.getInitSeries().then((res) => {
|
||||
requestPoolManager.startTaskTimer()
|
||||
res.map((item) => {
|
||||
this.loadInitialImage(item)
|
||||
})
|
||||
var i = res.findIndex(s => s.isCurrentTask)
|
||||
if (i > -1) {
|
||||
var p = parseInt(new Date().getTime())
|
||||
// var p = this.visitTaskId === this.currentTaskId ? parseInt(new Date().getTime()) : 999 // 非当前任务,符合自动下载的权重次之
|
||||
var idx = this.visitTaskList.findIndex(i => i.VisitTaskId === this.visitTaskId)
|
||||
if (idx > -1) {
|
||||
this.measureData = this.visitTaskList[idx].MeasureData
|
||||
this.studyList = this.visitTaskList[idx].StudyList
|
||||
|
||||
this.studyList.map((study, studyIndex) => {
|
||||
study.SeriesList.map((series, seriesIndex) => {
|
||||
if (series.modality !== 'SR') {
|
||||
// var sliceThickness = isNaN(parseInt(series.sliceThickness)) ? null : parseInt(series.sliceThickness)
|
||||
// if (sliceThickness === 5 || series.instanceCount <= 100) {
|
||||
series.imageIds.map(image => {
|
||||
let priority = 0
|
||||
if (series.seriesId === res[i].seriesId) {
|
||||
priority = parseInt(new Date().getTime()) * 10
|
||||
} else {
|
||||
priority = --p
|
||||
}
|
||||
this.imageList.push({ imageId: image, seriesId: series.seriesId, studyIndex: studyIndex, seriesIndex: seriesIndex, visitTaskId: series.visitTaskId, priority })
|
||||
})
|
||||
}
|
||||
if (res[i].isExistMutiFrames) {
|
||||
res[i].instanceInfoList.map(image => {
|
||||
priority--
|
||||
this.imageList.push({ imageId: image.ImageId, seriesId: res[i].seriesId, studyIndex: res[i].studyIndex, seriesIndex: res[i].seriesIndex, visitTaskId: res[i].visitTaskId, priority })
|
||||
})
|
||||
})
|
||||
} else {
|
||||
res[i].imageIds.map(image => {
|
||||
priority--
|
||||
this.imageList.push({ imageId: image, seriesId: res[i].seriesId, studyIndex: res[i].studyIndex, seriesIndex: res[i].seriesIndex, visitTaskId: res[i].visitTaskId, priority })
|
||||
})
|
||||
}
|
||||
this.loopLoad()
|
||||
}
|
||||
}
|
||||
|
@ -331,14 +318,9 @@ export default {
|
|||
loadInitialImage(seriesInfo) {
|
||||
var p = parseInt(new Date().getTime())
|
||||
var imageId = seriesInfo.imageIds[seriesInfo.imageIdIndex]
|
||||
requestPoolManager.loadAndCacheImagePlus(imageId, seriesInfo.seriesId, p * 100).then(res => {
|
||||
if (seriesInfo.isCurrentTask) {
|
||||
this.imageLoaded({ studyIndex: seriesInfo.studyIndex, seriesIndex: seriesInfo.seriesIndex, imageId: res.imageId }, res.data.string('x0020000e'))
|
||||
}
|
||||
})
|
||||
requestPoolManager.loadAndCacheImagePlus(imageId, seriesInfo.seriesId, p * 100)
|
||||
},
|
||||
getStudyList() {
|
||||
console.log('getStudyList')
|
||||
if (!this.isRender) {
|
||||
var idx = this.visitTaskList.findIndex(i => i.VisitTaskId === this.visitTaskId)
|
||||
if (idx > -1 && this.visitTaskList[idx].StudyList && this.visitTaskList[idx].StudyList.length > 0) {
|
||||
|
@ -349,8 +331,27 @@ export default {
|
|||
this.studyIndex = sIdx
|
||||
this.seriesIndex = 0
|
||||
this.activeNames = [`${this.studyList[sIdx].StudyId}`]
|
||||
|
||||
this.loadImages(this.visitTaskList[idx])
|
||||
// 下载关键序列
|
||||
const i = this.studyList.findIndex(i => i.IsCriticalSequence)
|
||||
if (i > -1 && this.studyList[i].SeriesList[0].length > 0) {
|
||||
const series = this.studyList[i].SeriesList[0]
|
||||
if (!series.loadStatus) {
|
||||
let priority = parseInt(new Date().getTime())
|
||||
if (series.isExistMutiFrames) {
|
||||
series.instanceInfoList.map(image => {
|
||||
priority = priority - 1
|
||||
this.imageList.push({ imageId: image.ImageId, seriesId: series.seriesId, studyIndex: i, seriesIndex: 0, visitTaskId: series.visitTaskId, priority })
|
||||
})
|
||||
} else {
|
||||
series.imageIds.map(imageId => {
|
||||
priority = priority - 1
|
||||
this.imageList.push({ imageId: imageId, seriesId: series.seriesId, studyIndex: i, seriesIndex: 0, visitTaskId: series.visitTaskId, priority })
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
this.loopLoad()
|
||||
// this.loadImages(this.visitTaskList[idx])
|
||||
}
|
||||
}
|
||||
this.isRender = true
|
||||
|
@ -362,7 +363,22 @@ export default {
|
|||
var isReadingTaskViewInOrder = JSON.parse(this.$router.currentRoute.query.isReadingTaskViewInOrder)
|
||||
var idx = this.visitTaskList.findIndex(i => i.VisitTaskId === this.visitTaskId)
|
||||
this.studyList = this.visitTaskList[idx].StudyList
|
||||
if (this.visitTaskList[idx].IsBaseLineTask || !isReadingTaskViewInOrder) {
|
||||
if (isReadingTaskViewInOrder === 2) {
|
||||
// 受试者内随机
|
||||
const studyList = this.visitTaskList[idx].StudyList.filter(i => i.IsDicom)
|
||||
const seriesArr = studyList.map(s => s.SeriesList).flat()
|
||||
if (seriesArr.length === 1) {
|
||||
seriesList.push(seriesArr[0], seriesArr[0])
|
||||
this.studyIndex = seriesArr[0].studyIndex
|
||||
this.seriesIndex = seriesArr[0].seriesIndex
|
||||
this.activeNames = [`${seriesArr[0].studyId}`]
|
||||
} else if (seriesArr.length > 1) {
|
||||
seriesList.push(seriesArr[0], seriesArr[1])
|
||||
this.studyIndex = seriesArr[1].studyIndex
|
||||
this.seriesIndex = seriesArr[1].seriesIndex
|
||||
this.activeNames = [`${seriesArr[1].studyId}`]
|
||||
}
|
||||
} else if (this.visitTaskList[idx].IsBaseLineTask || isReadingTaskViewInOrder === 0){
|
||||
// 基线
|
||||
const obj = this.getFirstMarkedSeries(this.visitTaskList[idx].MeasureData, [...this.visitTaskList[idx].StudyList])
|
||||
if (Object.keys(obj).length !== 0) {
|
||||
|
@ -393,7 +409,7 @@ export default {
|
|||
|
||||
if (bsIdx > -1) {
|
||||
var trialId = this.$router.currentRoute.query.trialId
|
||||
await store.dispatch('reading/getMeasuredData', this.visitTaskList[bsIdx].VisitTaskId)
|
||||
await store.dispatch('reading/getCustomizeMeasuredData', this.visitTaskList[bsIdx].VisitTaskId)
|
||||
await store.dispatch('reading/getStudyInfo', { trialId: trialId, subjectVisitId: this.visitTaskList[bsIdx].VisitId, visitTaskId: this.visitTaskList[bsIdx].VisitTaskId, taskBlindName: this.visitTaskList[bsIdx].TaskBlindName })
|
||||
|
||||
const firstObj = this.getFirstMarkedSeries(this.visitTaskList[bsIdx].MeasureData, [...this.visitTaskList[bsIdx].StudyList])
|
||||
|
@ -432,9 +448,11 @@ export default {
|
|||
const sdIndx = studyList.findIndex(sd => sd.StudyId === measureDatas[i].StudyId)
|
||||
const seriesList = studyList[sdIndx].SeriesList
|
||||
const srIdx = seriesList.findIndex(sr => sr.seriesId === measureDatas[i].SeriesId)
|
||||
// const instanceList = seriesList[srIdx].imageIds
|
||||
const instanceList = seriesList[srIdx].instanceList
|
||||
const isIdx = instanceList.findIndex(is => is.includes(measureDatas[i].InstanceId))
|
||||
// const instanceList = seriesList[srIdx].instanceList
|
||||
// const isIdx = instanceList.findIndex(is => is.includes(measureDatas[i].InstanceId))
|
||||
const imageIds = seriesList[srIdx].imageIds
|
||||
let filterStr = seriesList[srIdx].isExistMutiFrames ? `frame=${measureDatas[i].MeasureData.frame}&instanceId=${measureDatas[i].InstanceId}` : `instanceId=${measureDatas[i].InstanceId}`
|
||||
const isIdx = imageIds.findIndex(is => is.includes(filterStr))
|
||||
const series = seriesList[srIdx]
|
||||
series.imageIdIndex = isIdx
|
||||
|
||||
|
@ -504,9 +522,11 @@ export default {
|
|||
if (sdIndx > -1) {
|
||||
const seriesList = studyList[sdIndx].SeriesList
|
||||
const srIdx = seriesList.findIndex(sr => sr.seriesId === measureDatas[mIdx].SeriesId)
|
||||
// const instanceList = seriesList[srIdx].imageIds
|
||||
const instanceList = seriesList[srIdx].instanceList
|
||||
const isIdx = instanceList.findIndex(is => is.includes(measureDatas[mIdx].InstanceId))
|
||||
// const instanceList = seriesList[srIdx].instanceList
|
||||
// const isIdx = instanceList.findIndex(is => is.includes(measureDatas[mIdx].InstanceId))
|
||||
const imageIds = seriesList[srIdx].imageIds
|
||||
let filterStr = seriesList[srIdx].isExistMutiFrames ? `frame=${measureDatas[mIdx].MeasureData.frame}&instanceId=${measureDatas[mIdx].InstanceId}` : `instanceId=${measureDatas[mIdx].InstanceId}`
|
||||
const isIdx = imageIds.findIndex(is => is.includes(filterStr))
|
||||
const series = seriesList[srIdx]
|
||||
series.imageIdIndex = isIdx
|
||||
|
||||
|
@ -535,19 +555,18 @@ export default {
|
|||
obj.series = seriesObj.series
|
||||
obj.seriesId = seriesObj.series.seriesId
|
||||
obj.isMarked = false
|
||||
} else {
|
||||
const sIdx = studyList.findIndex(s => s.IsDicom)
|
||||
if (sIdx > -1) {
|
||||
// 判断是否存在层厚为5的序列,否则显示第一个检查的第一个序列
|
||||
const series = studyList[sIdx].SeriesList[0]
|
||||
var imageIdIndex = series.imageIds.length > 1 ? Math.floor(series.imageIds.length / 2) - 1 : 0
|
||||
obj.studyIndex = sIdx
|
||||
obj.seriesIndex = 0
|
||||
obj.series = series
|
||||
obj.series.imageIdIndex = imageIdIndex >= 0 ? imageIdIndex : 0
|
||||
obj.seriesId = series.seriesId
|
||||
obj.isMarked = false
|
||||
}
|
||||
}
|
||||
}
|
||||
if (Object.keys(obj).length === 0) {
|
||||
const sIdx = studyList.findIndex(s => s.IsDicom)
|
||||
if (sIdx > -1) {
|
||||
obj.studyIndex = sIdx
|
||||
obj.seriesIndex = 0
|
||||
obj.series = studyList[obj.studyIndex].SeriesList[obj.seriesIndex]
|
||||
const imageIdIndex = Math.floor(obj.series.imageIds.length / 2)
|
||||
obj.series.imageIdIndex = imageIdIndex >= 0 ? imageIdIndex : 0
|
||||
// obj.seriesId = series.seriesId
|
||||
obj.isMarked = false
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -604,7 +623,9 @@ export default {
|
|||
this.studyIndex = studyIndex
|
||||
this.seriesIndex = seriesIndex
|
||||
this.studyList[studyIndex].SeriesList[seriesIndex].measureData = this.measureData
|
||||
var dicomStatck = this.studyList[studyIndex].SeriesList[seriesIndex]
|
||||
var dicomStatck = Object.assign({},this.studyList[studyIndex].SeriesList[seriesIndex])
|
||||
|
||||
dicomStatck.imageIdIndex = 0
|
||||
this.$emit('loadImageStack', dicomStatck)
|
||||
if (!series.loadStatus && series.modality !== 'SR') {
|
||||
this.loopLoadStatus = -1
|
||||
|
@ -617,9 +638,15 @@ export default {
|
|||
}
|
||||
if (!isAddToTakPool) {
|
||||
var priority = parseInt(new Date().getTime())
|
||||
series.imageIds.map((imageId) => {
|
||||
this.imageList.push({ imageId: imageId, seriesId: series.seriesId, studyIndex: studyIndex, seriesIndex: seriesIndex, visitTaskId: series.visitTaskId, priority })
|
||||
})
|
||||
if (series.isExistMutiFrames) {
|
||||
series.instanceInfoList.map(image => {
|
||||
this.imageList.push({ imageId: image.ImageId, seriesId: series.seriesId, studyIndex: studyIndex, seriesIndex: seriesIndex, visitTaskId: series.visitTaskId, priority })
|
||||
})
|
||||
} else {
|
||||
series.imageIds.map(imageId => {
|
||||
this.imageList.push({ imageId: imageId, seriesId: series.seriesId, studyIndex: studyIndex, seriesIndex: seriesIndex, visitTaskId: series.visitTaskId, priority })
|
||||
})
|
||||
}
|
||||
if (this.imageList.length > 0) {
|
||||
this.loopLoadStatus = 0
|
||||
this.loopLoad()
|
||||
|
@ -638,6 +665,58 @@ export default {
|
|||
|
||||
store.dispatch('reading/setActiveSeries', series)
|
||||
},
|
||||
showMultiFrames(studyIndex, series, seriesIndex, instanceInfo) {
|
||||
this.currentSeriesIndex = seriesIndex
|
||||
var idx = this.visitTaskIdx
|
||||
this.studyIndex = studyIndex
|
||||
this.seriesIndex = seriesIndex
|
||||
this.studyList[studyIndex].SeriesList[seriesIndex].measureData = this.measureData
|
||||
var dicomStatck = Object.assign({},this.studyList[studyIndex].SeriesList[seriesIndex])
|
||||
const imageIds = []
|
||||
if (instanceInfo.KeyFramesList.length > 0) {
|
||||
instanceInfo.KeyFramesList.map(i => {
|
||||
imageIds.push(`wadouri:${localStorage.getItem('location') !== 'USA' ? this.OSSclientConfig.basePath : this.OSSclientConfig.basePath}${instanceInfo.Path}?frame=${i}&instanceId=${instanceInfo.Id}&visitTaskId=${this.visitTaskId}&idx=${studyIndex}|${seriesIndex}|${idx}`)
|
||||
})
|
||||
} else if (instanceInfo.NumberOfFrames && instanceInfo.NumberOfFrames > 1) {
|
||||
for (let j = 0; j < instanceInfo.NumberOfFrames; j++) {
|
||||
imageIds.push(`wadouri:${localStorage.getItem('location') !== 'USA' ? this.OSSclientConfig.basePath : this.OSSclientConfig.basePath}${instanceInfo.Path}?frame=${j}&instanceId=${instanceInfo.Id}&visitTaskId=${this.visitTaskId}&idx=${studyIndex}|${seriesIndex}|${idx}`)
|
||||
}
|
||||
} else {
|
||||
imageIds.push(`wadouri:${localStorage.getItem('location') !== 'USA' ? this.OSSclientConfig.basePath : this.OSSclientConfig.basePath}${instanceInfo.Path}?instanceId=${instanceInfo.Id}&visitTaskId=${this.visitTaskId}&idx=${studyIndex}|${seriesIndex}|${idx}`)
|
||||
}
|
||||
dicomStatck.imageIds = imageIds
|
||||
dicomStatck.imageIdIndex = 0
|
||||
this.$emit('loadImageStack', dicomStatck)
|
||||
this.loopLoadStatus = -1
|
||||
series.isLoading = true
|
||||
var isAddToTakPool = false
|
||||
if (this.showSeriesList.includes(`${studyIndex}_${seriesIndex}`)) {
|
||||
isAddToTakPool = true
|
||||
} else {
|
||||
this.showSeriesList.push(`${studyIndex}_${seriesIndex}`)
|
||||
}
|
||||
if (!isAddToTakPool) {
|
||||
var priority = parseInt(new Date().getTime())
|
||||
if (series.isExistMutiFrames) {
|
||||
series.instanceInfoList.map(image => {
|
||||
this.imageList.push({ imageId: image.ImageId, seriesId: series.seriesId, studyIndex: studyIndex, seriesIndex: seriesIndex, visitTaskId: series.visitTaskId, priority })
|
||||
})
|
||||
} else {
|
||||
series.imageIds.map((imageId) => {
|
||||
this.imageList.push({ imageId: imageId, seriesId: series.seriesId, studyIndex: studyIndex, seriesIndex: seriesIndex, visitTaskId: series.visitTaskId, priority })
|
||||
})
|
||||
}
|
||||
|
||||
if (this.imageList.length > 0) {
|
||||
this.loopLoadStatus = 0
|
||||
this.loopLoad()
|
||||
}
|
||||
} else {
|
||||
requestPoolManager.changePriority(series.seriesId)
|
||||
}
|
||||
|
||||
DicomEvent.$emit('loadMeasurementList', { visitTaskId: this.visitTaskId, taskBlindName: this.taskBlindName })
|
||||
},
|
||||
setSeriesActive(obj) {
|
||||
var idx = this.visitTaskList.findIndex(i => i.VisitTaskId === this.visitTaskId)
|
||||
if (idx === -1) return
|
||||
|
@ -647,7 +726,8 @@ export default {
|
|||
var activeNames = `${this.studyList[obj.studyIndex].StudyId}`
|
||||
if (this.activeNames.includes(activeNames)) return
|
||||
this.activeNames.push(activeNames)
|
||||
this.loadImages(this.visitTaskList[idx])
|
||||
// this.loadImages(this.visitTaskList[idx])
|
||||
this.loadImages(obj)
|
||||
},
|
||||
selectSeries(obj) {
|
||||
var seriseList = this.studyList.map(s => s.SeriesList).flat()
|
||||
|
@ -672,38 +752,25 @@ export default {
|
|||
var activeNames = `${this.studyList[series.studyIndex].StudyId}`
|
||||
if (this.activeNames.includes(activeNames)) return
|
||||
this.activeNames.push(activeNames)
|
||||
this.loadImages(this.visitTaskList[idx])
|
||||
this.loadImages(series)
|
||||
// this.loadImages(this.visitTaskList[idx])
|
||||
store.dispatch('reading/setActiveSeries', series)
|
||||
},
|
||||
loadImages(taskInfo) {
|
||||
// const isBaseLineTask = taskInfo.IsBaseLineTask
|
||||
const isCurrentTask = taskInfo.IsCurrentTask
|
||||
// var priority = isCurrentTask ? parseInt(new Date().getTime()) : 999
|
||||
loadImages(series) {
|
||||
var priority = parseInt(new Date().getTime())
|
||||
this.studyList.map((study, studyIndex) => {
|
||||
study.SeriesList.map((series, seriesIndex) => {
|
||||
if (!series.loadStatus && series.isDicom && series.modality !== 'SR') {
|
||||
// if (isCurrentTask || isBaseLineTask) {
|
||||
// // 当前任务/基线任务下载所有影像
|
||||
// series.imageIds.map(image => {
|
||||
// this.imageList.push({ imageId: image, seriesId: series.seriesId, studyIndex: studyIndex, seriesIndex: seriesIndex, visitTaskId: series.visitTaskId, priority })
|
||||
// })
|
||||
// } else if (!isBaseLineTask && !isCurrentTask && study.IsCriticalSequence) {
|
||||
// // 非当前随访任务下载关键影像
|
||||
// series.imageIds.map(image => {
|
||||
// this.imageList.push({ imageId: image, seriesId: series.seriesId, studyIndex: studyIndex, seriesIndex: seriesIndex, visitTaskId: series.visitTaskId, priority })
|
||||
// })
|
||||
// }
|
||||
// 均只下载关键序列
|
||||
if (!isCurrentTask && study.IsCriticalSequence) {
|
||||
series.imageIds.map(image => {
|
||||
priority = priority - 1
|
||||
this.imageList.push({ imageId: image, seriesId: series.seriesId, studyIndex: studyIndex, seriesIndex: seriesIndex, visitTaskId: series.visitTaskId, priority })
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
})
|
||||
if (!series.loadStatus && series.isDicom && series.modality !== 'SR') {
|
||||
if (series.isExistMutiFrames) {
|
||||
series.instanceInfoList.map(image => {
|
||||
priority = priority - 1
|
||||
this.imageList.push({ imageId: image.ImageId, seriesId: series.seriesId, studyIndex: series.studyIndex, seriesIndex: series.seriesIndex, visitTaskId: series.visitTaskId, priority })
|
||||
})
|
||||
} else {
|
||||
series.imageIds.map(imageId => {
|
||||
priority = priority - 1
|
||||
this.imageList.push({ imageId: imageId, seriesId: series.seriesId, studyIndex: series.studyIndex, seriesIndex: series.seriesIndex, visitTaskId: series.visitTaskId, priority })
|
||||
})
|
||||
}
|
||||
}
|
||||
this.loopLoad()
|
||||
},
|
||||
|
||||
|
@ -711,9 +778,7 @@ export default {
|
|||
if (this.imageList.length > 0) {
|
||||
// requestPoolManager.startTaskTimer()
|
||||
this.imageList.map(image => {
|
||||
requestPoolManager.loadAndCacheImagePlus(image.imageId, image.seriesId, image.priority).then(res => {
|
||||
this.imageLoaded(image, res.data.string('x0020000e'))
|
||||
})
|
||||
requestPoolManager.loadAndCacheImagePlus(image.imageId, image.seriesId, image.priority)
|
||||
})
|
||||
requestPoolManager.sortTaskPool()
|
||||
|
||||
|
@ -733,12 +798,21 @@ export default {
|
|||
}
|
||||
if (!isAddToTakPool) {
|
||||
const priority = parseInt(new Date().getTime())
|
||||
series.imageIds.map(image => {
|
||||
const index = this.cachedImages.findIndex(item => item.uri === image)
|
||||
if (index === -1) {
|
||||
this.imageList.push({ imageId: image, seriesId: series.seriesId, studyIndex: studyIndex, seriesIndex: seriesIndex, visitTaskId: series.visitTaskId, priority })
|
||||
}
|
||||
})
|
||||
if (series.isExistMutiFrames) {
|
||||
series.instanceInfoList.map(image => {
|
||||
const index = this.cachedImages.findIndex(item => item.uri === image)
|
||||
if (index === -1) {
|
||||
this.imageList.push({ imageId: image.ImageId, seriesId: series.seriesId, studyIndex: studyIndex, seriesIndex: seriesIndex, visitTaskId: series.visitTaskId, priority })
|
||||
}
|
||||
})
|
||||
} else {
|
||||
series.imageIds.map(image => {
|
||||
const index = this.cachedImages.findIndex(item => item.uri === image)
|
||||
if (index === -1) {
|
||||
this.imageList.push({ imageId: image, seriesId: series.seriesId, studyIndex: studyIndex, seriesIndex: seriesIndex, visitTaskId: series.visitTaskId, priority })
|
||||
}
|
||||
})
|
||||
}
|
||||
if (this.imageList.length > 0) {
|
||||
this.loopLoadStatus = 0
|
||||
this.loopLoad()
|
||||
|
@ -753,83 +827,6 @@ export default {
|
|||
requestPoolManager.removeTask(series.seriesId)
|
||||
this.$set(this.studyList[studyIndex].SeriesList[seriesIndex], 'isLoading', false)
|
||||
},
|
||||
async imageLoaded(image, seriesUid) {
|
||||
// await store.dispatch('reading/updateStudyList', { visitTaskId: image.visitTaskId, imageId: image.imageId, seriesUid })
|
||||
// console.log(this.studyList[image.studyIndex].SeriesList[image.seriesIndex])
|
||||
if (image.studyIndex > -1 && image.seriesIndex > -1) {
|
||||
var prefetchInstanceCount = this.studyList[image.studyIndex].SeriesList[image.seriesIndex].prefetchInstanceCount
|
||||
var instanceCount = this.studyList[image.studyIndex].SeriesList[image.seriesIndex].instanceCount
|
||||
if (this.studyList[image.studyIndex].SeriesList[image.seriesIndex].imageloadedArr.indexOf(image.imageId) < 0) {
|
||||
this.studyList[image.studyIndex].SeriesList[image.seriesIndex].imageloadedArr.push(image.imageId)
|
||||
prefetchInstanceCount = prefetchInstanceCount + 1
|
||||
this.studyList[image.studyIndex].SeriesList[image.seriesIndex].prefetchInstanceCount = prefetchInstanceCount
|
||||
}
|
||||
if (prefetchInstanceCount >= instanceCount) {
|
||||
this.studyList[image.studyIndex].SeriesList[image.seriesIndex].prefetchInstanceCount = this.studyList[image.studyIndex].SeriesList[image.seriesIndex].instanceCount
|
||||
// 设置当前序列状态为已下载完成
|
||||
this.studyList[image.studyIndex].SeriesList[image.seriesIndex].loadStatus = true
|
||||
}
|
||||
}
|
||||
|
||||
// store.dispatch('reading/updateSeriesList', { visitTaskindex: this.visitTaskIdx, studyIndex: image.studyIndex, seriesIndex: image.seriesIndex, imageId: image.imageId })
|
||||
},
|
||||
// instance下载成功回调
|
||||
async cornerstoneImageLoaded(e) {
|
||||
// var idx = this.visitTaskList.findIndex(i => i.VisitTaskId === this.visitTaskId)
|
||||
// if (idx === -1) return
|
||||
// this.studyList = this.visitTaskList[idx].StudyList
|
||||
// if (!this.studyList || this.studyList.length === 0) {
|
||||
// return
|
||||
// }
|
||||
// if (!this.visitTaskList[idx].IsInit) {
|
||||
// const loading = this.$loading({ fullscreen: true })
|
||||
// await store.dispatch('reading/getMeasuredData', this.visitTaskList[idx].VisitTaskId)
|
||||
// await store.dispatch('reading/getStudyInfo', { trialId: this.trialId, subjectVisitId: this.visitTaskList[idx].VisitId, visitTaskId: this.visitTaskList[idx].VisitTaskId, taskBlindName: this.visitTaskList[idx].TaskBlindName })
|
||||
// await store.dispatch('reading/getReadingQuestionAndAnswer', { trialId: this.trialId, visitTaskId: this.visitTaskList[idx].VisitTaskId })
|
||||
// await store.dispatch('reading/getDicomReadingQuestionAnswer', { trialId: this.trialId, visitTaskId: this.visitTaskList[idx].VisitTaskId })
|
||||
// await store.dispatch('reading/setStatus', { visitTaskId: this.visitTaskList[idx].VisitTaskId })
|
||||
// loading.close()
|
||||
// }
|
||||
// await store.dispatch('reading/updateStudyList', { visitTaskId: this.visitTaskId, imageId: e.detail.image.imageId, seriesUid: e.detail.image.data.string('x0020000e') })
|
||||
// const uri = e.detail.image.sharedCacheKey
|
||||
// const index = this.cachedImages.findIndex(item => item.uri === uri)
|
||||
// if (index === -1) {
|
||||
// this.cachedImages.push({ uri: uri, timestamp: new Date().getTime() })
|
||||
// } else {
|
||||
// this.cachedImages[index].timestamp = new Date().getTime()
|
||||
// }
|
||||
// var imageId = e.detail.image.imageId
|
||||
// var seriesUid = e.detail.image.data.string('x0020000e')
|
||||
// var studyIndex = -1
|
||||
// var seriesIndex = -1
|
||||
// for (let i = 0; i < this.studyList.length; ++i) {
|
||||
// for (let j = 0; j < this.studyList[i].SeriesList.length; ++j) {
|
||||
// if (this.studyList[i].SeriesList[j].seriesUid === seriesUid) {
|
||||
// studyIndex = i
|
||||
// seriesIndex = j
|
||||
// break
|
||||
// }
|
||||
// }
|
||||
// if (studyIndex > 0) break
|
||||
// }
|
||||
// if (seriesIndex < 0) return
|
||||
|
||||
// const imageIdIndex = this.studyList[studyIndex].SeriesList[seriesIndex].imageIds.indexOf(imageId)
|
||||
// if (imageIdIndex < 0) return
|
||||
// if (this.studyList[studyIndex].SeriesList[seriesIndex].imageloadedArr.indexOf(imageId) < 0) {
|
||||
// if (this.studyList[studyIndex].SeriesList[seriesIndex].prefetchInstanceCount >= this.studyList[studyIndex].SeriesList[seriesIndex].instanceCount) {
|
||||
// // 设置当前序列状态为已下载完成
|
||||
// this.studyList[studyIndex].SeriesList[seriesIndex].loadStatus = true
|
||||
// }
|
||||
// }
|
||||
},
|
||||
cornerstoneimagecachechanged(e) {
|
||||
const cacheInfo = cornerstone.imageCache.getCacheInfo()
|
||||
console.log(cacheInfo)
|
||||
},
|
||||
cornerstoneimagecachefull(e) {
|
||||
console.log('超过内存了')
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
@ -977,3 +974,40 @@ export default {
|
|||
}
|
||||
|
||||
</style>
|
||||
<style>
|
||||
.instance_frame_wrapper{
|
||||
min-width: 120px;
|
||||
background-color: #2c2c2c;
|
||||
border: 1px solid #2c2c2c;
|
||||
padding: 5px;
|
||||
}
|
||||
.frame_list{
|
||||
max-height: 500px;
|
||||
overflow-y: auto;
|
||||
}
|
||||
.instance_frame_wrapper ::-webkit-scrollbar {
|
||||
width: 7px;
|
||||
height: 7px;
|
||||
}
|
||||
.instance_frame_wrapper ::-webkit-scrollbar-thumb {
|
||||
border-radius: 10px;
|
||||
background: #d0d0d0;
|
||||
}
|
||||
.frame_content{
|
||||
height: 50px;
|
||||
padding: 5px;
|
||||
display: flex;
|
||||
justify-content: flex-start;
|
||||
color: #ddd;
|
||||
font-size: 12px;
|
||||
border: 1px solid #404040;
|
||||
}
|
||||
.frame_content:hover {
|
||||
/* font-weight: bold; */
|
||||
/* box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1); */
|
||||
cursor: pointer;
|
||||
/* color: #428bca; */
|
||||
border-color: #213a54 !important;
|
||||
background-color: #213a54;
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -57,10 +57,11 @@ export default {
|
|||
this.getHotkeys()
|
||||
},
|
||||
methods: {
|
||||
getHotkeys(isReset = false) {
|
||||
async getHotkeys(isReset = false) {
|
||||
this.loading = true
|
||||
this.hotKeyList = []
|
||||
getDoctorShortcutKey({ imageToolType: this.readingTool }).then(res => {
|
||||
try{
|
||||
let res = await getDoctorShortcutKey({ imageToolType: this.readingTool })
|
||||
res.Result.map(item => {
|
||||
this.hotKeyList.push({ id: item.Id, keys: { controlKey: { altKey: item.AltKey, ctrlKey: item.CtrlKey, shiftKey: item.ShiftKey, metaKey: item.MetaKey, key: item.Keyboardkey, code: item.Code }, text: item.Text }, label: item.ShortcutKeyEnum })
|
||||
})
|
||||
|
@ -68,11 +69,12 @@ export default {
|
|||
this.$emit('reset', this.hotKeyList)
|
||||
}
|
||||
this.loading = false
|
||||
}).catch(() => {
|
||||
}catch(e){
|
||||
this.loading = false
|
||||
})
|
||||
}
|
||||
|
||||
},
|
||||
handleSave() {
|
||||
async handleSave() {
|
||||
this.loading = true
|
||||
var params = {
|
||||
imageToolType: this.readingTool,
|
||||
|
@ -93,28 +95,34 @@ export default {
|
|||
)
|
||||
})
|
||||
params.shortcutKeyList = shortcutKeyList
|
||||
setShortcutKey(params).then(res => {
|
||||
try {
|
||||
await setShortcutKey(params)
|
||||
this.$emit('reset', this.hotKeyList)
|
||||
this.$emit('close')
|
||||
this.loading = false
|
||||
}).catch(() => {
|
||||
}catch(e){
|
||||
this.loading = false
|
||||
})
|
||||
}
|
||||
},
|
||||
handleReset() {
|
||||
async handleReset() {
|
||||
// '是否确认重置?'
|
||||
this.$confirm(this.$t('trials:hotkeys:message:confirmReset'), {
|
||||
type: 'warning',
|
||||
distinguishCancelAndClose: true
|
||||
})
|
||||
.then(() => {
|
||||
this.loading = true
|
||||
restoreDefaultShortcutKey({ imageToolType: this.readingTool }).then(res => {
|
||||
this.$message.success(this.$t('trials:hotkeys:message:resetSuccessfully')) // '重置成功!'
|
||||
this.getHotkeys(true)
|
||||
}).catch(() => { this.loading = false })
|
||||
})
|
||||
.catch(action => {})
|
||||
const confirm = await this.$confirm(
|
||||
this.$t('trials:hotkeys:message:confirmReset'),
|
||||
{
|
||||
type: 'warning',
|
||||
distinguishCancelAndClose: true
|
||||
}
|
||||
)
|
||||
if (confirm !== 'confirm') return
|
||||
this.loading = true
|
||||
try{
|
||||
await restoreDefaultShortcutKey({ imageToolType: this.readingTool })
|
||||
this.$message.success(this.$t('trials:hotkeys:message:resetSuccessfully')) // '重置成功!'
|
||||
this.getHotkeys(true)
|
||||
this.loading = false
|
||||
}catch(e){
|
||||
this.loading = false
|
||||
}
|
||||
},
|
||||
handleHotkeyVerify(hotkey) {
|
||||
for (const item of this.hotKeyList) {
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
</div>
|
||||
<div class="right-wrapper">
|
||||
<div class="right-content">
|
||||
<iframe v-if="selected.filePath" :src="`/static/pdfjs/web/viewer.html?file=${OSSclientConfig.basePath}${selected.filePath}?userName=${currentUser}`" width="100%" height="100%" frameborder="0" />
|
||||
<iframe v-if="selected.filePath" :src="`/static/pdfjs/web/viewer.html?file=${OSSclientConfig.basePath}${selected.filePath}?userName=${currentUser}&COMPANY=${COMPANY}`" width="100%" height="100%" frameborder="0" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -44,26 +44,30 @@ export default {
|
|||
},
|
||||
fileList: [],
|
||||
loading: false,
|
||||
currentUser: zzSessionStorage.getItem('userName')
|
||||
currentUser: zzSessionStorage.getItem('userName'),
|
||||
COMPANY:process.env.VUE_APP_COMPANY_NAME
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.getList()
|
||||
},
|
||||
methods: {
|
||||
getList() {
|
||||
async getList() {
|
||||
this.loading = true
|
||||
var param = {
|
||||
trialId: this.trialId
|
||||
}
|
||||
getManualList(param).then(res => {
|
||||
try{
|
||||
let res = await getManualList(param)
|
||||
this.fileList = res.Result
|
||||
|
||||
if (this.fileList.length > 0) {
|
||||
this.preview(this.fileList[0])
|
||||
}
|
||||
this.loading = false
|
||||
}).catch(() => { this.loading = false })
|
||||
}catch(e){
|
||||
this.loading = false
|
||||
}
|
||||
},
|
||||
preview(file) {
|
||||
this.$set(this.selected, 'filePath', file.Path)
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
<div class="base-dialog-body" style="height:380px;overflow-y: auto;">
|
||||
<el-form ref="otherForm" :model="form">
|
||||
<el-form-item
|
||||
label="是否自动切换到下一任务"
|
||||
:label="$t('trials:reading:label:autoSwitch')"
|
||||
prop="AutoCutNextTask"
|
||||
:rules="[
|
||||
{ required: true, message: $t('common:ruleMessage:select')}
|
||||
|
@ -35,27 +35,27 @@ export default {
|
|||
this.initForm()
|
||||
},
|
||||
methods: {
|
||||
initForm() {
|
||||
async initForm() {
|
||||
this.loading = true
|
||||
getAutoCutNextTask().then(async res => {
|
||||
try{
|
||||
await getAutoCutNextTask()
|
||||
this.form.AutoCutNextTask = res.Result.AutoCutNextTask
|
||||
this.loading = false
|
||||
}).catch(() => {
|
||||
}catch(e){
|
||||
this.loading = false
|
||||
})
|
||||
}
|
||||
},
|
||||
handleSave() {
|
||||
this.$refs.otherForm.validate((valid) => {
|
||||
if (valid) {
|
||||
this.loading = true
|
||||
setAutoCutNextTask(this.form).then((res) => {
|
||||
this.loading = false
|
||||
this.$message.success(this.$t('common:message:savedSuccessfully'))
|
||||
}).catch(() => {
|
||||
this.loading = false
|
||||
})
|
||||
}
|
||||
})
|
||||
async handleSave() {
|
||||
let valid = await this.$refs.otherForm.validate()
|
||||
if (!valid) return
|
||||
this.loading = true
|
||||
try{
|
||||
await setAutoCutNextTask(this.form)
|
||||
this.loading = false
|
||||
this.$message.success(this.$t('common:message:savedSuccessfully'))
|
||||
}catch(e){
|
||||
this.loading = false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,16 +7,19 @@
|
|||
style="width: 100%"
|
||||
class="wl-table"
|
||||
>
|
||||
<!-- 名称 -->
|
||||
<el-table-column
|
||||
label="名称"
|
||||
:label="$t('trials:reading:label:wlTplName')"
|
||||
prop="TemplateName"
|
||||
/>
|
||||
<!-- 窗宽 -->
|
||||
<el-table-column
|
||||
label="窗宽"
|
||||
:label="$t('trials:reading:label:wlTplWW')"
|
||||
prop="WW"
|
||||
/>
|
||||
<!-- 窗位 -->
|
||||
<el-table-column
|
||||
label="窗位"
|
||||
:label="$t('trials:reading:label:wlTplWL')"
|
||||
prop="WL"
|
||||
/>
|
||||
<el-table-column
|
||||
|
@ -24,22 +27,25 @@
|
|||
width="200"
|
||||
>
|
||||
<template slot="header">
|
||||
<!-- 新增 -->
|
||||
<el-button
|
||||
size="mini"
|
||||
@click="handleAdd"
|
||||
>Add</el-button>
|
||||
>{{ $t('common:button:new') }}</el-button>
|
||||
</template>
|
||||
<template slot-scope="scope">
|
||||
<!-- 编辑 -->
|
||||
<el-button
|
||||
type="text"
|
||||
size="mini"
|
||||
@click="handleEdit(scope.row)"
|
||||
>Edit</el-button>
|
||||
>{{ $t('common:button:edit') }}</el-button>
|
||||
<!-- 删除 -->
|
||||
<el-button
|
||||
type="text"
|
||||
size="mini"
|
||||
@click="handleDelete(scope.row)"
|
||||
>Delete</el-button>
|
||||
>{{ $t('common:button:delete') }}</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
@ -77,16 +83,19 @@ export default {
|
|||
this.getWL()
|
||||
},
|
||||
methods: {
|
||||
getWL() {
|
||||
async getWL() {
|
||||
this.loading = true
|
||||
getUserWLTemplateList().then(res => {
|
||||
try {
|
||||
const res = await getUserWLTemplateList()
|
||||
this.tableData = res.Result
|
||||
this.loading = false
|
||||
this.$emit('getWwcTpl')
|
||||
}).catch(() => { this.loading = false })
|
||||
} catch (e) {
|
||||
this.loading = false
|
||||
}
|
||||
},
|
||||
handleAdd() {
|
||||
this.customWwc.title = this.$t('common:button:add')
|
||||
this.customWwc.title = this.$t('common:button:new')
|
||||
this.row = {}
|
||||
this.customWwc.visible = true
|
||||
},
|
||||
|
@ -95,20 +104,27 @@ export default {
|
|||
this.row = Object.assign({}, row)
|
||||
this.customWwc.visible = true
|
||||
},
|
||||
handleDelete(row) {
|
||||
var msg = this.$t('trials:staffResearch:message:confirmDel')
|
||||
this.$confirm(msg, {
|
||||
type: 'warning',
|
||||
distinguishCancelAndClose: true
|
||||
}).then(() => {
|
||||
this.loading = true
|
||||
deleteUserWLTemplate(row.Id).then(res => {
|
||||
this.loading = false
|
||||
// 删除成功
|
||||
this.$message.success(this.$t('common:message:deletedSuccessfully'))
|
||||
this.getWL()
|
||||
}).catch(() => { this.loading = false })
|
||||
})
|
||||
async handleDelete(row) {
|
||||
// '是否确认删除?'
|
||||
var msg = this.$t('trials:reading:wlTemplate:delete')
|
||||
const confirm = await this.$confirm(
|
||||
msg,
|
||||
{
|
||||
type: 'warning',
|
||||
distinguishCancelAndClose: true
|
||||
}
|
||||
)
|
||||
if (confirm !== 'confirm') return
|
||||
this.loading = true
|
||||
try {
|
||||
await deleteUserWLTemplate(row.Id)
|
||||
this.loading = false
|
||||
// 删除成功
|
||||
this.$message.success(this.$t('common:message:deletedSuccessfully'))
|
||||
this.getWL()
|
||||
} catch (e) {
|
||||
this.loading = false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,14 +8,16 @@
|
|||
size="small"
|
||||
>
|
||||
<!-- 名称 -->
|
||||
<el-form-item label="名称" prop="TemplateName">
|
||||
<el-form-item :label="$t('trials:reading:label:wlTplName')" prop="TemplateName">
|
||||
<el-input v-model="form.TemplateName" />
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('CustomWwwcForm:form:label:ww')" prop="WW">
|
||||
<el-input-number v-model="form.WW" controls-position="right" :min="1" :precision="0" :step="1" />
|
||||
<!-- 窗宽 -->
|
||||
<el-form-item :label="$t('trials:reading:label:wlTplWW')" prop="WW">
|
||||
<el-input-number v-model="form.WW" controls-position="right" :min="1" :max="100000" :precision="0" :step="1" />
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('CustomWwwcForm:form:label:wl')" prop="WL">
|
||||
<el-input-number v-model="form.WL" controls-position="right" :precision="0" :step="1" />
|
||||
<!-- 窗位 -->
|
||||
<el-form-item :label="$t('trials:reading:label:wlTplWL')" prop="WL">
|
||||
<el-input-number v-model="form.WL" controls-position="right" :min="-100000" :max="100000" :precision="0" :step="1" />
|
||||
</el-form-item>
|
||||
<el-form-item style="text-align:right;">
|
||||
<!-- Cancel -->
|
||||
|
@ -81,24 +83,23 @@ export default {
|
|||
}
|
||||
},
|
||||
methods: {
|
||||
handleSave() {
|
||||
this.$refs.wlForm.validate((valid) => {
|
||||
if (valid) {
|
||||
this.loading = true
|
||||
addOrUpdateUserWLTemplate(this.form).then((res) => {
|
||||
this.loading = false
|
||||
this.$emit('getWL')
|
||||
this.$emit('close')
|
||||
if (this.form.Id) {
|
||||
this.$message.success(this.$t('common:message:savedSuccessfully'))
|
||||
} else {
|
||||
this.$message.success(this.$t('common:message:addedSuccessfully'))
|
||||
}
|
||||
}).catch(() => {
|
||||
this.loading = false
|
||||
})
|
||||
async handleSave() {
|
||||
const valid = await this.$refs.wlForm.validate()
|
||||
if (!valid) return
|
||||
this.loading = true
|
||||
try {
|
||||
await addOrUpdateUserWLTemplate(this.form)
|
||||
this.loading = false
|
||||
this.$emit('getWL')
|
||||
this.$emit('close')
|
||||
if (this.form.Id) {
|
||||
this.$message.success(this.$t('common:message:savedSuccessfully'))
|
||||
} else {
|
||||
this.$message.success(this.$t('common:message:addedSuccessfully'))
|
||||
}
|
||||
})
|
||||
} catch (e) {
|
||||
this.loading = false
|
||||
}
|
||||
},
|
||||
handleCancel() {
|
||||
this.$emit('close')
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<template>
|
||||
<div ref="container" style="width:100%;height:100%" class="dicom-container">
|
||||
<!-- 访视阅片 -->
|
||||
<div v-if="(isReadingTaskViewInOrder || (!isReadingTaskViewInOrder && isShow)) && readingCategory=== 1 && CriterionType !== 0" class="reading-wrapper">
|
||||
<div v-if="(isReadingTaskViewInOrder === 1 || ((isReadingTaskViewInOrder !== 1) && isShow)) && readingCategory=== 1 && CriterionType !== 0" class="reading-wrapper">
|
||||
<el-tabs v-model="activeName" v-loading="loading" :before-leave="beforeLeave">
|
||||
<!-- 阅片 -->
|
||||
<el-tab-pane :label="$t('trials:reading:tabTitle:review')" name="read">
|
||||
|
@ -19,22 +19,24 @@
|
|||
:is-exists-clinical-data="isExistsClinicalData"
|
||||
:is-exists-no-dicom-file="isExistsNoDicomFile"
|
||||
:is-exists-manual="isExistsManual"
|
||||
:ise-c-r-f-show-in-dicom-reading="IseCRFShowInDicomReading"
|
||||
@previewCD="previewCD"
|
||||
/>
|
||||
</el-tab-pane>
|
||||
<!-- 报告 -->
|
||||
<el-tab-pane :label="$t('trials:reading:tabTitle:report')" name="report">
|
||||
<el-tab-pane v-if="!IseCRFShowInDicomReading" :label="$t('trials:reading:tabTitle:report')" name="report">
|
||||
<ReportPage v-if="tabs.includes('report') && isShow" ref="reportPage" :question-form-change-state="questionFormChangeState" :visit-task-id="visitTaskId" />
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
</div>
|
||||
<div v-if="(isReadingTaskViewInOrder || (!isReadingTaskViewInOrder && isShow)) && readingCategory=== 1 && CriterionType === 0" class="reading-wrapper">
|
||||
<div v-if="(isReadingTaskViewInOrder === 1 || ((isReadingTaskViewInOrder !== 1) && isShow)) && readingCategory=== 1 && CriterionType === 0" class="reading-wrapper">
|
||||
<el-tabs v-model="activeName" v-loading="loading" :before-leave="beforeLeaveCustomize">
|
||||
<!-- 阅片 -->
|
||||
<el-tab-pane :label="$t('trials:reading:tabTitle:review')" name="read">
|
||||
<CustomizeReadPage
|
||||
v-if="tabs.includes('read')"
|
||||
:trial-id="trialId"
|
||||
:trial-reading-criterion-id="TrialReadingCriterionId"
|
||||
:visit-task-id="visitTaskId"
|
||||
:subject-id="subjectId"
|
||||
:subject-code="subjectCode"
|
||||
|
@ -116,6 +118,7 @@
|
|||
:trial-id="trialId"
|
||||
:subject-id="subjectId"
|
||||
:visit-task-id="cdVisitTaskId"
|
||||
:is-reading-show-subject-info="isReadingShowSubjectInfo"
|
||||
/>
|
||||
</div>
|
||||
<span v-if="!closeCDVisible" slot="footer" class="dialog-footer">
|
||||
|
@ -134,24 +137,24 @@
|
|||
<!-- 提示 -->
|
||||
{{ $t('trials:iRecist:warnning:msg44') }}
|
||||
</span>
|
||||
<div style="line-height: 24px;">
|
||||
<div style="font-size: 14px;font-weight: bold;">
|
||||
<div>
|
||||
<div>
|
||||
<!-- 您确定当前访视的整体评估结果为PD。根据《独立影像评估章程》,该访视进入iRECIST阅片环节。请对新病灶进行重新评估: -->
|
||||
{{ $t('trials:iRecist:warnning:msg45') }}
|
||||
</div>
|
||||
<div style="color: #f44336;font-size: 13px;margin: 5px;">
|
||||
<div style="color: #f44336;font-size: 12px;margin: 5px;">
|
||||
<!-- (1)新病灶可转为:新靶病灶、新非靶病灶、其它既往新病灶。 -->
|
||||
{{ $t('trials:iRecist:warnning:msg46') }}
|
||||
</div>
|
||||
<div style="color: #f44336;font-size: 13px;margin: 5px;">
|
||||
<div style="color: #f44336;font-size: 12px;margin: 5px;">
|
||||
<!-- (2)新靶病灶:状态为明确的新病灶才能转换为新靶病灶。新靶病灶的选择规则与RECIST1.1相同;如果当前病灶已有标记,但不符合新靶病灶的要求,请清除标记,重新标注。 -->
|
||||
{{ $t('trials:iRecist:warnning:msg47') }}
|
||||
</div>
|
||||
<div style="color: #f44336;font-size: 13px;margin: 5px;">
|
||||
<div style="color: #f44336;font-size: 12px;margin: 5px;">
|
||||
<!-- (3)新非靶病灶:状态为明确的新病灶才能转换为新非靶病灶。新靶病灶的选择规则与RECIST1.1相同。 -->
|
||||
{{ $t('trials:iRecist:warnning:msg48') }}
|
||||
</div>
|
||||
<div style="color: #f44336;font-size: 13px;margin: 5px;">
|
||||
<div style="color: #f44336;font-size: 12px;margin: 5px;">
|
||||
<!-- (4)其它既往新病灶:系统会自动将状态为疑似、消失的新病灶,转换为其它既往新病灶,无需修改。 -->
|
||||
{{ $t('trials:iRecist:warnning:msg49') }}
|
||||
</div>
|
||||
|
@ -163,12 +166,10 @@
|
|||
</span>
|
||||
</el-dialog>
|
||||
|
||||
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import { getNextTask, readClinicalData, verifyDefaultQuestionBeAnswer } from '@/api/trials'
|
||||
import { confirmTaskReminder } from '@/api/reading'
|
||||
import ReadPage from './components/ReadPage'
|
||||
import CustomizeReadPage from './customize/CustomizeReadPage'
|
||||
import ReportPage from './components/ReportPage'
|
||||
|
@ -179,7 +180,7 @@ import OncologyReview from '@/views/trials/trials-panel/reading/oncology-review'
|
|||
import ClinicalData from '@/views/trials/trials-panel/reading/clinical-data'
|
||||
import DicomEvent from './components/DicomEvent'
|
||||
import store from '@/store'
|
||||
import { getToken } from '@/utils/auth'
|
||||
// import { getToken } from '@/utils/auth'
|
||||
import { changeURLStatic } from '@/utils/history.js'
|
||||
import requestPoolManager from '@/utils/request-pool'
|
||||
export default {
|
||||
|
@ -212,7 +213,7 @@ export default {
|
|||
isNeedReadClinicalData: false,
|
||||
isReadClinicalData: false,
|
||||
digitPlaces: 2,
|
||||
isReadingTaskViewInOrder: false,
|
||||
isReadingTaskViewInOrder: null,
|
||||
firstTaskReadingCategory: null,
|
||||
criterionType: null,
|
||||
readingTool: null,
|
||||
|
@ -227,8 +228,7 @@ export default {
|
|||
isFullscreen: false,
|
||||
tipVisible: false,
|
||||
closeCDVisible: false,
|
||||
cdVisitTaskId: '',
|
||||
isConfirmTaskReminder: false
|
||||
cdVisitTaskId: ''
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
|
@ -245,7 +245,7 @@ export default {
|
|||
store.dispatch('reading/setLastCanvasTaskId', '')
|
||||
this.isQualityIssueSaved = false
|
||||
this.firstTaskReadingCategory = this.readingCategory
|
||||
if (!this.isReadingTaskViewInOrder) {
|
||||
if (this.isReadingTaskViewInOrder !== 1) {
|
||||
// 清除缓存visitTaskList
|
||||
store.dispatch('reading/resetVisitTasks')
|
||||
}
|
||||
|
@ -263,18 +263,19 @@ export default {
|
|||
this.subjectCode = this.$router.currentRoute.query.subjectCode
|
||||
this.subjectId = this.$router.currentRoute.query.subjectId
|
||||
this.visitTaskId = this.$router.currentRoute.query.visitTaskId
|
||||
this.isReadingTaskViewInOrder = JSON.parse(this.$router.currentRoute.query.isReadingTaskViewInOrder)
|
||||
this.criterionType = this.$router.currentRoute.query.criterionType
|
||||
this.readingTool = this.$router.currentRoute.query.readingTool
|
||||
// this.isReadingTaskViewInOrder = parseInt(this.$router.currentRoute.query.isReadingTaskViewInOrder)
|
||||
// this.criterionType = this.$router.currentRoute.query.criterionType
|
||||
// this.readingTool = this.$router.currentRoute.query.readingTool
|
||||
this.TrialReadingCriterionId = this.$router.currentRoute.query.TrialReadingCriterionId
|
||||
this.isNewSubject = this.$router.currentRoute.query.isNewSubject
|
||||
if (this.isNewSubject && this.isReadingTaskViewInOrder) {
|
||||
// 已开始受试者${this.subjectCode}阅片任务
|
||||
var msg = this.$t('trials:reading:warnning:msg1')
|
||||
msg = msg.replace('xxx', this.subjectCode)
|
||||
this.$message.success(msg)
|
||||
changeURLStatic('isNewSubject', '')
|
||||
}
|
||||
// this.isNewSubject = this.$router.currentRoute.query.isNewSubject
|
||||
|
||||
// if (this.isNewSubject && this.isReadingTaskViewInOrder !== 0) {
|
||||
// // 已开始受试者${this.subjectCode}阅片任务
|
||||
// var msg = this.$t('trials:reading:warnning:msg1')
|
||||
// msg = msg.replace('xxx', this.subjectCode)
|
||||
// this.$message.success(msg)
|
||||
// changeURLStatic('isNewSubject', '')
|
||||
// }
|
||||
if (this.$router.currentRoute.query.TokenKey) {
|
||||
store.dispatch('user/setToken', this.$router.currentRoute.query.TokenKey)
|
||||
changeURLStatic('TokenKey', '')
|
||||
|
@ -318,7 +319,9 @@ export default {
|
|||
// }
|
||||
// }
|
||||
this.subjectId = res.Result.SubjectId
|
||||
localStorage.setItem('subjectId', res.Result.SubjectId)
|
||||
this.subjectCode = res.Result.SubjectCode
|
||||
localStorage.setItem('subjectCode', res.Result.SubjectCode)
|
||||
this.taskBlindName = res.Result.TaskBlindName
|
||||
this.isReadingShowSubjectInfo = res.Result.IsReadingShowSubjectInfo
|
||||
this.isReadingShowPreviousResults = res.Result.IsReadingShowPreviousResults
|
||||
|
@ -330,7 +333,8 @@ export default {
|
|||
this.CriterionType = res.Result.CriterionType
|
||||
this.digitPlaces = res.Result.DigitPlaces
|
||||
this.IseCRFShowInDicomReading = res.Result.IseCRFShowInDicomReading
|
||||
this.isConfirmTaskReminder = res.Result.IsConfirmReminder
|
||||
this.isReadingTaskViewInOrder = res.Result.IsReadingTaskViewInOrder
|
||||
localStorage.setItem('isReadingTaskViewInOrder', this.isReadingTaskViewInOrder)
|
||||
localStorage.setItem('CriterionType', res.Result.CriterionType)
|
||||
localStorage.setItem('digitPlaces', res.Result.DigitPlaces)
|
||||
this.readingCategory = res.Result.ReadingCategory
|
||||
|
@ -345,10 +349,7 @@ export default {
|
|||
this.activeName = 'read'
|
||||
this.tabs = [this.activeName]
|
||||
}
|
||||
if (!this.isConfirmTaskReminder && res.Result.IsBaseLineTask && parseInt(this.criterionType) !== 10) {
|
||||
this.handleConfirmReminder()
|
||||
}
|
||||
if (this.firstTaskReadingCategory === 1 && res.Result.ReadingCategory === 1 && this.isReadingTaskViewInOrder && flag) {
|
||||
if (this.firstTaskReadingCategory === 1 && res.Result.ReadingCategory === 1 && this.isReadingTaskViewInOrder !== 0 && flag) {
|
||||
this.activeName = 'read'
|
||||
this.tabs = [this.activeName]
|
||||
this.$nextTick(() => {
|
||||
|
@ -377,7 +378,7 @@ export default {
|
|||
this.$refs.reportPage.setScrollTop(1)
|
||||
})
|
||||
} else {
|
||||
this.isShow = false
|
||||
// this.isShow = false
|
||||
}
|
||||
return Promise.resolve(true)
|
||||
},
|
||||
|
@ -477,38 +478,17 @@ export default {
|
|||
})
|
||||
})
|
||||
},
|
||||
async handleConfirmReminder() {
|
||||
let criterionType = parseInt(this.criterionType)
|
||||
criterionType = criterionType === 17 ? 1 : criterionType
|
||||
let i = this.$d.CriterionType.findIndex(i=>i.value === criterionType)
|
||||
if (i === -1) return
|
||||
let criterionName = this.$d.CriterionType[i].label
|
||||
let msg = this.$t('trials:reading:criterion:message').replace('xxx', criterionName)
|
||||
this.$alert(msg, this.$t('common:message:prompt'), {
|
||||
callback: action => {
|
||||
let params = {
|
||||
visitTaskId: this.visitTaskId,
|
||||
}
|
||||
const loading = this.$loading({ fullscreen: true })
|
||||
confirmTaskReminder(params).then(res=>{
|
||||
loading.close()
|
||||
this.isConfirmTaskReminder = true
|
||||
this.$message.success(this.$t("common:message:confirmSuccessfully"))
|
||||
}).catch(e=>{
|
||||
console.log(e)
|
||||
loading.close()
|
||||
})
|
||||
}
|
||||
})
|
||||
},
|
||||
handleConfirmCD() {
|
||||
async handleConfirmCD() {
|
||||
this.loading = true
|
||||
var visitTaskId = this.visitTaskId
|
||||
readClinicalData({ visitTaskId }).then(res => {
|
||||
try {
|
||||
await readClinicalData({ visitTaskId })
|
||||
this.loading = false
|
||||
this.dialogVisible = false
|
||||
this.isReadClinicalData = true
|
||||
}).catch(() => { this.loading = false })
|
||||
} catch (e) {
|
||||
this.loading = false
|
||||
}
|
||||
},
|
||||
previewCD() {
|
||||
this.closeCDVisible = true
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
</div>
|
||||
<!-- 文件层级 -->
|
||||
<div v-if="study.NoneDicomStudyFileList.length === 0" class="empty-text">
|
||||
<slot name="empty">暂无数据</slot>
|
||||
<slot name="empty">{{ $t('trials:audit:message:noData') }}</slot>
|
||||
</div>
|
||||
<div v-else id="imgList" style="height:100%;">
|
||||
<div
|
||||
|
@ -28,7 +28,14 @@
|
|||
class="img-box"
|
||||
@click="selected(item,i,j,true)"
|
||||
>
|
||||
{{ `${j+1}. ${item.FileName}` }}
|
||||
<div v-if="item.FileName.length < 15" class="img-text">
|
||||
{{ `${j+1}. ${item.FileName}` }}
|
||||
</div>
|
||||
<el-tooltip v-else :content="item.FileName" placement="bottom">
|
||||
<div class="img-text">
|
||||
{{ `${j+1}. ${item.FileName}` }}
|
||||
</div>
|
||||
</el-tooltip>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
@ -95,10 +102,12 @@ export default {
|
|||
subjectCode: '',
|
||||
visistTaskId: '',
|
||||
taskBlindName: '',
|
||||
readingTaskState: 2
|
||||
readingTaskState: 2,
|
||||
bp: []
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
async mounted() {
|
||||
this.bp = await this.$getBodyPart(this.$route.query.trialId)
|
||||
if (this.$router.currentRoute.query.TokenKey) {
|
||||
store.dispatch('user/setToken', this.$router.currentRoute.query.TokenKey)
|
||||
changeURLStatic('TokenKey', '')
|
||||
|
@ -186,7 +195,7 @@ export default {
|
|||
}
|
||||
var arr = bodyPart.split(separator)
|
||||
var newArr = arr.map(i => {
|
||||
return this.$fd('Bodypart', i.trim())
|
||||
return this.$fd('Bodypart', i.trim(), 'Code', { Bodypart: this.bp }, 'Name')
|
||||
})
|
||||
return newArr.join(' | ')
|
||||
}
|
||||
|
@ -263,13 +272,19 @@ export default {
|
|||
display: inline-block;
|
||||
box-sizing: border-box;
|
||||
border-bottom: 2px solid #f3f3f3;
|
||||
width: 180px;
|
||||
height: 50px;
|
||||
line-height: 50px;
|
||||
cursor: pointer;
|
||||
// margin-bottom: 5px;
|
||||
padding-left: 5px;
|
||||
}
|
||||
.img-text{
|
||||
display: inline-block;
|
||||
width: 200px;
|
||||
height: 50px;
|
||||
line-height: 50px;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis; /* 用省略号表示溢出的文本 */
|
||||
white-space: nowrap;
|
||||
}
|
||||
.img-box:nth-last-child(1){
|
||||
margin-bottom: 0px;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,452 @@
|
|||
import * as cornerstoneTools from 'cornerstone-tools'
|
||||
const external = cornerstoneTools.external
|
||||
|
||||
// State
|
||||
const getToolState = cornerstoneTools.getToolState
|
||||
const toolStyle = cornerstoneTools.toolStyle
|
||||
const toolColors = cornerstoneTools.toolColors
|
||||
const getModule = cornerstoneTools.getModule
|
||||
|
||||
// Drawing
|
||||
const getNewContext = cornerstoneTools.import('drawing/getNewContext')
|
||||
const draw = cornerstoneTools.import('drawing/draw')
|
||||
const setShadow = cornerstoneTools.import('drawing/setShadow')
|
||||
const drawCircle = cornerstoneTools.import('drawing/drawCircle')
|
||||
const drawHandles = cornerstoneTools.import('drawing/drawHandles')
|
||||
const drawLinkedTextBox = cornerstoneTools.import('drawing/drawLinkedTextBox')
|
||||
|
||||
// Util
|
||||
// const calculateSUV = cornerstoneTools.import('util/calculateSUV')
|
||||
|
||||
const throttle = cornerstoneTools.import('util/throttle')
|
||||
const getPixelSpacing = cornerstoneTools.import('util/getPixelSpacing')
|
||||
|
||||
const circleRoiCursor = cornerstoneTools.import('tools/cursors')
|
||||
const getROITextBoxCoords = cornerstoneTools.import('util/getROITextBoxCoords')
|
||||
import getCircleCoords from './getCircleCoords'
|
||||
// const getCircleCoords = cornerstoneTools.import('util/getCircleCoords')
|
||||
const numbersWithCommas = cornerstoneTools.import('util/numbersWithCommas')
|
||||
|
||||
// import calculateSUV from './../../util/calculateSUV.js'
|
||||
// import { calculateEllipseStatistics } from './../../util/ellipse/index.js'
|
||||
// import getROITextBoxCoords from '../../util/getROITextBoxCoords.js'
|
||||
// import numbersWithCommas from './../../util/numbersWithCommas.js'
|
||||
// import throttle from './../../util/throttle.js'
|
||||
// import { getLogger } from '../../util/logger.js'
|
||||
// import getPixelSpacing from '../../util/getPixelSpacing'
|
||||
|
||||
// import { circleRoiCursor } from '../cursors/index.js'
|
||||
// import getCircleCoords from '../../util/getCircleCoords'
|
||||
|
||||
// const logger = getLogger('tools:annotation:CircleRoiTool')
|
||||
|
||||
/**
|
||||
* @public
|
||||
* @class CircleRoiTool
|
||||
* @memberof Tools.Annotation
|
||||
* @classdesc Tool for drawing circular regions of interest, and measuring
|
||||
* the statistics of the enclosed pixels.
|
||||
* @extends Tools.Base.BaseAnnotationTool
|
||||
*/
|
||||
export default class CircleRoiTool extends cornerstoneTools.CircleRoiTool {
|
||||
constructor(props = {}) {
|
||||
const defaultProps = {
|
||||
name: 'CircleRoi',
|
||||
supportedInteractionTypes: ['Mouse', 'Touch'],
|
||||
svgCursor: circleRoiCursor,
|
||||
configuration: {
|
||||
centerPointRadius: 0,
|
||||
renderDashed: false,
|
||||
hideHandlesIfMoving: false,
|
||||
digits: 1,
|
||||
showRadius: false,
|
||||
showPerimeter: false
|
||||
}
|
||||
}
|
||||
|
||||
super(props, defaultProps)
|
||||
console.log(props.configuration)
|
||||
// this.digits = isNaN(parseInt(props.configuration.digits)) ? 2 : props.configuration.digits
|
||||
// console.log(this.digits)
|
||||
this.throttledUpdateCachedStats = throttle(this.updateCachedStats, 110)
|
||||
}
|
||||
|
||||
renderToolData(evt) {
|
||||
const toolData = getToolState(evt.currentTarget, this.name)
|
||||
|
||||
if (!toolData) {
|
||||
return
|
||||
}
|
||||
|
||||
const getDistance = external.cornerstoneMath.point.distance
|
||||
const eventData = evt.detail
|
||||
const { image, element, canvasContext } = eventData
|
||||
const lineWidth = toolStyle.getToolWidth()
|
||||
const {
|
||||
handleRadius,
|
||||
drawHandlesOnHover,
|
||||
hideHandlesIfMoving,
|
||||
renderDashed,
|
||||
centerPointRadius
|
||||
} = this.configuration
|
||||
const newContext = getNewContext(canvasContext.canvas)
|
||||
const { rowPixelSpacing, colPixelSpacing } = getPixelSpacing(image)
|
||||
const lineDash = getModule('globalConfiguration').configuration.lineDash
|
||||
|
||||
// Meta
|
||||
const seriesModule =
|
||||
external.cornerstone.metaData.get('generalSeriesModule', image.imageId) ||
|
||||
{}
|
||||
|
||||
// Pixel Spacing
|
||||
const modality = seriesModule.modality
|
||||
const hasPixelSpacing = rowPixelSpacing && colPixelSpacing
|
||||
|
||||
draw(newContext, context => {
|
||||
// If we have tool data for this element, iterate over each set and draw it
|
||||
for (let i = 0; i < toolData.data.length; i++) {
|
||||
const data = toolData.data[i]
|
||||
|
||||
if (data.visible === false) {
|
||||
continue
|
||||
}
|
||||
|
||||
// Configure
|
||||
const color = toolColors.getColorIfActive(data)
|
||||
const handleOptions = {
|
||||
color,
|
||||
handleRadius,
|
||||
drawHandlesIfActive: drawHandlesOnHover,
|
||||
hideHandlesIfMoving
|
||||
}
|
||||
|
||||
setShadow(context, this.configuration)
|
||||
|
||||
const startCanvas = external.cornerstone.pixelToCanvas(
|
||||
element,
|
||||
data.handles.start
|
||||
)
|
||||
|
||||
const endCanvas = external.cornerstone.pixelToCanvas(
|
||||
element,
|
||||
data.handles.end
|
||||
)
|
||||
|
||||
// Calculating the radius where startCanvas is the center of the circle to be drawn
|
||||
const radius = getDistance(startCanvas, endCanvas)
|
||||
|
||||
const circleOptions = { color }
|
||||
|
||||
if (renderDashed) {
|
||||
circleOptions.lineDash = lineDash
|
||||
}
|
||||
|
||||
// Draw Circle
|
||||
drawCircle(
|
||||
context,
|
||||
element,
|
||||
data.handles.start,
|
||||
radius,
|
||||
circleOptions,
|
||||
'pixel'
|
||||
)
|
||||
|
||||
if (centerPointRadius && radius > 3 * centerPointRadius) {
|
||||
drawCircle(
|
||||
context,
|
||||
element,
|
||||
data.handles.start,
|
||||
centerPointRadius,
|
||||
circleOptions,
|
||||
'pixel'
|
||||
)
|
||||
}
|
||||
|
||||
if (data.handles) {
|
||||
data.handles.start.drawnIndependently = true
|
||||
data.handles.end.drawnIndependently = true
|
||||
}
|
||||
|
||||
drawHandles(context, eventData, data.handles, handleOptions)
|
||||
|
||||
// Update textbox stats
|
||||
if (data.invalidated === true) {
|
||||
if (data.cachedStats) {
|
||||
this.throttledUpdateCachedStats(image, element, data)
|
||||
} else {
|
||||
this.updateCachedStats(image, element, data)
|
||||
}
|
||||
}
|
||||
|
||||
// Default to textbox on right side of ROI
|
||||
if (!data.handles.textBox.hasMoved) {
|
||||
const defaultCoords = getROITextBoxCoords(
|
||||
eventData.viewport,
|
||||
data.handles
|
||||
)
|
||||
|
||||
Object.assign(data.handles.textBox, defaultCoords)
|
||||
}
|
||||
|
||||
const textBoxAnchorPoints = handles =>
|
||||
_findTextBoxAnchorPoints(handles.start, handles.end)
|
||||
|
||||
const textBoxContent = _createTextBoxContent(
|
||||
context,
|
||||
image.color,
|
||||
data.cachedStats,
|
||||
modality,
|
||||
hasPixelSpacing,
|
||||
this.configuration
|
||||
)
|
||||
if (data.remark) {
|
||||
textBoxContent.unshift(data.remark)
|
||||
}
|
||||
data.unit = _getUnit(modality, this.configuration.showHounsfieldUnits)
|
||||
|
||||
drawLinkedTextBox(
|
||||
context,
|
||||
element,
|
||||
data.handles.textBox,
|
||||
textBoxContent,
|
||||
data.handles,
|
||||
textBoxAnchorPoints,
|
||||
color,
|
||||
lineWidth,
|
||||
20,
|
||||
true
|
||||
)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param {*} startHandle
|
||||
* @param {*} endHandle
|
||||
* @returns {Array.<{x: number, y: number}>}
|
||||
*/
|
||||
function _findTextBoxAnchorPoints(startHandle, endHandle) {
|
||||
const { left, top, width, height } = getCircleCoords(startHandle, endHandle)
|
||||
|
||||
return [
|
||||
{
|
||||
// Top middle point of ellipse
|
||||
x: left + width / 2,
|
||||
y: top
|
||||
},
|
||||
{
|
||||
// Left middle point of ellipse
|
||||
x: left,
|
||||
y: top + height / 2
|
||||
},
|
||||
{
|
||||
// Bottom middle point of ellipse
|
||||
x: left + width / 2,
|
||||
y: top + height
|
||||
},
|
||||
{
|
||||
// Right middle point of ellipse
|
||||
x: left + width,
|
||||
y: top + height / 2
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
function _getUnit(modality, showHounsfieldUnits) {
|
||||
return modality === 'CT' && showHounsfieldUnits !== false ? 'HU' : ''
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param {*} context
|
||||
* @param {*} isColorImage
|
||||
* @param {*} { area, mean, stdDev, min, max, meanStdDevSUV }
|
||||
* @param {*} modality
|
||||
* @param {*} hasPixelSpacing
|
||||
* @param {*} [options={}] - { showMinMax, showHounsfieldUnits }
|
||||
* @returns {string[]}
|
||||
*/
|
||||
function _createTextBoxContent(
|
||||
context,
|
||||
isColorImage,
|
||||
{
|
||||
area = 0,
|
||||
radius = 0,
|
||||
perimeter = 0,
|
||||
mean = 0,
|
||||
stdDev = 0,
|
||||
min = 0,
|
||||
max = 0,
|
||||
meanStdDevSUV = 0
|
||||
} = {},
|
||||
modality,
|
||||
hasPixelSpacing,
|
||||
options = {}
|
||||
) {
|
||||
const showMinMax = options.showMinMax || false
|
||||
const digits = options.digits || 1
|
||||
const textLines = []
|
||||
|
||||
// Don't display mean/standardDev for color images
|
||||
const otherLines = []
|
||||
|
||||
if (!isColorImage) {
|
||||
const hasStandardUptakeValues = meanStdDevSUV && meanStdDevSUV.mean !== 0
|
||||
const unit = _getUnit(modality, options.showHounsfieldUnits)
|
||||
|
||||
let meanString = `Mean: ${numbersWithCommas(mean.toFixed(digits))} ${unit}`
|
||||
const stdDevString = `Std Dev: ${numbersWithCommas(
|
||||
stdDev.toFixed(digits)
|
||||
)} ${unit}`
|
||||
|
||||
// If this image has SUV values to display, concatenate them to the text line
|
||||
if (hasStandardUptakeValues) {
|
||||
const SUVtext = ' SUV: '
|
||||
|
||||
const meanSuvString = `${SUVtext}${numbersWithCommas(
|
||||
meanStdDevSUV.mean.toFixed(digits)
|
||||
)}`
|
||||
const stdDevSuvString = `${SUVtext}${numbersWithCommas(
|
||||
meanStdDevSUV.stdDev.toFixed(digits)
|
||||
)}`
|
||||
|
||||
const targetStringLength = Math.floor(
|
||||
context.measureText(`${stdDevString} `).width
|
||||
)
|
||||
|
||||
while (context.measureText(meanString).width < targetStringLength) {
|
||||
meanString += ' '
|
||||
}
|
||||
|
||||
otherLines.push(`${meanString}${meanSuvString}`)
|
||||
otherLines.push(`${stdDevString} ${stdDevSuvString}`)
|
||||
} else {
|
||||
// otherLines.push(`${meanString} ${stdDevString}`)
|
||||
otherLines.push(`${meanString}`)
|
||||
otherLines.push(`${stdDevString}`)
|
||||
}
|
||||
|
||||
if (showMinMax) {
|
||||
let minString = `Min: ${min} ${unit}`
|
||||
const maxString = `Max: ${max} ${unit}`
|
||||
const targetStringLength = hasStandardUptakeValues
|
||||
? Math.floor(context.measureText(`${stdDevString} `).width)
|
||||
: Math.floor(context.measureText(`${meanString} `).width)
|
||||
|
||||
while (context.measureText(minString).width < targetStringLength) {
|
||||
minString += ' '
|
||||
}
|
||||
otherLines.push(`${minString}`)
|
||||
otherLines.push(`${maxString}`)
|
||||
// otherLines.push(`${minString}${maxString}`)
|
||||
}
|
||||
}
|
||||
|
||||
textLines.push(_formatArea(area, hasPixelSpacing, digits))
|
||||
const showRadius = options.showRadius || false
|
||||
if (radius && showRadius) {
|
||||
textLines.push(_formatLength(radius, 'Radius', hasPixelSpacing, digits))
|
||||
}
|
||||
const showPerimeter = options.showPerimeter || false
|
||||
if (perimeter && showPerimeter) {
|
||||
textLines.push(_formatLength(perimeter, 'Perimeter', hasPixelSpacing, digits))
|
||||
}
|
||||
otherLines.forEach(x => textLines.push(x))
|
||||
// console.log(this.digits)
|
||||
return textLines
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param {*} area
|
||||
* @param {*} hasPixelSpacing
|
||||
* @returns {string} The formatted label for showing area
|
||||
*/
|
||||
function _formatArea(area, hasPixelSpacing, digits) {
|
||||
// This uses Char code 178 for a superscript 2
|
||||
const suffix = hasPixelSpacing
|
||||
? ` mm${String.fromCharCode(178)}`
|
||||
: ` px${String.fromCharCode(178)}`
|
||||
|
||||
return `Area: ${numbersWithCommas(area.toFixed(digits))}${suffix}`
|
||||
}
|
||||
|
||||
function _formatLength(value, name, hasPixelSpacing, digits) {
|
||||
if (!value) {
|
||||
return ''
|
||||
}
|
||||
const suffix = hasPixelSpacing ? ' mm' : ' px'
|
||||
|
||||
return `${name}: ${numbersWithCommas(value.toFixed(digits))}${suffix}`
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param {*} image
|
||||
* @param {*} element
|
||||
* @param {*} handles
|
||||
* @param {*} modality
|
||||
* @param {*} pixelSpacing
|
||||
* @returns {Object} The Stats object
|
||||
*/
|
||||
// function _calculateStats(image, element, handles, modality, pixelSpacing) {
|
||||
// // Retrieve the bounds of the ellipse in image coordinates
|
||||
// const circleCoordinates = getCircleCoords(handles.start, handles.end)
|
||||
|
||||
// // Retrieve the array of pixels that the ellipse bounds cover
|
||||
// const pixels = external.cornerstone.getPixels(
|
||||
// element,
|
||||
// circleCoordinates.left,
|
||||
// circleCoordinates.top,
|
||||
// circleCoordinates.width,
|
||||
// circleCoordinates.height
|
||||
// )
|
||||
|
||||
// // Calculate the mean & standard deviation from the pixels and the ellipse details.
|
||||
// const ellipseMeanStdDev = calculateEllipseStatistics(
|
||||
// pixels,
|
||||
// circleCoordinates
|
||||
// )
|
||||
|
||||
// let meanStdDevSUV
|
||||
|
||||
// if (modality === 'PT') {
|
||||
// meanStdDevSUV = {
|
||||
// mean: calculateSUV(image, ellipseMeanStdDev.mean, true) || 0,
|
||||
// stdDev: calculateSUV(image, ellipseMeanStdDev.stdDev, true) || 0
|
||||
// }
|
||||
// }
|
||||
|
||||
// const radius =
|
||||
// (circleCoordinates.width *
|
||||
// ((pixelSpacing && pixelSpacing.colPixelSpacing) || 1)) /
|
||||
// 2
|
||||
// const perimeter = 2 * Math.PI * radius
|
||||
// const area =
|
||||
// Math.PI *
|
||||
// ((circleCoordinates.width *
|
||||
// ((pixelSpacing && pixelSpacing.colPixelSpacing) || 1)) /
|
||||
// 2) *
|
||||
// ((circleCoordinates.height *
|
||||
// ((pixelSpacing && pixelSpacing.rowPixelSpacing) || 1)) /
|
||||
// 2)
|
||||
|
||||
// return {
|
||||
// area: area || 0,
|
||||
// radius: radius || 0,
|
||||
// perimeter: perimeter || 0,
|
||||
// count: ellipseMeanStdDev.count || 0,
|
||||
// mean: ellipseMeanStdDev.mean || 0,
|
||||
// variance: ellipseMeanStdDev.variance || 0,
|
||||
// stdDev: ellipseMeanStdDev.stdDev || 0,
|
||||
// min: ellipseMeanStdDev.min || 0,
|
||||
// max: ellipseMeanStdDev.max || 0,
|
||||
// meanStdDevSUV
|
||||
// }
|
||||
// }
|
|
@ -0,0 +1,21 @@
|
|||
import * as cornerstoneTools from 'cornerstone-tools'
|
||||
const external = cornerstoneTools.external
|
||||
|
||||
/**
|
||||
* Retrieve the bounds of the circle in image coordinates
|
||||
*
|
||||
* @param {*} startHandle
|
||||
* @param {*} endHandle
|
||||
* @returns {{ left: number, top: number, width: number, height: number }}
|
||||
*/
|
||||
export default function getCircleCoords(startHandle, endHandle) {
|
||||
const { distance } = external.cornerstoneMath.point
|
||||
const radius = distance(startHandle, endHandle)
|
||||
|
||||
return {
|
||||
left: Math.floor(Math.min(startHandle.x - radius, endHandle.x)),
|
||||
top: Math.floor(Math.min(startHandle.y - radius, endHandle.y)),
|
||||
width: radius * 2,
|
||||
height: radius * 2
|
||||
}
|
||||
}
|
|
@ -37,8 +37,8 @@ export default class LengthTool extends cornerstoneTools.LengthTool {
|
|||
drawHandlesOnHover: false,
|
||||
hideHandlesIfMoving: false,
|
||||
renderDashed: false,
|
||||
digits: 2
|
||||
}
|
||||
digits: 2,
|
||||
},
|
||||
}
|
||||
|
||||
super(props, defaultProps)
|
||||
|
@ -48,7 +48,7 @@ export default class LengthTool extends cornerstoneTools.LengthTool {
|
|||
createNewMeasurement(eventData) {
|
||||
const goodEventData =
|
||||
eventData && eventData.currentPoints && eventData.currentPoints.image
|
||||
|
||||
console.log('createNewMeasurement: ',goodEventData)
|
||||
if (!goodEventData) {
|
||||
console.log(
|
||||
`required eventData not supplied to tool ${this.name}'s createNewMeasurement`
|
||||
|
@ -84,7 +84,8 @@ export default class LengthTool extends cornerstoneTools.LengthTool {
|
|||
drawnIndependently: true,
|
||||
allowedOutsideImage: true,
|
||||
hasBoundingBox: true
|
||||
}
|
||||
},
|
||||
allowedOutsideImage:true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -40,7 +40,8 @@ export default class RectangleRoiTool extends cornerstoneTools.RectangleRoiTool
|
|||
drawHandles: true,
|
||||
drawHandlesOnHover: false,
|
||||
hideHandlesIfMoving: false,
|
||||
renderDashed: false
|
||||
renderDashed: false,
|
||||
showStatsText: false
|
||||
// showMinMax: false,
|
||||
// showHounsfieldUnits: true
|
||||
},
|
||||
|
@ -531,12 +532,15 @@ function _createTextBoxContent(
|
|||
minString += ' '
|
||||
}
|
||||
|
||||
otherLines.push(`${minString}${maxString}`)
|
||||
otherLines.push(`${minString}`)
|
||||
otherLines.push(`${maxString}`)
|
||||
}
|
||||
}
|
||||
|
||||
// textLines.push(_formatArea(area, hasPixelSpacing))
|
||||
// otherLines.forEach(x => textLines.push(x))
|
||||
if (options.showStatsText) {
|
||||
textLines.push(_formatArea(area, hasPixelSpacing))
|
||||
otherLines.forEach(x => textLines.push(x))
|
||||
}
|
||||
|
||||
if (data.hasOwnProperty('remark')) {
|
||||
if (data.hasOwnProperty('status') && data.status) {
|
||||
textLines.push(`${data.remark}(${data.status})`)
|
||||
|
@ -546,3 +550,11 @@ function _createTextBoxContent(
|
|||
}
|
||||
return textLines
|
||||
}
|
||||
function _formatArea(area, hasPixelSpacing) {
|
||||
// This uses Char code 178 for a superscript 2
|
||||
const suffix = hasPixelSpacing
|
||||
? ` mm${String.fromCharCode(178)}`
|
||||
: ` px${String.fromCharCode(178)}`;
|
||||
|
||||
return `Area: ${numbersWithCommas(area.toFixed(2))}${suffix}`;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,432 @@
|
|||
<template>
|
||||
<el-form v-if="globalForm.taskList.length > 0" ref="globalRuleForm" :model="globalForm" class="global-form">
|
||||
<el-table
|
||||
v-loading="loading"
|
||||
:data="globalForm.taskList"
|
||||
>
|
||||
<!-- 访视名称 -->
|
||||
<el-table-column
|
||||
prop="BlindName"
|
||||
:label="$t('trials:globalReview:table:visitName')"
|
||||
show-overflow-tooltip
|
||||
width="150"
|
||||
/>
|
||||
<!-- 评估结果 -->
|
||||
<el-table-column
|
||||
:label="$t('trials:globalReview:table:evaluationRes')"
|
||||
align="center"
|
||||
prop=""
|
||||
>
|
||||
<template>
|
||||
<el-table-column
|
||||
v-for="(qs,index) in globalInfo.evaluationQsList"
|
||||
:key="index"
|
||||
prop=""
|
||||
:label="qs"
|
||||
show-overflow-tooltip
|
||||
width="150"
|
||||
>
|
||||
<!-- <template slot-scope="scope">
|
||||
<div v-if="scope.row.BeforeQuestionList.length>index && scope.row.BeforeQuestionList[index].Answer" :style="{color: scope.row.BeforeQuestionList[index].IsGlobalAnswer ? '#f66' : null}">
|
||||
<span v-if="scope.row.BeforeQuestionList[index].DictionaryCode">
|
||||
{{ $fd(scope.row.BeforeQuestionList[index].DictionaryCode,parseInt(scope.row.BeforeQuestionList[index].Answer)) }}
|
||||
</span>
|
||||
<span v-else>{{ scope.row.BeforeQuestionList[index].Answer }}</span>
|
||||
</div>
|
||||
</template> -->
|
||||
<template slot-scope="scope">
|
||||
<template v-if="(scope.row.IsBaseLine && (scope.row.BeforeQuestionList[index].GlobalReadingShowType ===1 || scope.row.BeforeQuestionList[index].GlobalReadingShowType ===5)) || (!scope.row.IsBaseLine && (scope.row.BeforeQuestionList[index].GlobalReadingShowType ===2 || scope.row.BeforeQuestionList[index].GlobalReadingShowType ===6)) || (scope.row.BeforeQuestionList[index].GlobalReadingShowType ===0 || scope.row.BeforeQuestionList[index].GlobalReadingShowType ===4)">
|
||||
<div v-if="scope.row.BeforeQuestionList.length>index && scope.row.BeforeQuestionList[index].Answer" :style="{color: scope.row.BeforeQuestionList[index].IsGlobalAnswer ? '#f66' : null}">
|
||||
<span v-if="scope.row.BeforeQuestionList[index].DictionaryCode">
|
||||
{{ $fd(scope.row.BeforeQuestionList[index].DictionaryCode,parseInt(scope.row.BeforeQuestionList[index].Answer)) }}
|
||||
</span>
|
||||
<span v-else>{{ scope.row.BeforeQuestionList[index].Answer }}</span>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
</template>
|
||||
</el-table-column>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<!-- 是否同意访视结果 -->
|
||||
<el-table-column
|
||||
prop=""
|
||||
:label="$t('trials:globalReview:table:isAgreeEvaluationRes')"
|
||||
show-overflow-tooltip
|
||||
width="170"
|
||||
>
|
||||
<template slot-scope="scope">
|
||||
<el-form-item
|
||||
v-if="readingTaskState<2"
|
||||
:prop="`${scope.$index}${scope.row.AgreeOrNot[0].GlobalAnswerType}`"
|
||||
label=""
|
||||
:rules="[
|
||||
{ required: true,message: $t('common:ruleMessage:select'), trigger: ['change','blur']},
|
||||
]"
|
||||
class="form-item"
|
||||
>
|
||||
<el-radio-group
|
||||
v-model="globalForm[`${scope.$index}${scope.row.AgreeOrNot[0].GlobalAnswerType}`]"
|
||||
@change="handleAgreeOrNotChange(scope.$index,scope.row.AgreeOrNot[0].GlobalAnswerType)"
|
||||
>
|
||||
<el-radio
|
||||
v-for="item of $d.ReadingYesOrNo"
|
||||
:key="'AgreeOrNot' + item.value"
|
||||
:label="String(item.value)"
|
||||
>
|
||||
{{ item.label }}
|
||||
</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
|
||||
<el-tag v-else-if="scope.row.AgreeOrNot.length > 0 && parseInt(scope.row.AgreeOrNot[0].Answer) === 1" type="primary">
|
||||
{{ $fd('ReadingYesOrNo',parseInt(scope.row.AgreeOrNot[0].Answer)) }}
|
||||
</el-tag>
|
||||
<el-tag v-else-if="scope.row.AgreeOrNot.length > 0 && parseInt(scope.row.AgreeOrNot[0].Answer) === 0" type="danger"> {{ $fd('ReadingYesOrNo',parseInt(scope.row.AgreeOrNot[0].Answer)) }}</el-tag>
|
||||
<span v-else />
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<!-- 调整后结果 -->
|
||||
<el-table-column
|
||||
:label="$t('trials:globalReview:table:adjustedRes')"
|
||||
align="center"
|
||||
prop=""
|
||||
>
|
||||
<template v-for="(qs,index) in globalInfo.adjustedQsList">
|
||||
<el-table-column
|
||||
v-if="qs.isShow"
|
||||
:key="index"
|
||||
prop=""
|
||||
:label="qs.questionName"
|
||||
show-overflow-tooltip
|
||||
:min-width="index === 3 ? '200' : '200'"
|
||||
>
|
||||
<template slot-scope="scope">
|
||||
<div v-if="readingTaskState<2 && (scope.row.AfterQuestionList[index].GlobalReadingShowType === 0 || (scope.row.IsBaseLine && scope.row.AfterQuestionList[index].GlobalReadingShowType === 1) || (!scope.row.IsBaseLine && scope.row.AfterQuestionList[index].GlobalReadingShowType === 2))">
|
||||
<el-form-item
|
||||
style="margin-bottom: 0;"
|
||||
:prop="`${scope.$index}${scope.row.AfterQuestionList[index].QuestionId?scope.row.AfterQuestionList[index].QuestionId:scope.row.AfterQuestionList[index].GlobalAnswerType}`"
|
||||
label=""
|
||||
:rules="[
|
||||
{ required:parseInt(globalForm[`${scope.$index}${scope.row.AgreeOrNot[0].GlobalAnswerType}`]) === 0,message: $t('common:ruleMessage:specify'), trigger: ['change','blur']},
|
||||
]"
|
||||
>
|
||||
<label v-if="parseInt(globalForm[`${scope.$index}${scope.row.AgreeOrNot[0].GlobalAnswerType}`]) === 0" />
|
||||
<!-- 裁判问题 -->
|
||||
<template v-if="scope.row.AfterQuestionList[index].GlobalAnswerType === 0 ">
|
||||
<el-select
|
||||
v-if="scope.row.AfterQuestionList[index].Type === 'select'"
|
||||
v-model="globalForm[`${scope.$index}${scope.row.AfterQuestionList[index].QuestionId?scope.row.AfterQuestionList[index].QuestionId:String(scope.row.AfterQuestionList[index].GlobalAnswerType)}`]"
|
||||
style="width:90%;"
|
||||
:disabled="parseInt(globalForm[`${scope.$index}${scope.row.AgreeOrNot[0].GlobalAnswerType}`]) !== 0"
|
||||
>
|
||||
<template v-if="scope.row.AfterQuestionList[index].TypeValue">
|
||||
<el-option
|
||||
v-for="val in scope.row.AfterQuestionList[index].TypeValue.split('|')"
|
||||
:key="val"
|
||||
:label="val"
|
||||
:value="val"
|
||||
/>
|
||||
</template>
|
||||
</el-select>
|
||||
<el-input
|
||||
v-if="scope.row.AfterQuestionList[index].Type ==='textarea'"
|
||||
v-model="globalForm[`${scope.$index}${scope.row.AfterQuestionList[index].QuestionId?scope.row.AfterQuestionList[index].QuestionId:String(scope.row.AfterQuestionList[index].GlobalAnswerType)}`]"
|
||||
type="textarea"
|
||||
:autosize="{ minRows: 2, maxRows: 4}"
|
||||
:disabled="parseInt(globalForm[`${scope.$index}${scope.row.AgreeOrNot[0].GlobalAnswerType}`]) !== 0"
|
||||
/>
|
||||
<!-- 输入框 -->
|
||||
<el-input
|
||||
v-if="scope.row.AfterQuestionList[index].Type ==='input'"
|
||||
v-model="globalForm[`${scope.$index}${scope.row.AfterQuestionList[index].QuestionId?scope.row.AfterQuestionList[index].QuestionId:String(scope.row.AfterQuestionList[index].GlobalAnswerType)}`]"
|
||||
:disabled="parseInt(globalForm[`${scope.$index}${scope.row.AgreeOrNot[0].GlobalAnswerType}`]) !== 0"
|
||||
/>
|
||||
<!-- 单选 -->
|
||||
<el-radio-group
|
||||
v-if="scope.row.AfterQuestionList[index].Type ==='radio'"
|
||||
v-model="globalForm[`${scope.$index}${scope.row.AfterQuestionList[index].QuestionId?scope.row.AfterQuestionList[index].QuestionId:String(scope.row.AfterQuestionList[index].GlobalAnswerType)}`]"
|
||||
:disabled="parseInt(globalForm[`${scope.$index}${scope.row.AgreeOrNot[0].GlobalAnswerType}`]) !== 0"
|
||||
>
|
||||
<el-radio
|
||||
v-for="val in scope.row.AfterQuestionList[index].TypeValue.split('|')"
|
||||
:key="val.trim()"
|
||||
:label="val.trim()"
|
||||
>
|
||||
{{ val.trim() }}
|
||||
</el-radio>
|
||||
</el-radio-group>
|
||||
<!-- 数值 -->
|
||||
<el-input
|
||||
type="number"
|
||||
v-if="scope.row.AfterQuestionList[index].Type === 'number'"
|
||||
v-model="globalForm[`${scope.$index}${scope.row.AfterQuestionList[index].QuestionId?scope.row.AfterQuestionList[index].QuestionId:String(scope.row.AfterQuestionList[index].GlobalAnswerType)}`]"
|
||||
:disabled="parseInt(globalForm[`${scope.$index}${scope.row.AgreeOrNot[0].GlobalAnswerType}`]) !== 0"
|
||||
>
|
||||
</el-input>
|
||||
</template>
|
||||
<!-- 评估更新类型 GlobalAnswerType:3 -->
|
||||
<template v-if="scope.row.AfterQuestionList[index].GlobalAnswerType === 3">
|
||||
<el-tooltip v-if="getText(globalForm[`${scope.$index}${scope.row.AfterQuestionList[index].GlobalAnswerType}`], scope.row.AfterQuestionList[index], scope.row.AfterQuestionList[index].GlobalAnswerType)" class="item" effect="dark" :content="getText(globalForm[`${scope.$index}${scope.row.AfterQuestionList[index].GlobalAnswerType}`], scope.row.AfterQuestionList[index], scope.row.AfterQuestionList[index].GlobalAnswerType)" placement="top-start">
|
||||
<el-select
|
||||
v-model="globalForm[`${scope.$index}${scope.row.AfterQuestionList[index].GlobalAnswerType}`]"
|
||||
style="width:90%;"
|
||||
:disabled="parseInt(globalForm[`${scope.$index}${scope.row.AgreeOrNot[0].GlobalAnswerType}`]) !== 0"
|
||||
>
|
||||
<el-option
|
||||
v-for="val in globalInfo.assessTypeList"
|
||||
v-show="(scope.row.IsBaseLine && val.IsBaseLineUse) || (!scope.row.IsBaseLine && val.IsFollowVisitUse)"
|
||||
:key="val.Code"
|
||||
:label="language === 'en'?val.Value:val.ValueCN"
|
||||
:value="val.Code"
|
||||
/>
|
||||
</el-select>
|
||||
</el-tooltip>
|
||||
<el-select
|
||||
v-else
|
||||
v-model="globalForm[`${scope.$index}${scope.row.AfterQuestionList[index].GlobalAnswerType}`]"
|
||||
style="width:90%;"
|
||||
:disabled="parseInt(globalForm[`${scope.$index}${scope.row.AgreeOrNot[0].GlobalAnswerType}`]) !== 0"
|
||||
>
|
||||
<el-option
|
||||
v-for="val in globalInfo.assessTypeList"
|
||||
v-show="(scope.row.IsBaseLine && val.IsBaseLineUse) || (!scope.row.IsBaseLine && val.IsFollowVisitUse)"
|
||||
:key="val.Code"
|
||||
:label="language === 'en'?val.Value:val.ValueCN"
|
||||
:value="val.Code"
|
||||
/>
|
||||
</el-select>
|
||||
</template>
|
||||
<el-input
|
||||
v-if="scope.row.AfterQuestionList[index].GlobalAnswerType === 1"
|
||||
v-model="globalForm[`${scope.$index}${scope.row.AfterQuestionList[index].QuestionId?scope.row.AfterQuestionList[index].QuestionId:String(scope.row.AfterQuestionList[index].GlobalAnswerType)}`]"
|
||||
type="textarea"
|
||||
maxlength="100"
|
||||
show-word-limit
|
||||
style="width:90%;"
|
||||
:autosize="{ minRows: 2 }"
|
||||
:disabled="parseInt(globalForm[`${scope.$index}${scope.row.AgreeOrNot[0].GlobalAnswerType}`]) !== 0"
|
||||
/>
|
||||
</el-form-item>
|
||||
</div>
|
||||
<div v-else>
|
||||
|
||||
<span v-if="scope.row.AfterQuestionList[index].GlobalAnswerType === 3">
|
||||
{{ getAssessType(scope.row.AfterQuestionList[index].Answer) }}
|
||||
</span>
|
||||
<span v-else-if="scope.row.AfterQuestionList[index].DictionaryCode">
|
||||
{{ $fd(scope.row.AfterQuestionList[index].DictionaryCode,parseInt(scope.row.AfterQuestionList[index].Answer)) }}
|
||||
</span>
|
||||
<span v-else>{{ scope.row.AfterQuestionList[index].Answer }}</span>
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
:label="$t('common:action:action')"
|
||||
width="100"
|
||||
>
|
||||
<template slot-scope="scope">
|
||||
<el-button
|
||||
circle
|
||||
:title="$t('trials:globalReview:table:view')"
|
||||
icon="el-icon-view"
|
||||
@click="handleView(scope.row)"
|
||||
/>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</el-form>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { getToken } from '@/utils/auth'
|
||||
import { batchSubmitGlobalReadingInfo } from '@/api/trials'
|
||||
import { mapGetters } from 'vuex'
|
||||
export default {
|
||||
props: {
|
||||
globalInfo: {
|
||||
type: Object,
|
||||
default() {
|
||||
return {}
|
||||
}
|
||||
},
|
||||
globalForm: {
|
||||
type: Object,
|
||||
default() {
|
||||
return {}
|
||||
}
|
||||
},
|
||||
readingTaskState: {
|
||||
type: Number,
|
||||
required: true
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
loading: false,
|
||||
assessTypes: []
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
...mapGetters(['language'])
|
||||
},
|
||||
mounted() {
|
||||
this.assessTypes = this.globalInfo.assessTypeList.filter(i => i.IsBaseLineUse === this.isBaseline)
|
||||
},
|
||||
methods: {
|
||||
getText(val, row, type) {
|
||||
if (type === 3) {
|
||||
var o = this.globalInfo.assessTypeList.find(v => {
|
||||
return parseInt(v.Code) === parseInt(val)
|
||||
})
|
||||
if (!o) {
|
||||
return ''
|
||||
}
|
||||
return this.language === 'en' ? o.Value : o.ValueCN
|
||||
} else if (row.TypeValue) {
|
||||
return val
|
||||
} else if (row.DictionaryCode) {
|
||||
return this.$fd(row.DictionaryCode, parseInt(val))
|
||||
}
|
||||
},
|
||||
|
||||
handleView(row) {
|
||||
var token = getToken()
|
||||
var visitTaskId = row.VisitTaskId
|
||||
var criterionType = this.$router.currentRoute.query.criterionType
|
||||
var readingTool = this.$router.currentRoute.query.readingTool
|
||||
readingTool = isNaN(parseInt(readingTool)) ? null : parseInt(readingTool)
|
||||
var isReadingTaskViewInOrder = this.$router.currentRoute.query.isReadingTaskViewInOrder
|
||||
var trialReadingCriterionId = this.$router.currentRoute.query.TrialReadingCriterionId
|
||||
var path = ''
|
||||
if (readingTool === 0) {
|
||||
path = `/readingDicoms?TrialReadingCriterionId=${trialReadingCriterionId}&trialId=${this.globalInfo.trialId}&subjectCode=${this.globalInfo.subjectCode}&subjectId=${this.globalInfo.subjectId}&visitTaskId=${visitTaskId}&isReadingTaskViewInOrder=${isReadingTaskViewInOrder}&criterionType=${criterionType}&readingTool=${readingTool}&TokenKey=${token}`
|
||||
} else {
|
||||
path = `/noneDicomReading?TrialReadingCriterionId=${trialReadingCriterionId}&trialId=${this.globalInfo.trialId}&subjectCode=${this.globalInfo.subjectCode}&subjectId=${this.globalInfo.subjectId}&visitTaskId=${visitTaskId}&isReadingTaskViewInOrder=${isReadingTaskViewInOrder}&criterionType=${criterionType}&readingTool=${readingTool}&TokenKey=${token}`
|
||||
}
|
||||
const routeData = this.$router.resolve({ path })
|
||||
var newWindow = window.open(routeData.href, '_blank')
|
||||
this.$emit('setOpenWindow', newWindow)
|
||||
},
|
||||
getLesionCount(lesionList, lesionType) {
|
||||
const lesion = lesionList.find(i => i.LesionType === lesionType)
|
||||
return lesion ? lesion.Count : 0
|
||||
},
|
||||
handleSave(isPrompt = true) {
|
||||
return new Promise(async (resolve, reject) => {
|
||||
let valid = await this.$refs['globalRuleForm'].validate()
|
||||
if (valid) {
|
||||
this.loading = true
|
||||
var visitTaskAnswerList = []
|
||||
this.globalForm.taskList.forEach((item, index) => {
|
||||
var answerList = []
|
||||
item.AfterQuestionList.map(i => {
|
||||
var obj = {}
|
||||
if (i.QuestionId) {
|
||||
obj.questionId = i.QuestionId
|
||||
obj.globalAnswerType = i.GlobalAnswerType
|
||||
obj.answer = this.globalForm[ `${index}${i.QuestionId}`]
|
||||
} else {
|
||||
obj.questionId = ''
|
||||
obj.globalAnswerType = i.GlobalAnswerType
|
||||
obj.answer = this.globalForm[ `${index}${i.GlobalAnswerType}`]
|
||||
}
|
||||
answerList.push(obj)
|
||||
})
|
||||
answerList.push({ questionId: '', globalAnswerType: item.AgreeOrNot[0].GlobalAnswerType,
|
||||
answer: this.globalForm[ `${index}${item.AgreeOrNot[0].GlobalAnswerType}`] })
|
||||
|
||||
visitTaskAnswerList.push({ visitTaskId: item.VisitTaskId, answerList: answerList })
|
||||
})
|
||||
var params = {
|
||||
globalTaskId: this.globalInfo.visitTaskId,
|
||||
subjectId: this.globalInfo.subjectId,
|
||||
trialId: this.globalInfo.trialId,
|
||||
visitTaskAnswerList
|
||||
}
|
||||
try {
|
||||
await batchSubmitGlobalReadingInfo(params)
|
||||
this.loading = false
|
||||
if (isPrompt) {
|
||||
console.log(isPrompt)
|
||||
this.$message.success(this.$t('common:message:savedSuccessfully'))
|
||||
}
|
||||
this.$emit('getGlInfo')
|
||||
resolve()
|
||||
} catch (e) {
|
||||
this.loading = false
|
||||
reject()
|
||||
}
|
||||
} else {
|
||||
reject()
|
||||
}
|
||||
|
||||
})
|
||||
},
|
||||
getBeforeAnswer(qsId, row) {
|
||||
var i = row.BeforeQuestionList.findIndex(item => item.QuestionName === qsId)
|
||||
|
||||
if (i > -1 && row.BeforeQuestionList[i].Answer) {
|
||||
var answer = ''
|
||||
if (row.BeforeQuestionList[i].DictionaryCode) {
|
||||
answer = row.BeforeQuestionList[i].Answer
|
||||
} else {
|
||||
answer = row.BeforeQuestionList[i].Answer
|
||||
}
|
||||
return answer
|
||||
} else {
|
||||
return ''
|
||||
}
|
||||
},
|
||||
handleAgreeOrNotChange(index, globalAnswerType) {
|
||||
var agreeOrNot = parseInt(this.globalForm[`${index}${globalAnswerType}`])
|
||||
if (agreeOrNot === 1) {
|
||||
var qsList = this.globalForm.taskList[index].AfterQuestionList
|
||||
qsList.map(v => {
|
||||
if (v.QuestionId) {
|
||||
this.globalForm[`${index}${v.QuestionId}`] = ''
|
||||
} else if (v.GlobalAnswerType !== globalAnswerType) {
|
||||
this.globalForm[`${index}${v.GlobalAnswerType}`] = ''
|
||||
}
|
||||
})
|
||||
}
|
||||
console.log(this.globalForm)
|
||||
},
|
||||
getAssessType(v) {
|
||||
console.log(this.language)
|
||||
var i = this.globalInfo.assessTypeList.findIndex(i => String(i.Code) === String(v))
|
||||
if (i > -1) {
|
||||
return this.language === 'en' ? this.globalInfo.assessTypeList[i].Value : this.globalInfo.assessTypeList[i].ValueCN
|
||||
} else {
|
||||
return ''
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
/deep/ .el-form-item label:before {
|
||||
content: '*';
|
||||
color: #F56C6C;
|
||||
margin-right: 4px;
|
||||
}
|
||||
/deep/ .el-textarea .el-input__count{
|
||||
background: rgba(0,0,0,0);
|
||||
line-height: normal;
|
||||
}
|
||||
/deep/ .el-form-item{
|
||||
margin-bottom: 0px;
|
||||
}
|
||||
.global-form{
|
||||
/deep/ .el-form-item__content{
|
||||
padding-bottom: 10px;
|
||||
}
|
||||
/deep/ .form-item .el-form-item__error{
|
||||
top: 60%;
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -26,13 +26,24 @@
|
|||
show-overflow-tooltip
|
||||
width="150"
|
||||
>
|
||||
<template slot-scope="scope">
|
||||
<!-- <template slot-scope="scope">
|
||||
<div v-if="scope.row.BeforeQuestionList.length>index && scope.row.BeforeQuestionList[index].Answer" :style="{color: scope.row.BeforeQuestionList[index].IsGlobalAnswer ? '#f66' : null}">
|
||||
<span v-if="scope.row.BeforeQuestionList[index].DictionaryCode">
|
||||
{{ $fd(scope.row.BeforeQuestionList[index].DictionaryCode,parseInt(scope.row.BeforeQuestionList[index].Answer)) }}
|
||||
</span>
|
||||
<span v-else>{{ scope.row.BeforeQuestionList[index].Answer }}</span>
|
||||
</div>
|
||||
</template> -->
|
||||
<template slot-scope="scope">
|
||||
<template v-if="(scope.row.IsBaseLine && (scope.row.BeforeQuestionList[index].GlobalReadingShowType ===1 || scope.row.BeforeQuestionList[index].GlobalReadingShowType ===5)) || (!scope.row.IsBaseLine && (scope.row.BeforeQuestionList[index].GlobalReadingShowType ===2 || scope.row.BeforeQuestionList[index].GlobalReadingShowType ===6)) || (scope.row.BeforeQuestionList[index].GlobalReadingShowType ===0 || scope.row.BeforeQuestionList[index].GlobalReadingShowType ===4)">
|
||||
<div v-if="scope.row.BeforeQuestionList.length>index && scope.row.BeforeQuestionList[index].Answer" :style="{color: scope.row.BeforeQuestionList[index].IsGlobalAnswer ? '#f66' : null}">
|
||||
<span v-if="scope.row.BeforeQuestionList[index].DictionaryCode">
|
||||
{{ $fd(scope.row.BeforeQuestionList[index].DictionaryCode,parseInt(scope.row.BeforeQuestionList[index].Answer)) }}
|
||||
</span>
|
||||
<span v-else>{{ scope.row.BeforeQuestionList[index].Answer }}</span>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
</template>
|
||||
</el-table-column>
|
||||
</template>
|
||||
|
@ -85,20 +96,20 @@
|
|||
<template>
|
||||
<el-table-column
|
||||
v-for="(qs,index) in globalInfo.adjustedQsList"
|
||||
v-if="qs.isShow"
|
||||
:key="index"
|
||||
prop=""
|
||||
:label="qs"
|
||||
:label="qs.questionName"
|
||||
show-overflow-tooltip
|
||||
:min-width="index === 3 ? '200' : '200'"
|
||||
>
|
||||
<template slot-scope="scope">
|
||||
<div v-if="readingTaskState<2">
|
||||
<span v-if="(scope.row.IsBaseLine && scope.row.AfterQuestionList[index].LimitEdit === 2) || (!scope.row.IsBaseLine && scope.row.AfterQuestionList[index].LimitEdit === 1)">
|
||||
<div v-if="readingTaskState<2 && (scope.row.AfterQuestionList[index].GlobalReadingShowType === 0 || (scope.row.IsBaseLine && scope.row.AfterQuestionList[index].GlobalReadingShowType === 1) || (!scope.row.IsBaseLine && scope.row.AfterQuestionList[index].GlobalReadingShowType === 2))">
|
||||
<!-- <span v-if="(scope.row.IsBaseLine && scope.row.AfterQuestionList[index].LimitEdit === 2) || (!scope.row.IsBaseLine && scope.row.AfterQuestionList[index].LimitEdit === 1)">
|
||||
{{ $fd(scope.row.AfterQuestionList[index].DictionaryCode, parseInt(scope.row.AfterQuestionList[index].VisitAnswer)) }}
|
||||
</span>
|
||||
</span> -->
|
||||
|
||||
<el-form-item
|
||||
v-else
|
||||
style="margin-bottom: 0;"
|
||||
:prop="`${scope.$index}${scope.row.AfterQuestionList[index].QuestionId?scope.row.AfterQuestionList[index].QuestionId:scope.row.AfterQuestionList[index].GlobalAnswerType}`"
|
||||
label=""
|
||||
|
@ -255,7 +266,7 @@
|
|||
/>
|
||||
</el-form-item>
|
||||
</div>
|
||||
<div v-else-if="scope.row.AfterQuestionList.length>index && scope.row.AfterQuestionList[index].Answer">
|
||||
<div v-else>
|
||||
|
||||
<span v-if="scope.row.AfterQuestionList[index].GlobalAnswerType === 3">
|
||||
{{ getAssessType(scope.row.AfterQuestionList[index].Answer) }}
|
||||
|
@ -320,7 +331,6 @@ export default {
|
|||
...mapGetters(['language'])
|
||||
},
|
||||
mounted() {
|
||||
console.log('iRecist')
|
||||
this.assessTypes = this.globalInfo.assessTypeList.filter(i => i.IsBaseLineUse === this.isBaseline)
|
||||
},
|
||||
methods: {
|
||||
|
@ -346,11 +356,12 @@ export default {
|
|||
var readingTool = this.$router.currentRoute.query.readingTool
|
||||
readingTool = isNaN(parseInt(readingTool)) ? null : parseInt(readingTool)
|
||||
var isReadingTaskViewInOrder = this.$router.currentRoute.query.isReadingTaskViewInOrder
|
||||
var trialReadingCriterionId = this.$router.currentRoute.query.TrialReadingCriterionId
|
||||
var path = ''
|
||||
if (readingTool === 0) {
|
||||
path = `/readingDicoms?trialId=${this.globalInfo.trialId}&subjectCode=${this.globalInfo.subjectCode}&subjectId=${this.globalInfo.subjectId}&visitTaskId=${visitTaskId}&isReadingTaskViewInOrder=${isReadingTaskViewInOrder}&criterionType=${criterionType}&readingTool=${readingTool}&TokenKey=${token}`
|
||||
path = `/readingDicoms?TrialReadingCriterionId=${trialReadingCriterionId}&trialId=${this.globalInfo.trialId}&subjectCode=${this.globalInfo.subjectCode}&subjectId=${this.globalInfo.subjectId}&visitTaskId=${visitTaskId}&isReadingTaskViewInOrder=${isReadingTaskViewInOrder}&criterionType=${criterionType}&readingTool=${readingTool}&TokenKey=${token}`
|
||||
} else {
|
||||
path = `/noneDicomReading?trialId=${this.globalInfo.trialId}&subjectCode=${this.globalInfo.subjectCode}&subjectId=${this.globalInfo.subjectId}&visitTaskId=${visitTaskId}&isReadingTaskViewInOrder=${isReadingTaskViewInOrder}&criterionType=${criterionType}&readingTool=${readingTool}&TokenKey=${token}`
|
||||
path = `/noneDicomReading?TrialReadingCriterionId=${trialReadingCriterionId}&trialId=${this.globalInfo.trialId}&subjectCode=${this.globalInfo.subjectCode}&subjectId=${this.globalInfo.subjectId}&visitTaskId=${visitTaskId}&isReadingTaskViewInOrder=${isReadingTaskViewInOrder}&criterionType=${criterionType}&readingTool=${readingTool}&TokenKey=${token}`
|
||||
}
|
||||
const routeData = this.$router.resolve({ path })
|
||||
var newWindow = window.open(routeData.href, '_blank')
|
||||
|
@ -361,9 +372,10 @@ export default {
|
|||
return lesion ? lesion.Count : 0
|
||||
},
|
||||
handleSave(isPrompt = true) {
|
||||
return new Promise((resolve, reject) => {
|
||||
this.$refs['globalRuleForm'].validate(valid => {
|
||||
if (valid) {
|
||||
return new Promise(async (resolve, reject) => {
|
||||
let valid = await this.$refs['globalRuleForm'].validate()
|
||||
|
||||
if (valid) {
|
||||
this.loading = true
|
||||
var visitTaskAnswerList = []
|
||||
this.globalForm.taskList.forEach((item, index) => {
|
||||
|
@ -392,7 +404,8 @@ export default {
|
|||
trialId: this.globalInfo.trialId,
|
||||
visitTaskAnswerList
|
||||
}
|
||||
batchSubmitGlobalReadingInfo(params).then(res => {
|
||||
try {
|
||||
await batchSubmitGlobalReadingInfo(params)
|
||||
this.loading = false
|
||||
if (isPrompt) {
|
||||
console.log(isPrompt)
|
||||
|
@ -400,14 +413,13 @@ export default {
|
|||
}
|
||||
this.$emit('getGlInfo')
|
||||
resolve()
|
||||
}).catch(() => {
|
||||
} catch (e) {
|
||||
this.loading = false
|
||||
reject()
|
||||
})
|
||||
}
|
||||
} else {
|
||||
reject()
|
||||
}
|
||||
})
|
||||
})
|
||||
},
|
||||
getBeforeAnswer(qsId, row) {
|
||||
|
@ -452,23 +464,23 @@ export default {
|
|||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
>>>.el-form-item label:before {
|
||||
/deep/ .el-form-item label:before {
|
||||
content: '*';
|
||||
color: #F56C6C;
|
||||
margin-right: 4px;
|
||||
}
|
||||
>>>.el-textarea .el-input__count{
|
||||
/deep/ .el-textarea .el-input__count{
|
||||
background: rgba(0,0,0,0);
|
||||
line-height: normal;
|
||||
}
|
||||
>>>.el-form-item{
|
||||
/deep/ .el-form-item{
|
||||
margin-bottom: 0px;
|
||||
}
|
||||
.global-form{
|
||||
>>>.el-form-item__content{
|
||||
/deep/ .el-form-item__content{
|
||||
padding-bottom: 10px;
|
||||
}
|
||||
>>>.form-item .el-form-item__error{
|
||||
/deep/ .form-item .el-form-item__error{
|
||||
top: 60%;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,14 +26,16 @@
|
|||
width="200"
|
||||
>
|
||||
<template slot-scope="scope">
|
||||
<div v-if="scope.row.BeforeQuestionList.length>index && scope.row.BeforeQuestionList[index].Answer">
|
||||
<span v-if="scope.row.BeforeQuestionList[index].DictionaryCode">
|
||||
{{ $fd(scope.row.BeforeQuestionList[index].DictionaryCode,parseInt(scope.row.BeforeQuestionList[index].Answer)) }}
|
||||
</span>
|
||||
<span v-else-if="scope.row.BeforeQuestionList[index].QuestionType === 22">{{ scope.row.BeforeQuestionList[index].Answer === '-1' ? $t('trials:readingReport:title:unknow') : scope.row.BeforeQuestionList[index].Answer }}</span>
|
||||
<span v-else>{{ scope.row.BeforeQuestionList[index].Answer }}</span>
|
||||
</div>
|
||||
</template>
|
||||
<template v-if="(scope.row.IsBaseLine && (scope.row.BeforeQuestionList[index].GlobalReadingShowType ===1 || scope.row.BeforeQuestionList[index].GlobalReadingShowType ===5)) || (!scope.row.IsBaseLine && (scope.row.BeforeQuestionList[index].GlobalReadingShowType ===2 || scope.row.BeforeQuestionList[index].GlobalReadingShowType ===6)) || (scope.row.BeforeQuestionList[index].GlobalReadingShowType ===0 || scope.row.BeforeQuestionList[index].GlobalReadingShowType ===4)">
|
||||
<div v-if="scope.row.BeforeQuestionList.length>index && scope.row.BeforeQuestionList[index].Answer">
|
||||
<span v-if="scope.row.BeforeQuestionList[index].DictionaryCode">
|
||||
{{ $fd(scope.row.BeforeQuestionList[index].DictionaryCode,parseInt(scope.row.BeforeQuestionList[index].Answer)) }}
|
||||
</span>
|
||||
<span v-else-if="scope.row.BeforeQuestionList[index].QuestionType === 22">{{ scope.row.BeforeQuestionList[index].Answer === '-1' ? $t('trials:readingReport:title:unknow') : scope.row.BeforeQuestionList[index].Answer }}</span>
|
||||
<span v-else>{{ scope.row.BeforeQuestionList[index].Answer }}</span>
|
||||
</div>
|
||||
</template>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
@ -47,18 +49,18 @@
|
|||
<template>
|
||||
<el-table-column
|
||||
v-for="(qs,index) in globalInfo.adjustedQsList"
|
||||
v-if="qs.isShow"
|
||||
:key="index"
|
||||
prop=""
|
||||
:label="qs"
|
||||
:label="qs.questionName"
|
||||
:width="index > 0 ? '300' : '200'"
|
||||
>
|
||||
<template slot-scope="scope">
|
||||
<div v-if="readingTaskState<2 ">
|
||||
<span v-if="(scope.row.IsBaseLine && scope.row.AfterQuestionList[index].LimitEdit === 2) || (!scope.row.IsBaseLine && scope.row.AfterQuestionList[index].LimitEdit === 1)">
|
||||
<div v-if="readingTaskState<2 && (scope.row.AfterQuestionList[index].GlobalReadingShowType === 0 || (scope.row.IsBaseLine && scope.row.AfterQuestionList[index].GlobalReadingShowType === 1) || (!scope.row.IsBaseLine && scope.row.AfterQuestionList[index].GlobalReadingShowType === 2))">
|
||||
<!-- <span v-if="(scope.row.IsBaseLine && scope.row.AfterQuestionList[index].LimitEdit === 2) || (!scope.row.IsBaseLine && scope.row.AfterQuestionList[index].LimitEdit === 1)">
|
||||
{{ $fd(scope.row.AfterQuestionList[index].DictionaryCode, parseInt(scope.row.AfterQuestionList[index].VisitAnswer)) }}
|
||||
</span>
|
||||
</span> -->
|
||||
<el-form-item
|
||||
v-else
|
||||
:prop="`${scope.$index}${scope.row.AfterQuestionList[index].QuestionId?scope.row.AfterQuestionList[index].QuestionId:scope.row.AfterQuestionList[index].GlobalAnswerType}`"
|
||||
label=""
|
||||
:rules="[
|
||||
|
@ -107,7 +109,7 @@
|
|||
/>
|
||||
</el-form-item>
|
||||
</div>
|
||||
<div v-else-if="scope.row.AfterQuestionList.length>index && scope.row.AfterQuestionList[index].Answer">
|
||||
<div v-else>
|
||||
|
||||
<span v-if="scope.row.AfterQuestionList[index].GlobalAnswerType === 3">
|
||||
{{ getAssessType(scope.row.AfterQuestionList[index].Answer) }}
|
||||
|
@ -181,7 +183,6 @@ export default {
|
|||
}
|
||||
},
|
||||
mounted() {
|
||||
console.log(this.globalInfo.adjustedQsList)
|
||||
},
|
||||
methods: {
|
||||
selectChange(v, row, index) {
|
||||
|
@ -218,9 +219,9 @@ export default {
|
|||
this.$emit('handleView', row)
|
||||
},
|
||||
handleSave(isPrompt = true) {
|
||||
return new Promise((resolve, reject) => {
|
||||
this.$refs['globalRuleForm'].validate(valid => {
|
||||
if (valid) {
|
||||
return new Promise(async (resolve, reject) => {
|
||||
let valid = await this.$refs['globalRuleForm'].validate()
|
||||
if (valid) {
|
||||
this.loading = true
|
||||
var visitTaskAnswerList = []
|
||||
this.globalForm.taskList.forEach((item, index) => {
|
||||
|
@ -246,21 +247,21 @@ export default {
|
|||
trialId: this.globalInfo.trialId,
|
||||
visitTaskAnswerList
|
||||
}
|
||||
batchSubmitGlobalReadingInfo(params).then(res => {
|
||||
try {
|
||||
await batchSubmitGlobalReadingInfo(params)
|
||||
this.loading = false
|
||||
if (isPrompt) {
|
||||
this.$message.success(this.$t('common:message:savedSuccessfully'))
|
||||
}
|
||||
this.$emit('getGlInfo')
|
||||
resolve()
|
||||
}).catch(() => {
|
||||
} catch (e) {
|
||||
this.loading = false
|
||||
reject()
|
||||
})
|
||||
}
|
||||
} else {
|
||||
reject()
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -268,19 +269,19 @@ export default {
|
|||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
>>>.el-form-item label:before {
|
||||
/deep/ .el-form-item label:before {
|
||||
content: '*';
|
||||
color: #F56C6C;
|
||||
margin-right: 4px;
|
||||
}
|
||||
>>>.el-form-item--medium .el-form-item__content{
|
||||
/deep/ .el-form-item--medium .el-form-item__content{
|
||||
display: flex;
|
||||
}
|
||||
.global-form{
|
||||
>>>.el-form-item__content{
|
||||
/deep/ .el-form-item__content{
|
||||
padding-bottom: 10px;
|
||||
}
|
||||
>>>.form-item .el-form-item__error{
|
||||
/deep/ .form-item .el-form-item__error{
|
||||
top: 60%;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,13 +26,24 @@
|
|||
show-overflow-tooltip
|
||||
width="150"
|
||||
>
|
||||
<template slot-scope="scope">
|
||||
<!-- <template slot-scope="scope">
|
||||
<div v-if="scope.row.BeforeQuestionList.length>index && scope.row.BeforeQuestionList[index].Answer" :style="{color: scope.row.BeforeQuestionList[index].IsGlobalAnswer ? '#f66' : null}">
|
||||
<span v-if="scope.row.BeforeQuestionList[index].DictionaryCode">
|
||||
{{ $fd(scope.row.BeforeQuestionList[index].DictionaryCode,parseInt(scope.row.BeforeQuestionList[index].Answer)) }}
|
||||
</span>
|
||||
<span v-else>{{ scope.row.BeforeQuestionList[index].Answer }}</span>
|
||||
</div>
|
||||
</template> -->
|
||||
<template slot-scope="scope">
|
||||
<template v-if="(scope.row.IsBaseLine && (scope.row.BeforeQuestionList[index].GlobalReadingShowType ===1 || scope.row.BeforeQuestionList[index].GlobalReadingShowType ===5)) || (!scope.row.IsBaseLine && (scope.row.BeforeQuestionList[index].GlobalReadingShowType ===2 || scope.row.BeforeQuestionList[index].GlobalReadingShowType ===6)) || (scope.row.BeforeQuestionList[index].GlobalReadingShowType ===0 || scope.row.BeforeQuestionList[index].GlobalReadingShowType ===4)">
|
||||
<div v-if="scope.row.BeforeQuestionList.length>index && scope.row.BeforeQuestionList[index].Answer" :style="{color: scope.row.BeforeQuestionList[index].IsGlobalAnswer ? '#f66' : null}">
|
||||
<span v-if="scope.row.BeforeQuestionList[index].DictionaryCode">
|
||||
{{ $fd(scope.row.BeforeQuestionList[index].DictionaryCode,parseInt(scope.row.BeforeQuestionList[index].Answer)) }}
|
||||
</span>
|
||||
<span v-else>{{ scope.row.BeforeQuestionList[index].Answer }}</span>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
</template>
|
||||
</el-table-column>
|
||||
</template>
|
||||
|
@ -85,20 +96,20 @@
|
|||
<template>
|
||||
<el-table-column
|
||||
v-for="(qs,index) in globalInfo.adjustedQsList"
|
||||
v-if="qs.isShow"
|
||||
:key="index"
|
||||
prop=""
|
||||
:label="qs"
|
||||
:label="qs.questionName"
|
||||
show-overflow-tooltip
|
||||
:min-width="index === 3 ? '200' : '200'"
|
||||
>
|
||||
<template slot-scope="scope">
|
||||
<div v-if="readingTaskState<2">
|
||||
<span v-if="(scope.row.IsBaseLine && scope.row.AfterQuestionList[index].LimitEdit === 2) || (!scope.row.IsBaseLine && scope.row.AfterQuestionList[index].LimitEdit === 1)">
|
||||
<div v-if="readingTaskState<2 && (scope.row.AfterQuestionList[index].GlobalReadingShowType === 0 || (scope.row.IsBaseLine && scope.row.AfterQuestionList[index].GlobalReadingShowType === 1) || (!scope.row.IsBaseLine && scope.row.AfterQuestionList[index].GlobalReadingShowType === 2))">
|
||||
<!-- <span v-if="(scope.row.IsBaseLine && scope.row.AfterQuestionList[index].LimitEdit === 2) || (!scope.row.IsBaseLine && scope.row.AfterQuestionList[index].LimitEdit === 1)">
|
||||
{{ $fd(scope.row.AfterQuestionList[index].DictionaryCode, parseInt(scope.row.AfterQuestionList[index].VisitAnswer)) }}
|
||||
</span>
|
||||
</span> -->
|
||||
|
||||
<el-form-item
|
||||
v-else
|
||||
style="margin-bottom: 0;"
|
||||
:prop="`${scope.$index}${scope.row.AfterQuestionList[index].QuestionId?scope.row.AfterQuestionList[index].QuestionId:scope.row.AfterQuestionList[index].GlobalAnswerType}`"
|
||||
label=""
|
||||
|
@ -253,7 +264,7 @@
|
|||
/>
|
||||
</el-form-item>
|
||||
</div>
|
||||
<div v-else-if="scope.row.AfterQuestionList.length>index && scope.row.AfterQuestionList[index].Answer">
|
||||
<div v-else>
|
||||
|
||||
<span v-if="scope.row.AfterQuestionList[index].GlobalAnswerType === 3">
|
||||
{{ getAssessType(scope.row.AfterQuestionList[index].Answer) }}
|
||||
|
@ -342,11 +353,12 @@ export default {
|
|||
var readingTool = this.$router.currentRoute.query.readingTool
|
||||
readingTool = isNaN(parseInt(readingTool)) ? null : parseInt(readingTool)
|
||||
var isReadingTaskViewInOrder = this.$router.currentRoute.query.isReadingTaskViewInOrder
|
||||
var trialReadingCriterionId = this.$router.currentRoute.query.TrialReadingCriterionId
|
||||
var path = ''
|
||||
if (readingTool === 0) {
|
||||
path = `/readingDicoms?trialId=${this.globalInfo.trialId}&subjectCode=${this.globalInfo.subjectCode}&subjectId=${this.globalInfo.subjectId}&visitTaskId=${visitTaskId}&isReadingTaskViewInOrder=${isReadingTaskViewInOrder}&criterionType=${criterionType}&readingTool=${readingTool}&TokenKey=${token}`
|
||||
path = `/readingDicoms?TrialReadingCriterionId=${trialReadingCriterionId}&trialId=${this.globalInfo.trialId}&subjectCode=${this.globalInfo.subjectCode}&subjectId=${this.globalInfo.subjectId}&visitTaskId=${visitTaskId}&isReadingTaskViewInOrder=${isReadingTaskViewInOrder}&criterionType=${criterionType}&readingTool=${readingTool}&TokenKey=${token}`
|
||||
} else {
|
||||
path = `/noneDicomReading?trialId=${this.globalInfo.trialId}&subjectCode=${this.globalInfo.subjectCode}&subjectId=${this.globalInfo.subjectId}&visitTaskId=${visitTaskId}&isReadingTaskViewInOrder=${isReadingTaskViewInOrder}&criterionType=${criterionType}&readingTool=${readingTool}&TokenKey=${token}`
|
||||
path = `/noneDicomReading?TrialReadingCriterionId=${trialReadingCriterionId}&trialId=${this.globalInfo.trialId}&subjectCode=${this.globalInfo.subjectCode}&subjectId=${this.globalInfo.subjectId}&visitTaskId=${visitTaskId}&isReadingTaskViewInOrder=${isReadingTaskViewInOrder}&criterionType=${criterionType}&readingTool=${readingTool}&TokenKey=${token}`
|
||||
}
|
||||
const routeData = this.$router.resolve({ path })
|
||||
var newWindow = window.open(routeData.href, '_blank')
|
||||
|
@ -357,9 +369,9 @@ export default {
|
|||
return lesion ? lesion.Count : 0
|
||||
},
|
||||
handleSave(isPrompt = true) {
|
||||
return new Promise((resolve, reject) => {
|
||||
this.$refs['globalRuleForm'].validate(valid => {
|
||||
if (valid) {
|
||||
return new Promise(async(resolve, reject) => {
|
||||
let valid = await this.$refs['globalRuleForm'].validate()
|
||||
if (valid) {
|
||||
this.loading = true
|
||||
var visitTaskAnswerList = []
|
||||
this.globalForm.taskList.forEach((item, index) => {
|
||||
|
@ -388,7 +400,8 @@ export default {
|
|||
trialId: this.globalInfo.trialId,
|
||||
visitTaskAnswerList
|
||||
}
|
||||
batchSubmitGlobalReadingInfo(params).then(res => {
|
||||
try {
|
||||
await batchSubmitGlobalReadingInfo(params)
|
||||
this.loading = false
|
||||
if (isPrompt) {
|
||||
console.log(isPrompt)
|
||||
|
@ -396,14 +409,13 @@ export default {
|
|||
}
|
||||
this.$emit('getGlInfo')
|
||||
resolve()
|
||||
}).catch(() => {
|
||||
} catch (e) {
|
||||
this.loading = false
|
||||
reject()
|
||||
})
|
||||
}
|
||||
} else {
|
||||
reject()
|
||||
}
|
||||
})
|
||||
})
|
||||
},
|
||||
getBeforeAnswer(qsId, row) {
|
||||
|
@ -448,23 +460,23 @@ export default {
|
|||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
>>>.el-form-item label:before {
|
||||
/deep/ .el-form-item label:before {
|
||||
content: '*';
|
||||
color: #F56C6C;
|
||||
margin-right: 4px;
|
||||
}
|
||||
>>>.el-textarea .el-input__count{
|
||||
/deep/ .el-textarea .el-input__count{
|
||||
background: rgba(0,0,0,0);
|
||||
line-height: normal;
|
||||
}
|
||||
>>>.el-form-item{
|
||||
/deep/ .el-form-item{
|
||||
margin-bottom: 0px;
|
||||
}
|
||||
.global-form{
|
||||
>>>.el-form-item__content{
|
||||
/deep/ .el-form-item__content{
|
||||
padding-bottom: 10px;
|
||||
}
|
||||
>>>.form-item .el-form-item__error{
|
||||
/deep/ .form-item .el-form-item__error{
|
||||
top: 60%;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,13 +26,24 @@
|
|||
show-overflow-tooltip
|
||||
width="150"
|
||||
>
|
||||
<template slot-scope="scope">
|
||||
<!-- <template slot-scope="scope">
|
||||
<div v-if="scope.row.BeforeQuestionList.length>index && scope.row.BeforeQuestionList[index].Answer" :style="{color: scope.row.BeforeQuestionList[index].IsGlobalAnswer ? '#f66' : null}">
|
||||
<span v-if="scope.row.BeforeQuestionList[index].DictionaryCode">
|
||||
{{ $fd(scope.row.BeforeQuestionList[index].DictionaryCode,parseInt(scope.row.BeforeQuestionList[index].Answer)) }}
|
||||
</span>
|
||||
<span v-else>{{ scope.row.BeforeQuestionList[index].Answer }}</span>
|
||||
</div>
|
||||
</template> -->
|
||||
<template slot-scope="scope">
|
||||
<template v-if="(scope.row.IsBaseLine && (scope.row.BeforeQuestionList[index].GlobalReadingShowType ===1 || scope.row.BeforeQuestionList[index].GlobalReadingShowType ===5)) || (!scope.row.IsBaseLine && (scope.row.BeforeQuestionList[index].GlobalReadingShowType ===2 || scope.row.BeforeQuestionList[index].GlobalReadingShowType ===6)) || (scope.row.BeforeQuestionList[index].GlobalReadingShowType ===0 || scope.row.BeforeQuestionList[index].GlobalReadingShowType ===4)">
|
||||
<div v-if="scope.row.BeforeQuestionList.length>index && scope.row.BeforeQuestionList[index].Answer" :style="{color: scope.row.BeforeQuestionList[index].IsGlobalAnswer ? '#f66' : null}">
|
||||
<span v-if="scope.row.BeforeQuestionList[index].DictionaryCode">
|
||||
{{ $fd(scope.row.BeforeQuestionList[index].DictionaryCode,parseInt(scope.row.BeforeQuestionList[index].Answer)) }}
|
||||
</span>
|
||||
<span v-else>{{ scope.row.BeforeQuestionList[index].Answer }}</span>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
</template>
|
||||
</el-table-column>
|
||||
</template>
|
||||
|
@ -85,20 +96,19 @@
|
|||
<template>
|
||||
<el-table-column
|
||||
v-for="(qs,index) in globalInfo.adjustedQsList"
|
||||
v-if="qs.isShow"
|
||||
:key="index"
|
||||
prop=""
|
||||
:label="qs"
|
||||
:label="qs.questionName"
|
||||
show-overflow-tooltip
|
||||
:min-width="index === 3 ? '200' : '200'"
|
||||
>
|
||||
<template slot-scope="scope">
|
||||
<div v-if="readingTaskState<2">
|
||||
<span v-if="(scope.row.IsBaseLine && scope.row.AfterQuestionList[index].LimitEdit === 2) || (!scope.row.IsBaseLine && scope.row.AfterQuestionList[index].LimitEdit === 1)">
|
||||
<div v-if="readingTaskState<2 && (scope.row.AfterQuestionList[index].GlobalReadingShowType === 0 || (scope.row.IsBaseLine && scope.row.AfterQuestionList[index].GlobalReadingShowType === 1) || (!scope.row.IsBaseLine && scope.row.AfterQuestionList[index].GlobalReadingShowType === 2))">
|
||||
<!-- <span v-if="(scope.row.IsBaseLine && scope.row.AfterQuestionList[index].LimitEdit === 2) || (!scope.row.IsBaseLine && scope.row.AfterQuestionList[index].LimitEdit === 1)">
|
||||
{{ $fd(scope.row.AfterQuestionList[index].DictionaryCode, parseInt(scope.row.AfterQuestionList[index].VisitAnswer)) }}
|
||||
</span>
|
||||
|
||||
</span> -->
|
||||
<el-form-item
|
||||
v-else
|
||||
style="margin-bottom: 0;"
|
||||
:prop="`${scope.$index}${scope.row.AfterQuestionList[index].QuestionId?scope.row.AfterQuestionList[index].QuestionId:scope.row.AfterQuestionList[index].GlobalAnswerType}`"
|
||||
label=""
|
||||
|
@ -247,7 +257,7 @@
|
|||
/>
|
||||
</el-form-item>
|
||||
</div>
|
||||
<div v-else-if="scope.row.AfterQuestionList.length>index && scope.row.AfterQuestionList[index].Answer">
|
||||
<div v-else>
|
||||
|
||||
<span v-if="scope.row.AfterQuestionList[index].GlobalAnswerType === 3">
|
||||
{{ getAssessType(scope.row.AfterQuestionList[index].Answer) }}
|
||||
|
@ -337,11 +347,12 @@ export default {
|
|||
var readingTool = this.$router.currentRoute.query.readingTool
|
||||
readingTool = isNaN(parseInt(readingTool)) ? null : parseInt(readingTool)
|
||||
var isReadingTaskViewInOrder = this.$router.currentRoute.query.isReadingTaskViewInOrder
|
||||
var trialReadingCriterionId = this.$router.currentRoute.query.TrialReadingCriterionId
|
||||
var path = ''
|
||||
if (readingTool === 0) {
|
||||
path = `/readingDicoms?trialId=${this.globalInfo.trialId}&subjectCode=${this.globalInfo.subjectCode}&subjectId=${this.globalInfo.subjectId}&visitTaskId=${visitTaskId}&isReadingTaskViewInOrder=${isReadingTaskViewInOrder}&criterionType=${criterionType}&readingTool=${readingTool}&TokenKey=${token}`
|
||||
path = `/readingDicoms?TrialReadingCriterionId=${trialReadingCriterionId}&trialId=${this.globalInfo.trialId}&subjectCode=${this.globalInfo.subjectCode}&subjectId=${this.globalInfo.subjectId}&visitTaskId=${visitTaskId}&isReadingTaskViewInOrder=${isReadingTaskViewInOrder}&criterionType=${criterionType}&readingTool=${readingTool}&TokenKey=${token}`
|
||||
} else {
|
||||
path = `/noneDicomReading?trialId=${this.globalInfo.trialId}&subjectCode=${this.globalInfo.subjectCode}&subjectId=${this.globalInfo.subjectId}&visitTaskId=${visitTaskId}&isReadingTaskViewInOrder=${isReadingTaskViewInOrder}&criterionType=${criterionType}&readingTool=${readingTool}&TokenKey=${token}`
|
||||
path = `/noneDicomReading?TrialReadingCriterionId=${trialReadingCriterionId}&trialId=${this.globalInfo.trialId}&subjectCode=${this.globalInfo.subjectCode}&subjectId=${this.globalInfo.subjectId}&visitTaskId=${visitTaskId}&isReadingTaskViewInOrder=${isReadingTaskViewInOrder}&criterionType=${criterionType}&readingTool=${readingTool}&TokenKey=${token}`
|
||||
}
|
||||
const routeData = this.$router.resolve({ path })
|
||||
var newWindow = window.open(routeData.href, '_blank')
|
||||
|
@ -352,9 +363,9 @@ export default {
|
|||
return lesion ? lesion.Count : 0
|
||||
},
|
||||
handleSave(isPrompt = true) {
|
||||
return new Promise((resolve, reject) => {
|
||||
this.$refs['globalRuleForm'].validate(valid => {
|
||||
if (valid) {
|
||||
return new Promise(async (resolve, reject) => {
|
||||
let valid = await this.$refs['globalRuleForm'].validate()
|
||||
if (valid) {
|
||||
this.loading = true
|
||||
var visitTaskAnswerList = []
|
||||
this.globalForm.taskList.forEach((item, index) => {
|
||||
|
@ -383,7 +394,8 @@ export default {
|
|||
trialId: this.globalInfo.trialId,
|
||||
visitTaskAnswerList
|
||||
}
|
||||
batchSubmitGlobalReadingInfo(params).then(res => {
|
||||
try {
|
||||
await batchSubmitGlobalReadingInfo(params)
|
||||
this.loading = false
|
||||
if (isPrompt) {
|
||||
console.log(isPrompt)
|
||||
|
@ -391,14 +403,14 @@ export default {
|
|||
}
|
||||
this.$emit('getGlInfo')
|
||||
resolve()
|
||||
}).catch(() => {
|
||||
} catch (e) {
|
||||
this.loading = false
|
||||
reject()
|
||||
})
|
||||
}
|
||||
} else {
|
||||
reject()
|
||||
}
|
||||
})
|
||||
|
||||
})
|
||||
},
|
||||
getBeforeAnswer(qsId, row) {
|
||||
|
@ -428,6 +440,7 @@ export default {
|
|||
}
|
||||
})
|
||||
}
|
||||
console.log(this.globalForm)
|
||||
},
|
||||
getAssessType(v) {
|
||||
console.log(this.language)
|
||||
|
@ -443,23 +456,23 @@ export default {
|
|||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
>>>.el-form-item label:before {
|
||||
/deep/ .el-form-item label:before {
|
||||
content: '*';
|
||||
color: #F56C6C;
|
||||
margin-right: 4px;
|
||||
}
|
||||
>>>.el-textarea .el-input__count{
|
||||
/deep/ .el-textarea .el-input__count{
|
||||
background: rgba(0,0,0,0);
|
||||
line-height: normal;
|
||||
}
|
||||
>>>.el-form-item{
|
||||
/deep/ .el-form-item{
|
||||
margin-bottom: 0px;
|
||||
}
|
||||
.global-form{
|
||||
>>>.el-form-item__content{
|
||||
/deep/ .el-form-item__content{
|
||||
padding-bottom: 10px;
|
||||
}
|
||||
>>>.form-item .el-form-item__error{
|
||||
/deep/ .form-item .el-form-item__error{
|
||||
top: 60%;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,7 +25,14 @@
|
|||
</div>
|
||||
|
||||
<div v-if=" readingTaskState < 2" style="text-align:right;margin:5px 0;">
|
||||
|
||||
<el-button
|
||||
type="primary"
|
||||
size="small"
|
||||
@click="skipTask"
|
||||
>
|
||||
<!-- 跳过 -->
|
||||
{{ $t('trials:readingReport:button:skip') }}
|
||||
</el-button>
|
||||
<el-button size="small" type="primary" @click="handleSave">
|
||||
{{ $t('common:button:save') }}
|
||||
</el-button>
|
||||
|
@ -34,8 +41,17 @@
|
|||
{{ $t('trials:globalReview:button:submit') }}
|
||||
</el-button>
|
||||
</div>
|
||||
<CustomizeTable
|
||||
v-if="CriterionType === 0 && Object.keys(globalInfo).length !== 0"
|
||||
ref="globalTbl"
|
||||
:global-info="globalInfo"
|
||||
:global-form="globalInfo.globalForm"
|
||||
:reading-task-state="readingTaskState"
|
||||
@getGlInfo="getGlInfo"
|
||||
@setOpenWindow="setOpenWindow"
|
||||
/>
|
||||
<RecistTable
|
||||
v-if="(CriterionType === 1 || CriterionType === 0) && Object.keys(globalInfo).length !== 0"
|
||||
v-if="CriterionType === 1 && Object.keys(globalInfo).length !== 0"
|
||||
ref="globalTbl"
|
||||
:global-info="globalInfo"
|
||||
:global-form="globalInfo.globalForm"
|
||||
|
@ -90,6 +106,12 @@
|
|||
show-overflow-tooltip
|
||||
width="200"
|
||||
/>
|
||||
<el-table-column
|
||||
prop="VisitBlindName"
|
||||
:label="$t('trials:globalReview:table:cutOffVisitName')"
|
||||
show-overflow-tooltip
|
||||
width="200"
|
||||
/>
|
||||
<el-table-column
|
||||
:label="$t('common:action:action')"
|
||||
width="200"
|
||||
|
@ -126,9 +148,11 @@
|
|||
<script>
|
||||
import { getGlobalReadingInfo, getReadingPastResultList, submitGlobalReadingInfo, saveGlobalReadingInfo } from '@/api/trials'
|
||||
import { getAutoCutNextTask } from '@/api/user'
|
||||
import { setSkipReadingCache } from '@/api/reading'
|
||||
import { getToken } from '@/utils/auth'
|
||||
import const_ from '@/const/sign-code'
|
||||
import DicomEvent from '@/views/trials/trials-panel/reading/dicoms/components/DicomEvent'
|
||||
import CustomizeTable from './components/CustomizeTable'
|
||||
import RecistTable from './components/RecistTable'
|
||||
import PCWG3Table from './components/PCWG3Table'
|
||||
import IRecistTable from './components/IRecistTable'
|
||||
|
@ -138,7 +162,7 @@ import { changeURLStatic } from '@/utils/history.js'
|
|||
import store from '@/store'
|
||||
export default {
|
||||
name: 'GlobalReview',
|
||||
components: { RecistTable, PCWG3Table, IRecistTable, RecistBMTable, SignForm },
|
||||
components: { CustomizeTable, RecistTable, PCWG3Table, IRecistTable, RecistBMTable, SignForm },
|
||||
props: {
|
||||
trialId: {
|
||||
type: String,
|
||||
|
@ -231,9 +255,10 @@ export default {
|
|||
}
|
||||
},
|
||||
methods: {
|
||||
getGlInfo() {
|
||||
async getGlInfo() {
|
||||
this.loading = true
|
||||
getGlobalReadingInfo({ visitTaskId: this.visitTaskId }).then(res => {
|
||||
try {
|
||||
let res = await getGlobalReadingInfo({ visitTaskId: this.visitTaskId })
|
||||
var evaluationQsList = []
|
||||
var adjustedQsList = []
|
||||
var agreeOrNotList = []
|
||||
|
@ -245,33 +270,38 @@ export default {
|
|||
evaluationQsList.push(qs.QuestionName)
|
||||
})
|
||||
qs.AfterQuestionList.map(qs => {
|
||||
console.log(qs)
|
||||
if (qs.GlobalAnswerType === 1 && (this.CriterionType === 10)) {
|
||||
// 访视阅片备注
|
||||
adjustedQsList.push(this.$t('trials:globalReview:table:visitRemark'))
|
||||
} else if (qs.GlobalAnswerType === 1 && (this.CriterionType === 1 || this.CriterionType === 3 || this.CriterionType === 17 || this.CriterionType === 0)) {
|
||||
adjustedQsList.push({questionName:this.$t('trials:globalReview:table:visitRemark'),isShow:true})
|
||||
} else if (qs.GlobalAnswerType === 1 && (this.CriterionType !== 10)) {
|
||||
// 全局阅片备注
|
||||
adjustedQsList.push(this.$t('trials:globalReview:table:globalRemark'))
|
||||
} else if (qs.GlobalAnswerType === 3 && (this.CriterionType === 1 || this.CriterionType === 3 || this.CriterionType === 17 || this.CriterionType === 0)) {
|
||||
adjustedQsList.push({questionName:this.$t('trials:globalReview:table:globalRemark'),isShow:true})
|
||||
} else if (qs.GlobalAnswerType === 3 && (this.CriterionType !== 10)) {
|
||||
// 评估更新类型
|
||||
adjustedQsList.push(this.$t('trials:globalReview:table:updateType'))
|
||||
adjustedQsList.push({questionName:this.$t('trials:globalReview:table:updateType'),isShow:true})
|
||||
} else {
|
||||
adjustedQsList.push(qs.QuestionName)
|
||||
var isShow = true
|
||||
if(this.CriterionType === 2 && (qs.QuestionType === 39 || qs.QuestionType === 40 || qs.QuestionType === 41)){
|
||||
isShow = false
|
||||
}
|
||||
adjustedQsList.push({questionName:qs.QuestionName,isShow:isShow})
|
||||
}
|
||||
})
|
||||
qs.AgreeOrNot.map(qs => {
|
||||
agreeOrNotList.push(qs.QuestionName)
|
||||
})
|
||||
}
|
||||
qs.AgreeOrNot.map(qs => {
|
||||
var answer = qs.Answer
|
||||
this.$set(globalForm, `${index}${qs.GlobalAnswerType}`, answer)
|
||||
})
|
||||
qs.AfterQuestionList.map(q => {
|
||||
if (q.Answer !== q.VisitAnswer) {
|
||||
this.$set(q, 'isChange', true)
|
||||
}
|
||||
var answer = ''
|
||||
if (q.DictionaryCode) {
|
||||
answer = q.Answer
|
||||
} else {
|
||||
answer = q.Answer
|
||||
}
|
||||
var answer = q.Answer
|
||||
|
||||
if (!q.QuestionId) {
|
||||
this.$set(globalForm, `${index}${q.GlobalAnswerType}`, answer)
|
||||
} else {
|
||||
|
@ -291,70 +321,44 @@ export default {
|
|||
trialId: this.trialId, subjectId: this.subjectId, subjectCode: this.subjectCode, visitTaskId: res.Result.GlobalTaskId, globalForm, globalUpdateType, evaluationQsList, adjustedQsList, agreeOrNotList, readingTaskState: this.readingTaskState, assessTypeList: res.Result.AssessTypeList
|
||||
}
|
||||
this.loading = false
|
||||
}).catch(() => { this.loading = false })
|
||||
} catch (e) {
|
||||
this.loading = false
|
||||
}
|
||||
},
|
||||
getHistoryGlobalInfo() {
|
||||
async getHistoryGlobalInfo() {
|
||||
this.historyLoading = true
|
||||
getReadingPastResultList({ visitTaskId: this.visitTaskId }).then(res => {
|
||||
try {
|
||||
let res = await getReadingPastResultList({ visitTaskId: this.visitTaskId })
|
||||
this.historyTaskList = res.Result
|
||||
this.historyLoading = false
|
||||
}).catch(() => { this.historyLoading = false })
|
||||
},
|
||||
changeAgreeOrNotList(callback, row, visitTaskId) {
|
||||
var message = ''
|
||||
if (parseInt(callback) === 1) {
|
||||
message = '是否确认更改?'
|
||||
row.Answer = '0'
|
||||
} else {
|
||||
message = '是否确认更改?'
|
||||
row.Answer = '1'
|
||||
} catch (e) {
|
||||
this.historyLoading = false
|
||||
}
|
||||
this.$confirm(message, {
|
||||
distinguishCancelAndClose: true,
|
||||
type: 'warning'
|
||||
}).then(() => {
|
||||
this.loading = true
|
||||
var params = {
|
||||
globalTaskId: this.visitTaskId,
|
||||
subjectId: this.subjectId,
|
||||
trialId: this.trialId,
|
||||
questionList: [
|
||||
{
|
||||
questionId: row.QuestionId ? row.QuestionId : '',
|
||||
visitTaskId: visitTaskId,
|
||||
globalAnswerType: row.GlobalAnswerType,
|
||||
answer: row.Answer === '1' ? '0' : '1'
|
||||
}
|
||||
]
|
||||
}
|
||||
saveGlobalReadingInfo(params).then(res => {
|
||||
this.loading = false
|
||||
if (res.IsSuccess) {
|
||||
this.$message.success('保存成功!')
|
||||
this.getGlInfo()
|
||||
}
|
||||
}).catch(() => { this.loading = false })
|
||||
}).catch(() => {})
|
||||
},
|
||||
// handleEdit(row) {
|
||||
// this.rowData = { ...row }
|
||||
// if (this.CriterionType === 1) {
|
||||
// this.rowData.AfterQuestionList.forEach(item => {
|
||||
// if (item.GlobalAnswerType === 1) {
|
||||
// // 全局阅片备注
|
||||
// item.QuestionName = this.$t('trials:globalReview:table:globalRemark')
|
||||
// } else if (item.GlobalAnswerType === 3) {
|
||||
// // 评估更新类型
|
||||
// item.QuestionName = this.$t('trials:globalReview:table:updateType')
|
||||
// }
|
||||
// })
|
||||
// }
|
||||
// // this.editVisible = true
|
||||
// },
|
||||
async handleSave() {
|
||||
this.loading = true
|
||||
await this.$refs['globalTbl'].handleSave(true)
|
||||
this.loading = false
|
||||
handleSave() {
|
||||
this.$refs['globalTbl'].handleSave(true)
|
||||
},
|
||||
async skipTask() {
|
||||
try {
|
||||
// 是否确认跳过?
|
||||
const confirm = await this.$confirm(
|
||||
this.$t('trials:readingReport:message:skipConfirm'),
|
||||
{
|
||||
type: 'warning',
|
||||
distinguishCancelAndClose: true
|
||||
}
|
||||
)
|
||||
if (confirm !== 'confirm') return
|
||||
this.loading = true
|
||||
const res = await setSkipReadingCache({ visitTaskId: this.visitTaskId })
|
||||
this.loading = false
|
||||
if (res.IsSuccess) {
|
||||
window.location.reload()
|
||||
}
|
||||
} catch (e) {
|
||||
this.loading = false
|
||||
console.log(e)
|
||||
}
|
||||
},
|
||||
async handleConfirm() {
|
||||
// 判断是否存在访视评估结果未确认
|
||||
|
@ -384,53 +388,51 @@ export default {
|
|||
}
|
||||
},
|
||||
// 签名并确认
|
||||
signConfirm(signInfo) {
|
||||
async signConfirm(signInfo) {
|
||||
this.loading = true
|
||||
|
||||
var params = {
|
||||
data: {
|
||||
globalTaskId: this.visitTaskId
|
||||
},
|
||||
signInfo: signInfo
|
||||
}
|
||||
submitGlobalReadingInfo(params).then(async res => {
|
||||
try{
|
||||
let res = await submitGlobalReadingInfo(params)
|
||||
if (res.IsSuccess) {
|
||||
this.$message.success(this.$t('common:message:savedSuccessfully'))
|
||||
this.$refs['signForm'].btnLoading = false
|
||||
this.signVisible = false
|
||||
// 设置当前任务阅片状态为已读
|
||||
this.readingTaskState = 2
|
||||
var isAutoTask = await this.getAutoTaskVal()
|
||||
const res = await getAutoCutNextTask()
|
||||
var isAutoTask = res.Result.AutoCutNextTask
|
||||
if (isAutoTask) {
|
||||
DicomEvent.$emit('getNextTask')
|
||||
// DicomEvent.$emit('getNextTask')
|
||||
window.location.reload()
|
||||
} else {
|
||||
// 当前阅片任务已完成,是否进入下一个阅片任务
|
||||
this.$confirm(this.$t('trials:globalReview:message:msg2'), {
|
||||
type: 'warning',
|
||||
distinguishCancelAndClose: true
|
||||
})
|
||||
.then(() => {
|
||||
store.dispatch('reading/resetVisitTasks')
|
||||
DicomEvent.$emit('getNextTask')
|
||||
})
|
||||
.catch(action => {
|
||||
changeURLStatic('visitTaskId', this.visitTaskId)
|
||||
})
|
||||
// 当前阅片任务已完成,是否进入下一个阅片任务
|
||||
const confirm = await this.$confirm(
|
||||
this.$t('trials:globalReview:message:msg2'),
|
||||
{
|
||||
type: 'warning',
|
||||
distinguishCancelAndClose: true
|
||||
}
|
||||
)
|
||||
if (confirm === 'confirm') {
|
||||
// store.dispatch('reading/resetVisitTasks')
|
||||
// DicomEvent.$emit('getNextTask')
|
||||
window.location.reload()
|
||||
} else {
|
||||
changeURLStatic('visitTaskId', this.visitTaskId)
|
||||
}
|
||||
}
|
||||
window.opener.postMessage('refreshTaskList', window.location)
|
||||
}
|
||||
this.loading = false
|
||||
}).catch(_ => {
|
||||
} catch (e) {
|
||||
this.loading = false
|
||||
this.$refs['signForm'].btnLoading = false
|
||||
})
|
||||
},
|
||||
getAutoTaskVal() {
|
||||
return new Promise((resolve, reject) => {
|
||||
getAutoCutNextTask().then(res => {
|
||||
resolve(res.Result.AutoCutNextTask)
|
||||
}).catch(() => { reject() })
|
||||
})
|
||||
}
|
||||
},
|
||||
handleView(row) {
|
||||
if (this.openWindow) {
|
||||
|
@ -439,15 +441,16 @@ export default {
|
|||
try {
|
||||
var token = getToken()
|
||||
var visitTaskId = row.VisitTaskId
|
||||
var trialReadingCriterionId = this.$router.currentRoute.query.TrialReadingCriterionId
|
||||
var criterionType = this.$router.currentRoute.query.criterionType
|
||||
var readingTool = this.$router.currentRoute.query.readingTool
|
||||
readingTool = isNaN(parseInt(readingTool)) ? null : parseInt(readingTool)
|
||||
var isReadingTaskViewInOrder = this.$router.currentRoute.query.isReadingTaskViewInOrder
|
||||
var path = ''
|
||||
if (readingTool === 0) {
|
||||
path = `/readingDicoms?trialId=${this.trialId}&subjectCode=${this.subjectCode}&subjectId=${this.subjectId}&visitTaskId=${visitTaskId}&isReadingTaskViewInOrder=${isReadingTaskViewInOrder}&criterionType=${criterionType}&readingTool=${readingTool}&TokenKey=${token}`
|
||||
path = `/readingDicoms?TrialReadingCriterionId=${trialReadingCriterionId}&trialId=${this.trialId}&subjectCode=${this.subjectCode}&subjectId=${this.subjectId}&visitTaskId=${visitTaskId}&isReadingTaskViewInOrder=${isReadingTaskViewInOrder}&criterionType=${criterionType}&readingTool=${readingTool}&TokenKey=${token}`
|
||||
} else {
|
||||
path = `/noneDicomReading?trialId=${this.trialId}&subjectCode=${this.subjectCode}&subjectId=${this.subjectId}&visitTaskId=${visitTaskId}&isReadingTaskViewInOrder=${isReadingTaskViewInOrder}&criterionType=${criterionType}&readingTool=${readingTool}&TokenKey=${token}`
|
||||
path = `/noneDicomReading?TrialReadingCriterionId=${trialReadingCriterionId}&trialId=${this.trialId}&subjectCode=${this.subjectCode}&subjectId=${this.subjectId}&visitTaskId=${visitTaskId}&isReadingTaskViewInOrder=${isReadingTaskViewInOrder}&criterionType=${criterionType}&readingTool=${readingTool}&TokenKey=${token}`
|
||||
}
|
||||
const routeData = this.$router.resolve({ path })
|
||||
this.openWindow = window.open(routeData.href, '_blank')
|
||||
|
|
|
@ -1,17 +1,15 @@
|
|||
<template>
|
||||
<!-- <el-tabs v-model="activeName" v-loading="loading" style="min-height:500px">-->
|
||||
<!-- <el-tab-pane-->
|
||||
<!-- v-for="criterion in criterions"-->
|
||||
<!-- :key="criterion.ReadingQuestionCriterionTrialId"-->
|
||||
<!-- :label="criterion.ReadingQuestionCriterionTrialName"-->
|
||||
<!-- :name="criterion.ReadingQuestionCriterionTrialId"-->
|
||||
<!-- >-->
|
||||
<div v-loading="loading" style="min-height:500px">
|
||||
<div style="min-height:500px">
|
||||
<h3 v-if="isReadingShowSubjectInfo" style="padding: 5px 0px;margin: 0;">
|
||||
<span v-if="subjectCode">{{ subjectCode }} </span>
|
||||
<span style="margin-left:5px;">{{ taskBlindName }}</span>
|
||||
</h3>
|
||||
<ECRF
|
||||
:trial-id="trialId"
|
||||
:subject-id="subjectId"
|
||||
:criterion-id="criterionId"
|
||||
:visit-task-id="visitTaskId"
|
||||
:iseCRFShowInDicomReading="iseCRFShowInDicomReading"
|
||||
/>
|
||||
</div>
|
||||
|
||||
|
@ -43,6 +41,22 @@ export default {
|
|||
criterionId: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
subjectCode: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
taskBlindName: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
isReadingShowSubjectInfo: {
|
||||
type: Boolean,
|
||||
required: true
|
||||
},
|
||||
iseCRFShowInDicomReading: {
|
||||
type: Boolean,
|
||||
required: true
|
||||
}
|
||||
},
|
||||
data() {
|
||||
|
|
|
@ -55,6 +55,7 @@
|
|||
:question-form="questionForm"
|
||||
:reading-task-state="readingTaskState"
|
||||
:visit-task-id="visitTaskId"
|
||||
:calculation-list="calculationList"
|
||||
@setFormItemData="setFormItemData"
|
||||
@resetFormItemData="resetFormItemData"
|
||||
/>
|
||||
|
@ -77,8 +78,15 @@
|
|||
|
||||
<el-form-item v-if="readingTaskState < 2">
|
||||
<div style="text-align:center;">
|
||||
<el-button type="primary" @click="handleSave">{{ $t('common:button:save') }}</el-button>
|
||||
<el-button type="primary" @click="handleSubmit">{{ $t('common:button:submit') }}</el-button>
|
||||
<el-button type="primary" @click="skipTask" v-if="iseCRFShowInDicomReading">
|
||||
{{ $t('trials:readingReport:button:skip') }}
|
||||
</el-button>
|
||||
<el-button type="primary" @click="handleSave">
|
||||
{{ $t('common:button:save') }}
|
||||
</el-button>
|
||||
<el-button type="primary" @click="handleSubmit" v-if="iseCRFShowInDicomReading">
|
||||
{{ $t('common:button:submit') }}
|
||||
</el-button>
|
||||
</div>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
@ -103,7 +111,8 @@
|
|||
|
||||
<script>
|
||||
|
||||
import { getTrialReadingQuestion, saveVisitTaskQuestions, submitVisitTaskQuestionsInDto } from '@/api/trials'
|
||||
import { getTrialReadingQuestion, saveVisitTaskQuestions, submitVisitTaskQuestionsInDto, getQuestionCalculateRelation } from '@/api/trials'
|
||||
import { setSkipReadingCache } from '@/api/reading'
|
||||
import const_ from '@/const/sign-code'
|
||||
import FormItem from './FormItem'
|
||||
import SignForm from '@/views/trials/components/newSignForm'
|
||||
|
@ -131,6 +140,10 @@ export default {
|
|||
visitTaskId: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
iseCRFShowInDicomReading: {
|
||||
type: Boolean,
|
||||
required: true
|
||||
}
|
||||
},
|
||||
data() {
|
||||
|
@ -145,104 +158,136 @@ export default {
|
|||
currentUser: zzSessionStorage.getItem('userName'),
|
||||
readingTaskState: 0,
|
||||
activeName: 0,
|
||||
formType: null
|
||||
formType: null,
|
||||
classArr: [],
|
||||
calculationList: []
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.getQuestionCalculateRelation()
|
||||
this.getQuestions()
|
||||
DicomEvent.$on('refreshQuestionAnswer', _ => {
|
||||
this.getQuestions()
|
||||
})
|
||||
},
|
||||
methods: {
|
||||
getQuestions() {
|
||||
async getQuestions() {
|
||||
this.loading = true
|
||||
var param = {
|
||||
readingQuestionCriterionTrialId: this.criterionId,
|
||||
visitTaskId: this.visitTaskId
|
||||
}
|
||||
getTrialReadingQuestion(param).then(res => {
|
||||
this.readingTaskState = res.OtherInfo.readingTaskState
|
||||
this.formType = res.OtherInfo.FormType
|
||||
if (res.OtherInfo.FormType === 2) {
|
||||
if (res.Result.MultiPage.length > 0) {
|
||||
res.Result.MultiPage.map((v) => {
|
||||
if (v.Type === 'group' && v.Childrens.length === 0) return
|
||||
if (!v.IsPage && v.Type !== 'group' && v.Type !== 'summary') {
|
||||
this.$set(this.questionForm, v.Id, v.Answer ? v.Answer : null)
|
||||
}
|
||||
if (v.Childrens.length > 0) {
|
||||
this.setChild(v.Childrens)
|
||||
}
|
||||
})
|
||||
this.questions = res.Result.MultiPage
|
||||
this.activeName = res.Result.MultiPage[0].PageName
|
||||
}
|
||||
if (res.Result.PublicPage.length > 0) {
|
||||
res.Result.PublicPage.map((v) => {
|
||||
if (v.Type === 'group' && v.Childrens.length === 0) return
|
||||
if (!v.IsPage && v.Type !== 'group' && v.Type !== 'summary') {
|
||||
this.$set(this.questionForm, v.Id, v.Answer ? v.Answer : null)
|
||||
}
|
||||
if (v.Childrens.length > 0) {
|
||||
this.setChild(v.Childrens)
|
||||
}
|
||||
})
|
||||
this.publicQuestions = res.Result.PublicPage
|
||||
}
|
||||
} else {
|
||||
res.Result.SinglePage.map((v) => {
|
||||
if (v.Type === 'group' && v.Childrens.length === 0) return
|
||||
if (!v.IsPage && v.Type !== 'group' && v.Type !== 'summary') {
|
||||
this.$set(this.questionForm, v.Id, v.Answer ? v.Answer : null)
|
||||
}
|
||||
if (v.Childrens.length > 0) {
|
||||
this.setChild(v.Childrens)
|
||||
}
|
||||
})
|
||||
this.questions = res.Result.SinglePage
|
||||
try {
|
||||
const param = {
|
||||
readingQuestionCriterionTrialId: this.criterionId,
|
||||
visitTaskId: this.visitTaskId
|
||||
}
|
||||
const res = await getTrialReadingQuestion(param)
|
||||
if (res.IsSuccess) {
|
||||
this.readingTaskState = res.OtherInfo.readingTaskState
|
||||
this.formType = res.OtherInfo.FormType
|
||||
if (res.OtherInfo.FormType === 2) {
|
||||
if (res.Result.MultiPage.length > 0) {
|
||||
res.Result.MultiPage.map((v) => {
|
||||
if (v.Type === 'group' && v.Childrens.length === 0) return
|
||||
if (!v.IsPage && v.Type !== 'group' && v.Type !== 'summary') {
|
||||
this.$set(this.questionForm, v.Id, v.Answer ? v.Answer : null)
|
||||
}
|
||||
if (v.Type === 'class') {
|
||||
this.classArr.push({triggerId: v.ClassifyQuestionId, classId: v.Id, classifyAlgorithms: v.ClassifyAlgorithms, classifyType: v.ClassifyType})
|
||||
}
|
||||
if (v.Childrens.length > 0) {
|
||||
this.setChild(v.Childrens)
|
||||
}
|
||||
})
|
||||
this.questions = res.Result.MultiPage
|
||||
this.activeName = res.Result.MultiPage[0].PageName
|
||||
}
|
||||
if (res.Result.PublicPage.length > 0) {
|
||||
res.Result.PublicPage.map((v) => {
|
||||
if (v.Type === 'group' && v.Childrens.length === 0) return
|
||||
if (!v.IsPage && v.Type !== 'group' && v.Type !== 'summary') {
|
||||
this.$set(this.questionForm, v.Id, v.Answer ? v.Answer : null)
|
||||
}
|
||||
if (v.Type === 'class') {
|
||||
this.classArr.push({triggerId: v.ClassifyQuestionId, classId: v.Id, classifyAlgorithms: v.ClassifyAlgorithms, classifyType: v.ClassifyType})
|
||||
}
|
||||
if (v.Childrens.length > 0) {
|
||||
this.setChild(v.Childrens)
|
||||
}
|
||||
})
|
||||
this.publicQuestions = res.Result.PublicPage
|
||||
}
|
||||
} else {
|
||||
res.Result.SinglePage.map((v) => {
|
||||
if (v.Type === 'group' && v.Childrens.length === 0) return
|
||||
if (!v.IsPage && v.Type !== 'group' && v.Type !== 'summary') {
|
||||
this.$set(this.questionForm, v.Id, v.Answer ? v.Answer : null)
|
||||
}
|
||||
if (v.Type === 'class') {
|
||||
this.classArr.push({triggerId: v.ClassifyQuestionId, classId: v.Id, classifyAlgorithms: v.ClassifyAlgorithms, classifyType: v.ClassifyType})
|
||||
}
|
||||
if (v.Childrens.length > 0) {
|
||||
this.setChild(v.Childrens)
|
||||
}
|
||||
})
|
||||
this.questions = res.Result.SinglePage
|
||||
}
|
||||
this.isRender = true
|
||||
}
|
||||
this.isRender = true
|
||||
this.loading = false
|
||||
}).catch(() => { this.loading = false })
|
||||
} catch (e) {
|
||||
this.loading = false
|
||||
}
|
||||
},
|
||||
setChild(obj) {
|
||||
obj.forEach(i => {
|
||||
if (i.Type !== 'group' && i.Type !== 'summary' && i.Id) {
|
||||
this.$set(this.questionForm, i.Id, i.Answer ? i.Answer : null)
|
||||
}
|
||||
if (i.Type === 'class') {
|
||||
this.classArr.push({triggerId: i.ClassifyQuestionId, classId: i.Id, classifyAlgorithms: i.ClassifyAlgorithms, classifyType: i.ClassifyType})
|
||||
}
|
||||
if (i.Childrens && i.Childrens.length > 0) {
|
||||
this.setChild(i.Childrens)
|
||||
}
|
||||
})
|
||||
},
|
||||
handleSave() {
|
||||
this.$refs['questions'].validate((valid) => {
|
||||
if (!valid) return
|
||||
this.loading = true
|
||||
var answers = []
|
||||
for (const k in this.questionForm) {
|
||||
answers.push({ readingQuestionTrialId: k, answer: this.questionForm[k] })
|
||||
}
|
||||
var params = {
|
||||
trialId: this.trialId,
|
||||
visitTaskId: this.visitTaskId,
|
||||
readingQuestionCriterionTrialId: this.criterionId,
|
||||
answerList: answers
|
||||
|
||||
}
|
||||
saveVisitTaskQuestions(params).then(res => {
|
||||
this.$message.success(this.$t('common:message:savedSuccessfully'))
|
||||
this.loading = false
|
||||
}).catch(() => {
|
||||
this.loading = false
|
||||
})
|
||||
})
|
||||
async getQuestionCalculateRelation() {
|
||||
try {
|
||||
let res = await getQuestionCalculateRelation({TrialReadingCriterionId: this.criterionId})
|
||||
this.calculationList = res.Result
|
||||
} catch(e) {
|
||||
console.log(e)
|
||||
}
|
||||
},
|
||||
handleSubmit() {
|
||||
this.$refs['questions'].validate((valid) => {
|
||||
if (!valid) return
|
||||
const { ImageAssessmentReportConfirmation } = const_.processSignature
|
||||
this.signCode = ImageAssessmentReportConfirmation
|
||||
this.signVisible = true
|
||||
})
|
||||
async handleSave() {
|
||||
const valid = await this.$refs['questions'].validate()
|
||||
if (!valid) return
|
||||
this.loading = true
|
||||
const answers = []
|
||||
for (const k in this.questionForm) {
|
||||
answers.push({ readingQuestionTrialId: k, answer: this.questionForm[k] })
|
||||
}
|
||||
const params = {
|
||||
trialId: this.trialId,
|
||||
visitTaskId: this.visitTaskId,
|
||||
readingQuestionCriterionTrialId: this.criterionId,
|
||||
answerList: answers
|
||||
}
|
||||
try {
|
||||
const res = await saveVisitTaskQuestions(params)
|
||||
if (res.IsSuccess) {
|
||||
DicomEvent.$emit('getReportInfo', true)
|
||||
this.$message.success(this.$t('common:message:savedSuccessfully'))
|
||||
}
|
||||
this.loading = false
|
||||
} catch (e) {
|
||||
this.loading = false
|
||||
}
|
||||
},
|
||||
async handleSubmit() {
|
||||
const valid = await this.$refs['questions'].validate()
|
||||
if (!valid) return
|
||||
const { ImageAssessmentReportConfirmation } = const_.processSignature
|
||||
this.signCode = ImageAssessmentReportConfirmation
|
||||
this.signVisible = true
|
||||
},
|
||||
// 关闭签名框
|
||||
closeSignDialog(isSign, signInfo) {
|
||||
|
@ -253,7 +298,7 @@ export default {
|
|||
}
|
||||
},
|
||||
// 签名并确认
|
||||
signConfirm(signInfo) {
|
||||
async signConfirm(signInfo) {
|
||||
this.loading = true
|
||||
var answers = []
|
||||
for (const k in this.questionForm) {
|
||||
|
@ -268,49 +313,80 @@ export default {
|
|||
},
|
||||
signInfo: signInfo
|
||||
}
|
||||
submitVisitTaskQuestionsInDto(params).then(res => {
|
||||
try {
|
||||
const res = await submitVisitTaskQuestionsInDto(params)
|
||||
this.loading = false
|
||||
if (res.IsSuccess) {
|
||||
DicomEvent.$emit('getReportInfo', true)
|
||||
this.$message.success(this.$t('common:message:savedSuccessfully'))
|
||||
this.isEdit = false
|
||||
this.$refs['signForm'].btnLoading = false
|
||||
this.signVisible = false
|
||||
this.readingTaskState = 2
|
||||
window.opener.postMessage('refreshTaskList', window.location)
|
||||
this.$confirm(this.$t('trials:globalReview:message:msg2'), {
|
||||
type: 'warning',
|
||||
distinguishCancelAndClose: true
|
||||
})
|
||||
.then(() => {
|
||||
DicomEvent.$emit('getNextTask')
|
||||
})
|
||||
.catch(action => {
|
||||
|
||||
})
|
||||
// window.location.reload()
|
||||
// window.opener.postMessage('refreshTaskList', window.location)
|
||||
// var token = getToken()
|
||||
// var subjectCode = this.$router.currentRoute.query.subjectCode
|
||||
// var criterionType = this.$router.currentRoute.query.criterionType
|
||||
// var readingTool = this.$router.currentRoute.query.readingTool
|
||||
// var isReadingTaskViewInOrder = this.$router.currentRoute.query.isReadingTaskViewInOrder
|
||||
// var trialReadingCriterionId = this.$router.currentRoute.query.TrialReadingCriterionId
|
||||
// const routeData = `/noneDicomReading?TrialReadingCriterionId=${trialReadingCriterionId}&trialId=${this.trialId}&subjectCode=${subjectCode}&subjectId=${this.subjectId}&isReadingTaskViewInOrder=${isReadingTaskViewInOrder}&criterionType=${criterionType}&readingTool=${readingTool}&TokenKey=${token}&key=${new Date().getTime()}`
|
||||
// this.$router.push({ path: routeData })
|
||||
// this.$router.push({
|
||||
// path: `/readingPage?subjectCode=${subjectCode}&subjectId=${this.subjectId}&trialId=${this.trialId}&TokenKey=${token}`
|
||||
// })
|
||||
const confirm = await this.$confirm(
|
||||
this.$t('trials:noneDicoms:message:msg1'),
|
||||
{
|
||||
type: 'warning',
|
||||
distinguishCancelAndClose: true
|
||||
}
|
||||
)
|
||||
if (confirm !== 'confirm') return
|
||||
window.location.reload()
|
||||
}
|
||||
this.loading = false
|
||||
}).catch(_ => {
|
||||
} catch (e) {
|
||||
this.loading = false
|
||||
this.$refs['signForm'].btnLoading = false
|
||||
})
|
||||
}
|
||||
},
|
||||
async skipTask() {
|
||||
try {
|
||||
// 是否确认跳过?
|
||||
const confirm = await this.$confirm(
|
||||
this.$t('trials:readingReport:message:skipConfirm'),
|
||||
{
|
||||
type: 'warning',
|
||||
distinguishCancelAndClose: true
|
||||
}
|
||||
)
|
||||
if (confirm !== 'confirm') return
|
||||
this.loading = true
|
||||
const res = await setSkipReadingCache({ visitTaskId: this.visitTaskId })
|
||||
this.loading = false
|
||||
if (res.IsSuccess) {
|
||||
window.location.reload()
|
||||
}
|
||||
} catch (e) {
|
||||
this.loading = false
|
||||
console.log(e)
|
||||
}
|
||||
},
|
||||
resetFormItemData(v) {
|
||||
this.questionForm[v] = null
|
||||
},
|
||||
setFormItemData(obj) {
|
||||
this.questionForm[obj.key] = obj.val
|
||||
this.$set(this.questionForm, obj.key, JSON.parse(JSON.stringify(obj.val)))
|
||||
this.classArr.map(i=>{
|
||||
if (i.triggerId === obj.key) {
|
||||
let answer = null
|
||||
let list = JSON.parse(i.classifyAlgorithms)
|
||||
if (i.classifyType === 0) {
|
||||
let o = list.find(v => {
|
||||
return (
|
||||
parseFloat(obj.val) >= parseFloat(v.gt) &&
|
||||
parseFloat(obj.val) < parseFloat(v.lt)
|
||||
)
|
||||
})
|
||||
answer = o ? o.label : null
|
||||
} else if (i.classifyType === 1) {
|
||||
let o = list.find(v => {
|
||||
return v.val.includes(obj.val)
|
||||
})
|
||||
answer = o ? o.label : null
|
||||
}
|
||||
this.$set(this.questionForm, i.classId, answer)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,8 +18,8 @@
|
|||
:label="`${question.QuestionName}`"
|
||||
:prop="question.Id"
|
||||
:rules="[
|
||||
{ required: (question.IsRequired === 0 || (question.IsRequired ===1 && question.RelevanceId && (questionForm[question.RelevanceId] === question.RelevanceValue))) && question.Type!=='group' && question.Type!=='summary',
|
||||
message: '请注明', trigger: ['blur', 'change']},
|
||||
{ required: (question.IsRequired === 0 || (question.IsRequired ===1 && question.RelevanceId && (question.RelevanceValueList.includes(isNaN(parseFloat(questionForm[question.RelevanceId])) ? questionForm[question.RelevanceId] : questionForm[question.RelevanceId].toString())))) && question.Type!=='group' && question.Type!=='summary',
|
||||
message: $t('common:ruleMessage:specify'), trigger: ['blur', 'change']},
|
||||
]"
|
||||
:class="[question.Type==='group'?'mb':question.Type==='upload'?'uploadWrapper':'']"
|
||||
>
|
||||
|
@ -39,27 +39,27 @@
|
|||
:disabled="readingTaskState >= 2"
|
||||
/>
|
||||
<!-- 下拉框 -->
|
||||
<!-- <el-select-->
|
||||
<!-- v-if="question.Type==='select'"-->
|
||||
<!-- v-model="questionForm[question.Id]"-->
|
||||
<!-- :disabled="readingTaskState >= 2"-->
|
||||
<!-- clearable-->
|
||||
<!-- @change="((val)=>{formItemChange(val, question)})"-->
|
||||
<!-- >-->
|
||||
<!-- <el-option-->
|
||||
<!-- v-for="val in question.TypeValue.split('|')"-->
|
||||
<!-- :key="val"-->
|
||||
<!-- :label="val"-->
|
||||
<!-- :value="val"-->
|
||||
<!-- />-->
|
||||
<!-- </el-select>-->
|
||||
<!-- <el-select-->
|
||||
<!-- v-if="question.Type==='select'"-->
|
||||
<!-- v-model="questionForm[question.Id]"-->
|
||||
<!-- :disabled="readingTaskState >= 2"-->
|
||||
<!-- clearable-->
|
||||
<!-- @change="((val)=>{formItemChange(val, question)})"-->
|
||||
<!-- >-->
|
||||
<!-- <el-option-->
|
||||
<!-- v-for="val in question.TypeValue.split('|')"-->
|
||||
<!-- :key="val"-->
|
||||
<!-- :label="val"-->
|
||||
<!-- :value="val"-->
|
||||
<!-- />-->
|
||||
<!-- </el-select>-->
|
||||
<el-select
|
||||
v-if="question.Type==='select'"
|
||||
v-model="questionForm[question.Id]"
|
||||
filterable
|
||||
:placeholder="$t('common:placeholder:select')"
|
||||
:disabled="readingTaskState >= 2"
|
||||
@change="((val)=>{formItemChange(val, qs)})"
|
||||
@change="((val)=>{formItemChange(val, question)})"
|
||||
>
|
||||
<template v-if="question.DictionaryCode">
|
||||
<el-option
|
||||
|
@ -72,9 +72,9 @@
|
|||
<template v-else-if="question.TypeValue">
|
||||
<el-option
|
||||
v-for="val in question.TypeValue.split('|')"
|
||||
:key="val"
|
||||
:label="val"
|
||||
:value="val"
|
||||
:key="val.trim()"
|
||||
:label="val.trim()"
|
||||
:value="val.trim()"
|
||||
/>
|
||||
</template>
|
||||
</el-select>
|
||||
|
@ -91,16 +91,16 @@
|
|||
:key="item.id"
|
||||
:label="item.value.toString()"
|
||||
>
|
||||
{{item.label}}
|
||||
{{ item.label }}
|
||||
</el-radio>
|
||||
</template>
|
||||
<template v-else-if="question.TypeValue">
|
||||
<el-radio
|
||||
v-for="val in question.TypeValue.split('|')"
|
||||
:key="val"
|
||||
:label="val"
|
||||
:key="val.trim()"
|
||||
:label="val.trim()"
|
||||
>
|
||||
{{ val }}
|
||||
{{ val.trim() }}
|
||||
</el-radio>
|
||||
</template>
|
||||
</el-radio-group>
|
||||
|
@ -112,23 +112,97 @@
|
|||
>
|
||||
<el-checkbox
|
||||
v-for="val in question.TypeValue.split('|')"
|
||||
:key="val"
|
||||
:label="val"
|
||||
:key="val.trim()"
|
||||
:label="val.trim()"
|
||||
>
|
||||
{{ val }}
|
||||
{{ val.trim() }}
|
||||
</el-checkbox>
|
||||
</el-checkbox-group>
|
||||
<!-- 数值 -->
|
||||
<!-- :precision="2" :step="0.1" :max="10" -->
|
||||
<el-input-number
|
||||
v-if="question.Type==='number'"
|
||||
<template v-if="question.Type==='number'">
|
||||
<!-- 数值 -->
|
||||
<el-select
|
||||
v-if="question.TypeValue"
|
||||
v-model="questionForm[question.Id]"
|
||||
clearable
|
||||
@change="(val) => { formItemNumberChange(val, question) }"
|
||||
>
|
||||
<el-option
|
||||
v-for="val in question.TypeValue.split('|')"
|
||||
:key="val"
|
||||
:label="val.trim()"
|
||||
:value="val.trim()"
|
||||
/>
|
||||
</el-select>
|
||||
<el-input
|
||||
type="number"
|
||||
v-if="question.DataSource !== 1"
|
||||
@change="(val) => { formItemNumberChange(val, question) }"
|
||||
onblur="value=parseFloat(value).toFixed(parseInt(localStorage.getItem('digitPlaces')));"
|
||||
@input="limitInput($event, questionForm, question.Id)"
|
||||
v-model="questionForm[question.Id]"
|
||||
>
|
||||
<template slot="append" v-if="question.Unit !== 0">{{question.Unit !== 4 ? $fd('ValueUnit', question.Unit) : question.CustomUnit}}</template>
|
||||
<template slot="append" v-else-if="question.ValueType === 2">%</template>
|
||||
</el-input>
|
||||
<el-input
|
||||
type="number"
|
||||
v-if="question.DataSource === 1"
|
||||
onblur="value=parseFloat(value).toFixed(parseInt(localStorage.getItem('digitPlaces')));"
|
||||
@input="limitInput($event, questionForm, question.Id)"
|
||||
:disabled="question.DataSource === 1"
|
||||
v-model="questionForm[question.Id]"
|
||||
>
|
||||
<template slot="append" v-if="question.Unit !== 0">{{question.Unit !== 4 ? $fd('ValueUnit', question.Unit) : question.CustomUnit}}</template>
|
||||
<template slot="append" v-else-if="question.ValueType === 2">%</template>
|
||||
</el-input>
|
||||
</template>
|
||||
<!-- 自动分类 -->
|
||||
<el-input
|
||||
v-if="question.Type === 'class' && question.ClassifyShowType === 1"
|
||||
v-model="questionForm[question.Id]"
|
||||
:disabled="readingTaskState >= 2"
|
||||
:disabled="!question.ClassifyEditType"
|
||||
/>
|
||||
<el-select
|
||||
v-if="question.Type === 'class' && question.ClassifyShowType === 2"
|
||||
v-model="questionForm[question.Id]"
|
||||
:disabled="!question.ClassifyEditType"
|
||||
@change="(val) => { formItemChange(val, question) }"
|
||||
>
|
||||
<el-option
|
||||
v-for="val in question.TypeValue.split('|')"
|
||||
:key="val"
|
||||
:label="val.trim()"
|
||||
:value="val.trim()"
|
||||
/>
|
||||
</el-select>
|
||||
<el-radio-group
|
||||
v-if="question.Type === 'class' && question.ClassifyShowType === 3"
|
||||
v-model="questionForm[question.Id]"
|
||||
:disabled="!question.ClassifyEditType"
|
||||
@change="(val) => { formItemChange(val, question) }"
|
||||
>
|
||||
<el-radio
|
||||
v-for="item of question.TypeValue.split('|')"
|
||||
:key="item.trim()"
|
||||
:label="item.trim()"
|
||||
>
|
||||
{{ item.trim() }}
|
||||
</el-radio>
|
||||
</el-radio-group>
|
||||
<el-input
|
||||
v-if="question.Type === 'class' && question.ClassifyShowType === 4"
|
||||
type="number"
|
||||
:disabled="!question.ClassifyEditType"
|
||||
v-model="questionForm[question.Id]"
|
||||
@change="(val) => { formItemNumberChange(val, question) }"
|
||||
/>
|
||||
<!-- 上传图像 -->
|
||||
<el-upload
|
||||
v-if="question.Type==='upload'"
|
||||
:action="accept"
|
||||
action
|
||||
:accept="accept"
|
||||
:limit="question.ImageCount"
|
||||
:on-preview="handlePictureCardPreview"
|
||||
:before-upload="handleBeforeUpload"
|
||||
|
@ -143,7 +217,6 @@
|
|||
<div slot="file" slot-scope="{file}">
|
||||
<img
|
||||
class="el-upload-list__item-thumbnail"
|
||||
crossOrigin="Anonymous"
|
||||
:src="OSSclientConfig.basePath + file.url"
|
||||
alt=""
|
||||
>
|
||||
|
@ -170,7 +243,7 @@
|
|||
:visible.sync="imgVisible"
|
||||
width="600px"
|
||||
>
|
||||
<el-image :src="imageUrl" width="100%">
|
||||
<el-image :src="OSSclientConfig.basePath + imageUrl" width="100%">
|
||||
<div slot="placeholder" class="image-slot">
|
||||
{{ $t('trials:readingUnit:qsList:message:loading') }}<span class="dot">...</span>
|
||||
</div>
|
||||
|
@ -186,13 +259,15 @@
|
|||
:reading-task-state="readingTaskState"
|
||||
:question-form="questionForm"
|
||||
:visit-task-id="visitTaskId"
|
||||
:calculationList="calculationList"
|
||||
@setFormItemData="setFormItemData"
|
||||
@resetFormItemData="resetFormItemData"
|
||||
@formItemNumberChange="formItemNumberChange"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import { uploadReadingAnswerImage } from '@/api/trials'
|
||||
// import { uploadReadingAnswerImage } from '@/api/trials'
|
||||
export default {
|
||||
name: 'FormItem',
|
||||
props: {
|
||||
|
@ -215,6 +290,12 @@ export default {
|
|||
visitTaskId: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
calculationList: {
|
||||
type: Array,
|
||||
default() {
|
||||
return []
|
||||
}
|
||||
}
|
||||
},
|
||||
data() {
|
||||
|
@ -223,15 +304,25 @@ export default {
|
|||
accept: '.png,.jpg,.jpeg',
|
||||
imgVisible: false,
|
||||
imageUrl: '',
|
||||
urls: []
|
||||
urls: [],
|
||||
digitPlaces: null,
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
questionForm: {
|
||||
deep: true,
|
||||
immediate: true,
|
||||
handler(v) {
|
||||
// console.log(v)
|
||||
handler(v, oldv) {
|
||||
try {
|
||||
if (!v || !v[this.question.Id] || !oldv || !oldv[this.question.Id])
|
||||
return
|
||||
} catch (e) {
|
||||
console.log(e, v)
|
||||
}
|
||||
if (this.question.Type === 'class') {
|
||||
this.$emit("setFormItemData", { key: this.question.Id, val: v[this.question.Id], question: v })
|
||||
}
|
||||
this.formItemNumberChange(this.question.Id, false)
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -242,15 +333,180 @@ export default {
|
|||
this.fileList = []
|
||||
|
||||
this.urls.map(url => {
|
||||
this.fileList.push({ name: '', url: `/api/${url}` })
|
||||
this.fileList.push({ name: '', url: `${url}` })
|
||||
})
|
||||
}
|
||||
}
|
||||
this.digitPlaces = localStorage.getItem('digitPlaces') ? parseInt(localStorage.getItem('digitPlaces')) : 0
|
||||
},
|
||||
methods: {
|
||||
limitInput(value, a, b) {
|
||||
if (value.indexOf('.') > -1) {
|
||||
if (value.split('.')[1].length >= this.digitPlaces) {
|
||||
this.$set(a, b, parseFloat(value).toFixed(this.digitPlaces))
|
||||
}
|
||||
}
|
||||
},
|
||||
logic(rules, num = 0) {
|
||||
try {
|
||||
if (rules.CalculateQuestionList.length === 0) {
|
||||
return false
|
||||
}
|
||||
let dataArr = []
|
||||
rules.CalculateQuestionList.forEach((o, i) => {
|
||||
if (i === 0) {
|
||||
if (rules.CustomCalculateMark > 4 && rules.CustomCalculateMark < 10) {
|
||||
switch (rules.CustomCalculateMark) {
|
||||
case 5:
|
||||
this.questionForm[o.QuestionId].forEach((q, qi) => {
|
||||
if (qi === 0) {
|
||||
num = parseFloat(q[o.TableQuestionId])
|
||||
} else {
|
||||
num *= parseFloat(q[o.TableQuestionId])
|
||||
}
|
||||
})
|
||||
break;
|
||||
case 6:
|
||||
this.questionForm[o.QuestionId].forEach((q, qi) => {
|
||||
if (qi === 0) {
|
||||
num = parseFloat(q[o.TableQuestionId])
|
||||
} else {
|
||||
num += parseFloat(q[o.TableQuestionId])
|
||||
}
|
||||
})
|
||||
break;
|
||||
case 7:
|
||||
this.questionForm[o.QuestionId].forEach((q, qi) => {
|
||||
if (qi === 0) {
|
||||
num = parseFloat(q[o.TableQuestionId])
|
||||
} else {
|
||||
num += parseFloat(q[o.TableQuestionId])
|
||||
}
|
||||
})
|
||||
num = this.questionForm[o.QuestionId].length === 0 ? 0 : num / this.questionForm[o.QuestionId].length
|
||||
break;
|
||||
case 8:
|
||||
var arr = []
|
||||
this.questionForm[o.QuestionId].forEach(q => {
|
||||
arr.push(q[o.TableQuestionId])
|
||||
})
|
||||
num = arr.length === 0 ? 0 : Math.max(...arr)
|
||||
break;
|
||||
case 9:
|
||||
var arr = []
|
||||
this.questionForm[o.QuestionId].forEach(q => {
|
||||
arr.push(q[o.TableQuestionId])
|
||||
})
|
||||
num = arr.length === 0 ? 0 : Math.min(...arr)
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
num = parseFloat(this.questionForm[o.TableQuestionId])
|
||||
if (!isNaN(num)) {
|
||||
dataArr.push(num)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
switch (rules.CustomCalculateMark) {
|
||||
case 1:
|
||||
num += parseFloat(this.questionForm[o.TableQuestionId])
|
||||
break;
|
||||
case 2:
|
||||
num -= parseFloat(this.questionForm[o.TableQuestionId])
|
||||
break;
|
||||
case 3:
|
||||
num *= parseFloat(this.questionForm[o.TableQuestionId])
|
||||
break;
|
||||
case 4:
|
||||
if (parseFloat(this.questionForm[o.TableQuestionId]) === 0) {
|
||||
num = 0
|
||||
} else {
|
||||
num /= parseFloat(this.questionForm[o.TableQuestionId])
|
||||
}
|
||||
break;
|
||||
case 10:
|
||||
if (!isNaN(parseFloat(this.questionForm[o.TableQuestionId]))) {
|
||||
dataArr.push(parseFloat(this.questionForm[o.TableQuestionId]))
|
||||
}
|
||||
num = dataArr.length === 0 ? 0 : dataArr.reduce((acc, curr) => {
|
||||
return acc + (typeof curr === "number" ? curr : 0);
|
||||
}, 0) / dataArr.length;
|
||||
break;
|
||||
case 11:
|
||||
if (!isNaN(parseFloat(this.questionForm[o.TableQuestionId]))) {
|
||||
dataArr.push(parseFloat(this.questionForm[o.TableQuestionId]))
|
||||
}
|
||||
num = Math.max(...dataArr);
|
||||
break;
|
||||
case 12:
|
||||
if (!isNaN(parseFloat(this.questionForm[o.TableQuestionId]))) {
|
||||
dataArr.push(parseFloat(this.questionForm[o.TableQuestionId]))
|
||||
}
|
||||
num = Math.min(...dataArr);
|
||||
break;
|
||||
case 13:
|
||||
if (!isNaN(parseFloat(this.questionForm[o.TableQuestionId]))) {
|
||||
dataArr.push(parseFloat(this.questionForm[o.TableQuestionId]))
|
||||
}
|
||||
num = dataArr.length === 0 ? 0 : dataArr.reduce((acc, curr) => acc && curr) ? 1 : 0
|
||||
break;
|
||||
case 14:
|
||||
if (!isNaN(parseFloat(this.questionForm[o.TableQuestionId]))) {
|
||||
dataArr.push(parseFloat(this.questionForm[o.TableQuestionId]))
|
||||
}
|
||||
num = dataArr.length === 0 ? 0 : dataArr.reduce((acc, curr) => acc || curr, 0) ? 1 : 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
})
|
||||
} catch (e) {
|
||||
console.log(e)
|
||||
}
|
||||
var digitPlaces = parseInt(localStorage.getItem('digitPlaces'))
|
||||
if (rules.ValueType === 2) {
|
||||
num = num * 100
|
||||
}
|
||||
if (rules.CustomCalculateMark === 13 || rules.CustomCalculateMark === 14) {
|
||||
return num
|
||||
} else {
|
||||
return num.toFixed(digitPlaces)
|
||||
}
|
||||
|
||||
},
|
||||
formItemNumberChange(questionId, isTable) {
|
||||
if (isTable) {
|
||||
this.calculationList.forEach((v, i) => {
|
||||
var find = v.CalculateQuestionList.filter(o => {
|
||||
return o.QuestionId === questionId
|
||||
})
|
||||
// find的自动计算值number
|
||||
if (find) {
|
||||
var num = this.logic(v)
|
||||
if (num !== false) {
|
||||
this.$emit('setFormItemData', { key: v.QuestionId, val: num, question: v })
|
||||
}
|
||||
}
|
||||
})
|
||||
} else {
|
||||
this.calculationList.forEach(v => {
|
||||
var find = v.CalculateQuestionList.filter(o => {
|
||||
return o.TableQuestionId === questionId
|
||||
})
|
||||
// find的自动计算值number
|
||||
if (find) {
|
||||
var num = this.logic(v)
|
||||
if (num !== false) {
|
||||
this.$emit('setFormItemData', { key: v.QuestionId, val: num, question: v })
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
},
|
||||
formItemChange(v, question) {
|
||||
if (question.Childrens.length > 0) {
|
||||
this.resetChild(question.Childrens)
|
||||
} else {
|
||||
this.$emit('setFormItemData', { key: question.Id, val: v, question: question})
|
||||
}
|
||||
},
|
||||
resetChild(obj) {
|
||||
|
@ -267,7 +523,7 @@ export default {
|
|||
setFormItemData(obj) {
|
||||
this.$emit('setFormItemData', obj)
|
||||
},
|
||||
uploadScreenshot(param) {
|
||||
async uploadScreenshot(param) {
|
||||
if (!this.visitTaskId) return
|
||||
const loading = this.$loading({
|
||||
target: document.querySelector('.ecrf-wrapper'),
|
||||
|
@ -276,18 +532,12 @@ export default {
|
|||
text: 'Loading',
|
||||
spinner: 'el-icon-loading'
|
||||
})
|
||||
const formData = new FormData()
|
||||
formData.append('file', param.file)
|
||||
uploadReadingAnswerImage(this.$route.query.trialId, this.visitTaskId, formData).then(res => {
|
||||
if (res.IsSuccess) {
|
||||
this.fileList.push({ url: `${res.Result.Path}` })
|
||||
this.urls.push(res.Result.Path)
|
||||
this.$emit('setFormItemData', { key: this.question.Id, val: this.urls.length > 0 ? this.urls.join('|') : '' })
|
||||
}
|
||||
loading.close()
|
||||
}).catch(() => {
|
||||
loading.close()
|
||||
})
|
||||
var file = await this.fileToBlob(param.file)
|
||||
const res = await this.OSSclient.put(`/${this.trialId}/ReadAttachment/${this.subjectId}/${this.visitTaskId}/${param.file.name}`, file)
|
||||
this.fileList.push({ name: param.file.name, url: this.$getObjectName(res.url) })
|
||||
this.urls.push(this.$getObjectName(res.url))
|
||||
this.$emit('setFormItemData', { key: this.question.Id, val: this.urls.length > 0 ? this.urls.join('|') : '' })
|
||||
loading.close()
|
||||
},
|
||||
handleBeforeUpload(file) {
|
||||
// 检测文件类型是否符合要求
|
||||
|
@ -310,7 +560,7 @@ export default {
|
|||
},
|
||||
// 预览图片
|
||||
handlePictureCardPreview(file) {
|
||||
this.imageUrl = file.url
|
||||
this.imageUrl = this.OSSclientConfig.basePath + file.url
|
||||
this.imgVisible = true
|
||||
},
|
||||
// 删除图片
|
||||
|
@ -328,7 +578,7 @@ export default {
|
|||
margin-bottom: 0px;
|
||||
}
|
||||
.disabled{
|
||||
>>>.el-upload--picture-card {
|
||||
/deep/ .el-upload--picture-card {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,956 @@
|
|||
<template>
|
||||
<div class="report-wrapper">
|
||||
<el-card v-loading="loading" shadow="never" style="display:flex;flex-direction: column;">
|
||||
<div slot="header" class="clearfix report-header">
|
||||
<h3 style="margin:0;padding:0;">{{ $t('trials:readingReport:title:eicrf') }}</h3>
|
||||
<div style="margin-left:auto">
|
||||
<!-- <el-switch
|
||||
v-model="isShowDetail"
|
||||
:active-text="$t('trials:readingReport:title:expandDetails')"
|
||||
:inactive-text="$t('trials:readingReport:title:collapseDetails')"
|
||||
style="margin-right:5px"
|
||||
@change="handleShowDetail"
|
||||
/> -->
|
||||
<el-button
|
||||
v-if="readingTaskState<2"
|
||||
type="primary"
|
||||
size="small"
|
||||
@click="skipTask"
|
||||
>
|
||||
<!-- 跳过 -->
|
||||
{{ $t('trials:readingReport:button:skip') }}
|
||||
</el-button>
|
||||
<el-button v-if="readingTaskState<2" type="primary" size="small" @click="getReportInfo">{{ $t('trials:readingReport:button:refresh') }}</el-button>
|
||||
<el-button v-if="readingTaskState<2" type="primary" size="small" @click="handleSave(true)">{{ $t('common:button:save') }}</el-button>
|
||||
<el-button v-if="readingTaskState<2" type="primary" size="small" @click="handleConfirm">{{ $t('common:button:submit') }}</el-button>
|
||||
</div>
|
||||
</div>
|
||||
<div style="flex: 1">
|
||||
<el-table
|
||||
v-if="taskQuestions.length > 0"
|
||||
ref="reportList"
|
||||
v-adaptive="{bottomOffset:0}"
|
||||
:data="taskQuestions"
|
||||
row-key="Id"
|
||||
border
|
||||
default-expand-all
|
||||
height="100"
|
||||
:tree-props="{children: 'Childrens', hasChildren: 'hasChildren'}"
|
||||
size="mini"
|
||||
>
|
||||
<el-table-column
|
||||
prop=""
|
||||
label=""
|
||||
show-overflow-tooltip
|
||||
width="350px"
|
||||
>
|
||||
<template slot-scope="scope">
|
||||
<span v-if="scope.row.QuestionName">{{ scope.row.BlindName ? scope.row.QuestionName : scope.row.QuestionName }}</span>
|
||||
<span
|
||||
v-else
|
||||
style="font-weight: bold;font-size: 16px;color: #f44336;"
|
||||
>
|
||||
{{ scope.row.GroupName }}
|
||||
</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
v-for="task in visitTaskList"
|
||||
:key="task.VisitTaskId"
|
||||
prop="date"
|
||||
show-overflow-tooltip
|
||||
width="200px"
|
||||
>
|
||||
<template slot="header">
|
||||
<div v-if="task.IsCurrentTask">
|
||||
{{ task.BlindName }}
|
||||
</div>
|
||||
<div v-else>
|
||||
<div>
|
||||
{{ task.BlindName }}
|
||||
<el-button type="text" size="small" @click="previewDicoms(task)">
|
||||
<span class="el-icon-view" />
|
||||
</el-button>
|
||||
</div>
|
||||
<!-- <div v-if="task.LatestScanDate">-->
|
||||
<!-- {{ task.LatestScanDate.split(' ')[0] }}-->
|
||||
<!-- </div>-->
|
||||
<!-- {{ `(影像点击跳转)` }} -->
|
||||
<!-- {{ $t('trials:readingReport:button:jump') }}-->
|
||||
</div>
|
||||
</template>
|
||||
<template slot-scope="scope">
|
||||
<template v-if="readingTaskState<2 && task.VisitTaskId === visitTaskId && (scope.row.Type==='input' || scope.row.Type==='number' || scope.row.Type==='select' || scope.row.Type==='textarea' || scope.row.Type==='radio')">
|
||||
<template>
|
||||
<!-- 输入框 -->
|
||||
<div>
|
||||
<template v-if="!((task.IsBaseLine && scope.row.LimitEdit === 1) || (!task.IsBaseLine && scope.row.LimitEdit === 2) || scope.row.LimitEdit === 0)" />
|
||||
<el-input
|
||||
v-else-if="questionForm[scope.row.QuestionId] instanceof Array && (scope.row.Type==='input' || scope.row.Type==='textarea') && !scope.row.IsShowInDicom && ((task.IsBaseLine && scope.row.LimitEdit === 1) || (!task.IsBaseLine && scope.row.LimitEdit === 2) || scope.row.LimitEdit === 0)"
|
||||
v-model="questionForm[scope.row.QuestionId][scope.row.xfIndex][scope.row.TableQuestionId]"
|
||||
size="mini"
|
||||
/>
|
||||
<span v-else-if="questionForm[scope.row.QuestionId] instanceof Array && (scope.row.Type==='input' || scope.row.Type==='textarea')">
|
||||
{{ questionForm[scope.row.QuestionId][scope.row.xfIndex][scope.row.TableQuestionId] }}
|
||||
</span>
|
||||
<el-input
|
||||
v-else-if="(scope.row.Type==='input' || scope.row.Type==='textarea') && !scope.row.IsShowInDicom && ((task.IsBaseLine && scope.row.LimitEdit === 1) || (!task.IsBaseLine && scope.row.LimitEdit === 2) || scope.row.LimitEdit === 0)"
|
||||
v-model="questionForm[scope.row.QuestionId]"
|
||||
size="mini"
|
||||
/>
|
||||
<span v-else-if="scope.row.Type==='input' || scope.row.Type==='textarea'">
|
||||
{{ questionForm[scope.row.QuestionId] }}
|
||||
</span>
|
||||
<el-select
|
||||
v-else-if="questionForm[scope.row.QuestionId] instanceof Array && (scope.row.Type==='select' || scope.row.Type==='radio') && !scope.row.IsShowInDicom && ((task.IsBaseLine && scope.row.LimitEdit === 1) || (!task.IsBaseLine && scope.row.LimitEdit === 2) || scope.row.LimitEdit === 0)"
|
||||
v-model="questionForm[scope.row.QuestionId][scope.row.xfIndex][scope.row.TableQuestionId]"
|
||||
size="mini"
|
||||
clearable
|
||||
>
|
||||
<template>
|
||||
<el-option
|
||||
v-for="val in scope.row.TypeValue.split('|')"
|
||||
:key="val"
|
||||
:label="val"
|
||||
:value="val"
|
||||
/>
|
||||
</template>
|
||||
</el-select>
|
||||
<span v-else-if="questionForm[scope.row.QuestionId] instanceof Array && scope.row.Type==='select'">
|
||||
{{ questionForm[scope.row.QuestionId][scope.row.xfIndex][scope.row.TableQuestionId] }}
|
||||
</span>
|
||||
<el-select
|
||||
v-else-if="(scope.row.Type==='select' || scope.row.Type==='radio') && !scope.row.IsShowInDicom && ((task.IsBaseLine && scope.row.LimitEdit === 1) || (!task.IsBaseLine && scope.row.LimitEdit === 2) || scope.row.LimitEdit === 0)"
|
||||
v-model="questionForm[scope.row.QuestionId]"
|
||||
size="mini"
|
||||
clearable
|
||||
>
|
||||
<template>
|
||||
<el-option
|
||||
v-for="val in scope.row.TypeValue.split('|')"
|
||||
:key="val"
|
||||
:label="val"
|
||||
:value="val"
|
||||
/>
|
||||
</template>
|
||||
</el-select>
|
||||
<span v-else-if="scope.row.Type==='select' || scope.row.Type==='radio'">
|
||||
{{ questionForm[scope.row.QuestionId] }}
|
||||
</span>
|
||||
<el-input
|
||||
v-else-if="scope.row.DataSource !== 1 && questionForm[scope.row.QuestionId] instanceof Array && scope.row.Type==='number' && (scope.row.xfIndex || scope.row.xfIndex === 0) && !scope.row.IsShowInDicom && ((task.IsBaseLine && scope.row.LimitEdit === 1) || (!task.IsBaseLine && scope.row.LimitEdit === 2) || scope.row.LimitEdit === 0)"
|
||||
v-model="questionForm[scope.row.QuestionId][scope.row.xfIndex][scope.row.TableQuestionId]"
|
||||
:disabled="scope.row.DataSource === 1"
|
||||
size="mini"
|
||||
@blur="limitBlur(questionForm[scope.row.QuestionId][scope.row.xfIndex], scope.row.TableQuestionId, scope.row.ValueType)"
|
||||
@focus="() => {questionId = scope.row.QuestionId}"
|
||||
>
|
||||
<template v-if="scope.row.Unit !== 0" slot="append">{{ scope.row.Unit !== 4 ? $fd('ValueUnit', scope.row.Unit) : scope.row.CustomUnit }}</template>
|
||||
<template v-else-if="scope.row.ValueType === 2" slot="append">%</template>
|
||||
</el-input>
|
||||
<span v-else-if="questionForm[scope.row.QuestionId] instanceof Array && scope.row.Type==='number' && (scope.row.xfIndex || scope.row.xfIndex === 0)">
|
||||
<template v-if="(scope.row.ValueType === 0 || scope.row.ValueType === 1) && scope.row.Unit">
|
||||
{{ isNaN(parseInt(questionForm[scope.row.QuestionId][scope.row.xfIndex][scope.row.TableQuestionId]))? questionForm[scope.row.QuestionId][scope.row.xfIndex][scope.row.TableQuestionId]:`${questionForm[scope.row.QuestionId][scope.row.xfIndex][scope.row.TableQuestionId]} ${scope.row.Unit !== 4 ? $fd('ValueUnit',scope.row.Unit) : scope.row.CustomUnit}` }}
|
||||
</template>
|
||||
<template v-else-if="scope.row.ValueType === 2">
|
||||
{{ isNaN(parseInt(questionForm[scope.row.QuestionId][scope.row.xfIndex][scope.row.TableQuestionId])) ? questionForm[scope.row.QuestionId][scope.row.xfIndex][scope.row.TableQuestionId]:`${questionForm[scope.row.QuestionId][scope.row.xfIndex][scope.row.TableQuestionId]} %` }}
|
||||
</template>
|
||||
<template v-else>
|
||||
{{ isNaN(parseInt(questionForm[scope.row.QuestionId][scope.row.xfIndex][scope.row.TableQuestionId])) ? questionForm[scope.row.QuestionId][scope.row.xfIndex][scope.row.TableQuestionId]:`${questionForm[scope.row.QuestionId][scope.row.xfIndex][scope.row.TableQuestionId]}` }}
|
||||
</template>
|
||||
</span>
|
||||
<el-input
|
||||
v-else-if="scope.row.DataSource !== 1 && scope.row.Type==='number' && !scope.row.IsShowInDicom && ((task.IsBaseLine && scope.row.LimitEdit === 1) || (!task.IsBaseLine && scope.row.LimitEdit === 2) || scope.row.LimitEdit === 0)"
|
||||
v-model="questionForm[scope.row.QuestionId]"
|
||||
:disabled="scope.row.DataSource === 1"
|
||||
size="mini"
|
||||
@blur="limitBlur(questionForm, scope.row.QuestionId, scope.row.ValueType)"
|
||||
@focus="() => {questionId = scope.row.QuestionId}"
|
||||
>
|
||||
<template v-if="scope.row.Unit !== 0" slot="append">{{ scope.row.Unit !== 4 ? $fd('ValueUnit', scope.row.Unit) : scope.row.CustomUnit }}</template>
|
||||
<template v-else-if="scope.row.ValueType === 2" slot="append">%</template>
|
||||
</el-input>
|
||||
<span v-else-if="scope.row.Type==='number'">
|
||||
<template v-if="(scope.row.ValueType === 0 || scope.row.ValueType === 1) && scope.row.Unit">
|
||||
{{ isNaN(parseInt(questionForm[scope.row.QuestionId]))? questionForm[scope.row.QuestionId]:`${questionForm[scope.row.QuestionId]} ${scope.row.Unit !== 4 ? $fd('ValueUnit',scope.row.Unit) : scope.row.CustomUnit}` }}
|
||||
</template>
|
||||
<template v-else-if="scope.row.ValueType === 2">
|
||||
{{ isNaN(parseInt(questionForm[scope.row.QuestionId])) ? questionForm[scope.row.QuestionId]:`${questionForm[scope.row.QuestionId]} %` }}
|
||||
</template>
|
||||
<template v-else>
|
||||
{{ isNaN(parseInt(questionForm[scope.row.QuestionId])) ? questionForm[scope.row.QuestionId] : questionForm[scope.row.QuestionId] }}
|
||||
</template>
|
||||
</span>
|
||||
</div>
|
||||
</template>
|
||||
</template>
|
||||
<template v-else-if="task.VisitTaskId === visitTaskId && scope.row.Type === 'upload'">
|
||||
<UploadFile
|
||||
v-if="scope.row.Type==='upload' && (scope.row.xfIndex || scope.row.xfIndex === 0)"
|
||||
:visit-task-id="visitTaskId"
|
||||
:question="scope.row"
|
||||
:task="task"
|
||||
:reading-task-state="readingTaskState"
|
||||
:init-url="questionForm[scope.row.QuestionId][scope.row.xfIndex][scope.row.TableQuestionId]"
|
||||
@setImageUrl="(url) => {setImageUrl(scope.row.QuestionId, scope.row.xfIndex, scope.row.TableQuestionId, url, scope.row.RowId)}"
|
||||
/>
|
||||
<UploadFile
|
||||
v-else-if="scope.row.Type==='upload'"
|
||||
:visit-task-id="visitTaskId"
|
||||
:question="scope.row"
|
||||
:task="task"
|
||||
:reading-task-state="readingTaskState"
|
||||
:init-url="questionForm[scope.row.QuestionId]"
|
||||
@setImageUrl="(url) => {setImageUrl(scope.row.QuestionId, scope.row.xfIndex, scope.row.TableQuestionId, url)}"
|
||||
/>
|
||||
</template>
|
||||
<template v-else-if="scope.row.Type === 'upload'">
|
||||
<UploadFile
|
||||
v-if="scope.row.Type==='upload' && (scope.row.xfIndex || scope.row.xfIndex === 0)"
|
||||
:visit-task-id="visitTaskId"
|
||||
:question="scope.row"
|
||||
:task="task"
|
||||
:reading-task-state="readingTaskState"
|
||||
:init-url="scope.row.Answers[task.VisitTaskId]"
|
||||
/>
|
||||
<UploadFile
|
||||
v-else-if="scope.row.Type==='upload'"
|
||||
:visit-task-id="visitTaskId"
|
||||
:question="scope.row"
|
||||
:task="task"
|
||||
:reading-task-state="readingTaskState"
|
||||
:init-url="scope.row.Answers[task.VisitTaskId]"
|
||||
/>
|
||||
</template>
|
||||
<template v-else-if="scope.row.QuestionType=== 22">
|
||||
{{ scope.row.Answers[task.VisitTaskId] === '-1' ? '未知' : scope.row.Answers[task.VisitTaskId] }}
|
||||
</template>
|
||||
<template v-else-if="scope.row.DictionaryCode">
|
||||
{{ $fd(scope.row.DictionaryCode, scope.row.Answers[task.VisitTaskId]) }}
|
||||
</template>
|
||||
<template v-else-if="CriterionType === 10">
|
||||
{{ isNaN(parseInt(scope.row.Answers[task.VisitTaskId]))?scope.row.Answers[task.VisitTaskId]:`${scope.row.Answers[task.VisitTaskId]}` }}
|
||||
</template>
|
||||
<template v-else-if="!((task.IsBaseLine && scope.row.LimitEdit === 1) || (!task.IsBaseLine && scope.row.LimitEdit === 2) || scope.row.LimitEdit === 0)" />
|
||||
<template v-else-if="(scope.row.ValueType === 0 || scope.row.ValueType === 1) && scope.row.Unit">
|
||||
{{ isNaN(parseInt(scope.row.Answers[task.VisitTaskId]))?scope.row.Answers[task.VisitTaskId]:`${scope.row.Answers[task.VisitTaskId]} ${scope.row.Unit !== 4 ? $fd('ValueUnit',scope.row.Unit) : scope.row.CustomUnit}` }}
|
||||
</template>
|
||||
<template v-else-if="scope.row.ValueType === 2">
|
||||
{{ isNaN(parseInt(scope.row.Answers[task.VisitTaskId])) ? scope.row.Answers[task.VisitTaskId]:`${scope.row.Answers[task.VisitTaskId]} %` }}
|
||||
</template>
|
||||
<template v-else-if="scope.row.Answers && scope.row.Answers.hasOwnProperty(task.VisitTaskId)">
|
||||
{{ scope.row.Answers[task.VisitTaskId] }}
|
||||
</template>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
</el-card>
|
||||
|
||||
<!-- 签名框 -->
|
||||
<el-dialog
|
||||
v-if="signVisible"
|
||||
:visible.sync="signVisible"
|
||||
:close-on-click-modal="false"
|
||||
width="600px"
|
||||
custom-class="base-dialog-wrapper"
|
||||
>
|
||||
<div slot="title">
|
||||
<span style="font-size:18px;">{{ $t('common:dialogTitle:sign') }}</span>
|
||||
<span style="font-size:12px;margin-left:5px">{{ `(${$t('common:label:sign')}${ currentUser })` }}</span>
|
||||
</div>
|
||||
<SignForm ref="signForm" :sign-code-enum="signCode" @closeDialog="closeSignDialog" />
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import { changeCalculationAnswer, getReadingReportEvaluation, submitDicomVisitTask, verifyVisitTaskQuestions, getQuestionCalculateRelation } from '@/api/trials'
|
||||
import { setSkipReadingCache } from '@/api/reading'
|
||||
import DicomEvent from '@/views/trials/trials-panel/reading/dicoms/components/DicomEvent'
|
||||
import UploadFile from './UploadFile'
|
||||
import const_ from '@/const/sign-code'
|
||||
import SignForm from '@/views/trials/components/newSignForm'
|
||||
import { getToken } from '@/utils/auth'
|
||||
import store from '@/store'
|
||||
export default {
|
||||
name: 'Report',
|
||||
components: { SignForm, UploadFile },
|
||||
props: {
|
||||
trialId: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
visitTaskId: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
subjectId: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
readingTool: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
criterionType: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
isReadingTaskViewInOrder: {
|
||||
type: Number,
|
||||
required: true
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
currentUser: zzSessionStorage.getItem('userName'),
|
||||
signVisible: false,
|
||||
signCode: null,
|
||||
visitTaskList: [],
|
||||
taskQuestions: [],
|
||||
loading: false,
|
||||
answers: [],
|
||||
readingTaskState: 2,
|
||||
tumorEvaluate: null,
|
||||
currentEvaluateResult: null,
|
||||
isExistDisease: null,
|
||||
currentExistDisease: null,
|
||||
currentTaskReason: '',
|
||||
answerArr: [],
|
||||
questions: [],
|
||||
isShowDetail: false,
|
||||
CriterionType: 0,
|
||||
CalculationList: [],
|
||||
TrialReadingCriterionId: null,
|
||||
tableAnswers: {},
|
||||
questionForm: {},
|
||||
questionId: null
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
questionForm: {
|
||||
deep: true,
|
||||
immediate: true,
|
||||
handler(v, oldv) {
|
||||
try {
|
||||
if (!v[this.questionId] || !oldv[this.questionId]) return
|
||||
} catch (e) {
|
||||
}
|
||||
this.formItemNumberChange(this.questionId, false)
|
||||
}
|
||||
},
|
||||
taskQuestions() {
|
||||
this.$nextTick(() => {
|
||||
this.setScrollTop()
|
||||
})
|
||||
}
|
||||
},
|
||||
async mounted() {
|
||||
this.CriterionType = parseInt(localStorage.getItem('CriterionType'))
|
||||
this.digitPlaces = parseInt(localStorage.getItem('digitPlaces'))
|
||||
this.TrialReadingCriterionId = this.$route.query.TrialReadingCriterionId
|
||||
window.addEventListener('resize', () => {
|
||||
this.handleResize()
|
||||
this.setScrollTop()
|
||||
})
|
||||
DicomEvent.$on('getReportInfo', isRefresh => {
|
||||
if (!isRefresh) return
|
||||
this.getReportInfo()
|
||||
})
|
||||
await this.getQuestionCalculateRelation()
|
||||
this.getReportInfo()
|
||||
},
|
||||
beforeDestroy() {
|
||||
DicomEvent.$off('getReportInfo')
|
||||
},
|
||||
methods: {
|
||||
limitBlur(questionForm, id, valueType) {
|
||||
const value = questionForm[id]
|
||||
if (valueType === 0) {
|
||||
this.$set(questionForm, id, parseInt(value))
|
||||
} else if (valueType === 3) {
|
||||
this.$set(questionForm, id, parseFloat(value))
|
||||
} else {
|
||||
this.$set(questionForm, id, parseFloat(value).toFixed(this.digitPlaces))
|
||||
}
|
||||
},
|
||||
setImageUrl(qid, index, tqid, url, RowId) {
|
||||
if (index || index === 0) {
|
||||
// 表格问题
|
||||
this.$set(this.questionForm[qid][index], tqid, url)
|
||||
this.$set(this.questionForm[qid][index], tqid + '_RowId', RowId)
|
||||
// this.questionForm[qid][index][tqid] = url
|
||||
} else {
|
||||
// 非表格问题
|
||||
this.questionForm[qid] = url
|
||||
}
|
||||
},
|
||||
getTagterAnswers(list, questionId) {
|
||||
list.forEach(v => {
|
||||
if (v.QuestionId === questionId) {
|
||||
return Object.assign({}, v.Answers)
|
||||
} else if (v.Childrens.length > 0) {
|
||||
return this.getTagterAnswers(v.Childrens, questionId)
|
||||
}
|
||||
})
|
||||
},
|
||||
formItemNumberChange(questionId, isTable) {
|
||||
if (isTable) {
|
||||
this.CalculationList.forEach((v, i) => {
|
||||
var find = v.CalculateQuestionList.filter(o => {
|
||||
return o.QuestionId === questionId
|
||||
})
|
||||
// find的自动计算值number
|
||||
if (find) {
|
||||
var num = this.logic(v)
|
||||
if (num !== false) {
|
||||
this.$set(this.questionForm, v.QuestionId, num)
|
||||
// this.$emit('setFormItemData', { key: v.QuestionId, val: num })
|
||||
}
|
||||
}
|
||||
})
|
||||
} else {
|
||||
this.CalculationList.forEach(v => {
|
||||
var find = v.CalculateQuestionList.filter(o => {
|
||||
return o.TableQuestionId === questionId
|
||||
})
|
||||
// find的自动计算值number
|
||||
if (find) {
|
||||
var num = this.logic(v)
|
||||
if (num !== false) {
|
||||
this.$set(this.questionForm, v.QuestionId, num)
|
||||
// this.$emit('setFormItemData', { key: v.QuestionId, val: num })
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
// this.$emit('formItemNumberChange')
|
||||
},
|
||||
getTableAnswers(QuestionId, list) {
|
||||
var arr = []
|
||||
window.xfList = list
|
||||
list.forEach((v, i) => {
|
||||
var obj = {}
|
||||
v.Childrens.forEach((o) => {
|
||||
this.$set(o, 'xfIndex', i)
|
||||
obj[o.TableQuestionId + '_RowId'] = o.RowId
|
||||
obj[o.TableQuestionId] = o.Answers[this.visitTaskId]
|
||||
})
|
||||
arr.push(obj)
|
||||
})
|
||||
return arr
|
||||
},
|
||||
InitVisitTaskQuestionForm() {
|
||||
this.taskQuestions.map((v, i) => {
|
||||
if (v.Type === 'group' && v.Childrens.length === 0 && v.Type !== 'table') return
|
||||
if (!v.IsPage && v.Type !== 'group' && v.Type !== 'summary' && v.Type !== 'table' && v.Type !== 'number') {
|
||||
this.$set(this.questionForm, v.QuestionId, v.Answers[this.visitTaskId])
|
||||
}
|
||||
if (v.Type === 'table') {
|
||||
var tableAnswers = this.getTableAnswers(v.QuestionId, v.Childrens, i)
|
||||
this.$set(this.questionForm, v.QuestionId, tableAnswers)
|
||||
// this.$set(v, 'xfIndex', i)
|
||||
}
|
||||
if (v.Type === 'number') {
|
||||
let val = null
|
||||
if (v.ValueType === 0) {
|
||||
val = parseInt(v.Answers[this.visitTaskId])
|
||||
} else if (v.ValueType === 3) {
|
||||
val = v.Answers[this.visitTaskId]
|
||||
} else {
|
||||
val = v.Answers[this.visitTaskId] === '' ? parseFloat(0).toFixed(this.digitPlaces) : v.Answers[this.visitTaskId]
|
||||
}
|
||||
this.$set(this.questionForm, v.QuestionId, val)
|
||||
}
|
||||
if (v.Childrens.length > 0) {
|
||||
this.setChild(v.Childrens)
|
||||
}
|
||||
})
|
||||
this.formItemNumberChange(this.questionId, false)
|
||||
},
|
||||
setChild(obj) {
|
||||
obj.forEach((i, index) => {
|
||||
if (i.Type !== 'group' && i.Type !== 'summary' && i.Id && i.Type !== 'table') {
|
||||
this.$set(this.questionForm, i.QuestionId, i.Answers[this.visitTaskId])
|
||||
}
|
||||
if (i.Type === 'table') {
|
||||
var tableAnswers = this.getTableAnswers(i.QuestionId, i.Childrens, index)
|
||||
this.$set(this.questionForm, i.QuestionId, tableAnswers)
|
||||
}
|
||||
if (i.Type === 'number') {
|
||||
let val = null
|
||||
if (i.ValueType === 0) {
|
||||
val = parseInt(i.Answers[this.visitTaskId])
|
||||
} else if (i.ValueType === 3) {
|
||||
val = i.Answers[this.visitTaskId]
|
||||
} else {
|
||||
val = i.Answers[this.visitTaskId] === '' ? parseFloat(0).toFixed(this.digitPlaces) : i.Answers[this.visitTaskId]
|
||||
}
|
||||
this.$set(this.questionForm, i.QuestionId, val)
|
||||
}
|
||||
if (i.Childrens && i.Childrens.length > 0 && i.Type !== 'table') {
|
||||
this.setChild(i.Childrens)
|
||||
}
|
||||
})
|
||||
},
|
||||
getQuestionCalculateRelation() {
|
||||
return new Promise(resolve => {
|
||||
getQuestionCalculateRelation({
|
||||
TrialReadingCriterionId: this.TrialReadingCriterionId
|
||||
}).then(res => {
|
||||
this.CalculationList = res.Result
|
||||
resolve()
|
||||
})
|
||||
})
|
||||
},
|
||||
logic(rules, num = 0) {
|
||||
try {
|
||||
if (rules.CalculateQuestionList.length === 0) {
|
||||
return false
|
||||
}
|
||||
rules.CalculateQuestionList.forEach((o, i) => {
|
||||
if (i === 0) {
|
||||
if (rules.CustomCalculateMark > 4) {
|
||||
switch (rules.CustomCalculateMark) {
|
||||
case 5:
|
||||
this.questionForm[o.QuestionId].forEach((q, qi) => {
|
||||
if (qi === 0) {
|
||||
num = parseFloat(q[o.TableQuestionId])
|
||||
} else {
|
||||
num *= parseFloat(q[o.TableQuestionId])
|
||||
}
|
||||
})
|
||||
break
|
||||
case 6:
|
||||
this.questionForm[o.QuestionId].forEach((q, qi) => {
|
||||
if (qi === 0) {
|
||||
num = isNaN(parseFloat(q[o.TableQuestionId])) ? null : parseFloat(q[o.TableQuestionId])
|
||||
} else {
|
||||
num += isNaN(parseFloat(q[o.TableQuestionId])) ? null : parseFloat(q[o.TableQuestionId])
|
||||
}
|
||||
})
|
||||
break
|
||||
case 7:
|
||||
this.questionForm[o.QuestionId].forEach((q, qi) => {
|
||||
if (qi === 0) {
|
||||
num = parseFloat(q[o.TableQuestionId])
|
||||
} else {
|
||||
num += parseFloat(q[o.TableQuestionId])
|
||||
}
|
||||
})
|
||||
num = this.questionForm[o.QuestionId].length === 0 ? 0 : num / this.questionForm[o.QuestionId].length
|
||||
break
|
||||
case 8:
|
||||
var arr = []
|
||||
this.questionForm[o.QuestionId].forEach(q => {
|
||||
arr.push(q[o.TableQuestionId])
|
||||
})
|
||||
num = arr.length === 0 ? 0 : Math.max(...arr)
|
||||
break
|
||||
case 9:
|
||||
// eslint-disable-next-line no-redeclare
|
||||
var arr = []
|
||||
this.questionForm[o.QuestionId].forEach(q => {
|
||||
arr.push(q[o.TableQuestionId])
|
||||
})
|
||||
num = arr.length === 0 ? 0 : Math.min(...arr)
|
||||
break
|
||||
}
|
||||
} else {
|
||||
num = parseFloat(this.questionForm[o.TableQuestionId])
|
||||
}
|
||||
} else {
|
||||
switch (rules.CustomCalculateMark) {
|
||||
case 1:
|
||||
num += parseFloat(this.questionForm[o.TableQuestionId])
|
||||
break
|
||||
case 2:
|
||||
num -= parseFloat(this.questionForm[o.TableQuestionId])
|
||||
break
|
||||
case 3:
|
||||
num *= parseFloat(this.questionForm[o.TableQuestionId])
|
||||
break
|
||||
case 4:
|
||||
num /= parseFloat(this.questionForm[o.TableQuestionId])
|
||||
// num /= parseFloat(this.questionForm[o.TableQuestionId])
|
||||
break
|
||||
}
|
||||
}
|
||||
})
|
||||
} catch (e) {
|
||||
console.log(e)
|
||||
}
|
||||
var digitPlaces = parseInt(localStorage.getItem('digitPlaces'))
|
||||
if (rules.ValueType === 2) {
|
||||
num = num * 100
|
||||
}
|
||||
return isNaN(num) ? '' : isFinite(num) ? num.toFixed(digitPlaces) : '∞'
|
||||
},
|
||||
getReportInfo() {
|
||||
this.loading = true
|
||||
var params = {
|
||||
visitTaskId: this.visitTaskId,
|
||||
trialId: this.$router.currentRoute.query.trialId
|
||||
}
|
||||
this.taskQuestions = []
|
||||
getReadingReportEvaluation(params).then(res => {
|
||||
this.readingTaskState = res.Result.ReadingTaskState
|
||||
this.tumorEvaluate = res.Result.CalculateResult.TumorEvaluate ? parseInt(res.Result.CalculateResult.TumorEvaluate) : null
|
||||
this.isExistDisease = res.Result.CalculateResult.IsExistDisease ? parseInt(res.Result.CalculateResult.IsExistDisease) : null
|
||||
this.answerArr = []
|
||||
this.questions = res.Result.TaskQuestions.concat()
|
||||
var taskQuestions = this.getQuestions(res.Result.TaskQuestions, !this.isShowDetail, null, null)
|
||||
taskQuestions.forEach(item => {
|
||||
this.$set(this.taskQuestions, this.taskQuestions.length, item)
|
||||
})
|
||||
this.visitTaskList = res.Result.VisitTaskList
|
||||
this.InitVisitTaskQuestionForm()
|
||||
this.handleResize()
|
||||
this.setScrollTop()
|
||||
this.loading = false
|
||||
}).catch(() => { this.loading = false })
|
||||
},
|
||||
setScrollTop(a) {
|
||||
setTimeout(() => {
|
||||
this.$nextTick(() => {
|
||||
if (this.$refs.reportList) {
|
||||
this.$refs.reportList.bodyWrapper.scrollTop = this.$refs.reportList.bodyWrapper.scrollHeight
|
||||
this.$refs.reportList.bodyWrapper.scrollTop = this.$refs.reportList.bodyWrapper.scrollHeight
|
||||
}
|
||||
})
|
||||
}, 50)
|
||||
},
|
||||
getQuestions(questions, isNTFilterLength, lesionType, isLymphNodes) {
|
||||
const arr = []
|
||||
if (questions.length !== 0) {
|
||||
questions.forEach((item) => {
|
||||
// 过滤病灶标识 病灶名称 部位 器官 位置 是否淋巴结
|
||||
// 非靶病灶和新病灶 过滤长径和短径信息
|
||||
// 非淋巴结靶病灶 过滤短径
|
||||
|
||||
lesionType = item.LesionType
|
||||
var filterArr = []
|
||||
if ((item.LesionType === 1 || item.LesionType === 2) && isNTFilterLength) {
|
||||
filterArr = [0, 1, 3, 4, 5, 6, 2, 8, 10]
|
||||
} else {
|
||||
filterArr = [3, 4, 5, 6, 2, 8, 10]
|
||||
}
|
||||
if (lesionType === 0 && isLymphNodes === 0 && !this.isShowDetail && this.CriterionType === 1) {
|
||||
filterArr.push(1)
|
||||
}
|
||||
if (!(filterArr.includes(item.QuestionMark))) {
|
||||
const obj = item
|
||||
this.$set(obj, 'Answers', {})
|
||||
// obj.Answers = {}
|
||||
if (item.RowIndex > 0) {
|
||||
var idx = item.Childrens.findIndex(i => i.QuestionMark === 8)
|
||||
var idxLoc = item.Childrens.findIndex(i => i.QuestionMark === 10)
|
||||
|
||||
if (idx > -1) {
|
||||
if (item.Childrens[idx].Answer.length > 0) {
|
||||
var k = item.Childrens[idx].Answer.findIndex(v => v.Answer !== '')
|
||||
var part = ''
|
||||
if (obj.IsCanEditPosition) {
|
||||
part = `${item.Childrens[idx].Answer[k].Answer}--${item.Childrens[idxLoc].Answer[k].Answer}`
|
||||
} else {
|
||||
part = `${item.Childrens[idx].Answer[k].Answer}`
|
||||
}
|
||||
|
||||
if (item.SplitOrMergeLesionName && k > -1) {
|
||||
obj.QuestionName = `${obj.QuestionName} --${part} (Split from ${item.SplitOrMergeLesionName})`
|
||||
// obj.QuestionName = `${obj.QuestionName} `
|
||||
} else if (!item.SplitOrMergeLesionName && k > -1) {
|
||||
obj.QuestionName = `${obj.QuestionName} --${part}`
|
||||
// obj.QuestionName = `${obj.QuestionName} `
|
||||
} else {
|
||||
obj.QuestionName = `${obj.QuestionName} `
|
||||
}
|
||||
|
||||
if (this.CriterionType === 1) {
|
||||
var idxLymphNode = item.Childrens.findIndex(i => i.QuestionMark === 2)
|
||||
if (idxLymphNode > -1) {
|
||||
isLymphNodes = item.Childrens[idxLymphNode].Answer[k].Answer ? parseInt(item.Childrens[idxLymphNode].Answer[k].Answer) : null
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
var digitPlaces = parseInt(localStorage.getItem('digitPlaces')) || 0
|
||||
item.Answer.forEach(i => {
|
||||
if (item.DictionaryCode) {
|
||||
this.$set(obj.Answers, i.VisitTaskId, i.Answer ? parseInt(i.Answer) : null)
|
||||
// obj.Answers[i.VisitTaskId] = i.Answer ? parseInt(i.Answer) : null
|
||||
} else {
|
||||
if (item.Type === 'number') {
|
||||
let val = null
|
||||
if (item.ValueType === 0) {
|
||||
val = parseInt(i.Answer)
|
||||
} else if (item.ValueType === 3) {
|
||||
val = i.Answer
|
||||
} else {
|
||||
val = isNaN(parseFloat(i.Answer)) ? i.Answer : parseFloat(i.Answer).toFixed(digitPlaces)
|
||||
}
|
||||
this.$set(obj.Answers, i.VisitTaskId, val)
|
||||
} else {
|
||||
this.$set(obj.Answers, i.VisitTaskId, i.Answer)
|
||||
}
|
||||
// obj.Answers[i.VisitTaskId] = i.Answer
|
||||
}
|
||||
})
|
||||
if (item.Childrens.length >= 1) {
|
||||
obj.Childrens = this.getQuestions(item.Childrens, isNTFilterLength, lesionType, isLymphNodes)
|
||||
}
|
||||
arr.push(obj)
|
||||
}
|
||||
})
|
||||
}
|
||||
return arr
|
||||
},
|
||||
handleShowDetail(val) {
|
||||
this.getReportInfo()
|
||||
// this.taskQuestions = this.getQuestions(res.Result.TaskQuestions, !this.isShowDetail, null)
|
||||
},
|
||||
handleExistDiseaseChange(val) {
|
||||
// this.currentExistDisease = parseInt(val)
|
||||
|
||||
if (val === this.isExistDisease && this.tumorEvaluate === this.currentEvaluateResult) {
|
||||
this.currentTaskReason = ''
|
||||
this.evaluateReasonChange('')
|
||||
}
|
||||
var idx = this.answerArr.findIndex(i => i.questionType === 15)
|
||||
if (idx > -1) {
|
||||
this.answerArr[idx].answer = val
|
||||
}
|
||||
},
|
||||
handleEvaluateResultChange(val) {
|
||||
// this.currentEvaluateResult = parseInt(val)
|
||||
if (val === this.tumorEvaluate && this.isExistDisease === this.currentExistDisease) {
|
||||
this.currentTaskReason = ''
|
||||
this.evaluateReasonChange('')
|
||||
}
|
||||
var idx = this.answerArr.findIndex(i => i.questionType === 13)
|
||||
if (idx > -1) {
|
||||
this.answerArr[idx].answer = val
|
||||
}
|
||||
},
|
||||
|
||||
evaluateReasonChange(val) {
|
||||
var idx = this.answerArr.findIndex(i => i.questionType === 14)
|
||||
if (idx > -1) {
|
||||
this.answerArr[idx].answer = val
|
||||
}
|
||||
},
|
||||
async handleConfirm() {
|
||||
await this.handleSave(false)
|
||||
await this.verifyVisitTaskQuestions()
|
||||
const { ImageAssessmentReportConfirmation } = const_.processSignature
|
||||
this.signCode = ImageAssessmentReportConfirmation
|
||||
this.signVisible = true
|
||||
},
|
||||
verifyVisitTaskQuestions() {
|
||||
return new Promise((resolve, reject) => {
|
||||
this.loading = true
|
||||
verifyVisitTaskQuestions({ visitTaskId: this.visitTaskId }).then(res => {
|
||||
this.loading = false
|
||||
resolve()
|
||||
}).catch(() => {
|
||||
this.loading = false
|
||||
reject()
|
||||
})
|
||||
})
|
||||
},
|
||||
handleResize() {
|
||||
this.$nextTick(() => {
|
||||
this.$refs.reportList ? this.$refs.reportList.doLayout() : ''
|
||||
})
|
||||
},
|
||||
// 关闭签名框
|
||||
closeSignDialog(isSign, signInfo) {
|
||||
if (isSign) {
|
||||
this.signConfirm(signInfo)
|
||||
} else {
|
||||
this.signVisible = false
|
||||
}
|
||||
},
|
||||
// 签名并确认
|
||||
signConfirm(signInfo) {
|
||||
this.loading = true
|
||||
var params = {
|
||||
data: {
|
||||
visitTaskId: this.visitTaskId
|
||||
},
|
||||
signInfo: signInfo
|
||||
}
|
||||
submitDicomVisitTask(params).then(res => {
|
||||
if (res.IsSuccess) {
|
||||
this.$message.success(this.$t('common:message:savedSuccessfully'))
|
||||
if (this.$refs['signForm']) {
|
||||
this.$refs['signForm'].btnLoading = false
|
||||
}
|
||||
|
||||
this.signVisible = false
|
||||
// window.location.reload()
|
||||
// window.opener.postMessage('refreshTaskList', window.location)
|
||||
|
||||
// 设置当前任务阅片状态为已读
|
||||
this.readingTaskState = 2
|
||||
store.dispatch('reading/setVisitTaskReadingTaskState', { visitTaskId: this.visitTaskId, readingTaskState: 2 })
|
||||
DicomEvent.$emit('setReadingState', 2)
|
||||
window.opener.postMessage('refreshTaskList', window.location)
|
||||
this.$confirm(this.$t('trials:oncologyReview:title:msg2'), {
|
||||
type: 'warning',
|
||||
distinguishCancelAndClose: true
|
||||
})
|
||||
.then(() => {
|
||||
// var token = getToken()
|
||||
// var subjectCode = this.$router.currentRoute.query.subjectCode
|
||||
// var subjectId = this.$router.currentRoute.query.subjectId
|
||||
// var trialId = this.$router.currentRoute.query.trialId
|
||||
|
||||
// this.$router.push({
|
||||
// path: `/readingPage?subjectCode=${subjectCode}&subjectId=${subjectId}&trialId=${trialId}&TokenKey=${token}`
|
||||
// })
|
||||
// DicomEvent.$emit('getNextTask')
|
||||
window.location.reload()
|
||||
})
|
||||
.catch(action => {
|
||||
|
||||
})
|
||||
}
|
||||
this.loading = false
|
||||
}).catch(() => {
|
||||
this.loading = false
|
||||
if (this.$refs['signForm'] && this.$refs['signForm'].btnLoading) {
|
||||
this.$refs['signForm'].btnLoading = false
|
||||
}
|
||||
})
|
||||
},
|
||||
previewDicoms(task) {
|
||||
var token = getToken()
|
||||
// var subjectCode = this.$router.currentRoute.query.subjectCode
|
||||
var subjectCode = localStorage.getItem('subjectCode')
|
||||
var subjectId = this.subjectId
|
||||
var trialId = this.trialId
|
||||
var isReadingTaskViewInOrder = this.isReadingTaskViewInOrder
|
||||
var criterionType = this.criterionType
|
||||
var readingTool = this.readingTool
|
||||
var trialReadingCriterionId = this.$router.currentRoute.query.TrialReadingCriterionId
|
||||
var path = `/noneDicomReading?TrialReadingCriterionId=${trialReadingCriterionId}&trialId=${trialId}&subjectCode=${subjectCode}&subjectId=${subjectId}&visitTaskId=${task.VisitTaskId}&isReadingTaskViewInOrder=${isReadingTaskViewInOrder}&criterionType=${criterionType}&readingTool=${readingTool}&TokenKey=${token}`
|
||||
const routeData = this.$router.resolve({ path })
|
||||
window.open(routeData.href, '_blank')
|
||||
},
|
||||
handleSave(isPrompt) {
|
||||
return new Promise((resolve, reject) => {
|
||||
this.loading = true
|
||||
var answers = []
|
||||
var tableQuestionAnswer = []
|
||||
for (const k in this.questionForm) {
|
||||
if (this.questionForm[k] instanceof Array) {
|
||||
this.questionForm[k].forEach((v, i) => {
|
||||
Object.keys(v).forEach(o => {
|
||||
if (o.indexOf('_RowId') === -1) {
|
||||
tableQuestionAnswer.push({
|
||||
questionId: k,
|
||||
answer: v[o],
|
||||
tableQuestionId: o,
|
||||
rowId: v[o + '_RowId']
|
||||
})
|
||||
}
|
||||
})
|
||||
})
|
||||
// tableQuestionAnswer.push({})
|
||||
} else {
|
||||
answers.push({ questionId: k, answer: this.questionForm[k].toString() })
|
||||
}
|
||||
}
|
||||
var params = {
|
||||
visitTaskId: this.visitTaskId,
|
||||
questionAnswer: answers,
|
||||
tableQuestionAnswer: tableQuestionAnswer
|
||||
}
|
||||
changeCalculationAnswer(params).then(res => {
|
||||
if (isPrompt) {
|
||||
this.$message.success(this.$t('common:message:savedSuccessfully'))
|
||||
}
|
||||
DicomEvent.$emit('refreshQuestionAnswer')
|
||||
this.loading = false
|
||||
resolve()
|
||||
}).catch(() => {
|
||||
this.loading = false
|
||||
reject()
|
||||
})
|
||||
})
|
||||
},
|
||||
async skipTask() {
|
||||
try {
|
||||
// 是否确认跳过?
|
||||
const confirm = await this.$confirm(
|
||||
this.$t('trials:readingReport:message:skipConfirm'),
|
||||
{
|
||||
type: 'warning',
|
||||
distinguishCancelAndClose: true
|
||||
}
|
||||
)
|
||||
if (confirm !== 'confirm') return
|
||||
this.loading = true
|
||||
const res = await setSkipReadingCache({ visitTaskId: this.visitTaskId })
|
||||
this.loading = false
|
||||
if (res.IsSuccess) {
|
||||
window.location.reload()
|
||||
}
|
||||
} catch (e) {
|
||||
this.loading = false
|
||||
console.log(e)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.report-wrapper{
|
||||
|
||||
height: 100%;
|
||||
// background-color: #fff;
|
||||
// background-color: #000;
|
||||
::-webkit-scrollbar {
|
||||
width: 7px;
|
||||
height: 7px;
|
||||
}
|
||||
::-webkit-scrollbar-thumb {
|
||||
border-radius: 10px;
|
||||
// background: #d0d0d0;
|
||||
}
|
||||
.report-header{
|
||||
display: flex;
|
||||
}
|
||||
.el-card{
|
||||
// background-color: #000;
|
||||
// color: #ffffff;
|
||||
border:none;
|
||||
}
|
||||
/deep/ .el-table--border th.gutter:last-of-type{
|
||||
border: none;
|
||||
}
|
||||
/deep/ .el-card__header{
|
||||
border: none;
|
||||
padding: 10px;
|
||||
}
|
||||
/deep/ .el-upload-list--picture-card .el-upload-list__item{
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
}
|
||||
/deep/ .el-upload--picture-card{
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
line-height: 40px;
|
||||
}
|
||||
}
|
||||
/deep/ .el-switch__label.is-active{
|
||||
color: #428bca;
|
||||
}
|
||||
.uploadWrapper{
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,168 @@
|
|||
<template>
|
||||
<div>
|
||||
<el-upload
|
||||
action
|
||||
:accept="accept"
|
||||
:limit="question.ImageCount"
|
||||
:on-preview="handlePictureCardPreview"
|
||||
:before-upload="handleBeforeUpload"
|
||||
:http-request="uploadScreenshot"
|
||||
list-type="picture-card"
|
||||
:on-remove="handleRemove"
|
||||
:file-list="fileList"
|
||||
:class="{disabled:readingTaskState >= 2 || (fileList.length >= question.ImageCount) || (task.VisitTaskId !== visitTaskId) || question.IsShowInDicom || ((task.IsBaseLine && question.LimitEdit === 2) || (!task.IsBaseLine && question.LimitEdit === 1))}"
|
||||
:disabled="readingTaskState >= 2 || task.VisitTaskId !== visitTaskId || question.IsShowInDicom || ((task.IsBaseLine && question.LimitEdit === 2) || (!task.IsBaseLine && question.LimitEdit === 1))"
|
||||
>
|
||||
<i slot="default" class="el-icon-plus" />
|
||||
<div slot="file" slot-scope="{file}">
|
||||
<viewer
|
||||
:ref="file.url"
|
||||
:images="[imageUrl]"
|
||||
style="
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
"
|
||||
>
|
||||
<img
|
||||
class="el-upload-list__item-thumbnail"
|
||||
:src="OSSclientConfig.basePath + file.url"
|
||||
crossOrigin="anonymous"
|
||||
alt=""
|
||||
style="max-width: 100%; max-height: 100%"
|
||||
/>
|
||||
<span class="el-upload-list__item-actions">
|
||||
<span
|
||||
class="el-upload-list__item-preview"
|
||||
@click="handlePictureCardPreview(file)"
|
||||
>
|
||||
<i class="el-icon-zoom-in" />
|
||||
</span>
|
||||
|
||||
<span
|
||||
v-if="readingTaskState < 2"
|
||||
class="el-upload-list__item-delete"
|
||||
@click="handleRemove(file)"
|
||||
>
|
||||
<i class="el-icon-delete" />
|
||||
</span>
|
||||
</span>
|
||||
</viewer>
|
||||
</div>
|
||||
</el-upload>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: "UploadFile",
|
||||
props: {
|
||||
task: {
|
||||
Type: Object,
|
||||
required: true
|
||||
},
|
||||
question: {
|
||||
Type: Object,
|
||||
required: true
|
||||
},
|
||||
visitTaskId: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
readingTaskState: {
|
||||
type: Number,
|
||||
required: true
|
||||
},
|
||||
initUrl: {
|
||||
type: String,
|
||||
default: ''
|
||||
}
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
imgVisible: false,
|
||||
imageUrl: null,
|
||||
accept: '.png,.jpg,.jpeg',
|
||||
fileList: [],
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.urls = this.initUrl === '' ? [] : this.initUrl.split('|')
|
||||
console.log(this.visitTaskId, this.urls)
|
||||
this.fileList = []
|
||||
this.urls.map(url => {
|
||||
this.fileList.push({ name: '', url: `${url}` })
|
||||
})
|
||||
console.log(this.fileList)
|
||||
},
|
||||
methods: {
|
||||
checkFileSuffix(fileName) {
|
||||
var index = fileName.lastIndexOf('.')
|
||||
var suffix = fileName.substring(index + 1, fileName.length)
|
||||
if (this.accept.toLocaleLowerCase().search(suffix.toLocaleLowerCase()) === -1) {
|
||||
return false
|
||||
} else {
|
||||
return true
|
||||
}
|
||||
},
|
||||
async uploadScreenshot(param) {
|
||||
if (!this.visitTaskId) return
|
||||
const loading = this.$loading({
|
||||
target: document.querySelector('.ecrf-wrapper'),
|
||||
fullscreen: false,
|
||||
lock: true,
|
||||
text: 'Loading',
|
||||
spinner: 'el-icon-loading'
|
||||
})
|
||||
var trialId = this.$route.query.trialId
|
||||
var subjectId = this.$route.query.trialId
|
||||
var file = await this.fileToBlob(param.file)
|
||||
const res = await this.OSSclient.put(`/${trialId}/Read/${subjectId}/Visit/${param.file.name}`, file)
|
||||
console.log(res)
|
||||
this.fileList.push({ name: param.file.name, path: this.$getObjectName(res.url), url: this.$getObjectName(res.url)})
|
||||
this.urls.push(this.$getObjectName(res.url))
|
||||
this.$emit('setImageUrl', this.urls.length > 0 ? this.urls.join('|') : '')
|
||||
loading.close()
|
||||
},
|
||||
handleBeforeUpload(file) {
|
||||
// 检测文件类型是否符合要求
|
||||
if (this.checkFileSuffix(file.name)) {
|
||||
// this.fileList = []
|
||||
return true
|
||||
} else {
|
||||
this.$alert(`必须是 ${this.accept} 格式`)
|
||||
return false
|
||||
}
|
||||
},
|
||||
// 预览图片
|
||||
handlePictureCardPreview(file) {
|
||||
var suffix = file.url.substring(file.url.lastIndexOf(".")+1)
|
||||
suffix = suffix ? suffix.toLowerCase() : ''
|
||||
if (suffix === 'doc' || suffix === 'docx' || suffix === 'pdf'){
|
||||
window.open(this.OSSclientConfig.basePath + file.url,'_blank')
|
||||
}else{
|
||||
this.imageUrl = this.OSSclientConfig.basePath + file.url
|
||||
// this.imgVisible = true
|
||||
this.$refs[file.url].$viewer.show()
|
||||
}
|
||||
},
|
||||
// 删除图片
|
||||
handleRemove(file, fileList) {
|
||||
this.imageUrl = ''
|
||||
this.fileList.splice(this.fileList.findIndex(f => f.url === file.url), 1)
|
||||
this.urls.splice(this.fileList.findIndex(f => f === file.url), 1)
|
||||
this.$emit('setFormItemData', { key: this.question.Id, val: this.urls.length > 0 ? this.urls.join('|') : '' })
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.disabled{
|
||||
/deep/ .el-upload--picture-card {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -1,9 +1,9 @@
|
|||
<template>
|
||||
<div v-loading="loading" class="img-container">
|
||||
<el-card class="box-card left">
|
||||
<div v-if="otherInfo && otherInfo.IsReadingShowSubjectInfo" class="title">
|
||||
<span>{{$t('trials:auditRecord:table:subject')}}:{{ otherInfo.SubjectCode }} </span>
|
||||
<span>({{ otherInfo.TaskBlindName }})</span>
|
||||
<div class="img-container">
|
||||
<el-card v-loading="loading" class="box-card left">
|
||||
<div v-if="isReadingShowSubjectInfo" class="title">
|
||||
<h4>{{ subjectCode }} </h4>
|
||||
<h4>{{ taskBlindName }}</h4>
|
||||
</div>
|
||||
<el-tabs v-model="activeName" @tab-click="handleClick">
|
||||
<el-tab-pane :label="$t('trials:clinicaldara:title:currentTask')" name="first" class="left-content">
|
||||
|
@ -28,10 +28,16 @@
|
|||
'is-boxActive': item.Id === currentFileId
|
||||
}"
|
||||
class="img-box"
|
||||
style="text-overflow: ellipsis;overflow: hidden;white-space: nowrap;"
|
||||
@click="selected(item,i,j,true)"
|
||||
>
|
||||
{{ `${j+1}. ${item.FileName}` }}
|
||||
<div v-if="item.FileName.length < 15" class="img-text">
|
||||
{{ `${j+1}. ${item.FileName}` }}
|
||||
</div>
|
||||
<el-tooltip v-else :content="item.FileName" placement="bottom">
|
||||
<div class="img-text">
|
||||
{{ `${j+1}. ${item.FileName}` }}
|
||||
</div>
|
||||
</el-tooltip>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
@ -42,7 +48,7 @@
|
|||
<div style="height:100%;">
|
||||
<!-- 文件层级 -->
|
||||
<div v-if="associatedList.length === 0" class="empty-text">
|
||||
<slot name="empty">{{$t('trials:audit:message:noData')}}</slot>
|
||||
<slot name="empty">{{ $t('trials:audit:message:noData') }}</slot>
|
||||
</div>
|
||||
<div v-else>
|
||||
<div
|
||||
|
@ -54,9 +60,15 @@
|
|||
class="img-box"
|
||||
@click="handleImageRead(task)"
|
||||
>
|
||||
{{ `${j+1}. ${task.TaskBlindName}` }}
|
||||
<div v-if="task.TaskBlindName.length < 15" class="img-text">
|
||||
{{ `${j+1}. ${task.TaskBlindName}` }}
|
||||
</div>
|
||||
<el-tooltip v-else :content="task.TaskBlindName" placement="bottom">
|
||||
<div class="img-text">
|
||||
{{ `${j+1}. ${task.TaskBlindName}` }}
|
||||
</div>
|
||||
</el-tooltip>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</el-tab-pane>
|
||||
|
@ -64,7 +76,7 @@
|
|||
|
||||
</el-card>
|
||||
<!-- 预览图像 -->
|
||||
<el-card class="box-card right">
|
||||
<el-card v-loading="loading" class="box-card right">
|
||||
<div style="width:100%;height: 100%;">
|
||||
<Preview
|
||||
v-if="previewImage.imgList.length > 0"
|
||||
|
@ -79,20 +91,25 @@
|
|||
</el-card>
|
||||
|
||||
<el-card class="box-card" style="width:400px;height:100%;padding: 10px;margin-left:10px;overflow-y: auto;">
|
||||
<el-button
|
||||
v-if="otherInfo && otherInfo.IsExistsClinicalData"
|
||||
type="primary"
|
||||
size="mini"
|
||||
@click="previewCD"
|
||||
>
|
||||
{{ $t('trials:crcUpload:label:clinicalData') }}
|
||||
</el-button>
|
||||
<div style="text-align:right;">
|
||||
<el-button
|
||||
v-if="otherInfo && otherInfo.IsExistsClinicalData"
|
||||
type="text"
|
||||
@click="previewCD"
|
||||
>
|
||||
{{ $t('trials:crcUpload:label:clinicalData') }}
|
||||
</el-button>
|
||||
</div>
|
||||
<Criterions
|
||||
v-if="otherInfo && visitTaskId!== '' && subjectId!== '' && readingCategory!==null && readingCategory!==4"
|
||||
:trial-id="trialId"
|
||||
:subject-id="subjectId"
|
||||
:visit-task-id="visitTaskId"
|
||||
:criterion-id="otherInfo.TrialCriterionId"
|
||||
:subject-code="subjectCode"
|
||||
:task-blind-name="taskBlindName"
|
||||
:is-reading-show-subject-info="isReadingShowSubjectInfo"
|
||||
:ise-c-r-f-show-in-dicom-reading="iseCRFShowInDicomReading"
|
||||
/>
|
||||
</el-card>
|
||||
</div>
|
||||
|
@ -127,9 +144,33 @@ export default {
|
|||
type: String,
|
||||
required: true
|
||||
},
|
||||
taskBlindName: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
readingCategory: {
|
||||
type: Number,
|
||||
required: true
|
||||
},
|
||||
isReadingShowSubjectInfo: {
|
||||
type: Boolean,
|
||||
required: true
|
||||
},
|
||||
readingTool: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
criterionType: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
isReadingTaskViewInOrder: {
|
||||
type: Number,
|
||||
required: true
|
||||
},
|
||||
iseCRFShowInDicomReading: {
|
||||
type: Boolean,
|
||||
required: true
|
||||
}
|
||||
},
|
||||
data() {
|
||||
|
@ -155,7 +196,9 @@ export default {
|
|||
associatedList: [],
|
||||
currentTaskId: '',
|
||||
otherInfo: null,
|
||||
isReadingShowPreviousResults: false
|
||||
isReadingShowPreviousResults: false,
|
||||
bp: [],
|
||||
openWindow: null
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
|
@ -163,11 +206,17 @@ export default {
|
|||
return this.otherInfo && this.otherInfo.IsReadingShowPreviousResults && this.isReadingShowPreviousResults
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
async mounted() {
|
||||
this.bp = await this.$getBodyPart(this.$route.query.trialId)
|
||||
this.isReadingShowPreviousResults = this.$router.currentRoute.query.isReadingShowPreviousResults !== undefined ? this.$router.currentRoute.query.isReadingShowPreviousResults : true
|
||||
|
||||
this.getNoneDicomList(this.isReadingShowPreviousResults)
|
||||
},
|
||||
beforeDestroy() {
|
||||
if (this.openWindow) {
|
||||
this.openWindow.close()
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
// 获取非Dicom检查信息
|
||||
getNoneDicomList() {
|
||||
|
@ -248,18 +297,21 @@ export default {
|
|||
})
|
||||
},
|
||||
handleImageRead(task) {
|
||||
if (this.openWindow) {
|
||||
this.openWindow.close()
|
||||
}
|
||||
this.currentTaskId = task.VisitTaskId
|
||||
var criterionType = this.$router.currentRoute.query.criterionType
|
||||
var readingTool = this.$router.currentRoute.query.readingTool
|
||||
var isReadingTaskViewInOrder = this.$router.currentRoute.query.isReadingTaskViewInOrder
|
||||
var criterionType = this.criterionType
|
||||
var readingTool = this.readingTool
|
||||
var isReadingTaskViewInOrder = this.isReadingTaskViewInOrder
|
||||
var trialReadingCriterionId = this.$router.currentRoute.query.TrialReadingCriterionId
|
||||
var token = getToken()
|
||||
const path = `/noneDicomReading?TrialReadingCriterionId=${trialReadingCriterionId}&trialId=${this.trialId}&subjectCode=${this.subjectCode}&subjectId=${this.subjectId}&isReadingTaskViewInOrder=${isReadingTaskViewInOrder}&criterionType=${criterionType}&readingTool=${readingTool}&TokenKey=${token}`
|
||||
const path = `/noneDicomReading?TrialReadingCriterionId=${trialReadingCriterionId}&trialId=${this.trialId}&visitTaskId=${task.VisitTaskId}&subjectCode=${this.subjectCode}&subjectId=${this.subjectId}&isReadingTaskViewInOrder=${isReadingTaskViewInOrder}&criterionType=${criterionType}&readingTool=${readingTool}&TokenKey=${token}`
|
||||
// const routeData = this.$router.resolve({
|
||||
// path: `/readingPage?subjectId=${this.subjectId}&trialId=${this.trialId}&visitTaskId=${task.VisitTaskId}&TokenKey=${token}`
|
||||
// })
|
||||
const routeData = this.$router.resolve({ path })
|
||||
window.open(routeData.href, '_blank')
|
||||
this.openWindow = window.open(routeData.href, '_blank')
|
||||
},
|
||||
previewCD() {
|
||||
var token = getToken()
|
||||
|
@ -280,7 +332,7 @@ export default {
|
|||
}
|
||||
var arr = bodyPart.split(separator)
|
||||
var newArr = arr.map(i => {
|
||||
return this.$fd('Bodypart', i.trim())
|
||||
return this.$fd('Bodypart', i.trim(), 'Code', { Bodypart: this.bp }, 'Name')
|
||||
})
|
||||
return newArr.join(' | ')
|
||||
}
|
||||
|
@ -293,7 +345,7 @@ export default {
|
|||
flex: 1;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
padding: 10px;
|
||||
padding-bottom: 10px;
|
||||
display: flex;
|
||||
::-webkit-scrollbar {
|
||||
width: 7px;
|
||||
|
@ -303,7 +355,7 @@ export default {
|
|||
border-radius: 10px;
|
||||
background: #d0d0d0;
|
||||
}
|
||||
>>>.el-card__body{
|
||||
/deep/ .el-card__body{
|
||||
padding: 0px;
|
||||
}
|
||||
}
|
||||
|
@ -317,37 +369,43 @@ export default {
|
|||
width:240px;
|
||||
height: 100%;
|
||||
|
||||
>>>.el-card__body{
|
||||
/deep/ .el-card__body{
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
.title{
|
||||
height: 40px;
|
||||
line-height: 40px;
|
||||
// height: 40px;
|
||||
// line-height: 40px;
|
||||
border: 1ppx solid;
|
||||
border: 1px solid #ebe7e7;
|
||||
padding-left: 10px;
|
||||
// padding-left: 10px;
|
||||
background-color: #4e4e4e;
|
||||
color: #ffffff;
|
||||
h4{
|
||||
padding: 5px 0px;
|
||||
margin: 0;
|
||||
text-align: center;
|
||||
background-color: #4c4c4c;
|
||||
}
|
||||
}
|
||||
.left-content{
|
||||
flex: 1;
|
||||
overflow-y: auto;
|
||||
}
|
||||
>>>.el-tabs{
|
||||
/deep/ .el-tabs{
|
||||
height: 100%;
|
||||
display:flex;
|
||||
|
||||
flex-direction: column;
|
||||
}
|
||||
>>>.el-tabs__header{
|
||||
/deep/ .el-tabs__header{
|
||||
height: 40px;
|
||||
padding: 0 5px;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
>>>.el-tabs__content{
|
||||
/deep/ .el-tabs__content{
|
||||
flex: 1;
|
||||
overflow-y: auto;
|
||||
padding: 0 5px;
|
||||
|
@ -357,13 +415,19 @@ export default {
|
|||
display: inline-block;
|
||||
box-sizing: border-box;
|
||||
border-bottom: 2px solid #f3f3f3;
|
||||
width: 180px;
|
||||
height: 50px;
|
||||
line-height: 50px;
|
||||
cursor: pointer;
|
||||
// margin-bottom: 5px;
|
||||
padding-left: 5px;
|
||||
}
|
||||
.img-text{
|
||||
display: inline-block;
|
||||
width: 200px;
|
||||
height: 50px;
|
||||
line-height: 50px;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis; /* 用省略号表示溢出的文本 */
|
||||
white-space: nowrap;
|
||||
}
|
||||
.img-box:nth-last-child(1){
|
||||
margin-bottom: 0px;
|
||||
}
|
||||
|
@ -379,7 +443,7 @@ export default {
|
|||
flex: 1;
|
||||
height: 100%;
|
||||
margin-left: 10px;
|
||||
>>>.el-card__body{
|
||||
/deep/ .el-card__body{
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
}
|
||||
|
|
|
@ -1,15 +1,40 @@
|
|||
<template>
|
||||
<div ref="container" v-loading="loading" class="none-dicom-reading-container">
|
||||
<!-- 访视阅片 -->
|
||||
<VisitReview
|
||||
v-if="isShow && readingCategory && readingCategory=== 1"
|
||||
:trial-id="trialId"
|
||||
:subject-id="subjectId"
|
||||
:subject-code="subjectCode"
|
||||
:visit-task-id="visitTaskId"
|
||||
:reading-category="readingCategory"
|
||||
:is-exists-clinical-data="isExistsClinicalData"
|
||||
/>
|
||||
<div v-if="isShow && readingCategory && readingCategory=== 1" class="reading-wrapper">
|
||||
<el-tabs v-model="activeName" :before-leave="beforeLeave">
|
||||
<!-- 阅片 -->
|
||||
<el-tab-pane :label="$t('trials:reading:tabTitle:review')" name="read">
|
||||
<VisitReview
|
||||
:trial-id="trialId"
|
||||
:subject-id="subjectId"
|
||||
:subject-code="subjectCode"
|
||||
:visit-task-id="visitTaskId"
|
||||
:task-blind-name="taskBlindName"
|
||||
:reading-category="readingCategory"
|
||||
:readingTool="readingTool"
|
||||
:criterionType="criterionType"
|
||||
:isReadingShowSubjectInfo="isReadingShowSubjectInfo"
|
||||
:is-reading-task-view-in-order="isReadingTaskViewInOrder"
|
||||
:iseCRFShowInDicomReading="iseCRFShowInDicomReading"
|
||||
/>
|
||||
</el-tab-pane>
|
||||
<!-- 报告 -->
|
||||
<el-tab-pane :label="$t('trials:reading:tabTitle:report')" name="report" v-if="!iseCRFShowInDicomReading">
|
||||
<Report
|
||||
v-if="tabs.includes('report')"
|
||||
ref="reportPage"
|
||||
:trialId="trialId"
|
||||
:visit-task-id="visitTaskId"
|
||||
:subject-id="subjectId"
|
||||
:readingTool="readingTool"
|
||||
:criterionType="criterionType"
|
||||
:is-reading-task-view-in-order="isReadingTaskViewInOrder"
|
||||
/>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
</div>
|
||||
|
||||
<!-- 全局阅片 -->
|
||||
<GlobalReview
|
||||
v-else-if="isShow && readingCategory && readingCategory === 2"
|
||||
|
@ -59,7 +84,7 @@
|
|||
:show-close="false"
|
||||
>
|
||||
<span slot="title" class="dialog-footer">
|
||||
当前阅片任务存在临床数据,请查看。若已查看,请点击“确认”
|
||||
{{ $t('trials:reading:noneDicom:tip:hasCllinicalData') }}
|
||||
</span>
|
||||
<div :style="{'height':dialogH,'margin':0}">
|
||||
<ClinicalData
|
||||
|
@ -70,7 +95,7 @@
|
|||
</div>
|
||||
|
||||
<span slot="footer" class="dialog-footer">
|
||||
<el-button type="primary" @click="handleConfirmCD">确认</el-button>
|
||||
<el-button type="primary" @click="handleConfirmCD">{{ $t("common:button:confirm") }}</el-button>
|
||||
</span>
|
||||
</el-dialog>
|
||||
|
||||
|
@ -83,16 +108,18 @@ import { getNextTask, readClinicalData } from '@/api/trials'
|
|||
import store from '@/store'
|
||||
import { changeURLStatic } from '@/utils/history.js'
|
||||
import DicomEvent from '@/views/trials/trials-panel/reading/dicoms/components/DicomEvent'
|
||||
import Report from './components/Report'
|
||||
import VisitReview from './components/VisitReview'
|
||||
import GlobalReview from '@/views/trials/trials-panel/reading/global-review'
|
||||
import AdReview from '@/views/trials/trials-panel/reading/ad-review'
|
||||
import ClinicalData from '@/views/trials/trials-panel/reading/clinical-data'
|
||||
import { getToken } from '@/utils/auth'
|
||||
// import { getToken } from '@/utils/auth'
|
||||
import OncologyReview from '@/views/trials/trials-panel/reading/oncology-review'
|
||||
export default {
|
||||
name: 'NoneDicomReading',
|
||||
components: {
|
||||
VisitReview,
|
||||
Report,
|
||||
AdReview,
|
||||
GlobalReview,
|
||||
OncologyReview,
|
||||
|
@ -113,18 +140,21 @@ export default {
|
|||
isExistsClinicalData: false,
|
||||
isNeedReadClinicalData: false,
|
||||
isReadClinicalData: false,
|
||||
iseCRFShowInDicomReading: false,
|
||||
criterionType: null,
|
||||
readingTool: null,
|
||||
isNewSubject: null,
|
||||
dialogVisible: false,
|
||||
dialogH: 0,
|
||||
isShow: false
|
||||
isShow: false,
|
||||
activeName:'',
|
||||
tabs: []
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
DicomEvent.$on('getNextTask', () => {
|
||||
this.getTaskInfo()
|
||||
})
|
||||
})
|
||||
this.trialId = this.$router.currentRoute.query.trialId
|
||||
this.subjectCode = this.$router.currentRoute.query.subjectCode
|
||||
this.subjectId = this.$router.currentRoute.query.subjectId
|
||||
|
@ -136,7 +166,8 @@ export default {
|
|||
this.readingTool = this.$router.currentRoute.query.readingTool
|
||||
this.isNewSubject = this.$router.currentRoute.query.isNewSubject
|
||||
if (this.isNewSubject && this.isReadingTaskViewInOrder) {
|
||||
this.$message.success(`已开始受试者${this.subjectCode}阅片任务`)
|
||||
const message = this.$t('trials:reading:noneDicom:message:startRead').replace('xxx', this.subjectCode)
|
||||
this.$message.success(message)
|
||||
changeURLStatic('isNewSubject', '')
|
||||
}
|
||||
if (this.$router.currentRoute.query.TokenKey) {
|
||||
|
@ -163,10 +194,14 @@ export default {
|
|||
this.isShow = false
|
||||
getNextTask(param).then(res => {
|
||||
this.readingCategory = res.Result.ReadingCategory
|
||||
if (this.subjectId !== res.Result.SubjectId && this.isReadingTaskViewInOrder) {
|
||||
store.dispatch('reading/resetVisitTasks')
|
||||
var token = getToken()
|
||||
window.location.href = `/noneDicomReading?trialId=${this.trialId}&subjectCode=${res.Result.SubjectCode}&subjectId=${res.Result.SubjectId}&isReadingShowPreviousResults=${this.isReadingShowPreviousResults}&isReadingShowSubjectInfo=${this.isReadingShowSubjectInfo}&criterionType=${this.criterionType}&readingTool=${this.readingTool}&isNewSubject=1&isReadingTaskViewInOrder=${res.Result.IsReadingTaskViewInOrder}&TokenKey=${token}`
|
||||
// if (this.subjectId !== res.Result.SubjectId && this.isReadingTaskViewInOrder) {
|
||||
// store.dispatch('reading/resetVisitTasks')
|
||||
// var token = getToken()
|
||||
// window.location.href = `/noneDicomReading?trialId=${this.trialId}&subjectCode=${res.Result.SubjectCode}&subjectId=${res.Result.SubjectId}&isReadingShowPreviousResults=${this.isReadingShowPreviousResults}&isReadingShowSubjectInfo=${this.isReadingShowSubjectInfo}&criterionType=${this.criterionType}&readingTool=${this.readingTool}&isNewSubject=1&isReadingTaskViewInOrder=${res.Result.IsReadingTaskViewInOrder}&TokenKey=${token}`
|
||||
// }
|
||||
if (res.Result.ReadingCategory === 1) {
|
||||
this.activeName = 'read'
|
||||
this.tabs = [this.activeName]
|
||||
}
|
||||
this.subjectId = res.Result.SubjectId
|
||||
this.visitTaskId = res.Result.VisitTaskId
|
||||
|
@ -175,7 +210,8 @@ export default {
|
|||
this.isExistsClinicalData = res.Result.IsExistsClinicalData
|
||||
this.isReadClinicalData = res.Result.IsReadClinicalData
|
||||
this.isNeedReadClinicalData = res.Result.IsNeedReadClinicalData
|
||||
|
||||
this.iseCRFShowInDicomReading = res.Result.IseCRFShowInDicomReading
|
||||
this.isReadingTaskViewInOrder = res.Result.IsReadingTaskViewInOrder
|
||||
this.isReadingShowSubjectInfo = res.Result.IsReadingShowSubjectInfo
|
||||
this.isReadingShowPreviousResults = res.Result.IsReadingShowPreviousResults
|
||||
this.digitPlaces = res.Result.DigitPlaces
|
||||
|
@ -189,15 +225,32 @@ export default {
|
|||
this.loading = false
|
||||
}).catch(() => { this.loading = false })
|
||||
},
|
||||
handleConfirmCD() {
|
||||
async handleConfirmCD() {
|
||||
this.loading = true
|
||||
var visitTaskId = this.visitTaskId
|
||||
readClinicalData({ visitTaskId }).then(res => {
|
||||
try {
|
||||
await readClinicalData({ visitTaskId })
|
||||
this.loading = false
|
||||
this.dialogVisible = false
|
||||
this.isReadClinicalData = true
|
||||
}).catch(() => { this.loading = false })
|
||||
}
|
||||
} catch (e) {
|
||||
this.loading = false
|
||||
}
|
||||
},
|
||||
beforeLeave(activeName, oldActiveName) {
|
||||
if (!this.tabs.includes(activeName)) {
|
||||
this.tabs.push(activeName)
|
||||
}
|
||||
if (oldActiveName === 'read') {
|
||||
this.$nextTick(() => {
|
||||
if (this.$refs.reportPage) {
|
||||
// DicomEvent.$emit('getReportInfo', true)
|
||||
this.$refs.reportPage.setScrollTop(1)
|
||||
}
|
||||
})
|
||||
}
|
||||
return Promise.resolve(true)
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
@ -210,19 +263,50 @@ export default {
|
|||
flex-direction: column;
|
||||
.el-dialog{
|
||||
margin-top: 0px !important;
|
||||
>>>.el-dialog__wrapper{
|
||||
/deep/ .el-dialog__wrapper{
|
||||
margin-top: 0px !important;
|
||||
}
|
||||
>>>.el-dialog__body{
|
||||
/deep/ .el-dialog__body{
|
||||
padding: 10px;
|
||||
}
|
||||
}
|
||||
.reading-wrapper{
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
padding: 0 10px;
|
||||
box-sizing: border-box;
|
||||
/deep/.el-tabs{
|
||||
box-sizing: border-box;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
.el-tabs__item{
|
||||
// color: #fff;
|
||||
}
|
||||
.el-tabs__header{
|
||||
height: 50px;
|
||||
margin:0px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
.el-tabs__content{
|
||||
flex: 1;
|
||||
margin:0px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
.el-tabs__item{
|
||||
// color: #fff;
|
||||
}
|
||||
.el-tab-pane{
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
>>>.dialog-container{
|
||||
}
|
||||
}
|
||||
/deep/ .dialog-container{
|
||||
margin-top: 50px !important;
|
||||
|
||||
}
|
||||
>>>.el-dialog__body{
|
||||
/deep/ .el-dialog__body{
|
||||
padding: 10px;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,6 +26,14 @@
|
|||
>
|
||||
{{ $t('trials:oncologyReview:button:clinicalData') }}
|
||||
</el-button>
|
||||
<el-button
|
||||
type="primary"
|
||||
size="small"
|
||||
@click="skipTask"
|
||||
>
|
||||
<!-- 跳过 -->
|
||||
{{ $t('trials:readingReport:button:skip') }}
|
||||
</el-button>
|
||||
<!-- 保存 -->
|
||||
<el-button
|
||||
v-if="oncologyInfo.ReadingTaskState < 2"
|
||||
|
@ -93,7 +101,7 @@
|
|||
<span>{{ $fd('YesOrNo', scope.row.IsHaveChange ) }}</span>
|
||||
<!-- 查看详情 -->
|
||||
<el-button
|
||||
v-if="scope.row.IsHaveChange && !!oncologyInfo.GlobalTaskId"
|
||||
v-if="scope.row.IsHaveChange && oncologyInfo.GlobalTaskId"
|
||||
type="text"
|
||||
style="margin-left:5px;"
|
||||
@click="handleViewDetail(oncologyInfo.GlobalTaskId)"
|
||||
|
@ -122,18 +130,24 @@
|
|||
<!-- 结论 -->
|
||||
<el-table-column
|
||||
prop="EvaluationResult"
|
||||
:label="$t('trials:oncologyReview:title:findings')"
|
||||
show-overflow-tooltip
|
||||
width="150"
|
||||
>
|
||||
<template slot="header">
|
||||
<div>
|
||||
<span>{{ $t('trials:oncologyReview:title:findings') }}</span>
|
||||
<span style="color:red">*</span>
|
||||
</div>
|
||||
</template>
|
||||
<template slot-scope="scope">
|
||||
<el-select
|
||||
v-if="oncologyInfo.ReadingTaskState < 2"
|
||||
v-if="oncologyInfo.ReadingTaskState < 2 && !scope.row.IsBaseLine"
|
||||
v-model="scope.row.EvaluationResult"
|
||||
:placeholder="$t('common:ruleMessage:select')"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in assessTypeList"
|
||||
v-show="item.Code !== '-1'"
|
||||
:key="item.Id"
|
||||
:label="item.Value"
|
||||
:value="item.Code"
|
||||
|
@ -156,14 +170,14 @@
|
|||
<div>
|
||||
<!-- 原因 -->
|
||||
<span>{{ $t('trials:oncologyReview:title:reason') }}</span>
|
||||
<span style="color:red">*</span>
|
||||
<span style="color:red">!</span>
|
||||
</div>
|
||||
|
||||
</el-tooltip>
|
||||
</template>
|
||||
<template slot-scope="scope">
|
||||
<el-input
|
||||
v-if="oncologyInfo.ReadingTaskState < 2"
|
||||
v-if="oncologyInfo.ReadingTaskState < 2 && !scope.row.IsBaseLine"
|
||||
v-model="scope.row.EvaluationReason"
|
||||
/>
|
||||
<span v-else>{{ scope.row.EvaluationReason }}</span>
|
||||
|
@ -207,6 +221,12 @@
|
|||
show-overflow-tooltip
|
||||
width="200"
|
||||
/>
|
||||
<el-table-column
|
||||
prop="VisitName"
|
||||
:label="$t('trials:globalReview:table:cutOffVisitName')"
|
||||
show-overflow-tooltip
|
||||
width="200"
|
||||
/>
|
||||
<el-table-column
|
||||
:label="$t('common:action:action')"
|
||||
width="200"
|
||||
|
@ -241,8 +261,12 @@
|
|||
</template>
|
||||
<script>
|
||||
import { getOncologyReadingInfo, getReadingPastResultList, setOncologyReadingInfo, submitOncologyReadingInfo } from '@/api/trials'
|
||||
import { setSkipReadingCache } from '@/api/reading'
|
||||
import { getAutoCutNextTask } from '@/api/user'
|
||||
import const_ from '@/const/sign-code'
|
||||
import { getToken } from '@/utils/auth'
|
||||
// import store from '@/store'
|
||||
import { changeURLStatic } from '@/utils/history.js'
|
||||
import DicomEvent from '@/views/trials/trials-panel/reading/dicoms/components/DicomEvent'
|
||||
import SignForm from '@/views/trials/components/newSignForm'
|
||||
export default {
|
||||
|
@ -331,9 +355,10 @@ export default {
|
|||
}
|
||||
},
|
||||
methods: {
|
||||
getList() {
|
||||
async getList() {
|
||||
this.loading = true
|
||||
getOncologyReadingInfo({ visitTaskId: this.visitTaskId }).then(res => {
|
||||
try {
|
||||
const res = await getOncologyReadingInfo({ visitTaskId: this.visitTaskId })
|
||||
var questions = []
|
||||
if (res.Result.OncologyVisits.length > 0) {
|
||||
var task = res.Result.OncologyVisits[0]
|
||||
|
@ -345,7 +370,9 @@ export default {
|
|||
this.assessTypeList = res.Result.AssessTypeList
|
||||
this.oncologyInfo = res.Result
|
||||
this.loading = false
|
||||
}).catch(() => { this.loading = false })
|
||||
} catch (e) {
|
||||
this.loading = false
|
||||
}
|
||||
},
|
||||
getAssessType(val) {
|
||||
var idx = this.assessTypeList.findIndex(i => i.Code === val)
|
||||
|
@ -356,62 +383,81 @@ export default {
|
|||
}
|
||||
},
|
||||
handleSave(isPrompt) {
|
||||
this.loading = true
|
||||
var index = this.oncologyInfo.OncologyVisits.findIndex(item => !item.EvaluationResult)
|
||||
if (index > -1) {
|
||||
this.loading = false
|
||||
// '肿瘤学阅片结论不能为空!'
|
||||
this.$confirm(this.$t('trials:oncologyReview:message:msg1'), {
|
||||
type: 'warning',
|
||||
distinguishCancelAndClose: true
|
||||
})
|
||||
.then(() => {
|
||||
return Promise.reject(false)
|
||||
})
|
||||
.catch(action => {
|
||||
return Promise.reject(false)
|
||||
})
|
||||
} else {
|
||||
return new Promise(async(resolve, reject) => {
|
||||
this.loading = true
|
||||
var oncologyQuestionList = []
|
||||
this.oncologyInfo.OncologyVisits.map(item => {
|
||||
if (item.EvaluationResult) {
|
||||
oncologyQuestionList.push(
|
||||
{
|
||||
visitTaskId: item.VisitTaskId,
|
||||
evaluationResult: item.EvaluationResult,
|
||||
evaluationReason: item.EvaluationReason
|
||||
}
|
||||
)
|
||||
// var index = this.oncologyInfo.OncologyVisits.findIndex(item => !item.EvaluationResult && !item.IsBaseLine)
|
||||
var isDiffer = this.checkDifferResult()
|
||||
if (isDiffer) {
|
||||
this.loading = false
|
||||
const confirm = await this.$confirm(
|
||||
this.$t('trials:oncologyReview:message:msg2'),
|
||||
{
|
||||
type: 'warning',
|
||||
distinguishCancelAndClose: true
|
||||
}
|
||||
)
|
||||
if (confirm === 'confirm') reject(false)
|
||||
} else {
|
||||
this.loading = true
|
||||
var oncologyQuestionList = []
|
||||
this.oncologyInfo.OncologyVisits.map(item => {
|
||||
if (item.EvaluationResult && !item.IsBaseLine) {
|
||||
oncologyQuestionList.push(
|
||||
{
|
||||
visitTaskId: item.VisitTaskId,
|
||||
evaluationResult: item.EvaluationResult,
|
||||
evaluationReason: item.EvaluationReason
|
||||
}
|
||||
)
|
||||
}
|
||||
})
|
||||
var params = {
|
||||
oncologyTaskId: this.visitTaskId,
|
||||
oncologyQuestionList: oncologyQuestionList,
|
||||
globalTaskId: this.oncologyInfo.GlobalTaskId,
|
||||
relatedTaskId: this.oncologyInfo.RelatedTaskId
|
||||
}
|
||||
})
|
||||
var params = {
|
||||
oncologyTaskId: this.visitTaskId,
|
||||
oncologyQuestionList: oncologyQuestionList
|
||||
}
|
||||
return new Promise((resolve, reject) => {
|
||||
setOncologyReadingInfo(params).then(res => {
|
||||
try {
|
||||
await setOncologyReadingInfo(params)
|
||||
this.loading = false
|
||||
this.getList()
|
||||
if (isPrompt) {
|
||||
this.$message.success(this.$t('common:message:savedSuccessfully'))
|
||||
}
|
||||
resolve(true)
|
||||
}).catch(_ => {
|
||||
} catch (e) {
|
||||
this.loading = false
|
||||
reject(false)
|
||||
})
|
||||
})
|
||||
}
|
||||
},
|
||||
handleSubmit() {
|
||||
this.$refs['adForm'].validate((valid) => {
|
||||
if (!valid) return
|
||||
const { ImageAssessmentReportConfirmation } = const_.processSignature
|
||||
this.signCode = ImageAssessmentReportConfirmation
|
||||
this.signVisible = true
|
||||
}
|
||||
}
|
||||
})
|
||||
},
|
||||
checkDifferResult() {
|
||||
var isDiffer = false
|
||||
var criterionType = parseInt(this.$route.query.criterionType)
|
||||
if (criterionType === 2) {
|
||||
for (let i = 0; i < this.oncologyInfo.OncologyVisits.length; i++) {
|
||||
if (this.oncologyInfo.OncologyVisits[i].IsBaseLine) continue
|
||||
var tumorAssessment = ''
|
||||
var idx = this.oncologyInfo.OncologyVisits[i].QuestionList.findIndex(v => v.DictionaryCode === 'ImagingOverallAssessment_Lugano')
|
||||
if (idx > -1) {
|
||||
tumorAssessment = this.oncologyInfo.OncologyVisits[i].QuestionList[idx].Answer
|
||||
if (!(this.oncologyInfo.OncologyVisits[i].EvaluationResult !== '' && (tumorAssessment === this.oncologyInfo.OncologyVisits[i].EvaluationResult || (tumorAssessment !== this.oncologyInfo.OncologyVisits[i].EvaluationResult && this.oncologyInfo.OncologyVisits[i].EvaluationReason)))) {
|
||||
isDiffer = true
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return isDiffer
|
||||
},
|
||||
async handleSubmit() {
|
||||
const valid = await this.$refs['adForm'].validate()
|
||||
if (!valid) return
|
||||
const { ImageAssessmentReportConfirmation } = const_.processSignature
|
||||
this.signCode = ImageAssessmentReportConfirmation
|
||||
this.signVisible = true
|
||||
},
|
||||
// 关闭签名框
|
||||
closeSignDialog(isSign, signInfo) {
|
||||
if (isSign) {
|
||||
|
@ -420,17 +466,16 @@ export default {
|
|||
this.signVisible = false
|
||||
}
|
||||
},
|
||||
handleConfirm() {
|
||||
this.handleSave(false).then(res => {
|
||||
if (res) {
|
||||
const { ImageAssessmentReportConfirmation } = const_.processSignature
|
||||
this.signCode = ImageAssessmentReportConfirmation
|
||||
this.signVisible = true
|
||||
}
|
||||
})
|
||||
async handleConfirm() {
|
||||
const res = await this.handleSave(false)
|
||||
if (res) {
|
||||
const { ImageAssessmentReportConfirmation } = const_.processSignature
|
||||
this.signCode = ImageAssessmentReportConfirmation
|
||||
this.signVisible = true
|
||||
}
|
||||
},
|
||||
// 签名并确认
|
||||
signConfirm(signInfo) {
|
||||
async signConfirm(signInfo) {
|
||||
this.loading = true
|
||||
var params = {
|
||||
data: {
|
||||
|
@ -438,7 +483,8 @@ export default {
|
|||
},
|
||||
signInfo: signInfo
|
||||
}
|
||||
submitOncologyReadingInfo(params).then(res => {
|
||||
try {
|
||||
const res = await submitOncologyReadingInfo(params)
|
||||
if (res.IsSuccess) {
|
||||
this.$message.success(this.$t('common:message:savedSuccessfully'))
|
||||
this.isEdit = false
|
||||
|
@ -448,43 +494,47 @@ export default {
|
|||
// window.opener.postMessage('refreshTaskList', window.location)
|
||||
// 设置当前任务阅片状态为已读
|
||||
this.oncologyInfo.ReadingTaskState = 2
|
||||
window.opener.postMessage('refreshTaskList', window.location)
|
||||
// '当前阅片任务已完成,是否进入下一个阅片任务?'
|
||||
this.$confirm(this.$t('trials:oncologyReview:title:msg2'), {
|
||||
type: 'warning',
|
||||
distinguishCancelAndClose: true
|
||||
})
|
||||
.then(() => {
|
||||
// var token = getToken()
|
||||
// var criterionType = this.$router.currentRoute.query.criterionType
|
||||
// var readingTool = this.$router.currentRoute.query.readingTool
|
||||
// var isReadingTaskViewInOrder = this.$router.currentRoute.query.isReadingTaskViewInOrder
|
||||
// var trialReadingCriterionId = this.$router.currentRoute.query.TrialReadingCriterionId
|
||||
// var path = ''
|
||||
// if (readingTool && parseInt(readingTool) === 0) {
|
||||
// path = `/readingDicoms?TrialReadingCriterionId=${trialReadingCriterionId}&trialId=${this.trialId}&subjectCode=${this.subjectCode}&subjectId=${this.subjectId}&isReadingTaskViewInOrder=${isReadingTaskViewInOrder}&criterionType=${criterionType}&readingTool=${readingTool}&TokenKey=${token}&key=${new Date().getTime()}`
|
||||
// } else {
|
||||
// path = `/noneDicomReading?TrialReadingCriterionId=${trialReadingCriterionId}&trialId=${this.trialId}&subjectCode=${this.subjectCode}&subjectId=${this.subjectId}&isReadingTaskViewInOrder=${isReadingTaskViewInOrder}&criterionType=${criterionType}&readingTool=${readingTool}&TokenKey=${token}&key=${new Date().getTime()}`
|
||||
// }
|
||||
// this.$router.push({ path })
|
||||
DicomEvent.$emit('getNextTask')
|
||||
})
|
||||
.catch(action => {
|
||||
|
||||
})
|
||||
const res = await getAutoCutNextTask()
|
||||
var isAutoTask = res.Result.AutoCutNextTask
|
||||
if (isAutoTask) {
|
||||
// store.dispatch('reading/resetVisitTasks')
|
||||
// DicomEvent.$emit('getNextTask')
|
||||
window.location.reload()
|
||||
} else {
|
||||
// '当前阅片任务已完成,是否进入下一个阅片任务?'
|
||||
const confirm = await this.$confirm(
|
||||
this.$t('trials:oncologyReview:title:msg2'),
|
||||
{
|
||||
type: 'warning',
|
||||
distinguishCancelAndClose: true
|
||||
}
|
||||
)
|
||||
if (confirm === 'confirm') {
|
||||
// store.dispatch('reading/resetVisitTasks')
|
||||
// DicomEvent.$emit('getNextTask')
|
||||
window.location.reload()
|
||||
} else {
|
||||
changeURLStatic('visitTaskId', this.visitTaskId)
|
||||
}
|
||||
}
|
||||
window.opener.postMessage('refreshTaskList', window.location)
|
||||
}
|
||||
this.loading = false
|
||||
}).catch(_ => {
|
||||
} catch (e) {
|
||||
this.loading = false
|
||||
this.$refs['signForm'].btnLoading = false
|
||||
})
|
||||
}
|
||||
},
|
||||
getPriorList() {
|
||||
async getPriorList() {
|
||||
this.priorLoading = true
|
||||
getReadingPastResultList({ visitTaskId: this.visitTaskId }).then(res => {
|
||||
try {
|
||||
const res = await getReadingPastResultList({ visitTaskId: this.visitTaskId })
|
||||
this.priorList = res.Result
|
||||
this.priorLoading = false
|
||||
}).catch(() => { this.priorLoading = false })
|
||||
} catch (e) {
|
||||
this.priorLoading = false
|
||||
}
|
||||
},
|
||||
handleViewDetail(visitTaskId) {
|
||||
if (this.openWindow) {
|
||||
|
@ -514,6 +564,28 @@ export default {
|
|||
path: `/clinicalData?subjectId=${this.oncologyInfo.SubjectId}&trialId=${this.trialId}&visitTaskId=${this.oncologyInfo.OncologyTaskId}&TokenKey=${token}`
|
||||
})
|
||||
window.open(routeData.href, '_blank')
|
||||
},
|
||||
async skipTask() {
|
||||
try {
|
||||
// 是否确认跳过?
|
||||
const confirm = await this.$confirm(
|
||||
this.$t('trials:readingReport:message:skipConfirm'),
|
||||
{
|
||||
type: 'warning',
|
||||
distinguishCancelAndClose: true
|
||||
}
|
||||
)
|
||||
if (confirm !== 'confirm') return
|
||||
this.loading = true
|
||||
const res = await setSkipReadingCache({ visitTaskId: this.visitTaskId })
|
||||
this.loading = false
|
||||
if (res.IsSuccess) {
|
||||
window.location.reload()
|
||||
}
|
||||
} catch (e) {
|
||||
this.loading = false
|
||||
console.log(e)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -79,15 +79,15 @@ module.exports = {
|
|||
},
|
||||
plugins: [
|
||||
new CopyPlugin([
|
||||
{ from: './node_modules/cornerstone-wado-image-loader/dist/cornerstoneWADOImageLoaderWebWorker.min.js', to: 'webWorker.js' },
|
||||
{ from: './node_modules/cornerstone-wado-image-loader/dist/cornerstoneWADOImageLoader.min.js', to: 'dicomCodecs.js' },
|
||||
// { from: './node_modules/cornerstone-wado-image-loader/dist/cornerstoneWADOImageLoaderWebWorker.min.js', to: 'webWorker.js' },
|
||||
// { from: './node_modules/cornerstone-wado-image-loader/dist/cornerstoneWADOImageLoader.min.js', to: 'dicomCodecs.js' },
|
||||
// { from: './node_modules/@cornerstonejs/codec-charls/dist/charlsjs.js', to: 'charlsjs.js' },
|
||||
// { from: './node_modules/@cornerstonejs/codec-charls/dist/charlsjs.js.mem', to: './static/js/charlsjs.js.mem' },
|
||||
// { from: './node_modules/@cornerstonejs/codec-charls/dist/charlswasm.js', to: './static/js/charlswasm.js' },
|
||||
// { from: './node_modules/@cornerstonejs/codec-charls/dist/charlswasm.wasm', to: './static/js/charlswasm.wasm' },
|
||||
{ from: './node_modules/@ffmpeg/core/dist/ffmpeg-core.js', to: 'ffmpeg-core.js' },
|
||||
{ from: './node_modules/@ffmpeg/core/dist/ffmpeg-core.wasm', to: 'ffmpeg-core.wasm' },
|
||||
{ from: './node_modules/@ffmpeg/core/dist/ffmpeg-core.worker.js', to: 'ffmpeg-core.worker.js' },
|
||||
// { from: './node_modules/@ffmpeg/core/dist/ffmpeg-core.js', to: 'ffmpeg-core.js' },
|
||||
// { from: './node_modules/@ffmpeg/core/dist/ffmpeg-core.wasm', to: 'ffmpeg-core.wasm' },
|
||||
// { from: './node_modules/@ffmpeg/core/dist/ffmpeg-core.worker.js', to: 'ffmpeg-core.worker.js' },
|
||||
{
|
||||
from: path.resolve(__dirname, './static'),
|
||||
to: path.resolve(__dirname, './dist/static'),
|
||||
|
|
Loading…
Reference in New Issue