Merge branch 'main' of http://192.168.3.68:2000/XCKJ/irc_web
continuous-integration/drone/push Build is running
Details
continuous-integration/drone/push Build is running
Details
commit
b8478e6451
|
|
@ -27,6 +27,7 @@
|
||||||
"axios": "0.18.1",
|
"axios": "0.18.1",
|
||||||
"babel-eslint": "7.2.3",
|
"babel-eslint": "7.2.3",
|
||||||
"copy-webpack-plugin": "^4.5.2",
|
"copy-webpack-plugin": "^4.5.2",
|
||||||
|
"@aws-sdk/client-s3": "^3.370.0",
|
||||||
"core-js": "^3.8.3",
|
"core-js": "^3.8.3",
|
||||||
"cornerstone-core": "^2.6.1",
|
"cornerstone-core": "^2.6.1",
|
||||||
"cornerstone-math": "^0.1.10",
|
"cornerstone-math": "^0.1.10",
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,167 @@
|
||||||
|
<!--
|
||||||
|
mitm.html is the lite "man in the middle"
|
||||||
|
|
||||||
|
This is only meant to signal the opener's messageChannel to
|
||||||
|
the service worker - when that is done this mitm can be closed
|
||||||
|
but it's better to keep it alive since this also stops the sw
|
||||||
|
from restarting
|
||||||
|
|
||||||
|
The service worker is capable of intercepting all request and fork their
|
||||||
|
own "fake" response - wish we are going to craft
|
||||||
|
when the worker then receives a stream then the worker will tell the opener
|
||||||
|
to open up a link that will start the download
|
||||||
|
-->
|
||||||
|
<script>
|
||||||
|
// This will prevent the sw from restarting
|
||||||
|
let keepAlive = () => {
|
||||||
|
keepAlive = () => {}
|
||||||
|
var ping = location.href.substr(0, location.href.lastIndexOf('/')) + '/ping'
|
||||||
|
var interval = setInterval(() => {
|
||||||
|
if (sw) {
|
||||||
|
sw.postMessage('ping')
|
||||||
|
} else {
|
||||||
|
fetch(ping).then(res => res.text(!res.ok && clearInterval(interval)))
|
||||||
|
}
|
||||||
|
}, 10000)
|
||||||
|
}
|
||||||
|
|
||||||
|
// message event is the first thing we need to setup a listner for
|
||||||
|
// don't want the opener to do a random timeout - instead they can listen for
|
||||||
|
// the ready event
|
||||||
|
// but since we need to wait for the Service Worker registration, we store the
|
||||||
|
// message for later
|
||||||
|
let messages = []
|
||||||
|
window.onmessage = evt => messages.push(evt)
|
||||||
|
|
||||||
|
let sw = null
|
||||||
|
let scope = ''
|
||||||
|
|
||||||
|
function registerWorker() {
|
||||||
|
return navigator.serviceWorker.getRegistration('./').then(swReg => {
|
||||||
|
return swReg || navigator.serviceWorker.register('sw.js', { scope: './' })
|
||||||
|
}).then(swReg => {
|
||||||
|
const swRegTmp = swReg.installing || swReg.waiting
|
||||||
|
|
||||||
|
scope = swReg.scope
|
||||||
|
|
||||||
|
return (sw = swReg.active) || new Promise(resolve => {
|
||||||
|
swRegTmp.addEventListener('statechange', fn = () => {
|
||||||
|
if (swRegTmp.state === 'activated') {
|
||||||
|
swRegTmp.removeEventListener('statechange', fn)
|
||||||
|
sw = swReg.active
|
||||||
|
resolve()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// Now that we have the Service Worker registered we can process messages
|
||||||
|
function onMessage (event) {
|
||||||
|
let { data, ports, origin } = event
|
||||||
|
|
||||||
|
// It's important to have a messageChannel, don't want to interfere
|
||||||
|
// with other simultaneous downloads
|
||||||
|
if (!ports || !ports.length) {
|
||||||
|
throw new TypeError("[StreamSaver] You didn't send a messageChannel")
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeof data !== 'object') {
|
||||||
|
throw new TypeError("[StreamSaver] You didn't send a object")
|
||||||
|
}
|
||||||
|
|
||||||
|
// the default public service worker for StreamSaver is shared among others.
|
||||||
|
// so all download links needs to be prefixed to avoid any other conflict
|
||||||
|
data.origin = origin
|
||||||
|
|
||||||
|
// if we ever (in some feature versoin of streamsaver) would like to
|
||||||
|
// redirect back to the page of who initiated a http request
|
||||||
|
data.referrer = data.referrer || document.referrer || origin
|
||||||
|
|
||||||
|
// pass along version for possible backwards compatibility in sw.js
|
||||||
|
data.streamSaverVersion = new URLSearchParams(location.search).get('version')
|
||||||
|
|
||||||
|
if (data.streamSaverVersion === '1.2.0') {
|
||||||
|
console.warn('[StreamSaver] please update streamsaver')
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @since v2.0.0 */
|
||||||
|
if (!data.headers) {
|
||||||
|
console.warn("[StreamSaver] pass `data.headers` that you would like to pass along to the service worker\nit should be a 2D array or a key/val object that fetch's Headers api accepts")
|
||||||
|
} else {
|
||||||
|
// test if it's correct
|
||||||
|
// should thorw a typeError if not
|
||||||
|
new Headers(data.headers)
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @since v2.0.0 */
|
||||||
|
if (typeof data.filename === 'string') {
|
||||||
|
console.warn("[StreamSaver] You shouldn't send `data.filename` anymore. It should be included in the Content-Disposition header option")
|
||||||
|
// Do what File constructor do with fileNames
|
||||||
|
data.filename = data.filename.replace(/\//g, ':')
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @since v2.0.0 */
|
||||||
|
if (data.size) {
|
||||||
|
console.warn("[StreamSaver] You shouldn't send `data.size` anymore. It should be included in the content-length header option")
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @since v2.0.0 */
|
||||||
|
if (data.readableStream) {
|
||||||
|
console.warn("[StreamSaver] You should send the readableStream in the messageChannel, not throught mitm")
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @since v2.0.0 */
|
||||||
|
if (!data.pathname) {
|
||||||
|
console.warn("[StreamSaver] Please send `data.pathname` (eg: /pictures/summer.jpg)")
|
||||||
|
data.pathname = Math.random().toString().slice(-6) + '/' + data.filename
|
||||||
|
}
|
||||||
|
|
||||||
|
// remove all leading slashes
|
||||||
|
data.pathname = data.pathname.replace(/^\/+/g, '')
|
||||||
|
|
||||||
|
// remove protocol
|
||||||
|
let org = origin.replace(/(^\w+:|^)\/\//, '')
|
||||||
|
|
||||||
|
// set the absolute pathname to the download url.
|
||||||
|
data.url = new URL(`${scope + org}/${data.pathname}`).toString()
|
||||||
|
|
||||||
|
if (!data.url.startsWith(`${scope + org}/`)) {
|
||||||
|
throw new TypeError('[StreamSaver] bad `data.pathname`')
|
||||||
|
}
|
||||||
|
|
||||||
|
// This sends the message data as well as transferring
|
||||||
|
// messageChannel.port2 to the service worker. The service worker can
|
||||||
|
// then use the transferred port to reply via postMessage(), which
|
||||||
|
// will in turn trigger the onmessage handler on messageChannel.port1.
|
||||||
|
|
||||||
|
const transferable = data.readableStream
|
||||||
|
? [ ports[0], data.readableStream ]
|
||||||
|
: [ ports[0] ]
|
||||||
|
|
||||||
|
if (!(data.readableStream || data.transferringReadable)) {
|
||||||
|
keepAlive()
|
||||||
|
}
|
||||||
|
|
||||||
|
return sw.postMessage(data, transferable)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (window.opener) {
|
||||||
|
// The opener can't listen to onload event, so we need to help em out!
|
||||||
|
// (telling them that we are ready to accept postMessage's)
|
||||||
|
window.opener.postMessage('StreamSaver::loadedPopup', '*')
|
||||||
|
}
|
||||||
|
|
||||||
|
if (navigator.serviceWorker) {
|
||||||
|
registerWorker().then(() => {
|
||||||
|
window.onmessage = onMessage
|
||||||
|
messages.forEach(window.onmessage)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// FF v102 just started to supports transferable streams, but still needs to ping sw.js
|
||||||
|
// even tough the service worker dose not have to do any kind of work and listen to any
|
||||||
|
// messages... #305
|
||||||
|
keepAlive()
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
@ -0,0 +1,130 @@
|
||||||
|
/* global self ReadableStream Response */
|
||||||
|
|
||||||
|
self.addEventListener('install', () => {
|
||||||
|
self.skipWaiting()
|
||||||
|
})
|
||||||
|
|
||||||
|
self.addEventListener('activate', event => {
|
||||||
|
event.waitUntil(self.clients.claim())
|
||||||
|
})
|
||||||
|
|
||||||
|
const map = new Map()
|
||||||
|
|
||||||
|
// This should be called once per download
|
||||||
|
// Each event has a dataChannel that the data will be piped through
|
||||||
|
self.onmessage = event => {
|
||||||
|
// We send a heartbeat every x second to keep the
|
||||||
|
// service worker alive if a transferable stream is not sent
|
||||||
|
if (event.data === 'ping') {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
const data = event.data
|
||||||
|
const downloadUrl = data.url || self.registration.scope + Math.random() + '/' + (typeof data === 'string' ? data : data.filename)
|
||||||
|
const port = event.ports[0]
|
||||||
|
const metadata = new Array(3) // [stream, data, port]
|
||||||
|
|
||||||
|
metadata[1] = data
|
||||||
|
metadata[2] = port
|
||||||
|
|
||||||
|
// Note to self:
|
||||||
|
// old streamsaver v1.2.0 might still use `readableStream`...
|
||||||
|
// but v2.0.0 will always transfer the stream through MessageChannel #94
|
||||||
|
if (event.data.readableStream) {
|
||||||
|
metadata[0] = event.data.readableStream
|
||||||
|
} else if (event.data.transferringReadable) {
|
||||||
|
port.onmessage = evt => {
|
||||||
|
port.onmessage = null
|
||||||
|
metadata[0] = evt.data.readableStream
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
metadata[0] = createStream(port)
|
||||||
|
}
|
||||||
|
|
||||||
|
map.set(downloadUrl, metadata)
|
||||||
|
port.postMessage({ download: downloadUrl })
|
||||||
|
}
|
||||||
|
|
||||||
|
function createStream (port) {
|
||||||
|
// ReadableStream is only supported by chrome 52
|
||||||
|
return new ReadableStream({
|
||||||
|
start (controller) {
|
||||||
|
// When we receive data on the messageChannel, we write
|
||||||
|
port.onmessage = ({ data }) => {
|
||||||
|
if (data === 'end') {
|
||||||
|
return controller.close()
|
||||||
|
}
|
||||||
|
|
||||||
|
if (data === 'abort') {
|
||||||
|
controller.error('Aborted the download')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
controller.enqueue(data)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
cancel (reason) {
|
||||||
|
console.log('user aborted', reason)
|
||||||
|
port.postMessage({ abort: true })
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
self.onfetch = event => {
|
||||||
|
const url = event.request.url
|
||||||
|
|
||||||
|
// this only works for Firefox
|
||||||
|
if (url.endsWith('/ping')) {
|
||||||
|
return event.respondWith(new Response('pong'))
|
||||||
|
}
|
||||||
|
|
||||||
|
const hijacke = map.get(url)
|
||||||
|
|
||||||
|
if (!hijacke) return null
|
||||||
|
|
||||||
|
const [ stream, data, port ] = hijacke
|
||||||
|
|
||||||
|
map.delete(url)
|
||||||
|
|
||||||
|
// Not comfortable letting any user control all headers
|
||||||
|
// so we only copy over the length & disposition
|
||||||
|
const responseHeaders = new Headers({
|
||||||
|
'Content-Type': 'application/octet-stream; charset=utf-8',
|
||||||
|
|
||||||
|
// To be on the safe side, The link can be opened in a iframe.
|
||||||
|
// but octet-stream should stop it.
|
||||||
|
'Content-Security-Policy': "default-src 'none'",
|
||||||
|
'X-Content-Security-Policy': "default-src 'none'",
|
||||||
|
'X-WebKit-CSP': "default-src 'none'",
|
||||||
|
'X-XSS-Protection': '1; mode=block',
|
||||||
|
'Cross-Origin-Embedder-Policy': 'require-corp'
|
||||||
|
})
|
||||||
|
|
||||||
|
let headers = new Headers(data.headers || {})
|
||||||
|
|
||||||
|
if (headers.has('Content-Length')) {
|
||||||
|
responseHeaders.set('Content-Length', headers.get('Content-Length'))
|
||||||
|
}
|
||||||
|
|
||||||
|
if (headers.has('Content-Disposition')) {
|
||||||
|
responseHeaders.set('Content-Disposition', headers.get('Content-Disposition'))
|
||||||
|
}
|
||||||
|
|
||||||
|
// data, data.filename and size should not be used anymore
|
||||||
|
if (data.size) {
|
||||||
|
console.warn('Depricated')
|
||||||
|
responseHeaders.set('Content-Length', data.size)
|
||||||
|
}
|
||||||
|
|
||||||
|
let fileName = typeof data === 'string' ? data : data.filename
|
||||||
|
if (fileName) {
|
||||||
|
console.warn('Depricated')
|
||||||
|
// Make filename RFC5987 compatible
|
||||||
|
fileName = encodeURIComponent(fileName).replace(/['()]/g, escape).replace(/\*/g, '%2A')
|
||||||
|
responseHeaders.set('Content-Disposition', "attachment; filename*=UTF-8''" + fileName)
|
||||||
|
}
|
||||||
|
|
||||||
|
event.respondWith(new Response(stream, { headers: responseHeaders }))
|
||||||
|
|
||||||
|
port.postMessage({ debug: 'Download started' })
|
||||||
|
}
|
||||||
|
|
@ -8,11 +8,11 @@ export function requestPackageAndAnonymizImage(params) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
// 获取影像上传列表
|
// 获取影像上传列表
|
||||||
export function getSubjectImageUploadList(params) {
|
export function getSubjectImageUploadList(data) {
|
||||||
return request({
|
return request({
|
||||||
url: '/DownloadAndUpload/getSubjectImageUploadList',
|
url: '/DownloadAndUpload/getSubjectImageUploadList',
|
||||||
method: 'get',
|
method: 'post',
|
||||||
params
|
data
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
// 预上传
|
// 预上传
|
||||||
|
|
@ -40,3 +40,43 @@ export function deleteTaskStudy(params) {
|
||||||
params
|
params
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
// 获取iqc下载文件信息
|
||||||
|
export function getCRCUploadedStudyInfo(data) {
|
||||||
|
return request({
|
||||||
|
url: '/DownloadAndUpload/getCRCUploadedStudyInfo',
|
||||||
|
method: 'post',
|
||||||
|
data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
// 获取ir阅片和任务列表
|
||||||
|
export function getSubjectImageDownloadSelectList(data) {
|
||||||
|
return request({
|
||||||
|
url: '/DownloadAndUpload/getSubjectImageDownloadSelectList',
|
||||||
|
method: 'post',
|
||||||
|
data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
// 获取ir阅片和任务下载文件信息
|
||||||
|
export function getIRReadingDownloadStudyInfo(data) {
|
||||||
|
return request({
|
||||||
|
url: '/DownloadAndUpload/getIRReadingDownloadStudyInfo',
|
||||||
|
method: 'post',
|
||||||
|
data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
// 获取ir阅片和任务非dicom上传列表
|
||||||
|
export function getIRUploadTaskNoneDicomStudyList(data) {
|
||||||
|
return request({
|
||||||
|
url: '/DownloadAndUpload/getIRUploadTaskNoneDicomStudyList',
|
||||||
|
method: 'post',
|
||||||
|
data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
// 校验上传影像
|
||||||
|
export function verifyIRStudyAllowUpload(data) {
|
||||||
|
return request({
|
||||||
|
url: '/DownloadAndUpload/verifyIRStudyAllowUpload',
|
||||||
|
method: 'post',
|
||||||
|
data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
@ -194,3 +194,10 @@ export function resetReadingTask(param) {
|
||||||
data: param
|
data: param
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
export function getTaskUploadedDicomStudyList(param) {
|
||||||
|
return request({
|
||||||
|
url: `/DownloadAndUpload/getTaskUploadedDicomStudyList`,
|
||||||
|
method: 'post',
|
||||||
|
data: param
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -1364,9 +1364,9 @@ export function getForwardList(param) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getNoneDicomStudyList(subjectVisitId, sudyId = '', isFilterZip = false) {
|
export function getNoneDicomStudyList(subjectVisitId, sudyId = '', isFilterZip = false, visitTaskId = '') {
|
||||||
return request({
|
return request({
|
||||||
url: `/NoneDicomStudy/getNoneDicomStudyList?subjectVisitId=${subjectVisitId}&nonedicomStudyId=${sudyId}&isFilterZip=${isFilterZip}`,
|
url: `/NoneDicomStudy/getNoneDicomStudyList?subjectVisitId=${subjectVisitId}&nonedicomStudyId=${sudyId}&isFilterZip=${isFilterZip}&visitTaskId=${visitTaskId}`,
|
||||||
method: 'get'
|
method: 'get'
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -81,16 +81,25 @@
|
||||||
<!-- <div v-show="stack.firstImageLoading" class="load-indicator">
|
<!-- <div v-show="stack.firstImageLoading" class="load-indicator">
|
||||||
Loading Series #{{ stack.seriesNumber }}...
|
Loading Series #{{ stack.seriesNumber }}...
|
||||||
</div>-->
|
</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>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import Vue from 'vue'
|
|
||||||
import Contextmenu from 'vue-contextmenujs'
|
|
||||||
Vue.use(Contextmenu)
|
|
||||||
import * as cornerstone from 'cornerstone-core'
|
import * as cornerstone from 'cornerstone-core'
|
||||||
import * as cornerstoneMath from 'cornerstone-math'
|
import * as cornerstoneMath from 'cornerstone-math'
|
||||||
import * as cornerstoneTools from 'cornerstone-tools'
|
import * as cornerstoneTools from 'cornerstone-tools'
|
||||||
|
|
||||||
const scroll = cornerstoneTools.import('util/scrollToIndex')
|
const scroll = cornerstoneTools.import('util/scrollToIndex')
|
||||||
import Hammer from 'hammerjs'
|
import Hammer from 'hammerjs'
|
||||||
import getOrientationString from '@/views/trials/trials-panel/reading/dicoms/tools/OrientationMarkers/getOrientationString'
|
import getOrientationString from '@/views/trials/trials-panel/reading/dicoms/tools/OrientationMarkers/getOrientationString'
|
||||||
|
|
@ -108,8 +117,10 @@ cornerstoneTools.toolColors.setActiveColor('rgb(0, 255, 0)')
|
||||||
// cornerstoneTools.init({ showSVGCursors: true })
|
// cornerstoneTools.init({ showSVGCursors: true })
|
||||||
cornerstoneTools.init()
|
cornerstoneTools.init()
|
||||||
const ToolStateManager = cornerstoneTools.globalImageIdSpecificToolStateManager
|
const ToolStateManager = cornerstoneTools.globalImageIdSpecificToolStateManager
|
||||||
|
import DicomTags from './DicomTags'
|
||||||
export default {
|
export default {
|
||||||
name: 'DicomCanvas',
|
name: 'DicomCanvas',
|
||||||
|
components: { DicomTags },
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
loading: false,
|
loading: false,
|
||||||
|
|
@ -164,7 +175,8 @@ export default {
|
||||||
mousePosition: { x: '', y: '', mo: '' },
|
mousePosition: { x: '', y: '', mo: '' },
|
||||||
markers: { top: '', right: '', bottom: '', left: '' },
|
markers: { top: '', right: '', bottom: '', left: '' },
|
||||||
orientationMarkers: [],
|
orientationMarkers: [],
|
||||||
originalMarkers: []
|
originalMarkers: [],
|
||||||
|
dcmTag: { visible: false, title: this.$t('trials:dicom-tag:title') }
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
@ -364,8 +376,8 @@ export default {
|
||||||
if (this.dicomInfo.thick) {
|
if (this.dicomInfo.thick) {
|
||||||
this.dicomInfo.thick = this.dicomInfo.thick.toFixed(2)
|
this.dicomInfo.thick = this.dicomInfo.thick.toFixed(2)
|
||||||
}
|
}
|
||||||
let newImageIdIndex = this.stack.imageIds.findIndex(i=>i===e.detail.image.imageId)
|
const newImageIdIndex = this.stack.imageIds.findIndex(i => i === e.detail.image.imageId)
|
||||||
if(newImageIdIndex === -1) return
|
if (newImageIdIndex === -1) return
|
||||||
this.stack.currentImageIdIndex = newImageIdIndex
|
this.stack.currentImageIdIndex = newImageIdIndex
|
||||||
this.stack.imageIdIndex = newImageIdIndex
|
this.stack.imageIdIndex = newImageIdIndex
|
||||||
this.series.imageIdIndex = newImageIdIndex
|
this.series.imageIdIndex = newImageIdIndex
|
||||||
|
|
@ -636,7 +648,7 @@ export default {
|
||||||
enabledElement.renderingTools.renderCanvasData = renderCanvasData
|
enabledElement.renderingTools.renderCanvasData = renderCanvasData
|
||||||
},
|
},
|
||||||
scrollPage(offset) {
|
scrollPage(offset) {
|
||||||
if(this.loading) return
|
if (this.loading) return
|
||||||
var index = this.stack.currentImageIdIndex + offset
|
var index = this.stack.currentImageIdIndex + offset
|
||||||
if (index < 0) index = 0
|
if (index < 0) index = 0
|
||||||
else if (index >= this.stack.imageIds.length) {
|
else if (index >= this.stack.imageIds.length) {
|
||||||
|
|
@ -648,7 +660,7 @@ export default {
|
||||||
},
|
},
|
||||||
|
|
||||||
toggleClipPlay() {
|
toggleClipPlay() {
|
||||||
if(this.loading) return
|
if (this.loading) return
|
||||||
if (this.toolState.clipPlaying) {
|
if (this.toolState.clipPlaying) {
|
||||||
cornerstoneTools.stopClip(this.canvas)
|
cornerstoneTools.stopClip(this.canvas)
|
||||||
this.toolState.clipPlaying = false
|
this.toolState.clipPlaying = false
|
||||||
|
|
@ -668,7 +680,7 @@ export default {
|
||||||
resetWwwc() {
|
resetWwwc() {
|
||||||
this.toolState.viewportInvert = false
|
this.toolState.viewportInvert = false
|
||||||
var viewport = cornerstone.getViewport(this.canvas)
|
var viewport = cornerstone.getViewport(this.canvas)
|
||||||
viewport.invert = false
|
// viewport.invert = false
|
||||||
var image = cornerstone.getImage(this.canvas)
|
var image = cornerstone.getImage(this.canvas)
|
||||||
viewport.voi.windowWidth = image.windowWidth
|
viewport.voi.windowWidth = image.windowWidth
|
||||||
viewport.voi.windowCenter = image.windowCenter
|
viewport.voi.windowCenter = image.windowCenter
|
||||||
|
|
@ -747,6 +759,9 @@ export default {
|
||||||
var uid = cornerstone.getImage(this.canvas).data.string('x00080018')
|
var uid = cornerstone.getImage(this.canvas).data.string('x00080018')
|
||||||
cornerstoneTools.SaveAs(this.canvas, `${uid}.png`)
|
cornerstoneTools.SaveAs(this.canvas, `${uid}.png`)
|
||||||
},
|
},
|
||||||
|
showTags() {
|
||||||
|
this.dcmTag.visible = true
|
||||||
|
},
|
||||||
fitToWindow() {
|
fitToWindow() {
|
||||||
if (this.stack.seriesNumber) {
|
if (this.stack.seriesNumber) {
|
||||||
cornerstone.fitToWindow(this.canvas)
|
cornerstone.fitToWindow(this.canvas)
|
||||||
|
|
|
||||||
|
|
@ -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>
|
||||||
|
|
@ -233,6 +233,10 @@
|
||||||
<button :title="$t('trials:dicom-show:image')" class="btn-link" @click="currentDicomCanvas.saveImage()">
|
<button :title="$t('trials:dicom-show:image')" class="btn-link" @click="currentDicomCanvas.saveImage()">
|
||||||
<svg-icon icon-class="image" style="font-size:20px;" />
|
<svg-icon icon-class="image" style="font-size:20px;" />
|
||||||
</button>
|
</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>
|
</div>
|
||||||
<div class="measureTool-wrapper">
|
<div class="measureTool-wrapper">
|
||||||
|
|
@ -405,7 +409,7 @@ export default {
|
||||||
loadImageStack(dicomSeries) {
|
loadImageStack(dicomSeries) {
|
||||||
this.currentDicomCanvas.toolState.clipPlaying = false
|
this.currentDicomCanvas.toolState.clipPlaying = false
|
||||||
this.$nextTick(() => {
|
this.$nextTick(() => {
|
||||||
let series = Object.assign({}, dicomSeries)
|
const series = Object.assign({}, dicomSeries)
|
||||||
this.currentDicomCanvas.loadImageStack(series)
|
this.currentDicomCanvas.loadImageStack(series)
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
@ -416,7 +420,7 @@ export default {
|
||||||
Array.from(elements).forEach((element, index) => {
|
Array.from(elements).forEach((element, index) => {
|
||||||
const canvasIndex = element.getAttribute('data-index')
|
const canvasIndex = element.getAttribute('data-index')
|
||||||
if (index < seriesList.length && element.style.display !== 'none') {
|
if (index < seriesList.length && element.style.display !== 'none') {
|
||||||
let series = Object.assign({}, seriesList[index])
|
const series = Object.assign({}, seriesList[index])
|
||||||
this.$refs[`dicomCanvas${canvasIndex}`].loadImageStack(series)
|
this.$refs[`dicomCanvas${canvasIndex}`].loadImageStack(series)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,450 @@
|
||||||
|
<template>
|
||||||
|
<el-dialog
|
||||||
|
:visible.sync="visible"
|
||||||
|
:fullscreen="true"
|
||||||
|
:close-on-click-modal="false"
|
||||||
|
:before-close="beforeClose"
|
||||||
|
:append-to-body="true"
|
||||||
|
v-loading="btnLoading"
|
||||||
|
class="downloadDicomAndNonedicom"
|
||||||
|
>
|
||||||
|
<span slot="title">{{ title }}</span>
|
||||||
|
<div class="top">
|
||||||
|
<span>{{ $t('download:top:title') }}</span>
|
||||||
|
<div class="btnBox">
|
||||||
|
<el-button
|
||||||
|
type="primary"
|
||||||
|
size="mini"
|
||||||
|
v-if="hasDicom"
|
||||||
|
@click.stop="getIRReadingDownloadStudyInfo('dicom')"
|
||||||
|
>
|
||||||
|
{{ $t('download:button:downloadDicom') }}
|
||||||
|
</el-button>
|
||||||
|
<el-button
|
||||||
|
type="primary"
|
||||||
|
size="mini"
|
||||||
|
v-if="hasNonedicom"
|
||||||
|
@click.stop="getIRReadingDownloadStudyInfo('noneDicom')"
|
||||||
|
>
|
||||||
|
{{ $t('download:button:downloadNonedicom') }}
|
||||||
|
</el-button>
|
||||||
|
<el-button
|
||||||
|
type="primary"
|
||||||
|
size="mini"
|
||||||
|
@click.stop="getIRReadingDownloadStudyInfo('all')"
|
||||||
|
>
|
||||||
|
{{ $t('download:button:downloadAll') }}
|
||||||
|
</el-button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!--上传列表@selection-change="handleSelectionChange"-->
|
||||||
|
<el-table
|
||||||
|
ref="dicomFilesTable"
|
||||||
|
v-adaptive="{ bottomOffset: 85 }"
|
||||||
|
height="100"
|
||||||
|
:data="list"
|
||||||
|
:loading="loading"
|
||||||
|
class="dicomFiles-table"
|
||||||
|
@sort-change="handleSortByColumn"
|
||||||
|
:default-sort="{ prop: 'TaskBlindName', order: 'descending' }"
|
||||||
|
>
|
||||||
|
<!-- <el-table-column
|
||||||
|
type="selection"
|
||||||
|
width="55"
|
||||||
|
:selectable="handleSelectable"
|
||||||
|
/> -->
|
||||||
|
<el-table-column type="index" width="40" />
|
||||||
|
<!--受试者-->
|
||||||
|
<el-table-column
|
||||||
|
:label="$t('download:table:subjectCode')"
|
||||||
|
min-width="130"
|
||||||
|
prop="SubjectCode"
|
||||||
|
show-overflow-tooltip
|
||||||
|
/>
|
||||||
|
<!--任务名称-->
|
||||||
|
<el-table-column
|
||||||
|
:label="$t('download:table:taskName')"
|
||||||
|
min-width="130"
|
||||||
|
show-overflow-tooltip
|
||||||
|
prop="TaskBlindName"
|
||||||
|
sortable="custom"
|
||||||
|
/>
|
||||||
|
<!--检查类型-->
|
||||||
|
<el-table-column
|
||||||
|
:label="$t('download:table:studyType')"
|
||||||
|
min-width="130"
|
||||||
|
show-overflow-tooltip
|
||||||
|
prop="IsDicom"
|
||||||
|
sortable="custom"
|
||||||
|
>
|
||||||
|
<template slot-scope="scope">
|
||||||
|
<span>{{ $fd('IsDicom', scope.row.IsDicom) }}</span>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column
|
||||||
|
:label="$t('download:table:orginalStudyListNum')"
|
||||||
|
min-width="150"
|
||||||
|
show-overflow-tooltip
|
||||||
|
>
|
||||||
|
<template slot-scope="scope">
|
||||||
|
<el-button
|
||||||
|
v-if="
|
||||||
|
(scope.row.IsDicom &&
|
||||||
|
scope.row.DicomStudyList &&
|
||||||
|
scope.row.DicomStudyList.length >= 1) ||
|
||||||
|
(!scope.row.IsDicom &&
|
||||||
|
scope.row.NoneDicomStudyList &&
|
||||||
|
scope.row.NoneDicomStudyList.length >= 1)
|
||||||
|
"
|
||||||
|
type="text"
|
||||||
|
@click="handleOpenDialog(scope.row)"
|
||||||
|
>
|
||||||
|
<span>{{
|
||||||
|
scope.row.IsDicom
|
||||||
|
? scope.row.DicomStudyList.length
|
||||||
|
: scope.row.NoneDicomStudyList.length
|
||||||
|
}}</span>
|
||||||
|
</el-button>
|
||||||
|
<span v-else>0</span>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column
|
||||||
|
:label="$t('common:action:action')"
|
||||||
|
fixed="right"
|
||||||
|
width="150"
|
||||||
|
>
|
||||||
|
<template slot-scope="scope">
|
||||||
|
<!--预览--->
|
||||||
|
<el-button
|
||||||
|
circle
|
||||||
|
icon="el-icon-view"
|
||||||
|
:title="$t('download:button:preview')"
|
||||||
|
@click.stop="preview(scope.row)"
|
||||||
|
/>
|
||||||
|
<!--下载--->
|
||||||
|
<el-button
|
||||||
|
circle
|
||||||
|
icon="el-icon-download"
|
||||||
|
:title="$t('download:button:download')"
|
||||||
|
@click.stop="getIRReadingDownloadStudyInfo('one', scope.row)"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
<study-view
|
||||||
|
v-if="model_cfg.visible"
|
||||||
|
:model_cfg="model_cfg"
|
||||||
|
:modelList="modelList"
|
||||||
|
:IsDicom="IsDicom"
|
||||||
|
/>
|
||||||
|
</el-dialog>
|
||||||
|
</template>
|
||||||
|
<script>
|
||||||
|
import {
|
||||||
|
getSubjectImageDownloadSelectList,
|
||||||
|
getIRReadingDownloadStudyInfo,
|
||||||
|
} from '@/api/load.js'
|
||||||
|
import studyView from '@/components/uploadDicomAndNonedicom/study-view.vue'
|
||||||
|
import store from '@/store'
|
||||||
|
import { downLoadFile } from '@/utils/stream.js'
|
||||||
|
import { getToken } from '@/utils/auth'
|
||||||
|
let defaultSearchData = () => {
|
||||||
|
return {
|
||||||
|
SubjectId: null,
|
||||||
|
TrialReadingCriterionId: null,
|
||||||
|
SubjectCode: null,
|
||||||
|
Asc: false,
|
||||||
|
SortField: 'TaskBlindName',
|
||||||
|
}
|
||||||
|
}
|
||||||
|
export default {
|
||||||
|
name: 'downloadDicomAndNonedicom',
|
||||||
|
components: {
|
||||||
|
'study-view': studyView,
|
||||||
|
},
|
||||||
|
props: {
|
||||||
|
visible: {
|
||||||
|
required: true,
|
||||||
|
type: Boolean,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
SubjectId: {
|
||||||
|
type: String,
|
||||||
|
default: '',
|
||||||
|
},
|
||||||
|
TaskId: {
|
||||||
|
type: String,
|
||||||
|
default: '',
|
||||||
|
},
|
||||||
|
SubjectCode: {
|
||||||
|
type: String,
|
||||||
|
default: '',
|
||||||
|
},
|
||||||
|
Criterion: {
|
||||||
|
type: Object,
|
||||||
|
default: () => {
|
||||||
|
return {}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
title: null,
|
||||||
|
loading: false,
|
||||||
|
list: [],
|
||||||
|
searchData: defaultSearchData(),
|
||||||
|
btnLoading: false,
|
||||||
|
hasDicom: false,
|
||||||
|
hasNonedicom: false,
|
||||||
|
// 检查数弹框
|
||||||
|
model_cfg: {
|
||||||
|
visible: false,
|
||||||
|
showClose: true,
|
||||||
|
width: '1000px',
|
||||||
|
title: '',
|
||||||
|
appendToBody: true,
|
||||||
|
},
|
||||||
|
modelList: [],
|
||||||
|
IsDicom: true,
|
||||||
|
open: null,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this.getList()
|
||||||
|
this.title = `Download Images:${this.SubjectCode}(${this.Criterion.TrialReadingCriterionName})`
|
||||||
|
},
|
||||||
|
beforeDestroy() {
|
||||||
|
store.dispatch('trials/setUnLock', false)
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
beforeClose() {
|
||||||
|
this.$emit('update:visible', false)
|
||||||
|
},
|
||||||
|
// 获取列表
|
||||||
|
async getList() {
|
||||||
|
try {
|
||||||
|
this.searchData.SubjectId = this.SubjectId
|
||||||
|
this.searchData.TrialReadingCriterionId =
|
||||||
|
this.Criterion.TrialReadingCriterionId
|
||||||
|
this.searchData.SubjectCode = this.SubjectCode
|
||||||
|
if (this.TaskId) {
|
||||||
|
this.searchData.VisitTaskId = this.TaskId
|
||||||
|
}
|
||||||
|
this.loading = true
|
||||||
|
let res = await getSubjectImageDownloadSelectList(this.searchData)
|
||||||
|
this.loading = false
|
||||||
|
if (res.IsSuccess) {
|
||||||
|
this.list = res.Result
|
||||||
|
this.hasDicom = this.list.some((item) => item.IsDicom)
|
||||||
|
this.hasNonedicom = this.list.some((item) => !item.IsDicom)
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
this.loading = false
|
||||||
|
console.log(err)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// 获取下载文件信息
|
||||||
|
async getIRReadingDownloadStudyInfo(type, row) {
|
||||||
|
try {
|
||||||
|
let data = {
|
||||||
|
SubjectId: this.SubjectId,
|
||||||
|
TrialReadingCriterionId: this.Criterion.TrialReadingCriterionId,
|
||||||
|
SubjectCode: this.SubjectCode,
|
||||||
|
SubjectVisitTaskList: [],
|
||||||
|
DicomStudyIdList: [],
|
||||||
|
NoneDicomStudyIdList: [],
|
||||||
|
}
|
||||||
|
if (type === 'dicom' || type === 'all') {
|
||||||
|
this.list.forEach((item) => {
|
||||||
|
if (
|
||||||
|
item.IsDicom &&
|
||||||
|
item.DicomStudyList &&
|
||||||
|
item.DicomStudyList.length > 0
|
||||||
|
) {
|
||||||
|
data.SubjectVisitTaskList.push({
|
||||||
|
SubjectvisitId: item.SourceSubjectVisitId,
|
||||||
|
TaskId: item.VisitTaskId,
|
||||||
|
})
|
||||||
|
let arr = item.DicomStudyList.map((d) => d.Id)
|
||||||
|
data.DicomStudyIdList = [...data.DicomStudyIdList, ...arr]
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
if (type === 'noneDicom' || type === 'all') {
|
||||||
|
this.list.forEach((item) => {
|
||||||
|
if (
|
||||||
|
!item.IsDicom &&
|
||||||
|
item.NoneDicomStudyList &&
|
||||||
|
item.NoneDicomStudyList.length > 0
|
||||||
|
) {
|
||||||
|
data.SubjectVisitTaskList.push({
|
||||||
|
SubjectvisitId: item.SourceSubjectVisitId,
|
||||||
|
TaskId: item.VisitTaskId,
|
||||||
|
})
|
||||||
|
let arr = item.NoneDicomStudyList.map((d) => d.Id)
|
||||||
|
data.NoneDicomStudyIdList = [...data.NoneDicomStudyIdList, ...arr]
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
if (type === 'one') {
|
||||||
|
if (
|
||||||
|
row.IsDicom &&
|
||||||
|
row.DicomStudyList &&
|
||||||
|
row.DicomStudyList.length > 0
|
||||||
|
) {
|
||||||
|
data.SubjectVisitTaskList.push({
|
||||||
|
SubjectvisitId: row.SourceSubjectVisitId,
|
||||||
|
TaskId: row.VisitTaskId,
|
||||||
|
})
|
||||||
|
let arr = row.DicomStudyList.map((d) => d.Id)
|
||||||
|
data.DicomStudyIdList = [...data.DicomStudyIdList, ...arr]
|
||||||
|
}
|
||||||
|
if (
|
||||||
|
!row.IsDicom &&
|
||||||
|
row.NoneDicomStudyList &&
|
||||||
|
row.NoneDicomStudyList.length > 0
|
||||||
|
) {
|
||||||
|
data.SubjectVisitTaskList.push({
|
||||||
|
SubjectvisitId: row.SourceSubjectVisitId,
|
||||||
|
TaskId: row.VisitTaskId,
|
||||||
|
})
|
||||||
|
let arr = row.NoneDicomStudyList.map((d) => d.Id)
|
||||||
|
data.NoneDicomStudyIdList = [...data.NoneDicomStudyIdList, ...arr]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.btnLoading = true
|
||||||
|
let res = await getIRReadingDownloadStudyInfo(data)
|
||||||
|
this.btnLoading = false
|
||||||
|
if (res.IsSuccess) {
|
||||||
|
this.downloadImage(res.Result)
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
this.btnLoading = false
|
||||||
|
console.log(err)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// 打包下载
|
||||||
|
async downloadImage(data) {
|
||||||
|
try {
|
||||||
|
let { files, name, fileType } = this.formatDownloadFile(data)
|
||||||
|
await downLoadFile(files, name, 'zip')
|
||||||
|
} catch (err) {
|
||||||
|
console.log(err)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// 格式化下载文件路径
|
||||||
|
formatDownloadFile(list) {
|
||||||
|
let files = [],
|
||||||
|
name = `${list[0].SubjectCode}_${new Date().getTime()}.zip`
|
||||||
|
list.forEach((data) => {
|
||||||
|
if (data.StudyList && data.StudyList.length > 0) {
|
||||||
|
let StudyList = data.StudyList
|
||||||
|
StudyList.forEach((study) => {
|
||||||
|
if (study.SeriesList.length > 0) {
|
||||||
|
study.SeriesList.forEach((series) => {
|
||||||
|
if (series.InstancePathList.length > 0) {
|
||||||
|
series.InstancePathList.forEach((instance) => {
|
||||||
|
let fileName = instance.Path.split('/').pop()
|
||||||
|
let obj = {
|
||||||
|
name: `${data.SubjectCode}/${
|
||||||
|
data.TaskBlindName
|
||||||
|
}/${this.$fd('IsDicom', true)}/${
|
||||||
|
study.StudyCode
|
||||||
|
}/${fileName}`,
|
||||||
|
url: this.OSSclientConfig.basePath + instance.Path,
|
||||||
|
}
|
||||||
|
files.push(obj)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
if (data.NoneDicomStudyList && data.NoneDicomStudyList.length > 0) {
|
||||||
|
let NoneDicomStudyList = data.NoneDicomStudyList
|
||||||
|
// 多文件
|
||||||
|
NoneDicomStudyList.forEach((study) => {
|
||||||
|
if (study.FileList.length > 0) {
|
||||||
|
study.FileList.forEach((item) => {
|
||||||
|
let obj = {
|
||||||
|
name: `${data.SubjectCode}/${data.TaskBlindName}/${this.$fd(
|
||||||
|
'IsDicom',
|
||||||
|
false
|
||||||
|
)}/${study.StudyCode}/${item.FileName}`,
|
||||||
|
url: this.OSSclientConfig.basePath + item.Path,
|
||||||
|
}
|
||||||
|
files.push(obj)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
return { files, name }
|
||||||
|
},
|
||||||
|
handleOpenDialog(item) {
|
||||||
|
this.model_cfg.title = `${item.SubjectCode || ''} > ${item.TaskBlindName}`
|
||||||
|
if (item.IsDicom) {
|
||||||
|
this.modelList = item.DicomStudyList
|
||||||
|
} else {
|
||||||
|
this.modelList = item.NoneDicomStudyList
|
||||||
|
this.modelList.forEach((data) => {
|
||||||
|
data.SourceSubjectVisitId = item.SourceSubjectVisitId
|
||||||
|
})
|
||||||
|
}
|
||||||
|
this.IsDicom = item.IsDicom
|
||||||
|
this.model_cfg.visible = true
|
||||||
|
},
|
||||||
|
// 排序
|
||||||
|
handleSortByColumn(column) {
|
||||||
|
if (column.order === 'ascending') {
|
||||||
|
this.searchData.Asc = true
|
||||||
|
} else {
|
||||||
|
this.searchData.Asc = false
|
||||||
|
}
|
||||||
|
this.searchData.SortField = column.prop
|
||||||
|
this.searchData.PageIndex = 1
|
||||||
|
this.getList()
|
||||||
|
},
|
||||||
|
preview(row) {
|
||||||
|
if (!row.IsDicom) {
|
||||||
|
this.handlePreviewNoneDicomFiles(row)
|
||||||
|
} else {
|
||||||
|
this.handleViewReadingImages(row)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// 预览单个检查下非Dicom文件
|
||||||
|
handlePreviewNoneDicomFiles(row) {
|
||||||
|
if (this.open) {
|
||||||
|
this.open.close()
|
||||||
|
}
|
||||||
|
let trialId = this.$route.query.trialId
|
||||||
|
var token = getToken()
|
||||||
|
const routeData = this.$router.resolve({
|
||||||
|
path: `/showNoneDicoms?trialId=${trialId}&subjectVisitId=${row.SourceSubjectVisitId}&visitTaskId=${row.VisitTaskId}&TokenKey=${token}`,
|
||||||
|
})
|
||||||
|
this.open = window.open(routeData.href, '_blank')
|
||||||
|
},
|
||||||
|
// 预览阅片影像
|
||||||
|
handleViewReadingImages(row) {
|
||||||
|
if (this.open) {
|
||||||
|
this.open.close()
|
||||||
|
}
|
||||||
|
var token = getToken()
|
||||||
|
let trialId = this.$route.query.trialId
|
||||||
|
const routeData = this.$router.resolve({
|
||||||
|
path: `/showvisitdicoms?trialId=${trialId}&subjectVisitId=${row.SourceSubjectVisitId}&isReading=1&TokenKey=${token}`,
|
||||||
|
})
|
||||||
|
this.open = window.open(routeData.href, '_blank')
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.top {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
margin: 10px 0;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,95 @@
|
||||||
|
<template>
|
||||||
|
<el-dialog
|
||||||
|
:visible.sync="visible"
|
||||||
|
:fullscreen="true"
|
||||||
|
:close-on-click-modal="false"
|
||||||
|
:before-close="beforeClose"
|
||||||
|
:append-to-body="true"
|
||||||
|
class="uploadDicomAndNonedicom"
|
||||||
|
>
|
||||||
|
<span slot="title">{{ title }}</span>
|
||||||
|
<el-tabs type="border-card" v-model="activeName">
|
||||||
|
<el-tab-pane
|
||||||
|
:label="$t('uploadDicomAndNonedicom:label:dicom')"
|
||||||
|
name="dicom"
|
||||||
|
>
|
||||||
|
<dicomFile
|
||||||
|
v-if="activeName === 'dicom'"
|
||||||
|
:SubjectId="SubjectId"
|
||||||
|
:SubjectCode="SubjectCode"
|
||||||
|
:Criterion="Criterion"
|
||||||
|
/>
|
||||||
|
</el-tab-pane>
|
||||||
|
<el-tab-pane
|
||||||
|
:label="$t('uploadDicomAndNonedicom:label:nonedicom')"
|
||||||
|
name="nonedicom"
|
||||||
|
>
|
||||||
|
<nonedicomFile
|
||||||
|
v-if="activeName === 'nonedicom'"
|
||||||
|
:SubjectId="SubjectId"
|
||||||
|
:SubjectCode="SubjectCode"
|
||||||
|
:Criterion="Criterion"
|
||||||
|
/>
|
||||||
|
</el-tab-pane>
|
||||||
|
</el-tabs>
|
||||||
|
</el-dialog>
|
||||||
|
</template>
|
||||||
|
<script>
|
||||||
|
import dicomFile from './dicomFile.vue'
|
||||||
|
import nonedicomFile from './nonedicomFile.vue'
|
||||||
|
export default {
|
||||||
|
name: 'uploadDicomAndNonedicom',
|
||||||
|
components: { dicomFile, nonedicomFile },
|
||||||
|
props: {
|
||||||
|
visible: {
|
||||||
|
required: true,
|
||||||
|
type: Boolean,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
SubjectId: {
|
||||||
|
type: String,
|
||||||
|
default: '',
|
||||||
|
},
|
||||||
|
SubjectCode: {
|
||||||
|
type: String,
|
||||||
|
default: '',
|
||||||
|
},
|
||||||
|
Criterion: {
|
||||||
|
type: Object,
|
||||||
|
default: () => {
|
||||||
|
return {}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
title: '',
|
||||||
|
activeName: 'dicom',
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this.title = `Upload Images:${this.SubjectCode}(${this.Criterion.TrialReadingCriterionName})`
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
beforeClose() {
|
||||||
|
this.$emit('update:visible', false)
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
::v-deep.el-tabs--left .el-tabs__header.is-left {
|
||||||
|
margin-right: 0;
|
||||||
|
}
|
||||||
|
.uploadDicomAndNonedicom {
|
||||||
|
::v-deep.el-tabs--border-card > .el-tabs__header .el-tabs__item {
|
||||||
|
color: #909399;
|
||||||
|
}
|
||||||
|
::v-deep.el-tabs--border-card > .el-tabs__header .el-tabs__item.is-active {
|
||||||
|
color: #428bca;
|
||||||
|
background-color: #fff;
|
||||||
|
border-right-color: #dcdfe6;
|
||||||
|
border-left-color: #dcdfe6;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
@ -0,0 +1,788 @@
|
||||||
|
<template>
|
||||||
|
<div class="nonedicomFile">
|
||||||
|
<div class="top">
|
||||||
|
<span>{{ $t('upload:nonedicom:title') }}</span>
|
||||||
|
</div>
|
||||||
|
<!--检查列表-->
|
||||||
|
<el-table
|
||||||
|
:data="list"
|
||||||
|
style="width: 100%"
|
||||||
|
v-adaptive="{ bottomOffset: 40 }"
|
||||||
|
:loading="loading"
|
||||||
|
@sort-change="handleSortByColumn"
|
||||||
|
:default-sort="{ prop: 'TaskBlindName', order: 'descending' }"
|
||||||
|
>
|
||||||
|
<!--受试者-->
|
||||||
|
<el-table-column
|
||||||
|
prop="SubjectCode"
|
||||||
|
:label="$t('upload:nonedicom:table:subject')"
|
||||||
|
/>
|
||||||
|
<!--任务名称-->
|
||||||
|
<el-table-column
|
||||||
|
prop="TaskBlindName"
|
||||||
|
:label="$t('upload:nonedicom:table:taskName')"
|
||||||
|
sortable="custom"
|
||||||
|
/>
|
||||||
|
<!--检查类型-->
|
||||||
|
<el-table-column
|
||||||
|
prop="Modality"
|
||||||
|
:label="$t('upload:nonedicom:table:molityType')"
|
||||||
|
sortable="custom"
|
||||||
|
>
|
||||||
|
</el-table-column>
|
||||||
|
<!--检查部位-->
|
||||||
|
<el-table-column
|
||||||
|
prop="BodyPart"
|
||||||
|
:label="$t('upload:nonedicom:table:bodyPart')"
|
||||||
|
sortable="custom"
|
||||||
|
/>
|
||||||
|
<!--原文件数-->
|
||||||
|
<el-table-column
|
||||||
|
prop="FileCount"
|
||||||
|
:label="$t('upload:nonedicom:table:fileCount')"
|
||||||
|
>
|
||||||
|
<template slot-scope="scope">
|
||||||
|
<el-popover
|
||||||
|
v-if="scope.row.FileCount"
|
||||||
|
trigger="click"
|
||||||
|
placement="bottom"
|
||||||
|
>
|
||||||
|
<el-table :data="scope.row.FileList" height="300" size="small">
|
||||||
|
<!-- 文件名称 -->
|
||||||
|
<el-table-column
|
||||||
|
prop="FileName"
|
||||||
|
:label="$t('trials:audit:table:nonDicomsFileName')"
|
||||||
|
width="200"
|
||||||
|
/>
|
||||||
|
<el-table-column :label="$t('common:action:action')" width="120">
|
||||||
|
<template slot-scope="files">
|
||||||
|
<!-- 预览 -->
|
||||||
|
<el-button
|
||||||
|
type="text"
|
||||||
|
:disabled="
|
||||||
|
files.row.FileType &&
|
||||||
|
files.row.FileType.indexOf('zip') >= 0
|
||||||
|
"
|
||||||
|
@click.native.prevent="previewFile(files.row)"
|
||||||
|
>
|
||||||
|
{{ $t('trials:audit:button:nonDicomsPreview') }}
|
||||||
|
</el-button>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
<div slot="reference" class="name-wrapper">
|
||||||
|
<el-button type="text">
|
||||||
|
{{ scope.row.FileCount }}
|
||||||
|
</el-button>
|
||||||
|
</div>
|
||||||
|
</el-popover>
|
||||||
|
<span v-else>{{ scope.row.FileCount }}</span>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<!--后处理文件数-->
|
||||||
|
<el-table-column
|
||||||
|
prop="UploadedFileCount"
|
||||||
|
:label="$t('upload:nonedicom:table:uploadFileCount')"
|
||||||
|
>
|
||||||
|
<template slot-scope="scope">
|
||||||
|
<el-popover
|
||||||
|
v-if="scope.row.UploadedFileCount"
|
||||||
|
trigger="click"
|
||||||
|
placement="bottom"
|
||||||
|
>
|
||||||
|
<el-table
|
||||||
|
:data="scope.row.UploadedFileList"
|
||||||
|
height="300"
|
||||||
|
size="small"
|
||||||
|
>
|
||||||
|
<!-- 文件名称 -->
|
||||||
|
<el-table-column
|
||||||
|
prop="FileName"
|
||||||
|
:label="$t('trials:audit:table:nonDicomsFileName')"
|
||||||
|
width="200"
|
||||||
|
/>
|
||||||
|
<el-table-column :label="$t('common:action:action')" width="120">
|
||||||
|
<template slot-scope="files">
|
||||||
|
<!-- 预览 -->
|
||||||
|
<el-button
|
||||||
|
type="text"
|
||||||
|
:disabled="
|
||||||
|
files.row.FileType &&
|
||||||
|
files.row.FileType.indexOf('zip') >= 0
|
||||||
|
"
|
||||||
|
@click.native.prevent="previewFile(files.row)"
|
||||||
|
>
|
||||||
|
{{ $t('trials:audit:button:nonDicomsPreview') }}
|
||||||
|
</el-button>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
<div slot="reference" class="name-wrapper">
|
||||||
|
<el-button type="text">
|
||||||
|
{{ scope.row.UploadedFileCount }}
|
||||||
|
</el-button>
|
||||||
|
</div>
|
||||||
|
</el-popover>
|
||||||
|
<span v-else>{{ scope.row.UploadedFileCount }}</span>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column
|
||||||
|
:label="$t('common:action:action')"
|
||||||
|
fixed="right"
|
||||||
|
width="180"
|
||||||
|
>
|
||||||
|
<template slot-scope="scope">
|
||||||
|
<!--预览--->
|
||||||
|
<el-button
|
||||||
|
circle
|
||||||
|
:disabled="scope.row.UploadedFileCount <= 0"
|
||||||
|
icon="el-icon-view"
|
||||||
|
:title="$t('upload:nonedicom:button:preview')"
|
||||||
|
@click.stop="handlePreviewNoneDicomFiles(scope.row)"
|
||||||
|
/>
|
||||||
|
<!--上传--->
|
||||||
|
<el-button
|
||||||
|
circle
|
||||||
|
icon="el-icon-upload2"
|
||||||
|
:title="$t('upload:nonedicom:button:upload')"
|
||||||
|
@click.native.prevent="handleUpload(scope.row)"
|
||||||
|
/>
|
||||||
|
<!--删除--->
|
||||||
|
<el-button
|
||||||
|
:disabled="scope.row.UploadedFileCount <= 0"
|
||||||
|
circle
|
||||||
|
icon="el-icon-delete"
|
||||||
|
:title="$t('upload:nonedicom:button:delete')"
|
||||||
|
@click.stop="remove(scope.row)"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
<!-- 预览单个图像 -->
|
||||||
|
<el-dialog
|
||||||
|
v-if="imgObj.visible"
|
||||||
|
:visible.sync="imgObj.visible"
|
||||||
|
:title="$t('upload:nonedicom:dialogTitle:preview')"
|
||||||
|
append-to-body
|
||||||
|
width="565px"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
v-loading="imgObj.loading"
|
||||||
|
class="base-modal-body"
|
||||||
|
style="border: 2px solid #ccc; padding: 10px"
|
||||||
|
>
|
||||||
|
<el-image
|
||||||
|
:src="`${OSSclientConfig.basePath}${imgObj.url}`"
|
||||||
|
crossorigin="anonymous"
|
||||||
|
fit="fit"
|
||||||
|
style="height: 500px; width: 500px"
|
||||||
|
@error="imgObj.loading = false"
|
||||||
|
@load="imgObj.loading = false"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</el-dialog>
|
||||||
|
<!-- 上传非dicom文件 -->
|
||||||
|
<el-dialog
|
||||||
|
v-if="uploadVisible"
|
||||||
|
:visible.sync="uploadVisible"
|
||||||
|
:close-on-click-modal="false"
|
||||||
|
:title="$t('trials:uploadNonDicoms:dialogTitle:upload')"
|
||||||
|
width="800px"
|
||||||
|
append-to-body
|
||||||
|
custom-class="base-dialog-wrapper"
|
||||||
|
@close="resetFileDiaolg"
|
||||||
|
>
|
||||||
|
<!-- 多文件上传 -->
|
||||||
|
<form id="inputForm" ref="uploadForm">
|
||||||
|
<el-divider content-position="left">{{
|
||||||
|
$t('trials:uploadNonDicoms:label:fileType')
|
||||||
|
}}</el-divider>
|
||||||
|
<div class="form-group">
|
||||||
|
<div class="upload" style="margin-right: 10px">
|
||||||
|
<input
|
||||||
|
multiple="multiple"
|
||||||
|
webkitdirectory=""
|
||||||
|
directory
|
||||||
|
accept="*/*"
|
||||||
|
type="file"
|
||||||
|
name="uploadFolder"
|
||||||
|
class="select-file"
|
||||||
|
title=""
|
||||||
|
@change="beginScanFiles($event)"
|
||||||
|
v-if="!btnLoading"
|
||||||
|
/>
|
||||||
|
<div class="btn-select">
|
||||||
|
{{ $t('trials:uploadNonDicoms:button:selectFolder') }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="upload">
|
||||||
|
<input
|
||||||
|
class="select-file"
|
||||||
|
multiple=""
|
||||||
|
:accept="faccept.join(',')"
|
||||||
|
type="file"
|
||||||
|
name="uploadFile"
|
||||||
|
title=""
|
||||||
|
@change="beginScanFiles($event)"
|
||||||
|
v-if="!btnLoading"
|
||||||
|
/>
|
||||||
|
<div class="btn-select">
|
||||||
|
{{ $t('trials:uploadNonDicoms:button:select') }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- <span style="margin-left: 10px">{{
|
||||||
|
$store.state.trials.uploadTip
|
||||||
|
}}</span> -->
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
<!-- 文件列表 -->
|
||||||
|
<el-table
|
||||||
|
ref="filesTable"
|
||||||
|
:data="fileList"
|
||||||
|
class="dicomFiles-table"
|
||||||
|
height="300"
|
||||||
|
@selection-change="handleSelectionChange"
|
||||||
|
>
|
||||||
|
<el-table-column
|
||||||
|
type="selection"
|
||||||
|
width="55"
|
||||||
|
:selectable="(row, index) => row.status !== 2 && !btnLoading"
|
||||||
|
/>
|
||||||
|
<el-table-column type="index" width="50" />
|
||||||
|
<!-- 文件名称 -->
|
||||||
|
<el-table-column
|
||||||
|
prop="name"
|
||||||
|
:label="$t('trials:uploadNonDicoms:table:fileName')"
|
||||||
|
min-width="100"
|
||||||
|
/>
|
||||||
|
<!-- 文件大小 -->
|
||||||
|
<el-table-column
|
||||||
|
prop="size"
|
||||||
|
:label="$t('trials:uploadNonDicoms:table:fileSize')"
|
||||||
|
>
|
||||||
|
<template slot-scope="scope">
|
||||||
|
<span>{{
|
||||||
|
scope.row.size && scope.row.size > 0
|
||||||
|
? `${(scope.row.size / 1024 / 1024).toFixed(2)}MB`
|
||||||
|
: 0
|
||||||
|
}}</span>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<!-- 文件类型 -->
|
||||||
|
<el-table-column
|
||||||
|
prop="type"
|
||||||
|
:label="$t('trials:uploadNonDicoms:table:fileType')"
|
||||||
|
/>
|
||||||
|
<!-- 上传状态 -->
|
||||||
|
<el-table-column
|
||||||
|
prop="status"
|
||||||
|
:label="$t('trials:uploadNonDicoms:table:uploadStatus')"
|
||||||
|
min-width="100"
|
||||||
|
>
|
||||||
|
<template slot-scope="scope">
|
||||||
|
<el-tag
|
||||||
|
:type="['warning', 'info', 'success', 'danger'][scope.row.status]"
|
||||||
|
v-if="scope.row.status || scope.row.status === 0"
|
||||||
|
>{{ $fd('NoneDicomUploadStatus', scope.row.status) }}
|
||||||
|
</el-tag>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column
|
||||||
|
:label="$t('trials:uploadNonDicoms:table:failedFileCount')"
|
||||||
|
min-width="150"
|
||||||
|
show-overflow-tooltip
|
||||||
|
>
|
||||||
|
<template slot-scope="scope">
|
||||||
|
<el-progress
|
||||||
|
color="#409eff"
|
||||||
|
:percentage="
|
||||||
|
((scope.row.uploadFileSize * 100) / scope.row.size).toFixed(2) *
|
||||||
|
1
|
||||||
|
"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column :label="$t('common:action:action')">
|
||||||
|
<template slot-scope="scope">
|
||||||
|
<el-button
|
||||||
|
size="mini"
|
||||||
|
icon="el-icon-delete"
|
||||||
|
circle
|
||||||
|
:disabled="btnLoading"
|
||||||
|
:title="$t('trials:crcUpload:action:delete')"
|
||||||
|
@click="handleRemoveFile(scope.row)"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
<div style="text-align: right; padding: 10px 0px">
|
||||||
|
<span style="margin-right: 10px">{{
|
||||||
|
$store.state.trials.uploadTip
|
||||||
|
}}</span>
|
||||||
|
<el-button
|
||||||
|
size="small"
|
||||||
|
type="primary"
|
||||||
|
:disabled="selectArr.length == 0"
|
||||||
|
:loading="btnLoading"
|
||||||
|
@click="beginUpload"
|
||||||
|
>
|
||||||
|
{{ $t('trials:uploadNonDicoms:action:upload') }}
|
||||||
|
</el-button>
|
||||||
|
</div>
|
||||||
|
</el-dialog>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<script>
|
||||||
|
import {
|
||||||
|
getIRUploadTaskNoneDicomStudyList,
|
||||||
|
deleteTaskStudy,
|
||||||
|
} from '@/api/load.js'
|
||||||
|
import { preArchiveStudy, uploadNoneDicomFile } from '@/api/trials'
|
||||||
|
import store from '@/store'
|
||||||
|
import { getToken } from '@/utils/auth'
|
||||||
|
let defaultSearchData = () => {
|
||||||
|
return {
|
||||||
|
SubjectId: null,
|
||||||
|
TrialReadingCriterionId: null,
|
||||||
|
SubjectCode: null,
|
||||||
|
Asc: false,
|
||||||
|
SortField: 'TaskBlindName',
|
||||||
|
}
|
||||||
|
}
|
||||||
|
export default {
|
||||||
|
name: 'nonedicomFile',
|
||||||
|
props: {
|
||||||
|
SubjectId: {
|
||||||
|
type: String,
|
||||||
|
default: '',
|
||||||
|
},
|
||||||
|
SubjectCode: {
|
||||||
|
type: String,
|
||||||
|
default: '',
|
||||||
|
},
|
||||||
|
Criterion: {
|
||||||
|
type: Object,
|
||||||
|
default: () => {
|
||||||
|
return {}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
loading: false,
|
||||||
|
list: [],
|
||||||
|
searchData: defaultSearchData(),
|
||||||
|
imgObj: { url: '', visible: false, loading: false },
|
||||||
|
uploadVisible: false,
|
||||||
|
fileList: [],
|
||||||
|
selectArr: [],
|
||||||
|
successFileList: [],
|
||||||
|
isFail: false,
|
||||||
|
faccept: ['.jpg', '.jpeg', '.png', '.bmp', '.zip'],
|
||||||
|
fCount: 0,
|
||||||
|
btnLoading: false,
|
||||||
|
currentRow: {},
|
||||||
|
studyMonitorId: null,
|
||||||
|
open: null,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
isFail() {
|
||||||
|
if (this.isFail) {
|
||||||
|
this.$confirm(
|
||||||
|
this.$t('trials:visit:crcUpload:nomDicomFiles:failUpload'),
|
||||||
|
{
|
||||||
|
type: 'warning',
|
||||||
|
distinguishCancelAndClose: true,
|
||||||
|
confirmButtonText: this.$t('common:button:confirm'),
|
||||||
|
cancelButtonText: this.$t('common:button:cancel'),
|
||||||
|
}
|
||||||
|
)
|
||||||
|
.then(() => {
|
||||||
|
this.beginUpload()
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
this.btnLoading = false
|
||||||
|
console.log(err)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
},
|
||||||
|
btnLoading() {
|
||||||
|
store.dispatch('trials/setUnLock', this.btnLoading)
|
||||||
|
},
|
||||||
|
},
|
||||||
|
created() {
|
||||||
|
this.getList()
|
||||||
|
},
|
||||||
|
beforeDestroy() {
|
||||||
|
store.dispatch('trials/setUnLock', false)
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
async getList() {
|
||||||
|
try {
|
||||||
|
this.searchData.SubjectId = this.SubjectId
|
||||||
|
this.searchData.TrialReadingCriterionId =
|
||||||
|
this.Criterion.TrialReadingCriterionId
|
||||||
|
this.searchData.SubjectCode = this.SubjectCode
|
||||||
|
this.loading = true
|
||||||
|
let res = await getIRUploadTaskNoneDicomStudyList(this.searchData)
|
||||||
|
this.loading = false
|
||||||
|
if (res.IsSuccess) {
|
||||||
|
this.list = res.Result
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
this.loading = false
|
||||||
|
console.log(err)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// 扫描待上传文件
|
||||||
|
beginScanFiles(e) {
|
||||||
|
var files = [...e.target.files]
|
||||||
|
var sameFiles = []
|
||||||
|
files.forEach((file) => {
|
||||||
|
var extendName = file.name
|
||||||
|
.substring(file.name.lastIndexOf('.'))
|
||||||
|
.toLocaleLowerCase()
|
||||||
|
if (
|
||||||
|
this.faccept.indexOf(extendName) !== -1 &&
|
||||||
|
this.fileList.findIndex((v) => v.name === file.name) > -1
|
||||||
|
) {
|
||||||
|
sameFiles.push(file.name)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
var scope = this
|
||||||
|
if (sameFiles.length > 0) {
|
||||||
|
const h = this.$createElement
|
||||||
|
var msg = this.$t(
|
||||||
|
'trials:uploadNonDicoms:message:exsitSameFile'
|
||||||
|
).replace('xxx', sameFiles.join(', '))
|
||||||
|
this.$msgbox({
|
||||||
|
message: h('div', { style: 'maxHeight:300px;overflow: auto;' }, [
|
||||||
|
h('p', null, msg),
|
||||||
|
h(
|
||||||
|
'p',
|
||||||
|
null,
|
||||||
|
this.$t('trials:uploadNonDicoms:message:isContinueUpload')
|
||||||
|
),
|
||||||
|
]),
|
||||||
|
type: 'warning',
|
||||||
|
showCancelButton: true,
|
||||||
|
})
|
||||||
|
.then(() => {
|
||||||
|
scope.pendingUploadQuene(files)
|
||||||
|
})
|
||||||
|
.catch(() => {
|
||||||
|
scope.resetUploadForm()
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
scope.pendingUploadQuene(files)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
pendingUploadQuene(files) {
|
||||||
|
for (var i = 0; i < files.length; ++i) {
|
||||||
|
const fileName = files[i].name
|
||||||
|
var extendName = fileName
|
||||||
|
.substring(fileName.lastIndexOf('.'))
|
||||||
|
.toLocaleLowerCase()
|
||||||
|
if (this.faccept.indexOf(extendName) !== -1) {
|
||||||
|
files[i].id = `${files[i].lastModified}${files[i].name}`
|
||||||
|
let obj = {
|
||||||
|
name: files[i].name,
|
||||||
|
size: files[i].size,
|
||||||
|
type: extendName.split('.')[1],
|
||||||
|
status: 0,
|
||||||
|
file: files[i],
|
||||||
|
id: `${files[i].lastModified}${files[i].name}`,
|
||||||
|
fileType: files[i].type,
|
||||||
|
uploadFileSize: 0,
|
||||||
|
}
|
||||||
|
this.fileList.push(obj)
|
||||||
|
this.$refs.filesTable.toggleRowSelection(obj, true)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.resetUploadForm()
|
||||||
|
},
|
||||||
|
handleRemoveFile(row) {
|
||||||
|
this.$confirm(this.$t('trials:uploadNonDicoms:message:delete'), {
|
||||||
|
type: 'warning',
|
||||||
|
distinguishCancelAndClose: true,
|
||||||
|
})
|
||||||
|
.then(() => {
|
||||||
|
this.fileList.splice(
|
||||||
|
this.fileList.findIndex((item) => item.id === row.id),
|
||||||
|
1
|
||||||
|
)
|
||||||
|
let flag = this.successFileList.some((item) => item.id === row.id)
|
||||||
|
if (flag) {
|
||||||
|
this.successFileList.splice(
|
||||||
|
this.successFileList.findIndex((item) => item.id === row.id),
|
||||||
|
1
|
||||||
|
)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch(() => {})
|
||||||
|
},
|
||||||
|
resetUploadForm() {
|
||||||
|
this.$nextTick(() => {
|
||||||
|
this.$refs.uploadForm.reset()
|
||||||
|
})
|
||||||
|
},
|
||||||
|
// 打开上传文件弹窗
|
||||||
|
handleUpload(row) {
|
||||||
|
this.fileList = []
|
||||||
|
this.uploadVisible = true
|
||||||
|
this.fCount = 0
|
||||||
|
this.currentRow = { ...row }
|
||||||
|
},
|
||||||
|
resetFileDiaolg() {
|
||||||
|
this.btnLoading = false
|
||||||
|
this.uploadVisible = false
|
||||||
|
this.selectArr = []
|
||||||
|
this.successFileList = []
|
||||||
|
this.OSSclient.close()
|
||||||
|
},
|
||||||
|
// 预览文件
|
||||||
|
previewFile(row) {
|
||||||
|
// window.open(row.FullFilePath, '_blank')
|
||||||
|
this.imgObj.url = row.FullFilePath || row.Path
|
||||||
|
this.imgObj.loading = true
|
||||||
|
this.imgObj.visible = true
|
||||||
|
},
|
||||||
|
// 预览单个检查下非Dicom文件
|
||||||
|
handlePreviewNoneDicomFiles(row) {
|
||||||
|
if (this.open) {
|
||||||
|
this.open.close()
|
||||||
|
}
|
||||||
|
let trialId = this.$route.query.trialId
|
||||||
|
var token = getToken()
|
||||||
|
const routeData = this.$router.resolve({
|
||||||
|
path: `/showNoneDicoms?trialId=${trialId}&subjectVisitId=${row.SourceSubjectVisitId}&studyId=${row.Id}&visitTaskId=${row.VisitTaskId}&TokenKey=${token}`,
|
||||||
|
})
|
||||||
|
this.open = window.open(routeData.href, '_blank')
|
||||||
|
},
|
||||||
|
// 删除
|
||||||
|
async remove(item) {
|
||||||
|
try {
|
||||||
|
let confirm = await this.$confirm(
|
||||||
|
this.$t('upload:nonedicom:confirm:delMessage'),
|
||||||
|
{
|
||||||
|
type: 'warning',
|
||||||
|
distinguishCancelAndClose: true,
|
||||||
|
confirmButtonText: this.$t('common:button:confirm'),
|
||||||
|
cancelButtonText: this.$t('common:button:cancel'),
|
||||||
|
}
|
||||||
|
)
|
||||||
|
if (confirm !== 'confirm') return
|
||||||
|
let params = {
|
||||||
|
VisitTaskId: item.VisitTaskId,
|
||||||
|
IsDicom: false,
|
||||||
|
NoneDicomStudyId: item.Id,
|
||||||
|
}
|
||||||
|
let res = await deleteTaskStudy(params)
|
||||||
|
if (res.IsSuccess) {
|
||||||
|
this.getList()
|
||||||
|
this.$message.success(
|
||||||
|
this.$t('trials:uploadImage:message:delSuccess')
|
||||||
|
)
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
console.log(err)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// 排序
|
||||||
|
handleSortByColumn(column) {
|
||||||
|
if (column.order === 'ascending') {
|
||||||
|
this.searchData.Asc = true
|
||||||
|
} else {
|
||||||
|
this.searchData.Asc = false
|
||||||
|
}
|
||||||
|
this.searchData.SortField = column.prop
|
||||||
|
this.searchData.PageIndex = 1
|
||||||
|
this.getList()
|
||||||
|
},
|
||||||
|
// 获取待上传文件信息
|
||||||
|
handleSelectionChange(selection) {
|
||||||
|
this.selectArr = selection
|
||||||
|
},
|
||||||
|
// 开始上传文件
|
||||||
|
async beginUpload() {
|
||||||
|
this.btnLoading = true
|
||||||
|
this.isFail = false
|
||||||
|
const fileMaxSize = 1024 * 1024 * 1024 * 1 // 1G
|
||||||
|
var currentFilesSize = 0
|
||||||
|
this.selectArr.forEach((item) => {
|
||||||
|
currentFilesSize += item.size
|
||||||
|
})
|
||||||
|
if (currentFilesSize / fileMaxSize > 1) {
|
||||||
|
// 'Upload file size cannot exceed 1G'
|
||||||
|
this.$alert(this.$t('trials:uploadNonDicoms:message:uploadSize'))
|
||||||
|
this.btnLoading = false
|
||||||
|
} else {
|
||||||
|
this.selectArr.forEach((item) => (item.status = 0))
|
||||||
|
let num = this.selectArr.length > 6 ? 6 : this.selectArr.length
|
||||||
|
let funArr = []
|
||||||
|
let res = await preArchiveStudy({
|
||||||
|
subjectVisitId: this.currentRow.SourceSubjectVisitId,
|
||||||
|
isDicom: false,
|
||||||
|
})
|
||||||
|
if (res.IsSuccess) {
|
||||||
|
this.studyMonitorId = res.Result
|
||||||
|
for (let i = 0; i < num; i++) {
|
||||||
|
funArr.push(this.handleUploadTask(this.selectArr, i))
|
||||||
|
}
|
||||||
|
if (funArr.length > 0) {
|
||||||
|
let res = await Promise.all(funArr)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
this.isFail = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// 并发上传
|
||||||
|
async handleUploadTask(arr, index) {
|
||||||
|
if (!this.uploadVisible) return
|
||||||
|
let file = this.fileList.filter((item) => item.id === arr[index].id)[0]
|
||||||
|
file.status = 1
|
||||||
|
console.log(file)
|
||||||
|
let path = `/${this.$route.query.trialId}/TaskImage/${
|
||||||
|
this.currentRow.SubjectId
|
||||||
|
}/${this.currentRow.VisitTaskId}/${this.$guid()}${file.name
|
||||||
|
.substring(file.name.lastIndexOf('.'))
|
||||||
|
.toLocaleLowerCase()}`
|
||||||
|
console.log(path)
|
||||||
|
const fileData = await this.fileToBlob(file.file)
|
||||||
|
let res = await this.fileToOss(path, fileData, file)
|
||||||
|
if (res) {
|
||||||
|
file.status = 2
|
||||||
|
this.successFileList.push({
|
||||||
|
fileName: file.name,
|
||||||
|
filePath: this.$getObjectName(res.url),
|
||||||
|
fileFize: file.size,
|
||||||
|
fileType: file.fileType,
|
||||||
|
})
|
||||||
|
let flag = arr.every((item) => item.status === 2)
|
||||||
|
if (flag) {
|
||||||
|
return this.submitFile(this.successFileList)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
file.status = 3
|
||||||
|
}
|
||||||
|
let flag = arr.every((item) => item.status > 1)
|
||||||
|
if (flag) {
|
||||||
|
let failFileList = arr.filter((item) => item.status === 3)
|
||||||
|
if (failFileList && failFileList.length > 0) {
|
||||||
|
this.$refs.filesTable.clearSelection()
|
||||||
|
failFileList.forEach((row) => {
|
||||||
|
row.uploadFileSize = 0
|
||||||
|
this.$refs.filesTable.toggleRowSelection(row)
|
||||||
|
})
|
||||||
|
this.isFail = true
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let ind = arr.findIndex((item) => item.status === 0)
|
||||||
|
if (ind >= 0) {
|
||||||
|
return this.handleUploadTask(arr, ind)
|
||||||
|
} else {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// file上传到oss
|
||||||
|
async fileToOss(path, file, item) {
|
||||||
|
try {
|
||||||
|
let res = await this.OSSclient.multipartUpload(
|
||||||
|
{
|
||||||
|
path,
|
||||||
|
file,
|
||||||
|
speed: true,
|
||||||
|
},
|
||||||
|
(percentage, checkpoint, lastPer) => {
|
||||||
|
item.uploadFileSize += checkpoint.size * (percentage - lastPer)
|
||||||
|
if (item.uploadFileSize > file.fileSize) {
|
||||||
|
item.uploadFileSize = file.fileSize
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
if (res) {
|
||||||
|
return res
|
||||||
|
} else {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
console.log(err)
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// 非Dicom文件上传归档
|
||||||
|
submitFile(uploadedFileList) {
|
||||||
|
if (!this.uploadVisible) return
|
||||||
|
this.btnLoading = true
|
||||||
|
var params = {
|
||||||
|
trialId: this.$route.query.trialId,
|
||||||
|
subjectVisitId: this.currentRow.SourceSubjectVisitId,
|
||||||
|
noneDicomStudyId: this.currentRow.Id,
|
||||||
|
studyMonitorId: this.studyMonitorId,
|
||||||
|
VisitTaskId: this.currentRow.VisitTaskId,
|
||||||
|
uploadedFileList: uploadedFileList,
|
||||||
|
}
|
||||||
|
uploadNoneDicomFile(params)
|
||||||
|
.then((res) => {
|
||||||
|
this.resetFileDiaolg()
|
||||||
|
this.getList()
|
||||||
|
// 刷新父组件列表
|
||||||
|
this.$emit('getList')
|
||||||
|
this.$message.success(
|
||||||
|
this.$t('trials:uploadNonDicoms:message:uploadedSuccessfully')
|
||||||
|
)
|
||||||
|
})
|
||||||
|
.catch(() => {
|
||||||
|
this.btnLoading = false
|
||||||
|
})
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.top {
|
||||||
|
margin: 10px 0;
|
||||||
|
}
|
||||||
|
.upload {
|
||||||
|
display: inline-block;
|
||||||
|
height: 30px;
|
||||||
|
width: 90px;
|
||||||
|
padding: 2px 10px;
|
||||||
|
line-height: 23px;
|
||||||
|
position: relative;
|
||||||
|
text-decoration: none;
|
||||||
|
border-radius: 3px;
|
||||||
|
overflow: hidden;
|
||||||
|
text-align: center;
|
||||||
|
background: #428bca;
|
||||||
|
border-color: #428bca;
|
||||||
|
color: #fff;
|
||||||
|
.select-file {
|
||||||
|
height: 30px;
|
||||||
|
width: 90px;
|
||||||
|
position: absolute;
|
||||||
|
overflow: hidden;
|
||||||
|
left: 0;
|
||||||
|
top: 0;
|
||||||
|
opacity: 0;
|
||||||
|
font-size: 0;
|
||||||
|
}
|
||||||
|
.btn-select {
|
||||||
|
//给显示在页面上的按钮写样式
|
||||||
|
width: 90px;
|
||||||
|
height: 30px;
|
||||||
|
line-height: 30px;
|
||||||
|
text-align: center;
|
||||||
|
cursor: pointer;
|
||||||
|
border-radius: 24px;
|
||||||
|
overflow: hidden;
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
pointer-events: none; //pointer-events:none用来控制该标签的点击穿透事件
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
@ -0,0 +1,140 @@
|
||||||
|
<template>
|
||||||
|
<base-model :config="model_cfg">
|
||||||
|
<div slot="dialog-body">
|
||||||
|
<el-table :data="modelList" style="width: 100%" height="300">
|
||||||
|
<!--检查编号-->
|
||||||
|
<el-table-column
|
||||||
|
prop="StudyCode"
|
||||||
|
:label="$t('trials:uploadImage:table:StudyCode')"
|
||||||
|
/>
|
||||||
|
<!--检查类型-->
|
||||||
|
<el-table-column
|
||||||
|
prop="ModalityForEdit"
|
||||||
|
:label="$t('trials:uploadImage:table:ModalityForEdit')"
|
||||||
|
v-if="IsDicom"
|
||||||
|
/>
|
||||||
|
<!--检查模态-->
|
||||||
|
<el-table-column
|
||||||
|
prop="Modalities"
|
||||||
|
:label="$t('trials:uploadImage:table:Modalities')"
|
||||||
|
v-if="IsDicom"
|
||||||
|
/>
|
||||||
|
<!--检查部位-->
|
||||||
|
<el-table-column
|
||||||
|
prop="BodyPartForEdit"
|
||||||
|
:label="$t('trials:uploadImage:table:BodyPartForEdit')"
|
||||||
|
v-if="IsDicom"
|
||||||
|
/>
|
||||||
|
<!--序列数量-->
|
||||||
|
<el-table-column
|
||||||
|
prop="SeriesCount"
|
||||||
|
:label="$t('trials:uploadImage:table:SeriesCount')"
|
||||||
|
v-if="IsDicom"
|
||||||
|
/>
|
||||||
|
<!--图像数量-->
|
||||||
|
<el-table-column
|
||||||
|
prop="InstanceCount"
|
||||||
|
:label="$t('trials:uploadImage:table:InstanceCount')"
|
||||||
|
v-if="IsDicom"
|
||||||
|
/>
|
||||||
|
<!--检查时间-->
|
||||||
|
<el-table-column
|
||||||
|
prop="StudyTime"
|
||||||
|
:label="$t('trials:uploadImage:table:StudyTime')"
|
||||||
|
v-if="IsDicom"
|
||||||
|
min-width="130"
|
||||||
|
/>
|
||||||
|
<!--检查模态-->
|
||||||
|
<el-table-column
|
||||||
|
prop="Modality"
|
||||||
|
:label="$t('trials:uploadImage:table:Modalities')"
|
||||||
|
v-if="!IsDicom"
|
||||||
|
/>
|
||||||
|
<!--检查部位-->
|
||||||
|
<el-table-column
|
||||||
|
prop="BodyPart"
|
||||||
|
:label="$t('trials:uploadImage:table:BodyPartForEdit')"
|
||||||
|
v-if="!IsDicom"
|
||||||
|
/>
|
||||||
|
<!--文件数量-->
|
||||||
|
<el-table-column
|
||||||
|
prop="FileCount"
|
||||||
|
:label="$t('trials:uploadImage:table:FileCount')"
|
||||||
|
v-if="!IsDicom"
|
||||||
|
/>
|
||||||
|
<!--检查时间-->
|
||||||
|
<el-table-column
|
||||||
|
prop="ImageDate"
|
||||||
|
:label="$t('trials:uploadImage:table:StudyTime')"
|
||||||
|
v-if="!IsDicom"
|
||||||
|
min-width="130"
|
||||||
|
/>
|
||||||
|
<el-table-column
|
||||||
|
:label="$t('common:action:action')"
|
||||||
|
fixed="right"
|
||||||
|
width="80"
|
||||||
|
>
|
||||||
|
<template slot-scope="scope">
|
||||||
|
<!--预览--->
|
||||||
|
<el-button
|
||||||
|
circle
|
||||||
|
icon="el-icon-view"
|
||||||
|
:title="$t('trials:uploadImage:button:download')"
|
||||||
|
@click.stop="preview(scope.row)"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
</div>
|
||||||
|
</base-model>
|
||||||
|
</template>
|
||||||
|
<script>
|
||||||
|
import baseModel from '@/components/BaseModel'
|
||||||
|
import { getToken } from '@/utils/auth'
|
||||||
|
export default {
|
||||||
|
name: 'studyView',
|
||||||
|
props: {
|
||||||
|
model_cfg: {
|
||||||
|
type: Object,
|
||||||
|
default: () => {
|
||||||
|
return {}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
modelList: {
|
||||||
|
type: Array,
|
||||||
|
default: () => {
|
||||||
|
return []
|
||||||
|
},
|
||||||
|
},
|
||||||
|
IsDicom: {
|
||||||
|
required: true,
|
||||||
|
type: Boolean,
|
||||||
|
default: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
components: {
|
||||||
|
'base-model': baseModel,
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
// 预览
|
||||||
|
preview(row) {
|
||||||
|
let routeData = null
|
||||||
|
if (this.IsDicom) {
|
||||||
|
var token = getToken()
|
||||||
|
routeData = this.$router.resolve({
|
||||||
|
path: `/showdicom?studyId=${row.Id}&TokenKey=${token}&type=Study`,
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
let trialId = this.$route.query.trialId
|
||||||
|
var token = getToken()
|
||||||
|
routeData = this.$router.resolve({
|
||||||
|
path: `/showNoneDicoms?trialId=${trialId}&subjectVisitId=${row.SourceSubjectVisitId}&studyId=${row.Id}&TokenKey=${token}`,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
window.open(routeData.href, '_blank')
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
</style>
|
||||||
|
|
@ -102,7 +102,6 @@
|
||||||
import uploadList from "./components/upload-list.vue";
|
import uploadList from "./components/upload-list.vue";
|
||||||
import studyView from "./components/study-view.vue";
|
import studyView from "./components/study-view.vue";
|
||||||
import { getSubjectImageUploadList, deleteTaskStudy } from "@/api/load.js";
|
import { getSubjectImageUploadList, deleteTaskStudy } from "@/api/load.js";
|
||||||
import { downloadImage } from "@/utils/uploadZip.js";
|
|
||||||
import store from "@/store";
|
import store from "@/store";
|
||||||
export default {
|
export default {
|
||||||
name: "uploadImage",
|
name: "uploadImage",
|
||||||
|
|
@ -591,7 +590,7 @@ export default {
|
||||||
files.push(obj);
|
files.push(obj);
|
||||||
}
|
}
|
||||||
store.dispatch("trials/setUnLock", true);
|
store.dispatch("trials/setUnLock", true);
|
||||||
let res = await downloadImage(zipName, files);
|
// let res = await downloadImage(zipName, files);
|
||||||
store.dispatch("trials/setUnLock", false);
|
store.dispatch("trials/setUnLock", false);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
|
||||||
35
src/main.js
35
src/main.js
|
|
@ -28,25 +28,22 @@ Vue.use(permission)
|
||||||
|
|
||||||
import Viewer from 'v-viewer'
|
import Viewer from 'v-viewer'
|
||||||
import './assets/css/viewer.css'
|
import './assets/css/viewer.css'
|
||||||
|
|
||||||
Vue.use(Viewer)
|
|
||||||
Viewer.setDefaults({
|
Viewer.setDefaults({
|
||||||
Options: {
|
// navbar: true, //底部缩略图
|
||||||
'inline': true,
|
toolbar: {
|
||||||
'button': true,
|
zoomIn: true,
|
||||||
'navbar': true,
|
zoomOut: true,
|
||||||
'title': true,
|
reset: true,
|
||||||
'toolbar': true,
|
prev: true,
|
||||||
'tooltip': true,
|
next: true,
|
||||||
'movable': true,
|
rotateLeft: true,
|
||||||
'zoomable': true,
|
rotateRight: true,
|
||||||
'rotatable': true,
|
flipHorizontal: true,
|
||||||
'scalable': true,
|
flipVertical: true,
|
||||||
'transition': true,
|
|
||||||
'keyboard': true,
|
|
||||||
'url': 'data-source'
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
Vue.use(Viewer)
|
||||||
|
|
||||||
|
|
||||||
import hasPermi from './directive/permission'
|
import hasPermi from './directive/permission'
|
||||||
Vue.use(hasPermi)
|
Vue.use(hasPermi)
|
||||||
|
|
@ -148,6 +145,12 @@ Vue.config.productionTip = false
|
||||||
Vue.prototype.$upload = () => {
|
Vue.prototype.$upload = () => {
|
||||||
_vm.$forceUpdate()
|
_vm.$forceUpdate()
|
||||||
}
|
}
|
||||||
|
Vue.prototype.$guid = () => {
|
||||||
|
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
|
||||||
|
var r = Math.random() * 16 | 0, v = c == 'x' ? r : (r & 0x3 | 0x8);
|
||||||
|
return v.toString(16);
|
||||||
|
});
|
||||||
|
}
|
||||||
Vue.prototype.fileToBlob = (file) => {
|
Vue.prototype.fileToBlob = (file) => {
|
||||||
// 创建 FileReader 对象
|
// 创建 FileReader 对象
|
||||||
const reader = new FileReader()
|
const reader = new FileReader()
|
||||||
|
|
|
||||||
|
|
@ -6,11 +6,12 @@ import 'nprogress/nprogress.css'
|
||||||
import { getToken } from '@/utils/auth'
|
import { getToken } from '@/utils/auth'
|
||||||
import Vue from 'vue'
|
import Vue from 'vue'
|
||||||
import { OSSclient } from './utils/oss'
|
import { OSSclient } from './utils/oss'
|
||||||
|
import WHITELIST from "./utils/whiteList"
|
||||||
// import getPageTitle from '@/utils/get-page-title'
|
// import getPageTitle from '@/utils/get-page-title'
|
||||||
|
|
||||||
NProgress.configure({ showSpinner: false })
|
NProgress.configure({ showSpinner: false })
|
||||||
|
|
||||||
const whiteList = ['/ReviewersResearch', '/login', '/error', '/resetpassword', '/recompose', '/email-recompose', '/trialStats', '/showdicom', '/imagesShare', '/audit', '/preview', '/researchLogin', '/researchLogin_m', '/blindResumeInfo', '/trialsResume', '/joinVerify', '/showNoneDicoms', '/noneDicomReading', '/clinicalData', '/readingDicoms', '/readingPage', '/visitDicomReview', '/visitNondicomReview', '/globalReview', '/adReview', '/oncologyReview', '/nonedicoms']
|
const whiteList = WHITELIST
|
||||||
store.state.trials.whiteList = whiteList;
|
store.state.trials.whiteList = whiteList;
|
||||||
router.beforeEach(async (to, from, next) => {
|
router.beforeEach(async (to, from, next) => {
|
||||||
NProgress.start()
|
NProgress.start()
|
||||||
|
|
@ -25,15 +26,15 @@ router.beforeEach(async (to, from, next) => {
|
||||||
if (to.path === '/login' || to.path === '/recompose' || to.path === '/email-recompose' || to.path === '/error' || to.path === '/ReviewersResearchForm' || to.path === '/ReviewersResearch') {
|
if (to.path === '/login' || to.path === '/recompose' || to.path === '/email-recompose' || to.path === '/error' || to.path === '/ReviewersResearchForm' || to.path === '/ReviewersResearch') {
|
||||||
if (to.path === '/ReviewersResearch') {
|
if (to.path === '/ReviewersResearch') {
|
||||||
await this.$store.dispatch('user/logout')
|
await this.$store.dispatch('user/logout')
|
||||||
OSSclient()
|
await OSSclient()
|
||||||
}
|
}
|
||||||
if (to.path === '/ReviewersResearchForm') {
|
if (to.path === '/ReviewersResearchForm') {
|
||||||
OSSclient()
|
await OSSclient()
|
||||||
}
|
}
|
||||||
next()
|
next()
|
||||||
NProgress.done()
|
NProgress.done()
|
||||||
} else {
|
} else {
|
||||||
OSSclient()
|
await OSSclient()
|
||||||
const hasGetUserInfo = store.getters.userId
|
const hasGetUserInfo = store.getters.userId
|
||||||
if (hasGetUserInfo) {
|
if (hasGetUserInfo) {
|
||||||
next()
|
next()
|
||||||
|
|
@ -66,7 +67,7 @@ router.beforeEach(async (to, from, next) => {
|
||||||
} else {
|
} else {
|
||||||
// 在免登录whiteList中,直接进入
|
// 在免登录whiteList中,直接进入
|
||||||
if (to.path === '/readingDicoms' || to.path === '/noneDicomReading') {
|
if (to.path === '/readingDicoms' || to.path === '/noneDicomReading') {
|
||||||
OSSclient()
|
await OSSclient()
|
||||||
}
|
}
|
||||||
next()
|
next()
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -35,26 +35,50 @@ const getDefaultState = () => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
function getQuestions(questions) {
|
function getQuestions(questions) {
|
||||||
|
const criterionType = parseInt(localStorage.getItem('CriterionType'))
|
||||||
questions.forEach(item => {
|
questions.forEach(item => {
|
||||||
if (item.Type === 'table' && item.TableQuestions && item.TableQuestions.Answers.length > 0) {
|
if (item.Type === 'table' && item.TableQuestions && item.TableQuestions.Answers.length > 0) {
|
||||||
item.TableQuestions.Answers.forEach(answerObj => {
|
item.TableQuestions.Answers.forEach(answerObj => {
|
||||||
|
answerObj.isDicomReading = answerObj.IsDicomReading === 'True'
|
||||||
|
|
||||||
|
if (answerObj.RowId) {
|
||||||
|
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.lesionPart = getQuestionAnswer(item.TableQuestions.Questions, 8, answerObj)
|
||||||
answerObj.loctation = getQuestionAnswer(item.TableQuestions.Questions, 6, answerObj)
|
answerObj.loctation = getQuestionAnswer(item.TableQuestions.Questions, 6, answerObj)
|
||||||
answerObj.lesionLength = getQuestionAnswer(item.TableQuestions.Questions, 0, answerObj)
|
answerObj.lesionLength = getQuestionAnswer(item.TableQuestions.Questions, 0, answerObj)
|
||||||
answerObj.lesionShort = getQuestionAnswer(item.TableQuestions.Questions, 1, answerObj)
|
answerObj.lesionShort = getQuestionAnswer(item.TableQuestions.Questions, 1, answerObj)
|
||||||
answerObj.isDicomReading = answerObj.IsDicomReading === 'True'
|
let isLymphLesion = getQuestionAnswer(item.TableQuestions.Questions, 2, answerObj)
|
||||||
var isLymphLesion = getQuestionAnswer(item.TableQuestions.Questions, 2, answerObj)
|
|
||||||
isLymphLesion = isLymphLesion ? parseInt(isLymphLesion) : null
|
isLymphLesion = isLymphLesion ? parseInt(isLymphLesion) : null
|
||||||
answerObj.isLymphLesion = isLymphLesion
|
answerObj.isLymphLesion = isLymphLesion
|
||||||
answerObj.lesionState = getQuestionAnswer(item.TableQuestions.Questions, 7, answerObj)
|
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) {
|
|
||||||
// pcwg
|
|
||||||
answerObj.saveTypeEnum = isNaN(parseInt(answerObj.lesionNum)) ? 1 : 2
|
|
||||||
} else {
|
|
||||||
answerObj.saveTypeEnum = isNaN(parseInt(answerObj.lesionState)) ? 1 : 2
|
answerObj.saveTypeEnum = isNaN(parseInt(answerObj.lesionState)) ? 1 : 2
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -811,10 +835,17 @@ const actions = {
|
||||||
// }
|
// }
|
||||||
series.InstanceInfoList.forEach(instance => {
|
series.InstanceInfoList.forEach(instance => {
|
||||||
if (instance.NumberOfFrames && instance.NumberOfFrames > 1) {
|
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++) {
|
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}`
|
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)
|
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}`
|
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 {
|
} 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}`
|
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}`
|
||||||
|
|
@ -1053,7 +1084,10 @@ const actions = {
|
||||||
return new Promise(resolve => {
|
return new Promise(resolve => {
|
||||||
var isReadingTaskViewInOrder = localStorage.getItem('isReadingTaskViewInOrder')
|
var isReadingTaskViewInOrder = localStorage.getItem('isReadingTaskViewInOrder')
|
||||||
if (parseInt(isReadingTaskViewInOrder) === 2) {
|
if (parseInt(isReadingTaskViewInOrder) === 2) {
|
||||||
if (!state.lastCanvasTaskId) state.lastCanvasTaskId = taskId
|
if (!state.lastCanvasTaskId) {
|
||||||
|
console.log('setLastCanvasTaskId')
|
||||||
|
state.lastCanvasTaskId = taskId
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
state.lastCanvasTaskId = taskId
|
state.lastCanvasTaskId = taskId
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@ const getDefaultState = () => {
|
||||||
studyListQuery: null,
|
studyListQuery: null,
|
||||||
unlock: false,
|
unlock: false,
|
||||||
config: {},
|
config: {},
|
||||||
uploadTip: null,
|
uploadTip: '0.00KB/s',
|
||||||
timer: null,
|
timer: null,
|
||||||
whiteList: [],
|
whiteList: [],
|
||||||
checkTaskId: null
|
checkTaskId: null
|
||||||
|
|
|
||||||
|
|
@ -1,14 +1,14 @@
|
||||||
import Vue from 'vue'
|
import Vue from 'vue'
|
||||||
import { anonymization } from './anonymization'
|
import { anonymization } from './anonymization'
|
||||||
export const dcmUpload = async function (name, file, config) {
|
export const dcmUpload = async function (data, config, progressFn) {
|
||||||
return new Promise(async resolve => {
|
return new Promise(async resolve => {
|
||||||
try {
|
try {
|
||||||
// let blob = await encoder(file, config)
|
// let blob = await encoder(file, config)
|
||||||
let blob = await fileToBlob(file)
|
let blob = await fileToBlob(data.file)
|
||||||
if (config) {
|
if (config) {
|
||||||
blob = await anonymization(file, config)
|
blob = await anonymization(data.file, config)
|
||||||
}
|
}
|
||||||
let res = await Vue.prototype.OSSclient.put(name, blob.blob)
|
let res = await Vue.prototype.OSSclient.multipartUpload(Object.assign(data, { file: blob.blob }), progressFn)
|
||||||
resolve({
|
resolve({
|
||||||
...res,
|
...res,
|
||||||
image: blob.pixelDataElement
|
image: blob.pixelDataElement
|
||||||
|
|
@ -19,7 +19,7 @@ export const dcmUpload = async function (name, file, config) {
|
||||||
|
|
||||||
|
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.log(file, 'warning')
|
console.log(data.file, 'warning')
|
||||||
resolve(false)
|
resolve(false)
|
||||||
console.log(e)
|
console.log(e)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,457 @@
|
||||||
|
const {
|
||||||
|
CreateMultipartUploadCommand,
|
||||||
|
UploadPartCommand,
|
||||||
|
CompleteMultipartUploadCommand,
|
||||||
|
ListMultipartUploadsCommand,//bucket中正在上传的文件列表
|
||||||
|
ListPartsCommand,//列出文件已上传的分片
|
||||||
|
GetObjectCommand,//获取文件
|
||||||
|
} = require("@aws-sdk/client-s3");
|
||||||
|
import SparkMD5 from "./spark-md5.min.js";
|
||||||
|
import store from "@/store";
|
||||||
|
let timer = null, // 网速定时器
|
||||||
|
bytesReceivedPerSecond = {}; // 时间节点上传文件总量
|
||||||
|
export function AWSclose() {
|
||||||
|
if (timer) {
|
||||||
|
clearInterval(timer);
|
||||||
|
timer = null;
|
||||||
|
store.state.trials.uploadTip = '0KB/s'
|
||||||
|
}
|
||||||
|
bytesReceivedPerSecond = {};
|
||||||
|
}
|
||||||
|
//查询文件是否存在于bucket或者正在上传
|
||||||
|
export async function exist(s3, bucket, fileInformation, progressFn, changeStatus) {
|
||||||
|
// 拿到上传到的file
|
||||||
|
const File = fileInformation.file;
|
||||||
|
// 拿到上传的size
|
||||||
|
const uploadFileSize = File.size; // 这里拿到的单位是字节(uploadFileSize/ 1024 / 1024
|
||||||
|
// = 多少兆)
|
||||||
|
// 设置每一片的大小,shardSize 指定上传的每个分片的大小,范围为100 KB~5 GB。
|
||||||
|
// 分片标准为5MB,文件总大小大于5GB分片为20MB
|
||||||
|
let shardSize = 5 * 1024 * 1024;
|
||||||
|
if (uploadFileSize < shardSize) {
|
||||||
|
shardSize = uploadFileSize;
|
||||||
|
}
|
||||||
|
if (uploadFileSize > 5 * 1024 * 1024 * 1024) {
|
||||||
|
shardSize = 20 * 1024 * 1024;
|
||||||
|
}
|
||||||
|
fileInformation = Object.assign({
|
||||||
|
shardSize,
|
||||||
|
sharding: []
|
||||||
|
}, fileInformation)
|
||||||
|
if (fileInformation.speed) {
|
||||||
|
setTimer();
|
||||||
|
}
|
||||||
|
// 1、查询该文件是否已上传到bucket
|
||||||
|
//判断sharding里面是否有东西,有东西证明已经上传过分片了,不需要再进行检测
|
||||||
|
if (fileInformation.sharding.length === 0) {
|
||||||
|
let existBucket = await existInBucket({ s3, bucket, fileInformation: fileInformation });
|
||||||
|
if (existBucket === 'true') {
|
||||||
|
progressFn(0, fileInformation.file, 1);
|
||||||
|
changeStatus(fileInformation.path, 'success');//直接告诉前端,状态
|
||||||
|
return;
|
||||||
|
} else if (existBucket === 'same key') {
|
||||||
|
console.log(fileInformation.path + " bucket中存在同名不同内容的文件");
|
||||||
|
} else if (existBucket === 'not exist') {
|
||||||
|
console.log(fileInformation.path + " bucket中不存在该文件");
|
||||||
|
}
|
||||||
|
//2、查询该文件是否存在上传事件
|
||||||
|
let upload = await existUpload({ s3, bucket: bucket, fileInformation: fileInformation });
|
||||||
|
if (upload.code === 0) {
|
||||||
|
//存在该上传事件并且已经上传了多个分片
|
||||||
|
console.log(fileInformation.path + " 存在上传事件,并已经上传多个分片");
|
||||||
|
//将分片存入sharding
|
||||||
|
const uploadId = upload.uploadId;
|
||||||
|
let parts = upload.parts;
|
||||||
|
let SIZE = 0;
|
||||||
|
for (let i = 0; i < parts.length; i++) {
|
||||||
|
SIZE += parts[i].Size;
|
||||||
|
fileInformation.sharding.push({ ETag: parts[i].ETag, PartNumber: parts[i].PartNumber, Size: parts[i].Size, UploadId: uploadId });
|
||||||
|
}
|
||||||
|
progressFn(SIZE / uploadFileSize, { fileSize: uploadFileSize }, 0);//告诉前端,加入分片
|
||||||
|
//重新上传
|
||||||
|
await uploadFile({ fileInformation: fileInformation, uploadId: uploadId, bucket, changeStatus, getSuspend, progressFn });
|
||||||
|
} else if (upload.code === 1) {
|
||||||
|
// //重名但是不同文件
|
||||||
|
console.log('err 重名文件')
|
||||||
|
changeStatus(fileInformation.path, 'same key');
|
||||||
|
} else if (upload.code === 2) {
|
||||||
|
//没有上传事件
|
||||||
|
console.log(fileInformation.path + " 不存在上传事件");
|
||||||
|
//建立分段上传事件
|
||||||
|
const connect = await createMultipartUpload({ s3, bucket: bucket, key: fileInformation.path, type: fileInformation.file.type });
|
||||||
|
//上传整个文件
|
||||||
|
await uploadFile({ s3, fileInformation: fileInformation, uploadId: connect.UploadId, bucket: bucket, changeStatus, progressFn });
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
//分片组里面有东西
|
||||||
|
//重新上传
|
||||||
|
await uploadFile({ s3, fileInformation: fileInformation, uploadId: fileInformation.sharding[0].UploadId, bucket, changeStatus, progressFn });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//上传文件未上传的所有分片
|
||||||
|
async function uploadFile({ s3, fileInformation, uploadId, bucket, changeStatus, progressFn }) {// file:上传文件, uploadId parts:已上传的分片
|
||||||
|
const chunkCount = Math.ceil(fileInformation.file.size / fileInformation.shardSize)//总分片数
|
||||||
|
//循环切片并上传
|
||||||
|
for (let i = 0; i < chunkCount; i++) {
|
||||||
|
let start = i * fileInformation.shardSize;//文件分片开始位置
|
||||||
|
let end = Math.min(fileInformation.file.size, start + fileInformation.shardSize)//文件分片结束位置
|
||||||
|
let _chunkFile = fileInformation.file.slice(start, end);//切片文件 即 待上传文件分片
|
||||||
|
//判断parts中是否存在该分片
|
||||||
|
let res1 = fileInformation.sharding.filter((part) => {
|
||||||
|
return part.PartNumber === (i + 1);
|
||||||
|
});
|
||||||
|
if (res1.length === 0) {
|
||||||
|
//不包含该分片
|
||||||
|
const upload = await uploadPart({ s3, f: _chunkFile, uploadId: uploadId, key: fileInformation.path, bucket: bucket, num: i + 1 });//将分片上传
|
||||||
|
//判断sharding中是否存在该分片,如果不存在的话,才判错
|
||||||
|
let res2 = fileInformation.sharding.filter((part) => {
|
||||||
|
return part.PartNumber === (i + 1);
|
||||||
|
});
|
||||||
|
if (res2.length === 0) {
|
||||||
|
if (upload !== 'err') {//上传分片成功,并且没有暂停上传
|
||||||
|
//判断是否存在该分片
|
||||||
|
//判断parts中是否存在该分片
|
||||||
|
let res3 = fileInformation.sharding.filter((part) => {
|
||||||
|
return part.PartNumber === (i + 1);
|
||||||
|
});
|
||||||
|
if (res3.length === 0) {
|
||||||
|
let LASTSIZE = fileInformation.sharding.reduce((sum, item) => sum + item.Size, 0)
|
||||||
|
fileInformation.sharding.push({ ETag: upload.ETag, PartNumber: i + 1, Size: _chunkFile.size, UploadId: uploadId });//上传成功,存到sharding
|
||||||
|
let SIZE = fileInformation.sharding.reduce((sum, item) => sum + item.Size, 0)
|
||||||
|
let lastPercentage = LASTSIZE / fileInformation.file.size, percentage = SIZE / fileInformation.file.size;
|
||||||
|
progressFn(percentage, fileInformation.file, lastPercentage);
|
||||||
|
if (fileInformation.speed) {
|
||||||
|
let time = new Date().getTime();
|
||||||
|
let timeList = Object.keys(bytesReceivedPerSecond).sort((a, b) => a - b);
|
||||||
|
let bytesTime = timeList.find(item => time - item < 1000);
|
||||||
|
if (bytesTime) {
|
||||||
|
bytesReceivedPerSecond[bytesTime] += fileInformation.file.size * (percentage - lastPercentage);
|
||||||
|
} else {
|
||||||
|
console.log("未查询到时间")
|
||||||
|
if (timeList.length > 0) {
|
||||||
|
bytesReceivedPerSecond[timeList[timeList.length - 1]] += fileInformation.file.size * (percentage - lastPercentage);
|
||||||
|
} else {
|
||||||
|
bytesReceivedPerSecond[time] = fileInformation.file.size * (percentage - lastPercentage);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (upload === 'err') {
|
||||||
|
changeStatus(fileInformation.path, 'err');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}//for
|
||||||
|
if (fileInformation.sharding.length === chunkCount) {
|
||||||
|
//合并分片
|
||||||
|
const complete = await completeMultipartUpload({ s3, bucket: bucket, key: fileInformation.path, sharding: fileInformation.sharding, uploadId: uploadId });
|
||||||
|
if (complete !== 'err') {
|
||||||
|
changeStatus(fileInformation.path, 'success');//通知前端,上传成功
|
||||||
|
} else {
|
||||||
|
changeStatus(fileInformation.path, 'err');//通知前端,上传失败
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 判断该文件是否已经存在于bucket
|
||||||
|
// bucket file:上传文件
|
||||||
|
// 返回值 'same key':同名不同文件 'not exist':不存在该文件 'true':该文件已存在bucket中
|
||||||
|
async function existInBucket({ s3, bucket, fileInformation }) {
|
||||||
|
if (s3 === null) {
|
||||||
|
return console.log("未创建s3客户端,请先调用init事件");
|
||||||
|
}
|
||||||
|
//getObject 每次最多传回767448b的数据,所以要分段请求
|
||||||
|
let bucketFileUniArray = [];
|
||||||
|
// 分段
|
||||||
|
let count = Math.ceil(fileInformation.file.size / 767448);
|
||||||
|
if (count > 4) {
|
||||||
|
count = 4;
|
||||||
|
}
|
||||||
|
for (let i = 0; i < count; i++) {
|
||||||
|
const obj = await getObject({ s3, bucket: bucket, fileInformation: fileInformation, count: i });
|
||||||
|
if (obj !== 'err') {
|
||||||
|
//获取文件的文件体 计算某个分片的md5
|
||||||
|
const fileBody = obj.Body;
|
||||||
|
let fileUnitArray = await fileBody.transformToByteArray();
|
||||||
|
bucketFileUniArray = [...bucketFileUniArray, ...fileUnitArray];
|
||||||
|
} else {
|
||||||
|
return 'not exist';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let bucketFileBufferArray = new Uint8Array(bucketFileUniArray);
|
||||||
|
// 将传入文件的fileReader 转成 arrayBuffer
|
||||||
|
let fileArrayBuff = null;
|
||||||
|
fileArrayBuff = await new Promise((resolve) => {
|
||||||
|
let fileReader = new FileReader();
|
||||||
|
fileReader.readAsArrayBuffer(fileInformation.file.slice(0, count * 767448));
|
||||||
|
fileReader.onload = (e) => {
|
||||||
|
resolve(e.target.result);
|
||||||
|
};
|
||||||
|
});
|
||||||
|
if (fileArrayBuff.byteLength > count * 767448) {
|
||||||
|
fileArrayBuff = fileArrayBuff.slice(0, count * 767448);
|
||||||
|
}
|
||||||
|
let bodyMD5 = await getMD5({ arrayBuffer: bucketFileBufferArray.buffer });
|
||||||
|
let fileMD5 = await getMD5({ arrayBuffer: fileArrayBuff });
|
||||||
|
if (bodyMD5 === fileMD5) {
|
||||||
|
//证明是同一个文件 秒传
|
||||||
|
return 'true';
|
||||||
|
} else {
|
||||||
|
return 'same key';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//判断该文件是否正在上传
|
||||||
|
// bucket:bucket file:上传文件
|
||||||
|
//返回值 'not exist upload':不存在上传事件 'same key':同名不同文件
|
||||||
|
async function existUpload({ s3, bucket, fileInformation }) {
|
||||||
|
//判断该文件是否有上传事件
|
||||||
|
const listUploads = await listMultipartUploadsCommand({ s3, bucket: bucket, key: fileInformation.path });
|
||||||
|
if (listUploads !== 'err') {
|
||||||
|
if (listUploads.Uploads !== undefined && listUploads.Uploads.length > 0) {
|
||||||
|
//存在上传事件 获取上传的第一个分片的eTag,计算传入文件md5,相比较是否相同
|
||||||
|
const uploads = listUploads.Uploads;
|
||||||
|
for (const one in uploads) {//可能存在多个连接
|
||||||
|
let uploadOne = uploads[one];
|
||||||
|
const uploadId = uploadOne.UploadId;//UploadId
|
||||||
|
const key = uploadOne.Key;//key
|
||||||
|
//查询该文件已上传分片
|
||||||
|
const listParts = await listPartsCommand({ s3, bucket: bucket, key: key, uploadId: uploadId });
|
||||||
|
if (listParts !== 'err') {
|
||||||
|
if (listParts.Parts !== undefined && listParts.Parts.length !== 0) {
|
||||||
|
//存在分片
|
||||||
|
let etag = listParts.Parts[0].ETag;
|
||||||
|
//计算文件的第一个分片的md5
|
||||||
|
let fileSlice = null;
|
||||||
|
if (fileInformation.file.size > fileInformation.shardSize) {
|
||||||
|
fileSlice = fileInformation.file.slice(0, fileInformation.shardSize);
|
||||||
|
} else {
|
||||||
|
fileSlice = fileInformation.file;
|
||||||
|
}
|
||||||
|
let fileMD5 = await new Promise((resolve) => {
|
||||||
|
const fileReader = new FileReader();
|
||||||
|
var spark = new SparkMD5.ArrayBuffer();
|
||||||
|
fileReader.readAsArrayBuffer(fileSlice);
|
||||||
|
fileReader.onload = (e) => {
|
||||||
|
spark.append(e.target.result);
|
||||||
|
var m = spark.end();
|
||||||
|
resolve(m);
|
||||||
|
};
|
||||||
|
});
|
||||||
|
if (etag.split('"')[1] === fileMD5) {
|
||||||
|
//是同一个文件上传
|
||||||
|
return {
|
||||||
|
code: 0,
|
||||||
|
message: 'true',
|
||||||
|
uploadId: uploadId,
|
||||||
|
key: key,
|
||||||
|
parts: listParts.Parts
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
//同名不同文件
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
//该文件有进行上传,但没有上传完成一个分片
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
//有连接,没上传分片
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}//for
|
||||||
|
return {
|
||||||
|
code: 1,
|
||||||
|
message: 'same key'
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
//无连接
|
||||||
|
return {
|
||||||
|
code: 2,
|
||||||
|
message: 'not exist upload'
|
||||||
|
};
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
//无连接
|
||||||
|
return {
|
||||||
|
code: 2,
|
||||||
|
message: 'not exist upload'
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//计算arrayBuffer的md5值
|
||||||
|
async function getMD5({ arrayBuffer }) {
|
||||||
|
return await new Promise((resolve) => {
|
||||||
|
const spark = new SparkMD5.ArrayBuffer();
|
||||||
|
spark.append(arrayBuffer);
|
||||||
|
const m = spark.end();
|
||||||
|
resolve(m);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
//建立文件上传事件
|
||||||
|
async function createMultipartUpload({ s3, bucket, key, type }) {//bucket:bucket key:文件名 type:文件类型
|
||||||
|
if (s3 === null) {
|
||||||
|
return console.log("未创建s3客户端,请先调用init事件");
|
||||||
|
}
|
||||||
|
const params = {
|
||||||
|
Bucket: bucket,
|
||||||
|
Key: key,
|
||||||
|
ContentType: type
|
||||||
|
};
|
||||||
|
const res = async () => {
|
||||||
|
try {
|
||||||
|
return await s3.send(new CreateMultipartUploadCommand(params));
|
||||||
|
} catch (err) {
|
||||||
|
console.log('建立上传事件失败:', err.message)
|
||||||
|
return 'err';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return res();
|
||||||
|
}
|
||||||
|
|
||||||
|
//上传一个分片
|
||||||
|
async function uploadPart({ s3, f, uploadId, key, bucket, num }) { //f:文件分片,num:分片标号
|
||||||
|
if (s3 === null) {
|
||||||
|
return console.log("未创建s3客户端,请先调用init事件");
|
||||||
|
}
|
||||||
|
const params = {
|
||||||
|
Bucket: bucket,
|
||||||
|
Key: key,
|
||||||
|
PartNumber: num,
|
||||||
|
UploadId: uploadId,
|
||||||
|
Body: f,
|
||||||
|
// ContentDisposition: "attachment; filename=hahaha.dcm"
|
||||||
|
};
|
||||||
|
const res = async () => {
|
||||||
|
try {
|
||||||
|
return await s3.send(new UploadPartCommand(params));
|
||||||
|
} catch (err) {
|
||||||
|
console.log('上传分片第 ' + num + ' 片错误信息', err.message)
|
||||||
|
return 'err';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return res();
|
||||||
|
}
|
||||||
|
//将分片合并
|
||||||
|
async function completeMultipartUpload({ s3, bucket, key, sharding, uploadId }) {
|
||||||
|
if (s3 === null) {
|
||||||
|
return console.log("未创建s3客户端,请先调用init事件");
|
||||||
|
}
|
||||||
|
let parts = [];
|
||||||
|
for (let i = 0; i < sharding.length; i++) {
|
||||||
|
parts.push({
|
||||||
|
"ETag": sharding[i].ETag,
|
||||||
|
"PartNumber": sharding[i].PartNumber,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
const params = {
|
||||||
|
Bucket: bucket,
|
||||||
|
Key: key,
|
||||||
|
MultipartUpload: {
|
||||||
|
Parts: parts
|
||||||
|
},
|
||||||
|
UploadId: uploadId
|
||||||
|
};
|
||||||
|
const res = async () => {
|
||||||
|
try {
|
||||||
|
return await s3.send(new CompleteMultipartUploadCommand(params))
|
||||||
|
} catch (err) {
|
||||||
|
console.log("合并分片失败: ", err.message);
|
||||||
|
return 'err';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return res();
|
||||||
|
}
|
||||||
|
|
||||||
|
//查询某个文件已经上传的所有分片
|
||||||
|
async function listPartsCommand({ s3, bucket, key, uploadId }) {
|
||||||
|
if (s3 === null) {
|
||||||
|
return console.log("未创建s3客户端,请先调用init事件");
|
||||||
|
}
|
||||||
|
const params = {
|
||||||
|
Bucket: bucket,
|
||||||
|
Key: key,
|
||||||
|
UploadId: uploadId
|
||||||
|
};
|
||||||
|
const res = async () => {
|
||||||
|
try {
|
||||||
|
return await s3.send(new ListPartsCommand(params));
|
||||||
|
} catch (err) {
|
||||||
|
console.log("查询该文件已上传分片失败: " + err.message);
|
||||||
|
return 'err';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return res();
|
||||||
|
}
|
||||||
|
//查询该文件是否存在上传事件
|
||||||
|
async function listMultipartUploadsCommand({ s3, bucket, key }) {
|
||||||
|
if (s3 === null) {
|
||||||
|
return console.log("未创建s3客户端,请先调用init事件");
|
||||||
|
}
|
||||||
|
const params = {
|
||||||
|
Bucket: bucket,
|
||||||
|
Delimiter: '',
|
||||||
|
MaxUploads: 1000,
|
||||||
|
Prefix: key
|
||||||
|
};
|
||||||
|
const res = async () => {
|
||||||
|
try {
|
||||||
|
return await s3.send(new ListMultipartUploadsCommand(params));
|
||||||
|
} catch (err) {
|
||||||
|
console.log("查询 " + key + " 文件是否存在上传事件失败: " + err.message);
|
||||||
|
return 'err';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return res();
|
||||||
|
}
|
||||||
|
//获取文件
|
||||||
|
async function getObject({ s3, bucket, fileInformation, count }) {
|
||||||
|
//一次请求最多 767448
|
||||||
|
if (s3 === null) {
|
||||||
|
return console.log("未创建s3客户端,请先调用init事件");
|
||||||
|
}
|
||||||
|
let byte1 = ((count + 1) * 767448 - 1) > fileInformation.file.size ? fileInformation.file.size : ((count + 1) * 767448 - 1);
|
||||||
|
let byte2 = (count * 767448) > fileInformation.file.size ? fileInformation.file.size : (count * 767448);
|
||||||
|
let range = "bytes=" + byte2 + "-" + byte1;
|
||||||
|
const params = {
|
||||||
|
Bucket: bucket,
|
||||||
|
Key: fileInformation.path,
|
||||||
|
Range: range
|
||||||
|
};
|
||||||
|
const res = async () => {
|
||||||
|
try {
|
||||||
|
return await s3.send(new GetObjectCommand(params));
|
||||||
|
} catch (err) {
|
||||||
|
console.log('获取 ' + fileInformation.path + ' 文件失败:', err.message);
|
||||||
|
return 'err';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return res();
|
||||||
|
}
|
||||||
|
function setTimer() {
|
||||||
|
if (timer) return false;
|
||||||
|
timer = setInterval(() => {
|
||||||
|
let timeList = Object.keys(bytesReceivedPerSecond).sort((a, b) => a - b);
|
||||||
|
if (timeList.length > 0) {
|
||||||
|
let totalBytes = timeList.reduce((sum, bytes) => sum + bytesReceivedPerSecond[bytes], 0) / (5 * 1024);
|
||||||
|
let unit = 'KB/s';
|
||||||
|
if (totalBytes > 1024) {
|
||||||
|
totalBytes = totalBytes / 1024;
|
||||||
|
unit = "MB/s";
|
||||||
|
}
|
||||||
|
store.state.trials.uploadTip = totalBytes.toFixed(2) + unit;
|
||||||
|
}
|
||||||
|
if (timeList.length >= 5) {
|
||||||
|
delete bytesReceivedPerSecond[timeList[0]]
|
||||||
|
}
|
||||||
|
let time = new Date().getTime();
|
||||||
|
bytesReceivedPerSecond[time] = 0;
|
||||||
|
}, 1000)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
@ -0,0 +1,156 @@
|
||||||
|
import moment from "moment";
|
||||||
|
import store from "@/store";
|
||||||
|
let savaData = {},
|
||||||
|
checkData = {}, // 当前上传的节点文件和上一次提交进度
|
||||||
|
timer = null, // 网速定时器
|
||||||
|
bytesReceivedPerSecond = {}; // 时间节点上传文件总量
|
||||||
|
export function OSSclose() {
|
||||||
|
if (timer) {
|
||||||
|
clearInterval(timer);
|
||||||
|
timer = null;
|
||||||
|
store.state.trials.uploadTip = '0KB/s'
|
||||||
|
}
|
||||||
|
bytesReceivedPerSecond = {};
|
||||||
|
savaData = {};
|
||||||
|
checkData = {};
|
||||||
|
saveFinishedData(savaData);
|
||||||
|
}
|
||||||
|
export async function customerHttp(OSSclient, data, progressFn) {
|
||||||
|
// 拿到上传到的file
|
||||||
|
const uploadFile = data.file;
|
||||||
|
// 拿到上传的size
|
||||||
|
const uploadFileSize = uploadFile.size; // 这里拿到的单位是字节(uploadFileSize/ 1024 / 1024
|
||||||
|
// = 多少兆)
|
||||||
|
// 设置每一片的大小,partSize 指定上传的每个分片的大小,范围为100 KB~5 GB。
|
||||||
|
// 分片标准为5MB,文件总大小大于5GB分片为20MB
|
||||||
|
let partSize = 5 * 1024 * 1024;
|
||||||
|
if (uploadFileSize < partSize) {
|
||||||
|
partSize = uploadFileSize;
|
||||||
|
}
|
||||||
|
if (uploadFileSize > 5 * 1024 * 1024 * 1024) {
|
||||||
|
partSize = 20 * 1024 * 1024;
|
||||||
|
}
|
||||||
|
// 设置所有的文件上传所有的唯一的saveFileId
|
||||||
|
const saveFileId = `${uploadFileSize}_${data.path}`;
|
||||||
|
if (data.speed) {
|
||||||
|
setTimer();
|
||||||
|
}
|
||||||
|
initPage();
|
||||||
|
let res = await multipartUpload(OSSclient, partSize, saveFileId, uploadFile, data, progressFn);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function multipartUpload(OSSclient, partSize, saveFileId, uploadFile, data, progressFn) {
|
||||||
|
try {
|
||||||
|
// object-name目前我是用的uploadFile.name,其实也是要根据你们的项目而定,
|
||||||
|
// 有没有具体的规定, 要不要加项目名, 要不要加对应的环境;
|
||||||
|
// 上传的参数
|
||||||
|
const uploadParams = {
|
||||||
|
partSize,
|
||||||
|
progress: (percentage, checkpoint) => {
|
||||||
|
savaData[saveFileId] = checkpoint;
|
||||||
|
if (!checkData[saveFileId]) {
|
||||||
|
checkData[saveFileId] = 0
|
||||||
|
}
|
||||||
|
if (data.speed) {
|
||||||
|
let time = new Date().getTime();
|
||||||
|
let timeList = Object.keys(bytesReceivedPerSecond).sort((a, b) => a - b);
|
||||||
|
let bytesTime = timeList.find(item => time - item < 1000);
|
||||||
|
if (bytesTime) {
|
||||||
|
bytesReceivedPerSecond[bytesTime] += data.file.size * (percentage - checkData[saveFileId]);
|
||||||
|
} else {
|
||||||
|
// console.log("未查询到时间")
|
||||||
|
if (timeList.length > 0) {
|
||||||
|
bytesReceivedPerSecond[timeList[timeList.length - 1]] += data.file.size * (percentage - checkData[saveFileId]);
|
||||||
|
} else {
|
||||||
|
bytesReceivedPerSecond[time] = data.file.size * (percentage - checkData[saveFileId]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
savaData["lastSaveTime"] = new Date();
|
||||||
|
progressFn(percentage, data.file, checkData[saveFileId])
|
||||||
|
checkData[saveFileId] = percentage;
|
||||||
|
if (percentage === 1) {
|
||||||
|
delete checkData[saveFileId]
|
||||||
|
}
|
||||||
|
// 在上传过程中,把已经上传的数据存储下来
|
||||||
|
saveFinishedData(savaData);
|
||||||
|
},
|
||||||
|
// headers: {
|
||||||
|
// "Content-Disposition": `attachment; filename=hahaha.dcm`,
|
||||||
|
// "Cache-Control": "public, no-cache"
|
||||||
|
// }
|
||||||
|
};
|
||||||
|
// 断点续传
|
||||||
|
await resumeUpload(uploadParams, saveFileId);
|
||||||
|
const res = await OSSclient.multipartUpload(
|
||||||
|
data.path,
|
||||||
|
uploadFile,
|
||||||
|
uploadParams
|
||||||
|
);
|
||||||
|
if (res.res.status === 200) {
|
||||||
|
// 重新去掉某个缓存进行设置
|
||||||
|
delete savaData[saveFileId];
|
||||||
|
saveFinishedData(savaData);
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
} catch (e) {
|
||||||
|
console.log(e);
|
||||||
|
// 捕获超时异常。
|
||||||
|
if (e.code === "ConnectionTimeoutError") {
|
||||||
|
console.log("TimeoutError");
|
||||||
|
// do ConnectionTimeoutError operation
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
async function resumeUpload(uploadParams, saveFileId) {
|
||||||
|
if (localStorage.getItem("upload-function-name")) {
|
||||||
|
const obj = JSON.parse(localStorage.getItem("upload-function-name"));
|
||||||
|
if (Object.keys(obj).includes(saveFileId)) {
|
||||||
|
uploadParams.checkpoint = obj[saveFileId];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 存储到内存
|
||||||
|
function saveFinishedData(finishedData) {
|
||||||
|
localStorage.setItem(
|
||||||
|
"upload-function-name",
|
||||||
|
JSON.stringify(finishedData)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
function initPage() {
|
||||||
|
// 判断是不是有缓存
|
||||||
|
const localData = localStorage.getItem("upload-function-name");
|
||||||
|
if (!localData) return;
|
||||||
|
savaData = JSON.parse(localData);
|
||||||
|
// 当前时间 > 存储时间(1000 * 60 * 60表示1h,意思就是这些数据你要存多久,
|
||||||
|
// 可以是1h也可以是多少天,随意)
|
||||||
|
if (
|
||||||
|
moment(new Date()).diff(moment(savaData.lastSaveTime)) >
|
||||||
|
1000 * 60 * 60
|
||||||
|
) {
|
||||||
|
localStorage.removeItem("upload-function-name");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function setTimer() {
|
||||||
|
if (timer) return false;
|
||||||
|
timer = setInterval(() => {
|
||||||
|
// console.log(Object.assign({}, bytesReceivedPerSecond))
|
||||||
|
let timeList = Object.keys(bytesReceivedPerSecond).sort((a, b) => a - b);
|
||||||
|
if (timeList.length > 0) {
|
||||||
|
let totalBytes = timeList.reduce((sum, bytes) => sum + bytesReceivedPerSecond[bytes], 0) / (5 * 1024);
|
||||||
|
let unit = 'KB/s';
|
||||||
|
if (totalBytes > 1024) {
|
||||||
|
totalBytes = totalBytes / 1024;
|
||||||
|
unit = "MB/s";
|
||||||
|
}
|
||||||
|
store.state.trials.uploadTip = totalBytes.toFixed(2) + unit;
|
||||||
|
}
|
||||||
|
if (timeList.length >= 5) {
|
||||||
|
delete bytesReceivedPerSecond[timeList[0]]
|
||||||
|
}
|
||||||
|
let time = new Date().getTime();
|
||||||
|
bytesReceivedPerSecond[time] = 0;
|
||||||
|
}, 1000)
|
||||||
|
}
|
||||||
File diff suppressed because one or more lines are too long
230
src/utils/oss.js
230
src/utils/oss.js
|
|
@ -3,30 +3,32 @@ const router = require('@/router');
|
||||||
const Minio = require('minio')
|
const Minio = require('minio')
|
||||||
const stream = require('stream')
|
const stream = require('stream')
|
||||||
import Vue from 'vue'
|
import Vue from 'vue'
|
||||||
|
import { customerHttp, OSSclose } from "@/utils/multipartUpload/oss"
|
||||||
|
import { exist, AWSclose } from "@/utils/multipartUpload/aws"
|
||||||
const { GetObjectStoreToken } = require('../api/user.js')
|
const { GetObjectStoreToken } = require('../api/user.js')
|
||||||
|
const {
|
||||||
|
S3Client,
|
||||||
|
} = require("@aws-sdk/client-s3");
|
||||||
|
|
||||||
Vue.prototype.OSSclientConfig = {
|
Vue.prototype.OSSclientConfig = {
|
||||||
}
|
}
|
||||||
|
|
||||||
function blobToBuffer(blob, fileName) {
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
const file = new File([blob], fileName);
|
|
||||||
resolve(file)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
async function ossGenerateSTS() {
|
async function ossGenerateSTS() {
|
||||||
let res = await GetObjectStoreToken()
|
let res = await GetObjectStoreToken()
|
||||||
|
// res.Result.ObjectStoreUse = 'AWS';
|
||||||
Vue.prototype.OSSclientConfig = { ...res.Result[res.Result.ObjectStoreUse] }
|
Vue.prototype.OSSclientConfig = { ...res.Result[res.Result.ObjectStoreUse] }
|
||||||
Vue.prototype.OSSclientConfig.ObjectStoreUse = res.Result.ObjectStoreUse;
|
Vue.prototype.OSSclientConfig.ObjectStoreUse = res.Result.ObjectStoreUse;
|
||||||
Vue.prototype.OSSclientConfig.basePath = Vue.prototype.OSSclientConfig.viewEndpoint
|
Vue.prototype.OSSclientConfig.basePath = Vue.prototype.OSSclientConfig.viewEndpoint
|
||||||
switch (res.Result.ObjectStoreUse) {
|
switch (res.Result.ObjectStoreUse) {
|
||||||
case 'AliyunOSS':
|
case 'AliyunOSS':
|
||||||
Vue.prototype.OSSclientConfig.bucket = Vue.prototype.OSSclientConfig.bucketName
|
Vue.prototype.OSSclientConfig.bucket = Vue.prototype.OSSclientConfig.bucketName
|
||||||
|
Vue.prototype.OSSclientConfig.stsToken = Vue.prototype.OSSclientConfig.securityToken
|
||||||
Vue.prototype.OSSclientConfig.timeout = 10 * 60 * 1000
|
Vue.prototype.OSSclientConfig.timeout = 10 * 60 * 1000
|
||||||
let OSSclient = new OSS(Vue.prototype.OSSclientConfig)
|
let OSSclient = new OSS(Vue.prototype.OSSclientConfig)
|
||||||
Vue.prototype.OSSclient = {
|
Vue.prototype.OSSclient = {
|
||||||
put: function (objectName, object) {
|
put: async function (objectName, object) {
|
||||||
|
OSSclient = await RefreshClient(OSSclient)
|
||||||
return new Promise(async (resolve, reject) => {
|
return new Promise(async (resolve, reject) => {
|
||||||
try {
|
try {
|
||||||
let _vm = router.default.app
|
let _vm = router.default.app
|
||||||
|
|
@ -49,6 +51,46 @@ async function ossGenerateSTS() {
|
||||||
reject()
|
reject()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
},
|
||||||
|
multipartUpload: async (data, progress) => {
|
||||||
|
OSSclient = await RefreshClient(OSSclient)
|
||||||
|
return new Promise(async (resolve, reject) => {
|
||||||
|
try {
|
||||||
|
const { file, path } = data;
|
||||||
|
if (!file || !path) return reject('file and path be required');
|
||||||
|
let config = await getSTSToken(Vue.prototype.OSSclientConfig.expiration);
|
||||||
|
if (config) {
|
||||||
|
Vue.prototype.OSSclientConfig = { ...config.Result[config.Result.ObjectStoreUse] }
|
||||||
|
Vue.prototype.OSSclientConfig.ObjectStoreUse = config.Result.ObjectStoreUse;
|
||||||
|
Vue.prototype.OSSclientConfig.basePath = Vue.prototype.OSSclientConfig.viewEndpoint;
|
||||||
|
Vue.prototype.OSSclientConfig.bucket = Vue.prototype.OSSclientConfig.bucketName
|
||||||
|
Vue.prototype.OSSclientConfig.stsToken = Vue.prototype.OSSclientConfig.securityToken
|
||||||
|
Vue.prototype.OSSclientConfig.timeout = 10 * 60 * 1000
|
||||||
|
OSSclient = new OSS(Vue.prototype.OSSclientConfig);
|
||||||
|
}
|
||||||
|
let _vm = router.default.app
|
||||||
|
if (_vm._route.path !== '/trials/trials-panel/visit/crc-upload') {
|
||||||
|
var objectItem = data.path.split('/')
|
||||||
|
objectItem[objectItem.length - 1] = new Date().getTime() + '_' + objectItem[objectItem.length - 1]
|
||||||
|
data.path = objectItem.join('/')
|
||||||
|
}
|
||||||
|
let res = await customerHttp(OSSclient, data, progress);
|
||||||
|
if (res) {
|
||||||
|
resolve({
|
||||||
|
name: data.path,
|
||||||
|
url: Vue.prototype.OSSclientConfig.viewEndpoint + decodeUtf8(res.name)
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
reject()
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
console.log(err)
|
||||||
|
reject(err)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
close: () => {
|
||||||
|
OSSclose();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break
|
break
|
||||||
|
|
@ -86,49 +128,118 @@ async function ossGenerateSTS() {
|
||||||
console.log(e)
|
console.log(e)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
},
|
||||||
|
close: () => {
|
||||||
|
return false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break
|
break
|
||||||
case 'AWS':
|
case 'AWS':
|
||||||
let aws = new Minio.Client(Vue.prototype.OSSclientConfig);
|
Vue.prototype.OSSclientConfig.bucket = Vue.prototype.OSSclientConfig.bucketName
|
||||||
|
let aws = new S3Client({
|
||||||
|
endpoint: Vue.prototype.OSSclientConfig.viewEndpoint,
|
||||||
|
region: Vue.prototype.OSSclientConfig.region,
|
||||||
|
s3ForcePathStyle: true,
|
||||||
|
signatureVersion: 'v4',
|
||||||
|
forcePathStyle: true,
|
||||||
|
// SessionToken: '',
|
||||||
|
credentials: {
|
||||||
|
accessKeyId: Vue.prototype.OSSclientConfig.accessKeyId,
|
||||||
|
secretAccessKey: Vue.prototype.OSSclientConfig.secretAccessKey,
|
||||||
|
sessionToken: Vue.prototype.OSSclientConfig.sessionToken
|
||||||
|
}
|
||||||
|
});
|
||||||
Vue.prototype.OSSclient = {
|
Vue.prototype.OSSclient = {
|
||||||
put: function (objectName, object) {
|
put: async function (objectName, object) {
|
||||||
return new Promise(async (resolve, reject) => {
|
let data = {
|
||||||
try {
|
file: object,
|
||||||
var name = objectName.split('/')[objectName.split('/').length - 1]
|
path: objectName
|
||||||
let _vm = router.default.app
|
|
||||||
if (_vm._route.path !== '/trials/trials-panel/visit/crc-upload') {
|
|
||||||
var objectItem = objectName.split('/')
|
|
||||||
objectItem[objectItem.length - 1] = new Date().getTime() + '_' + objectItem[objectItem.length - 1]
|
|
||||||
objectName = objectItem.join('/')
|
|
||||||
}
|
}
|
||||||
const reader = new FileReader();
|
aws = await RefreshClient(aws);
|
||||||
reader.onload = (ex) => {
|
return uploadAWS(aws, data, () => { });
|
||||||
const bufferStream = new stream.PassThrough()
|
},
|
||||||
bufferStream.end(Buffer.from(ex.target.result))
|
multipartUpload: async (data, progress) => {
|
||||||
aws.putObject(Vue.prototype.OSSclientConfig.bucketName, objectName, bufferStream, function (err, etag) {
|
aws = await RefreshClient(aws);
|
||||||
if (err) {
|
return uploadAWS(aws, data, progress);
|
||||||
console.log(err)
|
},
|
||||||
reject()
|
close: () => {
|
||||||
} else {
|
AWSclose();
|
||||||
console.log(objectName);
|
|
||||||
resolve({
|
|
||||||
name: objectName,
|
|
||||||
url: Vue.prototype.OSSclientConfig.viewEndpoint + decodeUtf8(objectName)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
})
|
|
||||||
};
|
|
||||||
reader.readAsArrayBuffer(object);
|
|
||||||
} catch (e) {
|
|
||||||
console.log(e)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
// AWS上传函数
|
||||||
|
function uploadAWS(aws, data, progress) {
|
||||||
|
return new Promise(async (resolve, reject) => {
|
||||||
|
try {
|
||||||
|
const { file, path } = data;
|
||||||
|
if (!file || !path) return reject('file and path be required');
|
||||||
|
let _vm = router.default.app
|
||||||
|
if (_vm._route.path !== '/trials/trials-panel/visit/crc-upload') {
|
||||||
|
var objectItem = data.path.split('/')
|
||||||
|
objectItem[objectItem.length - 1] = new Date().getTime() + '_' + objectItem[objectItem.length - 1]
|
||||||
|
data.path = objectItem.join('/')
|
||||||
|
}
|
||||||
|
await exist(aws, Vue.prototype.OSSclientConfig.bucket, data, progress, (path, status) => {
|
||||||
|
if (status === 'success') {
|
||||||
|
resolve({
|
||||||
|
name: Vue.prototype.OSSclientConfig.bucket + "/" + decodeUtf8(path),
|
||||||
|
url: Vue.prototype.OSSclientConfig.viewEndpoint + Vue.prototype.OSSclientConfig.bucket + "/" + decodeUtf8(path)
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
reject()
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
} catch (err) {
|
||||||
|
console.log(err)
|
||||||
|
reject(err)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
// client过期刷新
|
||||||
|
async function RefreshClient(client) {
|
||||||
|
let config = await getSTSToken(Vue.prototype.OSSclientConfig.expiration);
|
||||||
|
if (config) {
|
||||||
|
// config.Result.ObjectStoreUse = 'AWS'
|
||||||
|
switch (config.Result.ObjectStoreUse) {
|
||||||
|
case 'AliyunOSS': {
|
||||||
|
Vue.prototype.OSSclientConfig = { ...config.Result[config.Result.ObjectStoreUse] }
|
||||||
|
Vue.prototype.OSSclientConfig.ObjectStoreUse = config.Result.ObjectStoreUse;
|
||||||
|
Vue.prototype.OSSclientConfig.basePath = Vue.prototype.OSSclientConfig.viewEndpoint;
|
||||||
|
Vue.prototype.OSSclientConfig.bucket = Vue.prototype.OSSclientConfig.bucketName
|
||||||
|
Vue.prototype.OSSclientConfig.stsToken = Vue.prototype.OSSclientConfig.securityToken
|
||||||
|
Vue.prototype.OSSclientConfig.timeout = 10 * 60 * 1000
|
||||||
|
return new OSS(Vue.prototype.OSSclientConfig);
|
||||||
|
}
|
||||||
|
case "MinIO": {
|
||||||
|
return client;
|
||||||
|
}
|
||||||
|
case "AWS": {
|
||||||
|
Vue.prototype.OSSclientConfig = { ...config.Result[config.Result.ObjectStoreUse] }
|
||||||
|
Vue.prototype.OSSclientConfig.ObjectStoreUse = config.Result.ObjectStoreUse;
|
||||||
|
Vue.prototype.OSSclientConfig.basePath = Vue.prototype.OSSclientConfig.viewEndpoint;
|
||||||
|
Vue.prototype.OSSclientConfig.bucket = Vue.prototype.OSSclientConfig.bucketName
|
||||||
|
return new S3Client({
|
||||||
|
endpoint: Vue.prototype.OSSclientConfig.viewEndpoint,
|
||||||
|
region: Vue.prototype.OSSclientConfig.region,
|
||||||
|
s3ForcePathStyle: true,
|
||||||
|
signatureVersion: 'v4',
|
||||||
|
forcePathStyle: true,
|
||||||
|
credentials: {
|
||||||
|
accessKeyId: Vue.prototype.OSSclientConfig.accessKeyId,
|
||||||
|
secretAccessKey: Vue.prototype.OSSclientConfig.secretAccessKey,
|
||||||
|
sessionToken: Vue.prototype.OSSclientConfig.sessionToken
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
return client;
|
||||||
|
}
|
||||||
|
}
|
||||||
function decodeUtf8(bytes) {
|
function decodeUtf8(bytes) {
|
||||||
let str = bytes.split('?');
|
let str = bytes.split('?');
|
||||||
let str2 = str[0].split('/');
|
let str2 = str[0].split('/');
|
||||||
|
|
@ -138,6 +249,47 @@ function decodeUtf8(bytes) {
|
||||||
str2.pop();
|
str2.pop();
|
||||||
return str2.join("/") + '/' + name;
|
return str2.join("/") + '/' + name;
|
||||||
}
|
}
|
||||||
|
const queue = []
|
||||||
|
let loading = false;
|
||||||
|
// 获取凭证
|
||||||
|
function getSTSToken(credentials) {
|
||||||
|
return new Promise(async (resolve, reject) => {
|
||||||
|
let isExpired = isCredentialsExpired(credentials);
|
||||||
|
if (isExpired) {
|
||||||
|
if (loading) {
|
||||||
|
queue.push({ resolve, reject })
|
||||||
|
}
|
||||||
|
if (!loading) {
|
||||||
|
loading = true;
|
||||||
|
let res = await GetObjectStoreToken();
|
||||||
|
loading = false;
|
||||||
|
resolve(res)
|
||||||
|
let p = queue.shift();
|
||||||
|
while (p) {
|
||||||
|
p.resolve(res)
|
||||||
|
p = queue.shift();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
// console.log("凭证未过期");
|
||||||
|
resolve(false)
|
||||||
|
}
|
||||||
|
|
||||||
|
})
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* oss判断临时凭证是否到期。
|
||||||
|
**/
|
||||||
|
function isCredentialsExpired(credentials) {
|
||||||
|
if (!credentials) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
const expireDate = new Date(credentials);
|
||||||
|
const now = new Date();
|
||||||
|
// 如果有效期不足五分钟,视为过期。
|
||||||
|
return expireDate.getTime() - now.getTime() <= 300000;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
export const OSSclient = ossGenerateSTS
|
export const OSSclient = ossGenerateSTS
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ import axios from 'axios'
|
||||||
import { Message, MessageBox, Alert } from 'element-ui'
|
import { Message, MessageBox, Alert } from 'element-ui'
|
||||||
import store from '@/store'
|
import store from '@/store'
|
||||||
import router from '@/router'
|
import router from '@/router'
|
||||||
import Vue from 'vue'
|
import WHITELIST from "./whiteList"
|
||||||
import moment from 'moment-timezone';
|
import moment from 'moment-timezone';
|
||||||
console.log(moment.tz.guess())
|
console.log(moment.tz.guess())
|
||||||
axios.defaults.withCredentials = false
|
axios.defaults.withCredentials = false
|
||||||
|
|
@ -27,7 +27,10 @@ service.interceptors.request.use(
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
if (eval(process.env.VUE_APP_LOGIN_FOR_PERMISSION)) {
|
if (eval(process.env.VUE_APP_LOGIN_FOR_PERMISSION)) {
|
||||||
if (!path || path === '/ReviewersResearchForm' || path === '/ReviewersResearch' || path === '/login' || path === '/researchForm' || path === '/researchDetail_m' || path === '/researchLogin_m' || path === '/researchLogin' || path === '/email-recompose' || path === '/recompose' || path === '/resetpassword' || path === '/error') {
|
// if (!path || path === '/ReviewersResearchForm' || path === '/ReviewersResearch' || path === '/login' || path === '/researchForm' || path === '/researchDetail_m' || path === '/researchLogin_m' || path === '/researchLogin' || path === '/email-recompose' || path === '/recompose' || path === '/resetpassword' || path === '/error') {
|
||||||
|
// return config
|
||||||
|
// }
|
||||||
|
if (!path || WHITELIST.some(item => item === path)) {
|
||||||
return config
|
return config
|
||||||
}
|
}
|
||||||
if (store.state.user.userId !== zzSessionStorage.getItem('userId')) {
|
if (store.state.user.userId !== zzSessionStorage.getItem('userId')) {
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,85 @@
|
||||||
|
import streamSaver from "streamsaver";
|
||||||
|
import "streamsaver/examples/zip-stream.js";
|
||||||
|
import store from '@/store'
|
||||||
|
streamSaver.mitm = `${window.location.origin}/mitm.html?version=2.0.0`
|
||||||
|
// 下载文件并压缩
|
||||||
|
function zipFiles(zipName, files) {
|
||||||
|
console.log("同步下载打包开始时间:" + new Date());
|
||||||
|
store.dispatch('trials/setUnLock', true)
|
||||||
|
files = formatFiles(files)
|
||||||
|
// 创建压缩文件输出流
|
||||||
|
const zipFileOutputStream = streamSaver.createWriteStream(zipName);
|
||||||
|
// 创建下载文件流
|
||||||
|
const fileIterator = files.values();
|
||||||
|
const readableZipStream = new ZIP({
|
||||||
|
async pull(ctrl) {
|
||||||
|
const fileInfo = fileIterator.next();
|
||||||
|
if (fileInfo.done) {//迭代终止
|
||||||
|
ctrl.close();
|
||||||
|
} else {
|
||||||
|
let { name, url } = fileInfo.value;
|
||||||
|
url = decodeUtf8(url);
|
||||||
|
return fetch(url).then(res => {
|
||||||
|
ctrl.enqueue({
|
||||||
|
name,
|
||||||
|
stream: () => res.body
|
||||||
|
});
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if (window.WritableStream && readableZipStream.pipeTo) {
|
||||||
|
// 开始下载
|
||||||
|
readableZipStream
|
||||||
|
.pipeTo(zipFileOutputStream)
|
||||||
|
.then(() => {
|
||||||
|
console.log("同步下载打包结束时间:" + new Date());
|
||||||
|
store.dispatch('trials/setUnLock', false)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 下载文件并修改名称
|
||||||
|
async function updateFile(file, name) {
|
||||||
|
try {
|
||||||
|
store.dispatch('trials/setUnLock', true)
|
||||||
|
const fileOutputStream = streamSaver.createWriteStream(name);
|
||||||
|
file = decodeUtf8(file);
|
||||||
|
let res = await fetch(file);
|
||||||
|
res.body.pipeTo(fileOutputStream).then(() => {
|
||||||
|
store.dispatch('trials/setUnLock', true)
|
||||||
|
});
|
||||||
|
} catch (err) {
|
||||||
|
console.log(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 同名文件修改名称
|
||||||
|
function formatFiles(files) {
|
||||||
|
let fileObj = {};
|
||||||
|
files.forEach(file => {
|
||||||
|
let arr = Object.keys(fileObj);
|
||||||
|
if (!~arr.indexOf(file.name)) {
|
||||||
|
fileObj[file.name] = 1;
|
||||||
|
} else {
|
||||||
|
let name = file.name;
|
||||||
|
file.name = name.split(".")[0] + `(${fileObj[name]})` + name
|
||||||
|
.substring(name.lastIndexOf('.'))
|
||||||
|
.toLocaleLowerCase()
|
||||||
|
fileObj[name]++;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
return files;
|
||||||
|
}
|
||||||
|
function decodeUtf8(bytes) {
|
||||||
|
let str = bytes.split('?');
|
||||||
|
let str2 = str[0].split('/');
|
||||||
|
let name = str2[str2.length - 1];
|
||||||
|
name = encodeURIComponent(name);
|
||||||
|
str.shift();
|
||||||
|
str2.pop();
|
||||||
|
return str2.join("/") + '/' + name;
|
||||||
|
}
|
||||||
|
export function downLoadFile(file, name, type = 'file') {
|
||||||
|
if (type === 'zip') return zipFiles(name, file);
|
||||||
|
return updateFile(file, name)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -1,168 +0,0 @@
|
||||||
import Vue from 'vue';
|
|
||||||
import store from "@/store";
|
|
||||||
import {
|
|
||||||
requestPackageAndAnonymizImage,
|
|
||||||
} from "@/api/load.js";
|
|
||||||
import streamSaver from "streamsaver";
|
|
||||||
import "streamsaver/examples/zip-stream.js"
|
|
||||||
let flag = {};
|
|
||||||
export const resetFlag = () => {
|
|
||||||
flag = {};
|
|
||||||
store.state.trials.uploadTip = null;
|
|
||||||
if (store.state.trials.timer) {
|
|
||||||
clearInterval(store.state.trials.timer);
|
|
||||||
store.state.trials.timer = null;
|
|
||||||
}
|
|
||||||
store.dispatch("trials/setUnLock", false);
|
|
||||||
}
|
|
||||||
export const downloadImage = async (id, id2, IsDicom = true) => {
|
|
||||||
// if (flag[`${id2}_${IsDicom}`]) return Vue.prototype.$message.warning(Vue.prototype.$t('trials:upload:tip:uploading'));
|
|
||||||
if (flag[`${id2}_${IsDicom}`]) return false;
|
|
||||||
flag[`${id2}_${IsDicom}`] = true
|
|
||||||
try {
|
|
||||||
let params = {
|
|
||||||
TrialId: id,
|
|
||||||
SubjectVisitId: id2,
|
|
||||||
IsDicom: IsDicom
|
|
||||||
}
|
|
||||||
store.dispatch("trials/setUnLock", true);
|
|
||||||
let res = await requestPackageAndAnonymizImage(params);
|
|
||||||
if (res.IsSuccess) {
|
|
||||||
if (!res.Result) {
|
|
||||||
flag[`${id2}_${IsDicom}`] = false;
|
|
||||||
// Vue.prototype.$message.warning(Vue.prototype.$t("trials:upload:message:not"))
|
|
||||||
let message = Vue.prototype.$t('trials:upload:tip:uploading').replace("xxx", res.OtherInfo.FileName);
|
|
||||||
store.state.trials.uploadTip = message;
|
|
||||||
if (!store.state.trials.timer) {
|
|
||||||
store.state.trials.timer = setInterval(() => {
|
|
||||||
downloadImage(id, id2, IsDicom);
|
|
||||||
}, 2000);
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (store.state.trials.timer) {
|
|
||||||
clearInterval(store.state.trials.timer);
|
|
||||||
store.state.trials.timer = null;
|
|
||||||
}
|
|
||||||
let fileName = res.Result.split("/").pop();
|
|
||||||
let href = Vue.prototype.OSSclientConfig.basePath + res.Result;
|
|
||||||
if (fileName !== res.OtherInfo.FileName) {
|
|
||||||
let message = Vue.prototype.$t('trials:upload:tip:uploading').replace("xxx", res.OtherInfo.FileName);
|
|
||||||
store.state.trials.uploadTip = message;
|
|
||||||
// Vue.prototype.$message.success(Vue.prototype.$t("trials:upload:message:startUpload"));
|
|
||||||
return download(href, res.OtherInfo.FileName, { id2, IsDicom });
|
|
||||||
|
|
||||||
}
|
|
||||||
let a = document.createElement("a");
|
|
||||||
a.download = res.OtherInfo.FileName;
|
|
||||||
a.href = href;
|
|
||||||
a.click();
|
|
||||||
URL.revokeObjectURL(href);
|
|
||||||
let timer = setTimeout(() => {
|
|
||||||
a = null;
|
|
||||||
href = null;
|
|
||||||
timer = null;
|
|
||||||
}, 500)
|
|
||||||
store.state.trials.uploadTip = null;
|
|
||||||
return true;
|
|
||||||
} else {
|
|
||||||
flag[`${id2}_${IsDicom}`] = false;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
} catch (err) {
|
|
||||||
flag[`${id2}_${IsDicom}`] = false;
|
|
||||||
console.log(err);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
export const fileDownload = (content, filename) => {
|
|
||||||
const eleLink = document.createElement("a");
|
|
||||||
eleLink.download = filename;
|
|
||||||
eleLink.style.display = "none";
|
|
||||||
const blob = new Blob([content]);
|
|
||||||
eleLink.href = URL.createObjectURL(blob);
|
|
||||||
document.body.appendChild(eleLink);
|
|
||||||
eleLink.click();
|
|
||||||
document.body.removeChild(eleLink);
|
|
||||||
};
|
|
||||||
let download = async (downloadUrl, downloadFileName, res) => {
|
|
||||||
const blob = await getBlob(downloadUrl);
|
|
||||||
flag[`${res.id2}_${res.IsDicom}`] = false;
|
|
||||||
store.state.trials.uploadTip = null;
|
|
||||||
store.dispatch("trials/setUnLock", false);
|
|
||||||
saveAsB(blob, downloadFileName);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
let getBlob = (url) => {
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
const xhr = new XMLHttpRequest();
|
|
||||||
|
|
||||||
xhr.open('GET', url, true);
|
|
||||||
xhr.responseType = 'blob';
|
|
||||||
xhr.onload = () => {
|
|
||||||
if (xhr.status === 200) {
|
|
||||||
resolve(xhr.response);
|
|
||||||
} else {
|
|
||||||
reject(new Error(`Request failed with status ${xhr.status}`));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
xhr.onerror = () => {
|
|
||||||
reject(new Error('Request failed'));
|
|
||||||
};
|
|
||||||
|
|
||||||
xhr.send();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
let saveAsB = (blob, filename) => {
|
|
||||||
const link = document.createElement('a');
|
|
||||||
const body = document.body;
|
|
||||||
|
|
||||||
link.href = window.URL.createObjectURL(blob);
|
|
||||||
link.download = filename;
|
|
||||||
|
|
||||||
// hide the link
|
|
||||||
link.style.display = 'none';
|
|
||||||
body.appendChild(link);
|
|
||||||
|
|
||||||
link.click();
|
|
||||||
body.removeChild(link);
|
|
||||||
|
|
||||||
window.URL.revokeObjectURL(link.href);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 前端流式打包下载
|
|
||||||
const handleBatchDown = async (item, zip) => {
|
|
||||||
return new Promise((resolve) => {
|
|
||||||
console.log("同步下载打包开始时间:" + new Date());
|
|
||||||
// 创建压缩文件输出流
|
|
||||||
const zipFileOutputStream = streamSaver.createWriteStream(zipName);
|
|
||||||
// 创建下载文件流
|
|
||||||
const fileIterator = files.values();
|
|
||||||
const readableZipStream = new window.ZIP({
|
|
||||||
async pull(ctrl) {
|
|
||||||
const fileInfo = fileIterator.next();
|
|
||||||
if (fileInfo.done) {//迭代终止
|
|
||||||
ctrl.close();
|
|
||||||
} else {
|
|
||||||
const { name, url } = fileInfo.value;
|
|
||||||
return fetch(url).then(res => {
|
|
||||||
ctrl.enqueue({
|
|
||||||
name,
|
|
||||||
stream: () => res.body
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
if (window.WritableStream && readableZipStream.pipeTo) {
|
|
||||||
// 开始下载
|
|
||||||
readableZipStream
|
|
||||||
.pipeTo(zipFileOutputStream)
|
|
||||||
.then(() => { console.log("同步下载打包结束时间:" + new Date()); resolve(true) })
|
|
||||||
} else {
|
|
||||||
resolve(false);
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
@ -0,0 +1,2 @@
|
||||||
|
const WHITELIST = ['/', '/ReviewersResearch', '/login', '/error', '/resetpassword', '/recompose', '/email-recompose', '/trialStats', '/showdicom', '/imagesShare', '/audit', '/preview', '/researchLogin', '/researchLogin_m', '/blindResumeInfo', '/trialsResume', '/joinVerify', '/showNoneDicoms', '/noneDicomReading', '/clinicalData', '/readingDicoms', '/readingPage', '/visitDicomReview', '/visitNondicomReview', '/globalReview', '/adReview', '/oncologyReview', '/nonedicoms']
|
||||||
|
export default WHITELIST
|
||||||
|
|
@ -6,7 +6,7 @@
|
||||||
<div class="sidePanelThumbs">
|
<div class="sidePanelThumbs">
|
||||||
<el-tabs v-model="activeName" type="border-card" @tab-click="handleTabClick">
|
<el-tabs v-model="activeName" type="border-card" @tab-click="handleTabClick">
|
||||||
<el-tab-pane :label="$t('trials:dicom-show:currentVisit')" name="current-study">
|
<el-tab-pane :label="$t('trials:dicom-show:currentVisit')" name="current-study">
|
||||||
<div class="text-desc" style="background:rgb(55 55 55);">
|
<div v-if="visitInfo" class="text-desc" style="background:rgb(55 55 55);">
|
||||||
{{ visitInfo }}
|
{{ visitInfo }}
|
||||||
</div>
|
</div>
|
||||||
<div class="viewerSidethumbs ps" style="position: relative;">
|
<div class="viewerSidethumbs ps" style="position: relative;">
|
||||||
|
|
@ -261,6 +261,7 @@ import * as cornerstoneWADOImageLoader from 'cornerstone-wado-image-loader'
|
||||||
import dicomViewer from '@/components/Dicom/DicomViewer'
|
import dicomViewer from '@/components/Dicom/DicomViewer'
|
||||||
import { getVisitStudyList, getAllRelationStudyList, getSeriesList } from '@/api/reading'
|
import { getVisitStudyList, getAllRelationStudyList, getSeriesList } from '@/api/reading'
|
||||||
import { setSeriesStatus } from '@/api/trials'
|
import { setSeriesStatus } from '@/api/trials'
|
||||||
|
import { getTaskUploadedDicomStudyList } from '@/api/reading'
|
||||||
import requestPoolManager from '@/utils/request-pool'
|
import requestPoolManager from '@/utils/request-pool'
|
||||||
import store from '@/store'
|
import store from '@/store'
|
||||||
import { changeURLStatic } from '@/utils/history.js'
|
import { changeURLStatic } from '@/utils/history.js'
|
||||||
|
|
@ -301,7 +302,8 @@ export default {
|
||||||
relationActiveName: [],
|
relationActiveName: [],
|
||||||
showSeriesList: [],
|
showSeriesList: [],
|
||||||
currentLoadIns: [],
|
currentLoadIns: [],
|
||||||
isFromCRCUpload: false
|
isFromCRCUpload: false,
|
||||||
|
visitTaskId: null
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
|
|
@ -318,6 +320,7 @@ export default {
|
||||||
this.isReading = this.$router.currentRoute.query.isReading ? this.$router.currentRoute.query.isReading * 1 : 0
|
this.isReading = this.$router.currentRoute.query.isReading ? this.$router.currentRoute.query.isReading * 1 : 0
|
||||||
this.showDelete = parseInt(this.$router.currentRoute.query.showDelete)
|
this.showDelete = parseInt(this.$router.currentRoute.query.showDelete)
|
||||||
this.isFromCRCUpload = !!this.$router.currentRoute.query.isFromCRCUpload
|
this.isFromCRCUpload = !!this.$router.currentRoute.query.isFromCRCUpload
|
||||||
|
this.visitTaskId = this.$router.currentRoute.query.visitTaskId
|
||||||
// cornerstone.events.addEventListener('cornerstoneimageloaded', this.cornerstoneImageLoaded)
|
// cornerstone.events.addEventListener('cornerstoneimageloaded', this.cornerstoneImageLoaded)
|
||||||
this.getStudiesInfo()
|
this.getStudiesInfo()
|
||||||
cornerstone.events.addEventListener('cornerstoneimageloadprogress', this.cornerstoneimageloadprogress)
|
cornerstone.events.addEventListener('cornerstoneimageloadprogress', this.cornerstoneimageloadprogress)
|
||||||
|
|
@ -338,7 +341,12 @@ export default {
|
||||||
async getStudiesInfo() {
|
async getStudiesInfo() {
|
||||||
this.studyList = []
|
this.studyList = []
|
||||||
try {
|
try {
|
||||||
const res = await getVisitStudyList(this.trialId, this.subjectVisitId, this.isReading)
|
let res = null
|
||||||
|
if (this.visitTaskId) {
|
||||||
|
res = await getTaskUploadedDicomStudyList({ visitTaskId: this.visitTaskId })
|
||||||
|
} else {
|
||||||
|
res = await getVisitStudyList(this.trialId, this.subjectVisitId, this.isReading)
|
||||||
|
}
|
||||||
if (res.IsSuccess) {
|
if (res.IsSuccess) {
|
||||||
res.Result.forEach((study, studyIndex) => {
|
res.Result.forEach((study, studyIndex) => {
|
||||||
const data = {}
|
const data = {}
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@
|
||||||
ref="sysTemplateFrom"
|
ref="sysTemplateFrom"
|
||||||
v-loading="loading"
|
v-loading="loading"
|
||||||
:model="form"
|
:model="form"
|
||||||
label-width="90px"
|
label-width="140px"
|
||||||
size="small"
|
size="small"
|
||||||
:rules="rules"
|
:rules="rules"
|
||||||
class="upload-temporary-file"
|
class="upload-temporary-file"
|
||||||
|
|
@ -15,7 +15,7 @@
|
||||||
<el-form-item label="业务场景: " prop="BusinessScenarioEnum">
|
<el-form-item label="业务场景: " prop="BusinessScenarioEnum">
|
||||||
<el-select
|
<el-select
|
||||||
v-model="form.BusinessScenarioEnum"
|
v-model="form.BusinessScenarioEnum"
|
||||||
style="width:100%;"
|
style="width: 100%"
|
||||||
size="small"
|
size="small"
|
||||||
filterable
|
filterable
|
||||||
>
|
>
|
||||||
|
|
@ -44,12 +44,14 @@
|
||||||
:on-exceed="handleExceed"
|
:on-exceed="handleExceed"
|
||||||
:disabled="!form.FileTypeEnum || !form.BusinessScenarioEnum"
|
:disabled="!form.FileTypeEnum || !form.BusinessScenarioEnum"
|
||||||
>
|
>
|
||||||
<el-button size="small" type="primary" :disabled="!form.FileTypeEnum || !form.BusinessScenarioEnum" :loading="btnLoading">Select</el-button>
|
<el-button
|
||||||
<span
|
size="small"
|
||||||
slot="tip"
|
type="primary"
|
||||||
style="margin-left:10px;"
|
:disabled="!form.FileTypeEnum || !form.BusinessScenarioEnum"
|
||||||
class="el-upload__tip"
|
:loading="btnLoading"
|
||||||
|
>Select</el-button
|
||||||
>
|
>
|
||||||
|
<span slot="tip" style="margin-left: 10px" class="el-upload__tip">
|
||||||
(must be in xlsx/xls/doc/docx format)
|
(must be in xlsx/xls/doc/docx format)
|
||||||
</span>
|
</span>
|
||||||
</el-upload>
|
</el-upload>
|
||||||
|
|
@ -58,37 +60,61 @@
|
||||||
<el-form-item label="文件名" prop="Name">
|
<el-form-item label="文件名" prop="Name">
|
||||||
<el-input v-model="form.Name" />
|
<el-input v-model="form.Name" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
<el-form-item
|
||||||
|
:label="$t('dictionary:attachment:export:form:nameCN')"
|
||||||
|
prop="NameCN"
|
||||||
|
>
|
||||||
|
<el-input v-model="form.NameCN" />
|
||||||
|
</el-form-item>
|
||||||
<el-form-item v-if="form.Id !== ''" label="是否废除: ">
|
<el-form-item v-if="form.Id !== ''" label="是否废除: ">
|
||||||
<el-radio-group v-model="form.IsDeleted">
|
<el-radio-group v-model="form.IsDeleted">
|
||||||
<el-radio v-for="item of $d.YesOrNo" :label="item.value">{{item.label}}</el-radio>
|
<el-radio
|
||||||
|
v-for="item of $d.YesOrNo"
|
||||||
|
:label="item.value"
|
||||||
|
:key="item.id"
|
||||||
|
>{{ item.label }}</el-radio
|
||||||
|
>
|
||||||
</el-radio-group>
|
</el-radio-group>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="描述">
|
<el-form-item label="描述">
|
||||||
<el-input
|
<el-input
|
||||||
v-model="form.Description"
|
v-model="form.Description"
|
||||||
type="textarea"
|
type="textarea"
|
||||||
:autosize="{ minRows: 2, maxRows: 4}"
|
:autosize="{ minRows: 2, maxRows: 4 }"
|
||||||
placeholder="请输入内容"
|
placeholder="请输入内容"
|
||||||
/>
|
/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</div>
|
</div>
|
||||||
<div class="base-dialog-footer" style="text-align:right;margin-top:10px;">
|
<div class="base-dialog-footer" style="text-align: right; margin-top: 10px">
|
||||||
<el-form-item style="text-align:right;">
|
<el-form-item style="text-align: right">
|
||||||
<el-button size="small" type="primary" :disabled="!form.FileTypeEnum || !form.BusinessScenarioEnum" :loading="saveBtnLoading" @click="handleSave">Save</el-button>
|
<el-button
|
||||||
|
size="small"
|
||||||
|
type="primary"
|
||||||
|
:disabled="!form.FileTypeEnum || !form.BusinessScenarioEnum"
|
||||||
|
:loading="saveBtnLoading"
|
||||||
|
@click="handleSave"
|
||||||
|
>Save</el-button
|
||||||
|
>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</div>
|
</div>
|
||||||
</el-form>
|
</el-form>
|
||||||
</template>
|
</template>
|
||||||
<script>
|
<script>
|
||||||
import { addOrUpdateCommonDocument, uploadCommonDoc, Upload } from '@/api/dictionary'
|
import {
|
||||||
|
addOrUpdateCommonDocument,
|
||||||
|
uploadCommonDoc,
|
||||||
|
Upload,
|
||||||
|
} from '@/api/dictionary'
|
||||||
import { getBasicDataSelects } from '@/api/dictionary/dictionary'
|
import { getBasicDataSelects } from '@/api/dictionary/dictionary'
|
||||||
export default {
|
export default {
|
||||||
name: 'TemplateForm',
|
name: 'TemplateForm',
|
||||||
props: {
|
props: {
|
||||||
data: {
|
data: {
|
||||||
type: Object,
|
type: Object,
|
||||||
default() { return {} }
|
default() {
|
||||||
}
|
return {}
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
data() {
|
data() {
|
||||||
|
|
@ -99,20 +125,30 @@ export default {
|
||||||
FileTypeEnum: null,
|
FileTypeEnum: null,
|
||||||
BusinessScenarioEnum: null,
|
BusinessScenarioEnum: null,
|
||||||
Name: '',
|
Name: '',
|
||||||
|
NameCN: '',
|
||||||
Path: '',
|
Path: '',
|
||||||
Description: '',
|
Description: '',
|
||||||
IsDeleted: false
|
IsDeleted: false,
|
||||||
},
|
},
|
||||||
rules: {
|
rules: {
|
||||||
Code: [{ required: true, message: 'Please specify', trigger: ['blur'] }],
|
Code: [
|
||||||
Name: [{ required: true, message: 'Please specify', trigger: ['blur'] }],
|
{ required: true, message: 'Please specify', trigger: ['blur'] },
|
||||||
BusinessScenarioEnum: [{ required: true, message: 'Please select', trigger: ['blur'] }]
|
],
|
||||||
|
Name: [
|
||||||
|
{ required: true, message: 'Please specify', trigger: ['blur'] },
|
||||||
|
],
|
||||||
|
NameCN: [
|
||||||
|
{ required: true, message: 'Please specify', trigger: ['blur'] },
|
||||||
|
],
|
||||||
|
BusinessScenarioEnum: [
|
||||||
|
{ required: true, message: 'Please select', trigger: ['blur'] },
|
||||||
|
],
|
||||||
},
|
},
|
||||||
fileList: [],
|
fileList: [],
|
||||||
btnLoading: false,
|
btnLoading: false,
|
||||||
saveBtnLoading: false,
|
saveBtnLoading: false,
|
||||||
loading: false,
|
loading: false,
|
||||||
dictionaryList: {}
|
dictionaryList: {},
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
|
|
@ -128,8 +164,8 @@ export default {
|
||||||
name: this.data.Name,
|
name: this.data.Name,
|
||||||
path: this.data.Path,
|
path: this.data.Path,
|
||||||
url: this.data.Path,
|
url: this.data.Path,
|
||||||
type: this.data.Type
|
type: this.data.Type,
|
||||||
}
|
},
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
for (const k in this.form) {
|
for (const k in this.form) {
|
||||||
|
|
@ -142,10 +178,12 @@ export default {
|
||||||
// 获取文件类型下拉框
|
// 获取文件类型下拉框
|
||||||
getDicData() {
|
getDicData() {
|
||||||
this.loading = true
|
this.loading = true
|
||||||
getBasicDataSelects(['Common_File_ModuleType', 'Common_File_Type']).then(res => {
|
getBasicDataSelects(['Common_File_ModuleType', 'Common_File_Type'])
|
||||||
|
.then((res) => {
|
||||||
this.dictionaryList = { ...res.Result }
|
this.dictionaryList = { ...res.Result }
|
||||||
this.loading = false
|
this.loading = false
|
||||||
}).catch(() => {
|
})
|
||||||
|
.catch(() => {
|
||||||
this.loading = false
|
this.loading = false
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
@ -165,28 +203,35 @@ export default {
|
||||||
const formData = new FormData()
|
const formData = new FormData()
|
||||||
formData.append('file', param.file)
|
formData.append('file', param.file)
|
||||||
this.form.FileName = param.file.name
|
this.form.FileName = param.file.name
|
||||||
Upload(formData, 1).then(res => {
|
Upload(formData, 1).then((res) => {
|
||||||
this.fileList.push({ name: param.file.name, path: res.Result.FilePath, fullPath: res.Result.FullFilePath, url: res.Result.FilePath })
|
this.fileList.push({
|
||||||
|
name: param.file.name,
|
||||||
|
path: res.Result.FilePath,
|
||||||
|
fullPath: res.Result.FullFilePath,
|
||||||
|
url: res.Result.FilePath,
|
||||||
|
})
|
||||||
this.form.Path = res.Result.FilePath
|
this.form.Path = res.Result.FilePath
|
||||||
this.form.Name = param.file.name
|
this.form.NameCN = param.file.name
|
||||||
this.loading = false
|
this.loading = false
|
||||||
this.btnLoading = false
|
this.btnLoading = false
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
handleSave() {
|
handleSave() {
|
||||||
this.$refs.sysTemplateFrom.validate(valid => {
|
this.$refs.sysTemplateFrom.validate((valid) => {
|
||||||
if (!valid) return
|
if (!valid) return
|
||||||
if (!this.form.Name) {
|
if (!this.form.Name) {
|
||||||
this.$alert('Please select file.')
|
this.$alert('Please select file.')
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
this.saveBtnLoading = true
|
this.saveBtnLoading = true
|
||||||
addOrUpdateCommonDocument(this.form).then(res => {
|
addOrUpdateCommonDocument(this.form)
|
||||||
|
.then((res) => {
|
||||||
this.saveBtnLoading = false
|
this.saveBtnLoading = false
|
||||||
this.$emit('closeDialog')
|
this.$emit('closeDialog')
|
||||||
this.$emit('getList')
|
this.$emit('getList')
|
||||||
this.$message.success('Uploaded successfully')
|
this.$message.success('Uploaded successfully')
|
||||||
}).catch(() => {
|
})
|
||||||
|
.catch(() => {
|
||||||
this.saveBtnLoading = false
|
this.saveBtnLoading = false
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
@ -194,6 +239,7 @@ export default {
|
||||||
handleRemoveFile() {
|
handleRemoveFile() {
|
||||||
this.fileList = []
|
this.fileList = []
|
||||||
this.form.Path = ''
|
this.form.Path = ''
|
||||||
|
this.form.NameCN = ''
|
||||||
this.form.Name = ''
|
this.form.Name = ''
|
||||||
},
|
},
|
||||||
handlePreview(file) {
|
handlePreview(file) {
|
||||||
|
|
@ -206,19 +252,21 @@ export default {
|
||||||
},
|
},
|
||||||
checkFileSuffix(fileName) {
|
checkFileSuffix(fileName) {
|
||||||
var typeArr = ['xls', 'xlsx', 'doc', 'docx']
|
var typeArr = ['xls', 'xlsx', 'doc', 'docx']
|
||||||
var extendName = fileName.substring(fileName.lastIndexOf('.') + 1).toLocaleLowerCase()
|
var extendName = fileName
|
||||||
|
.substring(fileName.lastIndexOf('.') + 1)
|
||||||
|
.toLocaleLowerCase()
|
||||||
if (typeArr.indexOf(extendName) !== -1) {
|
if (typeArr.indexOf(extendName) !== -1) {
|
||||||
return true
|
return true
|
||||||
} else {
|
} else {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
.upload-temporary-file{
|
.upload-temporary-file {
|
||||||
.upload-container .el-upload--text {
|
.upload-container .el-upload--text {
|
||||||
border: none;
|
border: none;
|
||||||
width: 80px;
|
width: 80px;
|
||||||
|
|
@ -231,8 +279,8 @@ export default {
|
||||||
color: #428bca;
|
color: #428bca;
|
||||||
font-size: 13px;
|
font-size: 13px;
|
||||||
}
|
}
|
||||||
.account_item_clear{
|
.account_item_clear {
|
||||||
.el-tag__close{
|
.el-tag__close {
|
||||||
display: none !important;
|
display: none !important;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@
|
||||||
<el-form-item label="业务场景">
|
<el-form-item label="业务场景">
|
||||||
<el-select
|
<el-select
|
||||||
v-model="searchData.BusinessScenarioEnum"
|
v-model="searchData.BusinessScenarioEnum"
|
||||||
style="width:150px;"
|
style="width: 150px"
|
||||||
>
|
>
|
||||||
<el-option
|
<el-option
|
||||||
v-for="item of $d.Common_File_BusinessScenario"
|
v-for="item of $d.Common_File_BusinessScenario"
|
||||||
|
|
@ -13,15 +13,10 @@
|
||||||
:label="item.label"
|
:label="item.label"
|
||||||
:value="item.value"
|
:value="item.value"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="文件名称">
|
<el-form-item label="文件名称">
|
||||||
<el-input
|
<el-input v-model="searchData.Name" style="width: 130px" clearable />
|
||||||
v-model="searchData.Name"
|
|
||||||
style="width:130px;"
|
|
||||||
clearable
|
|
||||||
/>
|
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
||||||
<el-form-item>
|
<el-form-item>
|
||||||
|
|
@ -30,24 +25,28 @@
|
||||||
{{ $t('common:button:search') }}
|
{{ $t('common:button:search') }}
|
||||||
</el-button>
|
</el-button>
|
||||||
<!-- 重置 -->
|
<!-- 重置 -->
|
||||||
<el-button type="primary" icon="el-icon-refresh-left" @click="handleReset">
|
<el-button
|
||||||
|
type="primary"
|
||||||
|
icon="el-icon-refresh-left"
|
||||||
|
@click="handleReset"
|
||||||
|
>
|
||||||
{{ $t('common:button:reset') }}
|
{{ $t('common:button:reset') }}
|
||||||
</el-button>
|
</el-button>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-form>
|
|
||||||
<el-button
|
<el-button
|
||||||
type="primary"
|
type="primary"
|
||||||
icon="el-icon-plus"
|
icon="el-icon-plus"
|
||||||
style="margin-left:auto;"
|
style="float: right"
|
||||||
size="small"
|
size="small"
|
||||||
@click="handleAdd"
|
@click="handleAdd"
|
||||||
>
|
>
|
||||||
{{ $t('common:button:new') }}
|
{{ $t('common:button:new') }}
|
||||||
</el-button>
|
</el-button>
|
||||||
|
</el-form>
|
||||||
</template>
|
</template>
|
||||||
<template slot="main-container">
|
<template slot="main-container">
|
||||||
<el-table
|
<el-table
|
||||||
v-adaptive="{bottomOffset:60}"
|
v-adaptive="{ bottomOffset: 60 }"
|
||||||
v-loading="loading"
|
v-loading="loading"
|
||||||
:data="list"
|
:data="list"
|
||||||
stripe
|
stripe
|
||||||
|
|
@ -69,9 +68,13 @@
|
||||||
sortable="custom"
|
sortable="custom"
|
||||||
>
|
>
|
||||||
<template slot-scope="scope">
|
<template slot-scope="scope">
|
||||||
{{ $fd('Common_File_BusinessScenario',scope.row.BusinessScenarioEnum) }}
|
{{
|
||||||
|
$fd(
|
||||||
|
'Common_File_BusinessScenario',
|
||||||
|
scope.row.BusinessScenarioEnum
|
||||||
|
)
|
||||||
|
}}
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
|
|
||||||
<el-table-column
|
<el-table-column
|
||||||
|
|
@ -80,6 +83,12 @@
|
||||||
show-overflow-tooltip
|
show-overflow-tooltip
|
||||||
sortable="custom"
|
sortable="custom"
|
||||||
/>
|
/>
|
||||||
|
<el-table-column
|
||||||
|
prop="NameCN"
|
||||||
|
:label="$t('dictionary:attachment:upload:table:nameCN')"
|
||||||
|
show-overflow-tooltip
|
||||||
|
sortable="custom"
|
||||||
|
/>
|
||||||
<el-table-column
|
<el-table-column
|
||||||
prop="Description"
|
prop="Description"
|
||||||
label="描述"
|
label="描述"
|
||||||
|
|
@ -92,8 +101,12 @@
|
||||||
sortable="custom"
|
sortable="custom"
|
||||||
>
|
>
|
||||||
<template slot-scope="scope">
|
<template slot-scope="scope">
|
||||||
<el-tag v-if="scope.row.IsDeleted" type="danger">{{ $fd('YesOrNo', scope.row.IsDeleted) }}</el-tag>
|
<el-tag v-if="scope.row.IsDeleted" type="danger">{{
|
||||||
<el-tag v-else type="primary">{{ $fd('YesOrNo', scope.row.IsDeleted) }}</el-tag>
|
$fd('YesOrNo', scope.row.IsDeleted)
|
||||||
|
}}</el-tag>
|
||||||
|
<el-tag v-else type="primary">{{
|
||||||
|
$fd('YesOrNo', scope.row.IsDeleted)
|
||||||
|
}}</el-tag>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column
|
<el-table-column
|
||||||
|
|
@ -105,29 +118,26 @@
|
||||||
|
|
||||||
<el-table-column label="Action">
|
<el-table-column label="Action">
|
||||||
<template slot-scope="scope">
|
<template slot-scope="scope">
|
||||||
<el-button
|
<el-button type="text" @click="handleDownload(scope.row)">
|
||||||
type="text"
|
|
||||||
@click="handleDownload(scope.row)"
|
|
||||||
>
|
|
||||||
下载
|
下载
|
||||||
</el-button>
|
</el-button>
|
||||||
<el-button
|
<el-button type="text" @click="handleEdit(scope.row)">
|
||||||
type="text"
|
|
||||||
@click="handleEdit(scope.row)"
|
|
||||||
>
|
|
||||||
编辑
|
编辑
|
||||||
</el-button>
|
</el-button>
|
||||||
<el-button
|
<el-button type="text" @click="handleDelete(scope.row)">
|
||||||
type="text"
|
|
||||||
@click="handleDelete(scope.row)"
|
|
||||||
>
|
|
||||||
删除
|
删除
|
||||||
</el-button>
|
</el-button>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
</el-table>
|
</el-table>
|
||||||
<!-- 分页组件 -->
|
<!-- 分页组件 -->
|
||||||
<pagination class="page" :total="total" :page.sync="searchData.PageIndex" :limit.sync="searchData.PageSize" @pagination="getList" />
|
<pagination
|
||||||
|
class="page"
|
||||||
|
:total="total"
|
||||||
|
:page.sync="searchData.PageIndex"
|
||||||
|
:limit.sync="searchData.PageSize"
|
||||||
|
@pagination="getList"
|
||||||
|
/>
|
||||||
|
|
||||||
<!-- 新增/编辑 -->
|
<!-- 新增/编辑 -->
|
||||||
<el-dialog
|
<el-dialog
|
||||||
|
|
@ -138,13 +148,21 @@
|
||||||
width="600px"
|
width="600px"
|
||||||
custom-class="base-dialog-wrapper"
|
custom-class="base-dialog-wrapper"
|
||||||
>
|
>
|
||||||
<TemplateForm :data="currentRow" @closeDialog="closeDialog" @getList="getList" />
|
<TemplateForm
|
||||||
|
:data="currentRow"
|
||||||
|
@closeDialog="closeDialog"
|
||||||
|
@getList="getList"
|
||||||
|
/>
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
</template>
|
</template>
|
||||||
</BaseContainer>
|
</BaseContainer>
|
||||||
</template>
|
</template>
|
||||||
<script>
|
<script>
|
||||||
import { getCommonDocumentList, DownloadCommonDoc, deleteCommonDocument } from '@/api/dictionary'
|
import {
|
||||||
|
getCommonDocumentList,
|
||||||
|
DownloadCommonDoc,
|
||||||
|
deleteCommonDocument,
|
||||||
|
} from '@/api/dictionary'
|
||||||
import BaseContainer from '@/components/BaseContainer'
|
import BaseContainer from '@/components/BaseContainer'
|
||||||
import Pagination from '@/components/Pagination'
|
import Pagination from '@/components/Pagination'
|
||||||
import TemplateForm from './TemplateForm'
|
import TemplateForm from './TemplateForm'
|
||||||
|
|
@ -155,7 +173,7 @@ const searchDataDefault = () => {
|
||||||
BusinessScenarioEnum: null,
|
BusinessScenarioEnum: null,
|
||||||
Name: '',
|
Name: '',
|
||||||
PageIndex: 1,
|
PageIndex: 1,
|
||||||
PageSize: 20
|
PageSize: 20,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
export default {
|
export default {
|
||||||
|
|
@ -168,7 +186,7 @@ export default {
|
||||||
total: 0,
|
total: 0,
|
||||||
currentRow: {},
|
currentRow: {},
|
||||||
editDialog: { title: '', visible: false },
|
editDialog: { title: '', visible: false },
|
||||||
loading: false
|
loading: false,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
|
|
@ -185,11 +203,13 @@ export default {
|
||||||
},
|
},
|
||||||
getList() {
|
getList() {
|
||||||
this.loading = true
|
this.loading = true
|
||||||
getCommonDocumentList(this.searchData).then(res => {
|
getCommonDocumentList(this.searchData)
|
||||||
|
.then((res) => {
|
||||||
this.loading = false
|
this.loading = false
|
||||||
this.list = res.Result.CurrentPageData
|
this.list = res.Result.CurrentPageData
|
||||||
this.total = res.Result.TotalCount
|
this.total = res.Result.TotalCount
|
||||||
}).catch(() => {
|
})
|
||||||
|
.catch(() => {
|
||||||
this.loading = false
|
this.loading = false
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
@ -202,9 +222,13 @@ export default {
|
||||||
// 下载
|
// 下载
|
||||||
handleDownload(row) {
|
handleDownload(row) {
|
||||||
this.loading = true
|
this.loading = true
|
||||||
DownloadCommonDoc(row.Code).then(data => {
|
DownloadCommonDoc(row.Code)
|
||||||
|
.then((data) => {
|
||||||
this.loading = false
|
this.loading = false
|
||||||
}).catch(() => { this.loading = false })
|
})
|
||||||
|
.catch(() => {
|
||||||
|
this.loading = false
|
||||||
|
})
|
||||||
},
|
},
|
||||||
// 编辑
|
// 编辑
|
||||||
handleEdit(row) {
|
handleEdit(row) {
|
||||||
|
|
@ -233,7 +257,12 @@ export default {
|
||||||
this.searchData.SortField = column.prop
|
this.searchData.SortField = column.prop
|
||||||
this.searchData.PageIndex = 1
|
this.searchData.PageIndex = 1
|
||||||
this.getList()
|
this.getList()
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
::v-deep .search {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
|
||||||
|
|
@ -110,7 +110,7 @@
|
||||||
|
|
||||||
<!-- 添加或修改菜单对话框 -->
|
<!-- 添加或修改菜单对话框 -->
|
||||||
<el-dialog :title="title" top="100px" :close-on-click-modal="false" id="check_config" :visible.sync="open" :width="form.DataType === 'Table' ? '1280px' : '680px'" append-to-body>
|
<el-dialog :title="title" top="100px" :close-on-click-modal="false" id="check_config" :visible.sync="open" :width="form.DataType === 'Table' ? '1280px' : '680px'" append-to-body>
|
||||||
<el-form ref="form" :model="form" :rules="rules" label-width="100px">
|
<el-form ref="form" :model="form" :rules="rules" label-width="120px">
|
||||||
<el-row>
|
<el-row>
|
||||||
<el-col v-show="title !== '复制'" :span="24">
|
<el-col v-show="title !== '复制'" :span="24">
|
||||||
<el-divider content-position="left">基本信息</el-divider>
|
<el-divider content-position="left">基本信息</el-divider>
|
||||||
|
|
@ -142,11 +142,16 @@
|
||||||
<el-input v-model="form.Identification" placeholder="请输入标识" />
|
<el-input v-model="form.Identification" placeholder="请输入标识" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col v-show="form.ConfigType === 'C' && title !== '复制'" :span="24">
|
<el-col v-show="form.ConfigType === 'C' && title !== '复制'" :span="12">
|
||||||
<el-form-item label="字段key">
|
<el-form-item label="字段key">
|
||||||
<el-input v-model="form.Code" placeholder="请输入字段key" />
|
<el-input v-model="form.Code" placeholder="请输入字段key" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
|
<el-col v-show="form.ConfigType === 'C' && title !== '复制'" :span="12">
|
||||||
|
<el-form-item label="字段key英文">
|
||||||
|
<el-input v-model="form.CodeEn" placeholder="请输入字段key英文" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
<el-col v-show="form.ConfigType === 'C' && title !== '复制'" :span="12">
|
<el-col v-show="form.ConfigType === 'C' && title !== '复制'" :span="12">
|
||||||
<el-form-item label="字段英文">
|
<el-form-item label="字段英文">
|
||||||
<el-input v-model="form.Value" placeholder="请输入字段英文" />
|
<el-input v-model="form.Value" placeholder="请输入字段英文" />
|
||||||
|
|
@ -392,6 +397,16 @@
|
||||||
<el-input :disabled="scope.row.IsFixedColumn" v-model="scope.row.ColumnName" placeholder="列字段名"/>
|
<el-input :disabled="scope.row.IsFixedColumn" v-model="scope.row.ColumnName" placeholder="列字段名"/>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
|
<el-table-column
|
||||||
|
prop="ColumnEnName"
|
||||||
|
min-width="120"
|
||||||
|
label="列字段名En"
|
||||||
|
show-overflow-tooltip
|
||||||
|
>
|
||||||
|
<template slot-scope="scope">
|
||||||
|
<el-input :disabled="scope.row.IsFixedColumn" v-model="scope.row.ColumnEnName" placeholder="列字段名En"/>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
<el-table-column
|
<el-table-column
|
||||||
prop="ColumnValue"
|
prop="ColumnValue"
|
||||||
min-width="120"
|
min-width="120"
|
||||||
|
|
@ -509,6 +524,14 @@
|
||||||
<el-input v-model="form.ChildDataLabel" placeholder="请输入子数据Lable" />
|
<el-input v-model="form.ChildDataLabel" placeholder="请输入子数据Lable" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
|
<el-col v-show="form.ConfigType === 'C' && title !== '复制' && form.DataType === 'Array'" :span="12">
|
||||||
|
<el-form-item>
|
||||||
|
<span slot="label">
|
||||||
|
子数据LableEN
|
||||||
|
</span>
|
||||||
|
<el-input v-model="form.ChildDataEnLabel" placeholder="请输入子数据LableEN" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
<el-col v-show="form.ConfigType === 'C' && title !== '复制' && form.DataType === 'Array'" :span="12">
|
<el-col v-show="form.ConfigType === 'C' && title !== '复制' && form.DataType === 'Array'" :span="12">
|
||||||
<el-form-item>
|
<el-form-item>
|
||||||
<span slot="label">
|
<span slot="label">
|
||||||
|
|
@ -668,6 +691,7 @@
|
||||||
height="100"
|
height="100"
|
||||||
>
|
>
|
||||||
<el-table-column prop="Code" label="字段名" min-width="120px" :show-overflow-tooltip="true" />
|
<el-table-column prop="Code" label="字段名" min-width="120px" :show-overflow-tooltip="true" />
|
||||||
|
<el-table-column prop="CodeEn" label="字段名英文" min-width="120px" :show-overflow-tooltip="true" />
|
||||||
<el-table-column prop="Value" label="字段英文" min-width="120px" :show-overflow-tooltip="true" />
|
<el-table-column prop="Value" label="字段英文" min-width="120px" :show-overflow-tooltip="true" />
|
||||||
<el-table-column prop="ValueCN" label="字段中文" min-width="120px" :show-overflow-tooltip="true" />
|
<el-table-column prop="ValueCN" label="字段中文" min-width="120px" :show-overflow-tooltip="true" />
|
||||||
<el-table-column
|
<el-table-column
|
||||||
|
|
@ -848,6 +872,7 @@ export default {
|
||||||
FixedColumnName: null,
|
FixedColumnName: null,
|
||||||
FixedColumnEnName: null,
|
FixedColumnEnName: null,
|
||||||
ColumnName: null,
|
ColumnName: null,
|
||||||
|
ColumnEnName: null,
|
||||||
ColumnValue: null,
|
ColumnValue: null,
|
||||||
IsMerge: false,
|
IsMerge: false,
|
||||||
MergeColumnName: null,
|
MergeColumnName: null,
|
||||||
|
|
@ -1124,6 +1149,7 @@ export default {
|
||||||
IsShowParent: 0,
|
IsShowParent: 0,
|
||||||
Sort: 0,
|
Sort: 0,
|
||||||
Code: null,
|
Code: null,
|
||||||
|
CodeEn: null,
|
||||||
Value: null,
|
Value: null,
|
||||||
ValueCN: null,
|
ValueCN: null,
|
||||||
EnumType: '',
|
EnumType: '',
|
||||||
|
|
@ -1138,6 +1164,7 @@ export default {
|
||||||
IsSpecialType: false,
|
IsSpecialType: false,
|
||||||
DataType: '',
|
DataType: '',
|
||||||
ChildDataLabel: null,
|
ChildDataLabel: null,
|
||||||
|
ChildDataEnLabel: null,
|
||||||
ChildDataValue: null,
|
ChildDataValue: null,
|
||||||
DateType: null,
|
DateType: null,
|
||||||
DictionaryCode: null,
|
DictionaryCode: null,
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,15 @@
|
||||||
>
|
>
|
||||||
<div class="base-dialog-body">
|
<div class="base-dialog-body">
|
||||||
<el-form-item label="类型" prop="Type">
|
<el-form-item label="类型" prop="Type">
|
||||||
<el-select v-model="form.Type" clearable @change="((val)=>{typeChange(val, form)})">
|
<el-select
|
||||||
|
v-model="form.Type"
|
||||||
|
clearable
|
||||||
|
@change="
|
||||||
|
(val) => {
|
||||||
|
typeChange(val, form)
|
||||||
|
}
|
||||||
|
"
|
||||||
|
>
|
||||||
<el-option
|
<el-option
|
||||||
v-for="item of $d.Criterion_Question_Type"
|
v-for="item of $d.Criterion_Question_Type"
|
||||||
:key="item.value"
|
:key="item.value"
|
||||||
|
|
@ -31,10 +39,7 @@
|
||||||
v-if="form.Type === 'group'"
|
v-if="form.Type === 'group'"
|
||||||
prop="GroupClassify"
|
prop="GroupClassify"
|
||||||
>
|
>
|
||||||
<el-select
|
<el-select v-model="form.GroupClassify" clearable>
|
||||||
v-model="form.GroupClassify"
|
|
||||||
clearable
|
|
||||||
>
|
|
||||||
<el-option
|
<el-option
|
||||||
v-for="item of groupClassifyList"
|
v-for="item of groupClassifyList"
|
||||||
:key="item.Id"
|
:key="item.Id"
|
||||||
|
|
@ -70,13 +75,9 @@
|
||||||
v-if="form.Type === 'number' || form.Type === 'calculation'"
|
v-if="form.Type === 'number' || form.Type === 'calculation'"
|
||||||
label="数值类型"
|
label="数值类型"
|
||||||
prop="ValueType"
|
prop="ValueType"
|
||||||
:rules="[
|
:rules="[{ required: true, message: '请选择' }]"
|
||||||
{ required: true, message: '请选择'}
|
|
||||||
]"
|
|
||||||
>
|
|
||||||
<el-radio-group
|
|
||||||
v-model="form.ValueType"
|
|
||||||
>
|
>
|
||||||
|
<el-radio-group v-model="form.ValueType">
|
||||||
<el-radio
|
<el-radio
|
||||||
v-for="item of $d.ValueType"
|
v-for="item of $d.ValueType"
|
||||||
:key="item.id"
|
:key="item.id"
|
||||||
|
|
@ -92,9 +93,7 @@
|
||||||
v-if="form.Type === 'number' || form.Type === 'calculation'"
|
v-if="form.Type === 'number' || form.Type === 'calculation'"
|
||||||
label="单位"
|
label="单位"
|
||||||
>
|
>
|
||||||
<el-radio-group
|
<el-radio-group v-model="form.Unit">
|
||||||
v-model="form.Unit"
|
|
||||||
>
|
|
||||||
<el-radio
|
<el-radio
|
||||||
v-for="item of $d.ValueUnit"
|
v-for="item of $d.ValueUnit"
|
||||||
:key="item.id"
|
:key="item.id"
|
||||||
|
|
@ -109,15 +108,12 @@
|
||||||
label="表格类型标识"
|
label="表格类型标识"
|
||||||
prop="LesionType"
|
prop="LesionType"
|
||||||
>
|
>
|
||||||
<el-select
|
<el-select v-model="form.LesionType" clearable>
|
||||||
v-model="form.LesionType"
|
|
||||||
clearable
|
|
||||||
>
|
|
||||||
<el-option
|
<el-option
|
||||||
v-for="item of lesionTypes"
|
v-for="item of lesionTypes"
|
||||||
:key="item.Code"
|
:key="item.Code"
|
||||||
:value="parseInt(item.Code)"
|
:value="parseInt(item.Code)"
|
||||||
:label="$fd('LesionType',parseInt(item.Code))"
|
:label="$fd('LesionType', parseInt(item.Code))"
|
||||||
/>
|
/>
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
@ -133,25 +129,27 @@
|
||||||
</el-form-item> -->
|
</el-form-item> -->
|
||||||
<!-- 选项类型 -->
|
<!-- 选项类型 -->
|
||||||
<el-form-item
|
<el-form-item
|
||||||
v-if="form.Type === 'select' || form.Type === 'radio' || form.Type === 'calculation'"
|
v-if="
|
||||||
|
form.Type === 'select' ||
|
||||||
|
form.Type === 'radio' ||
|
||||||
|
form.Type === 'calculation'
|
||||||
|
"
|
||||||
label="选项类型"
|
label="选项类型"
|
||||||
prop="QuestionGenre"
|
prop="QuestionGenre"
|
||||||
:rules="[
|
:rules="[{ required: form.Type !== 'calculation', message: '请选择' }]"
|
||||||
{ required: form.Type !== 'calculation', message: '请选择'}
|
|
||||||
]"
|
|
||||||
>
|
>
|
||||||
<el-radio-group
|
<el-radio-group
|
||||||
v-model="form.QuestionGenre"
|
v-model="form.QuestionGenre"
|
||||||
@change="((val)=>{questionGenreChange(val, form)})"
|
@change="
|
||||||
|
(val) => {
|
||||||
|
questionGenreChange(val, form)
|
||||||
|
}
|
||||||
|
"
|
||||||
>
|
>
|
||||||
<el-radio
|
<el-radio :label="-1"> 无 </el-radio>
|
||||||
:label="-1"
|
|
||||||
>
|
|
||||||
无
|
|
||||||
</el-radio>
|
|
||||||
<el-radio
|
<el-radio
|
||||||
v-for="item of $d.TableQuestionType"
|
v-for="item of $d.TableQuestionType"
|
||||||
v-show="item.value===0 || item.value===3"
|
v-show="item.value === 0 || item.value === 3"
|
||||||
:key="item.id"
|
:key="item.id"
|
||||||
:label="item.value"
|
:label="item.value"
|
||||||
>
|
>
|
||||||
|
|
@ -183,13 +181,8 @@
|
||||||
/>
|
/>
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item
|
<el-form-item label="转化显示类型" prop="ConvertShowType">
|
||||||
label="转化显示类型"
|
<el-radio-group v-model="form.ConvertShowType">
|
||||||
prop="ConvertShowType"
|
|
||||||
>
|
|
||||||
<el-radio-group
|
|
||||||
v-model="form.ConvertShowType"
|
|
||||||
>
|
|
||||||
<el-radio
|
<el-radio
|
||||||
v-for="item of $d.ConvertShowType"
|
v-for="item of $d.ConvertShowType"
|
||||||
:key="item.id"
|
:key="item.id"
|
||||||
|
|
@ -200,11 +193,19 @@
|
||||||
</el-radio-group>
|
</el-radio-group>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item
|
<el-form-item
|
||||||
v-if="form.QuestionGenre === 3 "
|
v-if="form.QuestionGenre === 3"
|
||||||
label="关联字典"
|
label="关联字典"
|
||||||
prop="DictionaryCode"
|
prop="DictionaryCode"
|
||||||
>
|
>
|
||||||
<el-select v-model="form.DictionaryCode" clearable @change="() => {form.DefaultValue = null}">
|
<el-select
|
||||||
|
v-model="form.DictionaryCode"
|
||||||
|
clearable
|
||||||
|
@change="
|
||||||
|
() => {
|
||||||
|
form.DefaultValue = null
|
||||||
|
}
|
||||||
|
"
|
||||||
|
>
|
||||||
<el-option
|
<el-option
|
||||||
v-for="item of dicList"
|
v-for="item of dicList"
|
||||||
:key="item.Id"
|
:key="item.Id"
|
||||||
|
|
@ -213,10 +214,7 @@
|
||||||
/>
|
/>
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item
|
<el-form-item v-if="form.QuestionGenre === 3" label="默认值">
|
||||||
v-if="form.QuestionGenre === 3 "
|
|
||||||
label="默认值"
|
|
||||||
>
|
|
||||||
<el-select v-model="form.DefaultValue" clearable>
|
<el-select v-model="form.DefaultValue" clearable>
|
||||||
<el-option
|
<el-option
|
||||||
v-for="item of form.DictionaryCode ? $d[form.DictionaryCode] : []"
|
v-for="item of form.DictionaryCode ? $d[form.DictionaryCode] : []"
|
||||||
|
|
@ -226,10 +224,7 @@
|
||||||
/>
|
/>
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item
|
<el-form-item v-if="form.QuestionGenre === 0" label="默认值">
|
||||||
v-if="form.QuestionGenre === 0 "
|
|
||||||
label="默认值"
|
|
||||||
>
|
|
||||||
<el-select v-model="form.DefaultValue" clearable>
|
<el-select v-model="form.DefaultValue" clearable>
|
||||||
<el-option
|
<el-option
|
||||||
v-for="item of form.TypeValue ? form.TypeValue.split('|') : []"
|
v-for="item of form.TypeValue ? form.TypeValue.split('|') : []"
|
||||||
|
|
@ -240,10 +235,18 @@
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
||||||
<el-form-item v-if="form.Type !== 'group'" label="是否显示" prop="ShowQuestion">
|
<el-form-item
|
||||||
|
v-if="form.Type !== 'group'"
|
||||||
|
label="是否显示"
|
||||||
|
prop="ShowQuestion"
|
||||||
|
>
|
||||||
<el-radio-group
|
<el-radio-group
|
||||||
v-model="form.ShowQuestion"
|
v-model="form.ShowQuestion"
|
||||||
@change="((val)=>{isShowQuestionChange(val, form)})"
|
@change="
|
||||||
|
(val) => {
|
||||||
|
isShowQuestionChange(val, form)
|
||||||
|
}
|
||||||
|
"
|
||||||
>
|
>
|
||||||
<el-radio
|
<el-radio
|
||||||
v-for="item of $d.ShowQuestion"
|
v-for="item of $d.ShowQuestion"
|
||||||
|
|
@ -257,14 +260,18 @@
|
||||||
|
|
||||||
<!-- 显示时依赖父问题 -->
|
<!-- 显示时依赖父问题 -->
|
||||||
<el-form-item
|
<el-form-item
|
||||||
v-if="form.Type !== 'group' && form.ShowQuestion===1"
|
v-if="form.Type !== 'group' && form.ShowQuestion === 1"
|
||||||
label="显示依赖父问题"
|
label="显示依赖父问题"
|
||||||
prop="ParentId"
|
prop="ParentId"
|
||||||
>
|
>
|
||||||
<el-select
|
<el-select
|
||||||
v-model="form.ParentId"
|
v-model="form.ParentId"
|
||||||
clearable
|
clearable
|
||||||
@change="((val)=>{parentQuestionChange(val, form)})"
|
@change="
|
||||||
|
(val) => {
|
||||||
|
parentQuestionChange(val, form)
|
||||||
|
}
|
||||||
|
"
|
||||||
>
|
>
|
||||||
<el-option
|
<el-option
|
||||||
v-for="item of parentOptions"
|
v-for="item of parentOptions"
|
||||||
|
|
@ -275,15 +282,19 @@
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<!-- 显示时依赖父问题触发值 -->
|
<!-- 显示时依赖父问题触发值 -->
|
||||||
<el-form-item v-if="form.ParentId && form.ShowQuestion===1" label="显示触发值" prop="ParentTriggerValueList">
|
<el-form-item
|
||||||
<!-- <el-select v-model="form.ParentTriggerValue" clearable>-->
|
v-if="form.ParentId && form.ShowQuestion === 1"
|
||||||
<!-- <el-option-->
|
label="显示触发值"
|
||||||
<!-- v-for="item of parentTriggerValOptions"-->
|
prop="ParentTriggerValueList"
|
||||||
<!-- :key="item.id"-->
|
>
|
||||||
<!-- :label="item.label"-->
|
<!-- <el-select v-model="form.ParentTriggerValue" clearable>-->
|
||||||
<!-- :value="item.value.toString()"-->
|
<!-- <el-option-->
|
||||||
<!-- />-->
|
<!-- v-for="item of parentTriggerValOptions"-->
|
||||||
<!-- </el-select>-->
|
<!-- :key="item.id"-->
|
||||||
|
<!-- :label="item.label"-->
|
||||||
|
<!-- :value="item.value.toString()"-->
|
||||||
|
<!-- />-->
|
||||||
|
<!-- </el-select>-->
|
||||||
<el-select v-model="form.ParentTriggerValueList" clearable multiple>
|
<el-select v-model="form.ParentTriggerValueList" clearable multiple>
|
||||||
<el-option
|
<el-option
|
||||||
v-for="item of parentTriggerValOptions"
|
v-for="item of parentTriggerValOptions"
|
||||||
|
|
@ -293,16 +304,44 @@
|
||||||
/>
|
/>
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item v-if="form.Type === 'select' || form.Type === 'radio' || form.Type === 'calculation'" label="是否裁判问题">
|
<el-form-item
|
||||||
<el-radio-group v-model="form.IsJudgeQuestion" @change="((val)=>{isJudgeQuestionChange(val, form)})">
|
v-if="
|
||||||
<el-radio v-for="item of $d.YesOrNo" :key="`YesOrNo${item.value}`" :label="item.value">{{ item.label }}</el-radio>
|
form.Type === 'select' ||
|
||||||
|
form.Type === 'radio' ||
|
||||||
|
form.Type === 'calculation' ||
|
||||||
|
form.Type === 'number'
|
||||||
|
"
|
||||||
|
label="是否裁判问题"
|
||||||
|
>
|
||||||
|
<el-radio-group
|
||||||
|
v-model="form.IsJudgeQuestion"
|
||||||
|
@change="
|
||||||
|
(val) => {
|
||||||
|
isJudgeQuestionChange(val, form)
|
||||||
|
}
|
||||||
|
"
|
||||||
|
>
|
||||||
|
<el-radio
|
||||||
|
v-for="item of $d.YesOrNo"
|
||||||
|
:key="`YesOrNo${item.value}`"
|
||||||
|
:label="item.value"
|
||||||
|
>{{ item.label }}</el-radio
|
||||||
|
>
|
||||||
</el-radio-group>
|
</el-radio-group>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item v-if="form.Type !== 'group' && form.Type !== 'table'" label="是否必填" prop="IsRequired">
|
<el-form-item
|
||||||
|
v-if="form.Type !== 'group' && form.Type !== 'table'"
|
||||||
|
label="是否必填"
|
||||||
|
prop="IsRequired"
|
||||||
|
>
|
||||||
<el-radio-group
|
<el-radio-group
|
||||||
v-model="form.IsRequired"
|
v-model="form.IsRequired"
|
||||||
:disabled="form.IsJudgeQuestion===true || form.ShowQuestion===2"
|
:disabled="form.IsJudgeQuestion === true || form.ShowQuestion === 2"
|
||||||
@change="((val)=>{isRequiredChange(val, form)})"
|
@change="
|
||||||
|
(val) => {
|
||||||
|
isRequiredChange(val, form)
|
||||||
|
}
|
||||||
|
"
|
||||||
>
|
>
|
||||||
<el-radio
|
<el-radio
|
||||||
v-for="item of $d.QuestionRequired"
|
v-for="item of $d.QuestionRequired"
|
||||||
|
|
@ -323,7 +362,11 @@
|
||||||
<el-select
|
<el-select
|
||||||
v-model="form.RelevanceId"
|
v-model="form.RelevanceId"
|
||||||
clearable
|
clearable
|
||||||
@change="((val)=>{relevanceQuestionChange(val, form)})"
|
@change="
|
||||||
|
(val) => {
|
||||||
|
relevanceQuestionChange(val, form)
|
||||||
|
}
|
||||||
|
"
|
||||||
>
|
>
|
||||||
<el-option
|
<el-option
|
||||||
v-for="item of parentOptions"
|
v-for="item of parentOptions"
|
||||||
|
|
@ -339,14 +382,14 @@
|
||||||
label="必填触发值"
|
label="必填触发值"
|
||||||
prop="RelevanceValueList"
|
prop="RelevanceValueList"
|
||||||
>
|
>
|
||||||
<!-- <el-select v-model="form.RelevanceValue" clearable>-->
|
<!-- <el-select v-model="form.RelevanceValue" clearable>-->
|
||||||
<!-- <el-option-->
|
<!-- <el-option-->
|
||||||
<!-- v-for="item of reParentTriggerValOptions"-->
|
<!-- v-for="item of reParentTriggerValOptions"-->
|
||||||
<!-- :key="item.id"-->
|
<!-- :key="item.id"-->
|
||||||
<!-- :label="item.label"-->
|
<!-- :label="item.label"-->
|
||||||
<!-- :value="item.value.toString()"-->
|
<!-- :value="item.value.toString()"-->
|
||||||
<!-- />-->
|
<!-- />-->
|
||||||
<!-- </el-select>-->
|
<!-- </el-select>-->
|
||||||
<el-select v-model="form.RelevanceValueList" clearable multiple>
|
<el-select v-model="form.RelevanceValueList" clearable multiple>
|
||||||
<el-option
|
<el-option
|
||||||
v-for="item of reParentTriggerValOptions"
|
v-for="item of reParentTriggerValOptions"
|
||||||
|
|
@ -385,7 +428,11 @@
|
||||||
</el-form-item> -->
|
</el-form-item> -->
|
||||||
|
|
||||||
<el-form-item v-if="form.Type !== 'group'" label="问题分组">
|
<el-form-item v-if="form.Type !== 'group'" label="问题分组">
|
||||||
<el-select v-model="form.GroupId" clearable :disabled="isParentExistGroup">
|
<el-select
|
||||||
|
v-model="form.GroupId"
|
||||||
|
clearable
|
||||||
|
:disabled="isParentExistGroup"
|
||||||
|
>
|
||||||
<el-option
|
<el-option
|
||||||
v-for="group of groupOptions"
|
v-for="group of groupOptions"
|
||||||
:key="group.GroupId"
|
:key="group.GroupId"
|
||||||
|
|
@ -396,12 +443,22 @@
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="限制编辑">
|
<el-form-item label="限制编辑">
|
||||||
<el-radio-group v-model="form.LimitEdit">
|
<el-radio-group v-model="form.LimitEdit">
|
||||||
<el-radio v-for="item of $d.LimitEdit" :key="`LimitEdit${item.value}`" :label="item.value">{{ item.label }}</el-radio>
|
<el-radio
|
||||||
|
v-for="item of $d.LimitEdit"
|
||||||
|
:key="`LimitEdit${item.value}`"
|
||||||
|
:label="item.value"
|
||||||
|
>{{ item.label }}</el-radio
|
||||||
|
>
|
||||||
</el-radio-group>
|
</el-radio-group>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="全局阅片是否显示">
|
<el-form-item label="全局阅片是否显示">
|
||||||
<el-radio-group v-model="form.GlobalReadingShowType">
|
<el-radio-group v-model="form.GlobalReadingShowType">
|
||||||
<el-radio v-for="item of $d.GlobalReadingShowType" :key="item.id" :label="item.value">{{ item.label }}</el-radio>
|
<el-radio
|
||||||
|
v-for="item of $d.GlobalReadingShowType"
|
||||||
|
:key="item.id"
|
||||||
|
:label="item.value"
|
||||||
|
>{{ item.label }}</el-radio
|
||||||
|
>
|
||||||
</el-radio-group>
|
</el-radio-group>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item
|
<el-form-item
|
||||||
|
|
@ -409,10 +466,7 @@
|
||||||
v-if="form.Type !== 'group'"
|
v-if="form.Type !== 'group'"
|
||||||
prop="QuestionType"
|
prop="QuestionType"
|
||||||
>
|
>
|
||||||
<el-select
|
<el-select v-model="form.QuestionType" clearable>
|
||||||
v-model="form.QuestionType"
|
|
||||||
clearable
|
|
||||||
>
|
|
||||||
<el-option
|
<el-option
|
||||||
v-for="item of CriterionDictionaryList.QuestionType"
|
v-for="item of CriterionDictionaryList.QuestionType"
|
||||||
:key="item.Id"
|
:key="item.Id"
|
||||||
|
|
@ -428,9 +482,18 @@
|
||||||
</el-radio-group>
|
</el-radio-group>
|
||||||
</el-form-item> -->
|
</el-form-item> -->
|
||||||
<el-form-item v-if="form.Type === 'upload'" label="最大上传个数">
|
<el-form-item v-if="form.Type === 'upload'" label="最大上传个数">
|
||||||
<el-input-number v-model="form.ImageCount" controls-position="right" :min="1" :max="10" />
|
<el-input-number
|
||||||
|
v-model="form.ImageCount"
|
||||||
|
controls-position="right"
|
||||||
|
:min="1"
|
||||||
|
:max="10"
|
||||||
|
/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item v-if="form.Type === 'select' || form.Type === 'radio'" label="高亮标记值" prop="HighlightAnswerList">
|
<el-form-item
|
||||||
|
v-if="form.Type === 'select' || form.Type === 'radio'"
|
||||||
|
label="高亮标记值"
|
||||||
|
prop="HighlightAnswerList"
|
||||||
|
>
|
||||||
<el-select v-model="form.HighlightAnswerList" clearable multiple>
|
<el-select v-model="form.HighlightAnswerList" clearable multiple>
|
||||||
<template v-if="form.TypeValue">
|
<template v-if="form.TypeValue">
|
||||||
<el-option
|
<el-option
|
||||||
|
|
@ -471,20 +534,23 @@
|
||||||
|
|
||||||
<el-form-item label="是否在阅片页面显示">
|
<el-form-item label="是否在阅片页面显示">
|
||||||
<el-radio-group v-model="form.IsShowInDicom">
|
<el-radio-group v-model="form.IsShowInDicom">
|
||||||
<el-radio v-for="item of $d.YesOrNo" :key="`YesOrNo${item.value}`" :label="item.value">{{ item.label }}</el-radio>
|
<el-radio
|
||||||
|
v-for="item of $d.YesOrNo"
|
||||||
|
:key="`YesOrNo${item.value}`"
|
||||||
|
:label="item.value"
|
||||||
|
>{{ item.label }}</el-radio
|
||||||
|
>
|
||||||
</el-radio-group>
|
</el-radio-group>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item
|
<el-form-item
|
||||||
:label="$t('trials:readingUnit:qsList:title:Remark')"
|
:label="$t('trials:readingUnit:qsList:title:Remark')"
|
||||||
prop="Remark"
|
prop="Remark"
|
||||||
>
|
>
|
||||||
<el-input
|
<el-input v-model="form.Remark" />
|
||||||
v-model="form.Remark"
|
|
||||||
/>
|
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="base-dialog-footer" style="text-align:right;margin-top:10px;">
|
<div class="base-dialog-footer" style="text-align: right; margin-top: 10px">
|
||||||
<el-form-item>
|
<el-form-item>
|
||||||
<!-- 取消 -->
|
<!-- 取消 -->
|
||||||
<el-button
|
<el-button
|
||||||
|
|
@ -496,7 +562,12 @@
|
||||||
{{ $t('common:button:cancel') }}
|
{{ $t('common:button:cancel') }}
|
||||||
</el-button>
|
</el-button>
|
||||||
<!-- 保存 -->
|
<!-- 保存 -->
|
||||||
<el-button size="small" type="primary" :loading="btnLoading" @click="save">
|
<el-button
|
||||||
|
size="small"
|
||||||
|
type="primary"
|
||||||
|
:loading="btnLoading"
|
||||||
|
@click="save"
|
||||||
|
>
|
||||||
{{ $t('common:button:save') }}
|
{{ $t('common:button:save') }}
|
||||||
</el-button>
|
</el-button>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
@ -504,19 +575,30 @@
|
||||||
</el-form>
|
</el-form>
|
||||||
</template>
|
</template>
|
||||||
<script>
|
<script>
|
||||||
import { getBasicConfigSelect, addOrUpdateReadingQuestionSystem, getSystemCriterionOtherQuestion, getSystemGroupNameList, getCriterionDictionary, getCriterionDictionaryList } from '@/api/dictionary'
|
import {
|
||||||
|
getBasicConfigSelect,
|
||||||
|
addOrUpdateReadingQuestionSystem,
|
||||||
|
getSystemCriterionOtherQuestion,
|
||||||
|
getSystemGroupNameList,
|
||||||
|
getCriterionDictionary,
|
||||||
|
getCriterionDictionaryList,
|
||||||
|
} from '@/api/dictionary'
|
||||||
import { getCriterionLesionType } from '@/api/trials'
|
import { getCriterionLesionType } from '@/api/trials'
|
||||||
export default {
|
export default {
|
||||||
name: 'AddOrUpdateClinicalData',
|
name: 'AddOrUpdateClinicalData',
|
||||||
props: {
|
props: {
|
||||||
data: {
|
data: {
|
||||||
type: Object,
|
type: Object,
|
||||||
default() { return {} }
|
default() {
|
||||||
|
return {}
|
||||||
|
},
|
||||||
},
|
},
|
||||||
type: {
|
type: {
|
||||||
type: String,
|
type: String,
|
||||||
default() { return '' }
|
default() {
|
||||||
}
|
return ''
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
var validateTypeVal = (rule, value, callback) => {
|
var validateTypeVal = (rule, value, callback) => {
|
||||||
|
|
@ -553,7 +635,7 @@ export default {
|
||||||
IsJudgeQuestion: false,
|
IsJudgeQuestion: false,
|
||||||
GroupName: '',
|
GroupName: '',
|
||||||
GroupEnName: '',
|
GroupEnName: '',
|
||||||
GroupClassify:null,
|
GroupClassify: null,
|
||||||
Remark: '',
|
Remark: '',
|
||||||
ImageCount: 1,
|
ImageCount: 1,
|
||||||
RelevanceId: '',
|
RelevanceId: '',
|
||||||
|
|
@ -570,32 +652,38 @@ export default {
|
||||||
GroupId: null,
|
GroupId: null,
|
||||||
ConvertShowType: 0,
|
ConvertShowType: 0,
|
||||||
QuestionClassify: null,
|
QuestionClassify: null,
|
||||||
HighlightAnswerList: []
|
HighlightAnswerList: [],
|
||||||
},
|
},
|
||||||
rules: {
|
rules: {
|
||||||
Type: [
|
Type: [{ required: true, message: '请选择', trigger: 'blur' }],
|
||||||
{ required: true, message: '请选择', trigger: 'blur' }
|
LesionType: [{ required: true, message: '请选择', trigger: 'blur' }],
|
||||||
|
QuestionName: [
|
||||||
|
{ required: true, message: '请注明', trigger: 'blur' },
|
||||||
|
{ max: 300, message: '最大长度为 300' },
|
||||||
],
|
],
|
||||||
LesionType: [
|
|
||||||
{ required: true, message: '请选择', trigger: 'blur' }
|
|
||||||
],
|
|
||||||
QuestionName: [{ required: true, message: '请注明', trigger: 'blur' },
|
|
||||||
{ max: 300, message: '最大长度为 300' }],
|
|
||||||
QuestionGenre: [{ required: true, message: '请选择', trigger: 'blur' }],
|
QuestionGenre: [{ required: true, message: '请选择', trigger: 'blur' }],
|
||||||
TypeValue: [{ required: true, message: '请注明', trigger: 'blur' },
|
TypeValue: [
|
||||||
|
{ required: true, message: '请注明', trigger: 'blur' },
|
||||||
{ validator: validateTypeVal, trigger: 'blur' },
|
{ validator: validateTypeVal, trigger: 'blur' },
|
||||||
{ max: 500, message: '最大长度为 500' }],
|
{ max: 500, message: '最大长度为 500' },
|
||||||
DictionaryCode: [{ required: true, message: '请选择', trigger: 'blur' }],
|
],
|
||||||
|
DictionaryCode: [
|
||||||
|
{ required: true, message: '请选择', trigger: 'blur' },
|
||||||
|
],
|
||||||
ShowQuestion: [{ required: true, message: '请选择', trigger: 'blur' }],
|
ShowQuestion: [{ required: true, message: '请选择', trigger: 'blur' }],
|
||||||
IsRequired: [{ required: true, message: '请选择', trigger: 'blur' }],
|
IsRequired: [{ required: true, message: '请选择', trigger: 'blur' }],
|
||||||
ParentId: [{ required: true, message: '请选择', trigger: 'blur' }],
|
ParentId: [{ required: true, message: '请选择', trigger: 'blur' }],
|
||||||
ParentTriggerValueList: [
|
ParentTriggerValueList: [
|
||||||
{ required: true, message: '请选择', trigger: 'blur' }
|
{ required: true, message: '请选择', trigger: 'blur' },
|
||||||
],
|
],
|
||||||
RelevanceId: [{ required: true, message: '请选择', trigger: 'blur' }],
|
RelevanceId: [{ required: true, message: '请选择', trigger: 'blur' }],
|
||||||
RelevanceValueList: [{ required: true, message: '请选择', trigger: 'blur' }],
|
RelevanceValueList: [
|
||||||
GroupName: [{ required: true, message: '请注明', trigger: 'blur' },
|
{ required: true, message: '请选择', trigger: 'blur' },
|
||||||
{ max: 50, message: '最大长度为 50' }]
|
],
|
||||||
|
GroupName: [
|
||||||
|
{ required: true, message: '请注明', trigger: 'blur' },
|
||||||
|
{ max: 50, message: '最大长度为 50' },
|
||||||
|
],
|
||||||
},
|
},
|
||||||
loading: false,
|
loading: false,
|
||||||
btnLoading: false,
|
btnLoading: false,
|
||||||
|
|
@ -606,8 +694,8 @@ export default {
|
||||||
lesionTypes: [],
|
lesionTypes: [],
|
||||||
dicList: [],
|
dicList: [],
|
||||||
CriterionDictionaryList: [],
|
CriterionDictionaryList: [],
|
||||||
groupClassifyList:[],
|
groupClassifyList: [],
|
||||||
highlightAnswers: []
|
highlightAnswers: [],
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
|
|
@ -622,14 +710,14 @@ export default {
|
||||||
}
|
}
|
||||||
let res = await getCriterionDictionary({
|
let res = await getCriterionDictionary({
|
||||||
ReadingCriterionId: this.data.ReadingQuestionCriterionSystemId,
|
ReadingCriterionId: this.data.ReadingQuestionCriterionSystemId,
|
||||||
DictionaryCode: this.form.DictionaryCode
|
DictionaryCode: this.form.DictionaryCode,
|
||||||
})
|
})
|
||||||
this.highlightAnswers = res.Result[this.form.DictionaryCode]
|
this.highlightAnswers = res.Result[this.form.DictionaryCode]
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.log(e)
|
console.log(e)
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
this.initForm()
|
this.initForm()
|
||||||
|
|
@ -638,16 +726,16 @@ export default {
|
||||||
getCriterionDictionary() {
|
getCriterionDictionary() {
|
||||||
getCriterionDictionary({
|
getCriterionDictionary({
|
||||||
ReadingCriterionId: this.data.ReadingQuestionCriterionSystemId,
|
ReadingCriterionId: this.data.ReadingQuestionCriterionSystemId,
|
||||||
DictionaryCode: 'QuestionType'
|
DictionaryCode: 'QuestionType',
|
||||||
}).then(res => {
|
}).then((res) => {
|
||||||
this.CriterionDictionaryList = res.Result
|
this.CriterionDictionaryList = res.Result
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
getGroupClassifyDictionary() {
|
getGroupClassifyDictionary() {
|
||||||
getCriterionDictionary({
|
getCriterionDictionary({
|
||||||
ReadingCriterionId: this.data.ReadingQuestionCriterionSystemId,
|
ReadingCriterionId: this.data.ReadingQuestionCriterionSystemId,
|
||||||
DictionaryCode: 'GroupClassify'
|
DictionaryCode: 'GroupClassify',
|
||||||
}).then(res => {
|
}).then((res) => {
|
||||||
this.groupClassifyList = res.Result.GroupClassify
|
this.groupClassifyList = res.Result.GroupClassify
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
@ -661,37 +749,47 @@ export default {
|
||||||
this.form[k] = this.data[k]
|
this.form[k] = this.data[k]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (this.form.ParentId !== '' && this.form.ParentId !== null && this.form.GroupName !== '') {
|
if (
|
||||||
|
this.form.ParentId !== '' &&
|
||||||
|
this.form.ParentId !== null &&
|
||||||
|
this.form.GroupName !== ''
|
||||||
|
) {
|
||||||
this.isParentExistGroup = true
|
this.isParentExistGroup = true
|
||||||
}
|
}
|
||||||
if (this.form.ParentId) {
|
if (this.form.ParentId) {
|
||||||
var index = this.parentOptions.findIndex(item => {
|
var index = this.parentOptions.findIndex((item) => {
|
||||||
return item.QuestionId === this.form.ParentId
|
return item.QuestionId === this.form.ParentId
|
||||||
})
|
})
|
||||||
if (index !== -1) {
|
if (index !== -1) {
|
||||||
if (this.parentOptions[index].QuestionGenre === 3) {
|
if (this.parentOptions[index].QuestionGenre === 3) {
|
||||||
this.parentTriggerValOptions = this.$d[this.parentOptions[index].DictionaryCode]
|
this.parentTriggerValOptions =
|
||||||
|
this.$d[this.parentOptions[index].DictionaryCode]
|
||||||
} else {
|
} else {
|
||||||
const options = []
|
const options = []
|
||||||
this.parentOptions[index].TypeValue.split('|').forEach((item, index) => {
|
this.parentOptions[index].TypeValue.split('|').forEach(
|
||||||
|
(item, index) => {
|
||||||
options.push({ id: index, label: item, value: item })
|
options.push({ id: index, label: item, value: item })
|
||||||
})
|
}
|
||||||
|
)
|
||||||
this.parentTriggerValOptions = options
|
this.parentTriggerValOptions = options
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (this.form.RelevanceId) {
|
if (this.form.RelevanceId) {
|
||||||
var index = this.parentOptions.findIndex(item => {
|
var index = this.parentOptions.findIndex((item) => {
|
||||||
return item.QuestionId === this.form.RelevanceId
|
return item.QuestionId === this.form.RelevanceId
|
||||||
})
|
})
|
||||||
if (index !== -1) {
|
if (index !== -1) {
|
||||||
if (this.parentOptions[index].QuestionGenre === 3) {
|
if (this.parentOptions[index].QuestionGenre === 3) {
|
||||||
this.reParentTriggerValOptions = this.$d[this.parentOptions[index].DictionaryCode]
|
this.reParentTriggerValOptions =
|
||||||
|
this.$d[this.parentOptions[index].DictionaryCode]
|
||||||
} else {
|
} else {
|
||||||
const options = []
|
const options = []
|
||||||
this.parentOptions[index].TypeValue.split('|').forEach((item, index) => {
|
this.parentOptions[index].TypeValue.split('|').forEach(
|
||||||
|
(item, index) => {
|
||||||
options.push({ id: index, label: item, value: item })
|
options.push({ id: index, label: item, value: item })
|
||||||
})
|
}
|
||||||
|
)
|
||||||
this.reParentTriggerValOptions = options
|
this.reParentTriggerValOptions = options
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -701,13 +799,14 @@ export default {
|
||||||
this.getGroupClassifyDictionary()
|
this.getGroupClassifyDictionary()
|
||||||
},
|
},
|
||||||
save() {
|
save() {
|
||||||
this.$refs.clinicalDataForm.validate(valid => {
|
this.$refs.clinicalDataForm.validate((valid) => {
|
||||||
if (!valid) return
|
if (!valid) return
|
||||||
this.btnLoading = true
|
this.btnLoading = true
|
||||||
if (this.form.Type !== 'upload') {
|
if (this.form.Type !== 'upload') {
|
||||||
this.form.ImageCount = 0
|
this.form.ImageCount = 0
|
||||||
}
|
}
|
||||||
addOrUpdateReadingQuestionSystem(this.form).then(res => {
|
addOrUpdateReadingQuestionSystem(this.form)
|
||||||
|
.then((res) => {
|
||||||
this.btnLoading = false
|
this.btnLoading = false
|
||||||
this.$emit('getList')
|
this.$emit('getList')
|
||||||
this.$emit('close')
|
this.$emit('close')
|
||||||
|
|
@ -722,13 +821,15 @@ export default {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
this.loading = true
|
this.loading = true
|
||||||
var param = {
|
var param = {
|
||||||
criterionId: this.data.ReadingQuestionCriterionSystemId
|
criterionId: this.data.ReadingQuestionCriterionSystemId,
|
||||||
}
|
}
|
||||||
getSystemGroupNameList(param).then(res => {
|
getSystemGroupNameList(param)
|
||||||
|
.then((res) => {
|
||||||
this.groupOptions = res.Result
|
this.groupOptions = res.Result
|
||||||
this.loading = false
|
this.loading = false
|
||||||
resolve()
|
resolve()
|
||||||
}).catch(() => {
|
})
|
||||||
|
.catch(() => {
|
||||||
this.loading = false
|
this.loading = false
|
||||||
reject()
|
reject()
|
||||||
})
|
})
|
||||||
|
|
@ -738,14 +839,17 @@ export default {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
this.loading = true
|
this.loading = true
|
||||||
var param = {
|
var param = {
|
||||||
readingQuestionCriterionSystemId: this.data.ReadingQuestionCriterionSystemId,
|
readingQuestionCriterionSystemId:
|
||||||
id: this.data.Id
|
this.data.ReadingQuestionCriterionSystemId,
|
||||||
|
id: this.data.Id,
|
||||||
}
|
}
|
||||||
getSystemCriterionOtherQuestion(param).then(res => {
|
getSystemCriterionOtherQuestion(param)
|
||||||
|
.then((res) => {
|
||||||
this.parentOptions = res.Result
|
this.parentOptions = res.Result
|
||||||
this.loading = false
|
this.loading = false
|
||||||
resolve()
|
resolve()
|
||||||
}).catch(() => {
|
})
|
||||||
|
.catch(() => {
|
||||||
this.loading = false
|
this.loading = false
|
||||||
reject()
|
reject()
|
||||||
})
|
})
|
||||||
|
|
@ -819,17 +923,20 @@ export default {
|
||||||
parentQuestionChange(val, form) {
|
parentQuestionChange(val, form) {
|
||||||
this.isParentExistGroup = false
|
this.isParentExistGroup = false
|
||||||
if (val) {
|
if (val) {
|
||||||
var index = this.parentOptions.findIndex(item => {
|
var index = this.parentOptions.findIndex((item) => {
|
||||||
return item.QuestionId === val
|
return item.QuestionId === val
|
||||||
})
|
})
|
||||||
if (index !== -1) {
|
if (index !== -1) {
|
||||||
if (this.parentOptions[index].QuestionGenre === 3) {
|
if (this.parentOptions[index].QuestionGenre === 3) {
|
||||||
this.parentTriggerValOptions = this.$d[this.parentOptions[index].DictionaryCode]
|
this.parentTriggerValOptions =
|
||||||
|
this.$d[this.parentOptions[index].DictionaryCode]
|
||||||
} else {
|
} else {
|
||||||
var options = []
|
var options = []
|
||||||
this.parentOptions[index].TypeValue.split('|').forEach((item, index) => {
|
this.parentOptions[index].TypeValue.split('|').forEach(
|
||||||
|
(item, index) => {
|
||||||
options.push({ id: index, label: item, value: item })
|
options.push({ id: index, label: item, value: item })
|
||||||
})
|
}
|
||||||
|
)
|
||||||
this.parentTriggerValOptions = options
|
this.parentTriggerValOptions = options
|
||||||
}
|
}
|
||||||
if (this.parentOptions[index].GroupName) {
|
if (this.parentOptions[index].GroupName) {
|
||||||
|
|
@ -845,17 +952,20 @@ export default {
|
||||||
},
|
},
|
||||||
relevanceQuestionChange(val, form) {
|
relevanceQuestionChange(val, form) {
|
||||||
if (val) {
|
if (val) {
|
||||||
var index = this.parentOptions.findIndex(item => {
|
var index = this.parentOptions.findIndex((item) => {
|
||||||
return item.QuestionId === val
|
return item.QuestionId === val
|
||||||
})
|
})
|
||||||
if (index !== -1) {
|
if (index !== -1) {
|
||||||
if (this.parentOptions[index].QuestionGenre === 3) {
|
if (this.parentOptions[index].QuestionGenre === 3) {
|
||||||
this.reParentTriggerValOptions = this.$d[this.parentOptions[index].DictionaryCode]
|
this.reParentTriggerValOptions =
|
||||||
|
this.$d[this.parentOptions[index].DictionaryCode]
|
||||||
} else {
|
} else {
|
||||||
var options = []
|
var options = []
|
||||||
this.parentOptions[index].TypeValue.split('|').forEach((item, index) => {
|
this.parentOptions[index].TypeValue.split('|').forEach(
|
||||||
|
(item, index) => {
|
||||||
options.push({ id: index, label: item, value: item })
|
options.push({ id: index, label: item, value: item })
|
||||||
})
|
}
|
||||||
|
)
|
||||||
this.reParentTriggerValOptions = options
|
this.reParentTriggerValOptions = options
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -871,13 +981,15 @@ export default {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
this.loading = true
|
this.loading = true
|
||||||
var param = {
|
var param = {
|
||||||
SystemCriterionId: this.data.ReadingQuestionCriterionSystemId
|
SystemCriterionId: this.data.ReadingQuestionCriterionSystemId,
|
||||||
}
|
}
|
||||||
getCriterionLesionType(param).then(res => {
|
getCriterionLesionType(param)
|
||||||
|
.then((res) => {
|
||||||
this.lesionTypes = res.Result
|
this.lesionTypes = res.Result
|
||||||
this.loading = false
|
this.loading = false
|
||||||
resolve()
|
resolve()
|
||||||
}).catch(() => {
|
})
|
||||||
|
.catch(() => {
|
||||||
this.loading = false
|
this.loading = false
|
||||||
reject()
|
reject()
|
||||||
})
|
})
|
||||||
|
|
@ -885,9 +997,8 @@ export default {
|
||||||
},
|
},
|
||||||
close() {
|
close() {
|
||||||
this.$emit('close')
|
this.$emit('close')
|
||||||
}
|
},
|
||||||
|
},
|
||||||
}
|
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
|
|
|
||||||
|
|
@ -69,7 +69,7 @@
|
||||||
>{{ item.label }}</el-radio>
|
>{{ item.label }}</el-radio>
|
||||||
</el-radio-group>
|
</el-radio-group>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="序号">
|
<el-form-item label="序号" prop="ShowOrder">
|
||||||
<el-input v-model="form.ShowOrder" type="number" />
|
<el-input v-model="form.ShowOrder" type="number" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<!-- 描述 -->
|
<!-- 描述 -->
|
||||||
|
|
@ -135,7 +135,8 @@ export default {
|
||||||
Part: [{ required: true, message: this.$t('common:ruleMessage:specify'), trigger: ['blur'] }],
|
Part: [{ required: true, message: this.$t('common:ruleMessage:specify'), trigger: ['blur'] }],
|
||||||
TULOC: [{ required: true, message: this.$t('common:ruleMessage:specify'), trigger: ['blur'] }],
|
TULOC: [{ required: true, message: this.$t('common:ruleMessage:specify'), trigger: ['blur'] }],
|
||||||
Remark: [{ max: 500, message: `${this.$t('common:ruleMessage:maxLength')} 500`, trigger: ['blur', 'change'] }],
|
Remark: [{ max: 500, message: `${this.$t('common:ruleMessage:maxLength')} 500`, trigger: ['blur', 'change'] }],
|
||||||
IsLymphNodes: [{ required: true, message: this.$t('common:ruleMessage:select'), trigger: ['blur'] }]
|
IsLymphNodes: [{ required: true, message: this.$t('common:ruleMessage:select'), trigger: ['blur'] }],
|
||||||
|
ShowOrder: [{ required: true, message: this.$t('common:ruleMessage:specify'), trigger: ['blur'] }]
|
||||||
},
|
},
|
||||||
lesionTypes: [],
|
lesionTypes: [],
|
||||||
loading: false,
|
loading: false,
|
||||||
|
|
|
||||||
|
|
@ -2,52 +2,65 @@
|
||||||
<div v-loading="loading" class="img-container">
|
<div v-loading="loading" class="img-container">
|
||||||
<el-card class="box-card left">
|
<el-card class="box-card left">
|
||||||
<div class="title">
|
<div class="title">
|
||||||
{{$t('trials:none-dicom-show:fileList')}}
|
{{ $t('trials:none-dicom-show:fileList') }}
|
||||||
</div>
|
</div>
|
||||||
<div class="left-content">
|
<div class="left-content">
|
||||||
<!-- 检查层级 -->
|
<!-- 检查层级 -->
|
||||||
<div v-for="(study,i) in studyList" :key="study.CodeView">
|
<div v-for="(study, i) in studyList" :key="study.CodeView">
|
||||||
<div class="study-desc">
|
<div class="study-desc">
|
||||||
<span>{{ study.CodeView }}</span>
|
<span>{{ study.CodeView }}</span>
|
||||||
<span style="margin:0 5px">{{ study.Modality }}</span>
|
<span style="margin: 0 5px">{{ study.Modality }}</span>
|
||||||
<span>{{ getBodyPart(study.BodyPart) }}</span>
|
<span>{{ getBodyPart(study.BodyPart) }}</span>
|
||||||
</div>
|
</div>
|
||||||
<!-- 文件层级 -->
|
<!-- 文件层级 -->
|
||||||
<div v-if="study.NoneDicomStudyFileList.length === 0" class="empty-text">
|
|
||||||
<slot name="empty">暂无数据</slot>
|
|
||||||
</div>
|
|
||||||
<div v-else id="imgList" style="height:100%;overflow: hidden">
|
|
||||||
<div
|
<div
|
||||||
v-for="(item,j) in study.NoneDicomStudyFileList"
|
v-if="study.NoneDicomStudyFileList.length === 0"
|
||||||
|
class="empty-text"
|
||||||
|
>
|
||||||
|
<slot name="empty">{{ $t('trials:audit:message:noData') }}</slot>
|
||||||
|
</div>
|
||||||
|
<div v-else id="imgList" style="height: 100%; overflow: hidden">
|
||||||
|
<div
|
||||||
|
v-for="(item, j) in study.NoneDicomStudyFileList"
|
||||||
:id="`img${item.Id}`"
|
:id="`img${item.Id}`"
|
||||||
:key="item.Id"
|
:key="item.Id"
|
||||||
:class="{
|
:class="{
|
||||||
'is-boxActive': item.Id === currentFileId
|
'is-boxActive': item.Id === currentFileId,
|
||||||
}"
|
}"
|
||||||
class="img-box"
|
class="img-box"
|
||||||
@click="selected(item,i,j,true)"
|
@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>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</el-card>
|
</el-card>
|
||||||
<!-- 预览图像 -->
|
<!-- 预览图像 -->
|
||||||
<el-card class="box-card right">
|
<el-card class="box-card right">
|
||||||
<div style="width:100%;height: 100%;">
|
<div style="width: 100%; height: 100%">
|
||||||
<Preview v-if="previewImage.imgList.length > 0" ref="previewImage" style="width:100%;" :preview-image="previewImage" :value="currentStudyFileIndex" @selectedImg="selectedImg" />
|
<Preview
|
||||||
|
v-if="previewImage.imgList.length > 0"
|
||||||
|
ref="previewImage"
|
||||||
|
style="width: 100%"
|
||||||
|
:preview-image="previewImage"
|
||||||
|
:value="currentStudyFileIndex"
|
||||||
|
@selectedImg="selectedImg"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</el-card>
|
</el-card>
|
||||||
|
|
||||||
<!-- <el-card class="box-card" style="width:300px;height:100%;padding: 10px;margin-left:10px;">
|
<!-- <el-card class="box-card" style="width:300px;height:100%;padding: 10px;margin-left:10px;">
|
||||||
<CheckForm />
|
<CheckForm />
|
||||||
</el-card> -->
|
</el-card> -->
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
|
@ -59,7 +72,7 @@ import Preview from './components/preview'
|
||||||
export default {
|
export default {
|
||||||
name: 'Notice',
|
name: 'Notice',
|
||||||
components: {
|
components: {
|
||||||
Preview
|
Preview,
|
||||||
// CheckForm
|
// CheckForm
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
|
|
@ -76,18 +89,18 @@ export default {
|
||||||
popup: true, // 弹窗的显示隐藏
|
popup: true, // 弹窗的显示隐藏
|
||||||
studyCode: '',
|
studyCode: '',
|
||||||
modality: '',
|
modality: '',
|
||||||
bodyPart: ''
|
bodyPart: '',
|
||||||
},
|
},
|
||||||
previewVisible: false,
|
previewVisible: false,
|
||||||
studyList: [],
|
studyList: [],
|
||||||
subjectVisitId: '',
|
subjectVisitId: '',
|
||||||
sudyId: '',
|
sudyId: '',
|
||||||
loading: false,
|
loading: false,
|
||||||
bp:[]
|
bp: [],
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
async created(){
|
async created() {
|
||||||
this.bp = await this.$getBodyPart(this.$route.query.trialId);
|
this.bp = await this.$getBodyPart(this.$route.query.trialId)
|
||||||
},
|
},
|
||||||
async mounted() {
|
async mounted() {
|
||||||
if (this.$router.currentRoute.query.TokenKey) {
|
if (this.$router.currentRoute.query.TokenKey) {
|
||||||
|
|
@ -112,31 +125,47 @@ export default {
|
||||||
separator = ','
|
separator = ','
|
||||||
}
|
}
|
||||||
var arr = bodyPart.split(separator)
|
var arr = bodyPart.split(separator)
|
||||||
var newArr = arr.map(i => {
|
var newArr = arr.map((i) => {
|
||||||
return this.$fd('Bodypart', i.trim(),'Code',{Bodypart:this.bp},'Name')
|
return this.$fd(
|
||||||
|
'Bodypart',
|
||||||
|
i.trim(),
|
||||||
|
'Code',
|
||||||
|
{ Bodypart: this.bp },
|
||||||
|
'Name'
|
||||||
|
)
|
||||||
})
|
})
|
||||||
console.log(newArr,this.bp)
|
console.log(newArr, this.bp)
|
||||||
return newArr.join(' | ')
|
return newArr.join(' | ')
|
||||||
},
|
},
|
||||||
// 获取非Dicom检查信息
|
// 获取非Dicom检查信息
|
||||||
getNoneDicomList() {
|
getNoneDicomList() {
|
||||||
this.loading = true
|
this.loading = true
|
||||||
getNoneDicomStudyList(this.subjectVisitId, this.studyId).then(res => {
|
getNoneDicomStudyList(
|
||||||
|
this.subjectVisitId,
|
||||||
|
this.studyId,
|
||||||
|
false,
|
||||||
|
this.$route.query.visitTaskId
|
||||||
|
)
|
||||||
|
.then((res) => {
|
||||||
this.studyList = res.Result
|
this.studyList = res.Result
|
||||||
this.loading = false
|
this.loading = false
|
||||||
const studyIndex = this.studyList.findIndex(item => {
|
const studyIndex = this.studyList.findIndex((item) => {
|
||||||
return item.NoneDicomStudyFileList.length > 0
|
return item.NoneDicomStudyFileList.length > 0
|
||||||
})
|
})
|
||||||
if (studyIndex > -1) {
|
if (studyIndex > -1) {
|
||||||
var fileObj = this.studyList[studyIndex]['NoneDicomStudyFileList']
|
var fileObj = this.studyList[studyIndex]['NoneDicomStudyFileList']
|
||||||
this.selected(fileObj[0], studyIndex, 0, true)
|
this.selected(fileObj[0], studyIndex, 0, true)
|
||||||
}
|
}
|
||||||
}).catch(() => { this.loading = false })
|
})
|
||||||
|
.catch(() => {
|
||||||
|
this.loading = false
|
||||||
|
})
|
||||||
},
|
},
|
||||||
selected(file, studyIndex, fileIndex, isChangeSub = false) {
|
selected(file, studyIndex, fileIndex, isChangeSub = false) {
|
||||||
this.currentFileId = file.Id
|
this.currentFileId = file.Id
|
||||||
this.currentStudyIndex = studyIndex
|
this.currentStudyIndex = studyIndex
|
||||||
this.previewImage.imgList = this.studyList[studyIndex].NoneDicomStudyFileList
|
this.previewImage.imgList =
|
||||||
|
this.studyList[studyIndex].NoneDicomStudyFileList
|
||||||
this.currentStudyFileIndex = fileIndex
|
this.currentStudyFileIndex = fileIndex
|
||||||
this.previewImage.index = fileIndex
|
this.previewImage.index = fileIndex
|
||||||
this.previewImage.studyCode = this.studyList[studyIndex].CodeView
|
this.previewImage.studyCode = this.studyList[studyIndex].CodeView
|
||||||
|
|
@ -151,11 +180,17 @@ export default {
|
||||||
selectedImg(fileIndex) {
|
selectedImg(fileIndex) {
|
||||||
if (this.studyList.length > 0) {
|
if (this.studyList.length > 0) {
|
||||||
this.currentStudyFileIndex = fileIndex
|
this.currentStudyFileIndex = fileIndex
|
||||||
this.currentFileId = this.studyList[this.currentStudyIndex].NoneDicomStudyFileList[fileIndex].Id
|
this.currentFileId =
|
||||||
|
this.studyList[this.currentStudyIndex].NoneDicomStudyFileList[
|
||||||
|
fileIndex
|
||||||
|
].Id
|
||||||
this.previewImage.index = fileIndex
|
this.previewImage.index = fileIndex
|
||||||
this.previewImage.studyCode = this.studyList[this.currentStudyIndex].CodeView
|
this.previewImage.studyCode =
|
||||||
this.previewImage.bodyPart = this.studyList[this.currentStudyIndex].BodyPart
|
this.studyList[this.currentStudyIndex].CodeView
|
||||||
this.previewImage.modality = this.studyList[this.currentStudyIndex].Modality
|
this.previewImage.bodyPart =
|
||||||
|
this.studyList[this.currentStudyIndex].BodyPart
|
||||||
|
this.previewImage.modality =
|
||||||
|
this.studyList[this.currentStudyIndex].Modality
|
||||||
this.$nextTick(() => {
|
this.$nextTick(() => {
|
||||||
const target = document.getElementById(`img${this.currentFileId}`)
|
const target = document.getElementById(`img${this.currentFileId}`)
|
||||||
const parent = document.getElementsByClassName('left-content')[0]
|
const parent = document.getElementsByClassName('left-content')[0]
|
||||||
|
|
@ -165,14 +200,13 @@ export default {
|
||||||
},
|
},
|
||||||
preview() {
|
preview() {
|
||||||
this.previewVisible = true
|
this.previewVisible = true
|
||||||
}
|
},
|
||||||
|
},
|
||||||
}
|
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
.img-container{
|
.img-container {
|
||||||
position: relative;
|
position: relative;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
|
|
@ -186,27 +220,27 @@ export default {
|
||||||
border-radius: 10px;
|
border-radius: 10px;
|
||||||
background: #d0d0d0;
|
background: #d0d0d0;
|
||||||
}
|
}
|
||||||
/deep/ .el-card__body{
|
/deep/ .el-card__body {
|
||||||
padding: 0px;
|
padding: 0px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.study-desc{
|
.study-desc {
|
||||||
padding: 15px 5px;
|
padding: 15px 5px;
|
||||||
line-height: 20px;
|
line-height: 20px;
|
||||||
background-color: #d5d5d5;
|
background-color: #d5d5d5;
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
}
|
}
|
||||||
.left{
|
.left {
|
||||||
width:220px;
|
width: 220px;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
|
|
||||||
/deep/ .el-card__body{
|
/deep/ .el-card__body {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
}
|
}
|
||||||
.title{
|
.title {
|
||||||
height: 40px;
|
height: 40px;
|
||||||
line-height: 40px;
|
line-height: 40px;
|
||||||
border: 1ppx solid;
|
border: 1ppx solid;
|
||||||
|
|
@ -215,7 +249,7 @@ export default {
|
||||||
background-color: #4e4e4e;
|
background-color: #4e4e4e;
|
||||||
color: #ffffff;
|
color: #ffffff;
|
||||||
}
|
}
|
||||||
.left-content{
|
.left-content {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
}
|
}
|
||||||
|
|
@ -231,21 +265,26 @@ export default {
|
||||||
// overflow-y: auto;
|
// overflow-y: auto;
|
||||||
// padding: 0;
|
// padding: 0;
|
||||||
// }
|
// }
|
||||||
.img-box{
|
.img-box {
|
||||||
// position: relative;
|
// position: relative;
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
border-bottom: 2px solid #f3f3f3;
|
border-bottom: 2px solid #f3f3f3;
|
||||||
width: 180px;
|
|
||||||
height: 50px;
|
|
||||||
line-height: 50px;
|
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
// margin-bottom: 5px;
|
// margin-bottom: 5px;
|
||||||
padding-left: 5px;
|
padding-left: 5px;
|
||||||
text-overflow:ellipsis;
|
}
|
||||||
|
.img-text {
|
||||||
|
display: inline-block;
|
||||||
|
width: 200px;
|
||||||
|
height: 50px;
|
||||||
|
line-height: 50px;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis; /* 用省略号表示溢出的文本 */
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
}
|
}
|
||||||
.img-box:nth-last-child(1){
|
.img-box:nth-last-child(1) {
|
||||||
margin-bottom: 0px;
|
margin-bottom: 0px;
|
||||||
}
|
}
|
||||||
.is-boxActive {
|
.is-boxActive {
|
||||||
|
|
@ -256,14 +295,13 @@ export default {
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.right{
|
.right {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
margin-left: 10px;
|
margin-left: 10px;
|
||||||
/deep/ .el-card__body{
|
/deep/ .el-card__body {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
|
|
|
||||||
|
|
@ -1,76 +1,130 @@
|
||||||
<template>
|
<template>
|
||||||
<div style="display: flex;justify-content: center">
|
<div style="display: flex; justify-content: center">
|
||||||
<div style="width: 600px;text-align: center;border: 1px solid #e6e6e6;margin-top:40px;padding:10px;">
|
<div
|
||||||
<div class="trial-myinfo-head" style="font-size: 30px;line-height: 120px;">
|
style="
|
||||||
|
width: 600px;
|
||||||
|
text-align: center;
|
||||||
|
border: 1px solid #e6e6e6;
|
||||||
|
margin-top: 40px;
|
||||||
|
padding: 10px;
|
||||||
|
"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="trial-myinfo-head"
|
||||||
|
style="font-size: 30px; line-height: 120px"
|
||||||
|
>
|
||||||
<!-- 首次登录修改密码 -->
|
<!-- 首次登录修改密码 -->
|
||||||
{{ $t('recompose:title:init') }}
|
{{ $t('recompose:title:init') }}
|
||||||
</div>
|
</div>
|
||||||
<el-form ref="passwordForm" v-loading="loading" label-position="right" :model="password" :rules="passwordFormRules" label-width="120px">
|
<el-form
|
||||||
|
ref="passwordForm"
|
||||||
|
v-loading="loading"
|
||||||
|
label-position="right"
|
||||||
|
:model="password"
|
||||||
|
:rules="passwordFormRules"
|
||||||
|
:label-width="$i18n.locale === 'en' ? '180px' : '120px'"
|
||||||
|
>
|
||||||
<!-- 用户名 -->
|
<!-- 用户名 -->
|
||||||
<el-form-item :label="$t('recompose:form:userName')" prop="NewUserName">
|
<el-form-item :label="$t('recompose:form:userName')" prop="NewUserName">
|
||||||
<el-input v-model="password.NewUserName" />
|
<el-input v-model="password.NewUserName" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<!-- 旧密码 -->
|
<!-- 旧密码 -->
|
||||||
<el-form-item :label="$t('recompose:form:oldPassword')" prop="OldPassWord">
|
<el-form-item
|
||||||
<el-input v-model="password.OldPassWord" type="password" show-password auto-complete="new-password" />
|
:label="$t('recompose:form:oldPassword')"
|
||||||
|
prop="OldPassWord"
|
||||||
|
>
|
||||||
|
<el-input
|
||||||
|
v-model="password.OldPassWord"
|
||||||
|
type="password"
|
||||||
|
show-password
|
||||||
|
auto-complete="new-password"
|
||||||
|
/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<!-- 新密码 -->
|
<!-- 新密码 -->
|
||||||
<el-form-item :label="$t('recompose:form:newPassword')" prop="NewPassWord">
|
<el-form-item
|
||||||
<el-input v-model="password.NewPassWord" type="password" show-password auto-complete="new-password" />
|
:label="$t('recompose:form:newPassword')"
|
||||||
|
prop="NewPassWord"
|
||||||
|
>
|
||||||
|
<el-input
|
||||||
|
v-model="password.NewPassWord"
|
||||||
|
type="password"
|
||||||
|
show-password
|
||||||
|
auto-complete="new-password"
|
||||||
|
/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<!-- 确认密码 -->
|
<!-- 确认密码 -->
|
||||||
<el-form-item :label="$t('recompose:form:confirmPassword')" prop="ConfirmPassWord">
|
<el-form-item
|
||||||
<el-input v-model="password.ConfirmPassWord" type="password" show-password auto-complete="new-password" />
|
:label="$t('recompose:form:confirmPassword')"
|
||||||
</el-form-item>
|
prop="ConfirmPassWord"
|
||||||
<el-form-item style="text-align:right">
|
|
||||||
<!-- 取消 -->
|
|
||||||
<el-button
|
|
||||||
size="small"
|
|
||||||
@click="cancel"
|
|
||||||
>
|
>
|
||||||
|
<el-input
|
||||||
|
v-model="password.ConfirmPassWord"
|
||||||
|
type="password"
|
||||||
|
show-password
|
||||||
|
auto-complete="new-password"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item style="text-align: right">
|
||||||
|
<!-- 取消 -->
|
||||||
|
<el-button size="small" @click="cancel">
|
||||||
{{ $t('recompose:button:cancel') }}
|
{{ $t('recompose:button:cancel') }}
|
||||||
</el-button>
|
</el-button>
|
||||||
<!-- 保存 -->
|
<!-- 保存 -->
|
||||||
<el-button
|
<el-button type="primary" size="small" @click="save">
|
||||||
type="primary"
|
|
||||||
size="small"
|
|
||||||
@click="save"
|
|
||||||
>
|
|
||||||
{{ $t('recompose:button:save') }}
|
{{ $t('recompose:button:save') }}
|
||||||
</el-button>
|
</el-button>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-form>
|
</el-form>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script>
|
<script>
|
||||||
import { modifyPassword } from '@/api/admin.js'
|
import { modifyPassword } from '@/api/admin.js'
|
||||||
import md5 from 'js-md5'
|
import md5 from 'js-md5'
|
||||||
import {mapMutations} from "vuex";
|
import { mapMutations } from 'vuex'
|
||||||
export default {
|
export default {
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
password: {
|
password: {
|
||||||
NewUserName: null
|
NewUserName: null,
|
||||||
},
|
},
|
||||||
passwordFormRules: {
|
passwordFormRules: {
|
||||||
NewUserName: [{ required: true, message: this.$t('common:ruleMessage:specify'), trigger: 'blur' }],
|
NewUserName: [
|
||||||
OldPassWord: [{ required: true, message: this.$t('common:ruleMessage:specify'), trigger: 'blur' }],
|
{
|
||||||
|
required: true,
|
||||||
|
message: this.$t('common:ruleMessage:specify'),
|
||||||
|
trigger: 'blur',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
OldPassWord: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: this.$t('common:ruleMessage:specify'),
|
||||||
|
trigger: 'blur',
|
||||||
|
},
|
||||||
|
],
|
||||||
NewPassWord: [
|
NewPassWord: [
|
||||||
{ required: true, message: this.$t('common:ruleMessage:specify'), trigger: 'blur' },
|
{
|
||||||
|
required: true,
|
||||||
|
message: this.$t('common:ruleMessage:specify'),
|
||||||
|
trigger: 'blur',
|
||||||
|
},
|
||||||
{
|
{
|
||||||
required: true,
|
required: true,
|
||||||
trigger: 'blur',
|
trigger: 'blur',
|
||||||
validator: this.$validatePassword
|
validator: this.$validatePassword,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
ConfirmPassWord: [
|
ConfirmPassWord: [
|
||||||
{ required: true, message: this.$t('common:ruleMessage:specify'), trigger: 'blur' },
|
{
|
||||||
]
|
required: true,
|
||||||
|
message: this.$t('common:ruleMessage:specify'),
|
||||||
|
trigger: 'blur',
|
||||||
|
},
|
||||||
|
],
|
||||||
},
|
},
|
||||||
userId: null,
|
userId: null,
|
||||||
loading: false
|
loading: false,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
|
|
@ -78,7 +132,6 @@ export default {
|
||||||
if (!this.password.NewUserName) {
|
if (!this.password.NewUserName) {
|
||||||
// 该页面只提供给首次进入系统的用户使用
|
// 该页面只提供给首次进入系统的用户使用
|
||||||
this.$alert(this.$t('recompose:message:warning'))
|
this.$alert(this.$t('recompose:message:warning'))
|
||||||
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
|
@ -96,7 +149,7 @@ export default {
|
||||||
this.$updateDictionary()
|
this.$updateDictionary()
|
||||||
},
|
},
|
||||||
save() {
|
save() {
|
||||||
this.$refs.passwordForm.validate(valid => {
|
this.$refs.passwordForm.validate((valid) => {
|
||||||
if (valid) {
|
if (valid) {
|
||||||
if (this.password.NewPassWord !== this.password.ConfirmPassWord) {
|
if (this.password.NewPassWord !== this.password.ConfirmPassWord) {
|
||||||
// 两次密码输入不一致
|
// 两次密码输入不一致
|
||||||
|
|
@ -106,58 +159,64 @@ export default {
|
||||||
const param = {
|
const param = {
|
||||||
NewUserName: this.password.NewUserName,
|
NewUserName: this.password.NewUserName,
|
||||||
NewPassWord: md5(this.password.NewPassWord),
|
NewPassWord: md5(this.password.NewPassWord),
|
||||||
OldPassWord: md5(this.password.OldPassWord)
|
OldPassWord: md5(this.password.OldPassWord),
|
||||||
}
|
}
|
||||||
this.loading = true
|
this.loading = true
|
||||||
modifyPassword(param).then(res => {
|
modifyPassword(param)
|
||||||
|
.then((res) => {
|
||||||
this.loading = false
|
this.loading = false
|
||||||
if (res.IsSuccess) {
|
if (res.IsSuccess) {
|
||||||
// 修改成功,请重新登录账号
|
// 修改成功,请重新登录账号
|
||||||
this.$message.success(this.$t('recompose:message:updatedSuccessfully'))
|
this.$message.success(
|
||||||
|
this.$t('recompose:message:updatedSuccessfully')
|
||||||
|
)
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
this.logout()
|
this.logout()
|
||||||
}, 500)
|
}, 500)
|
||||||
}
|
}
|
||||||
}).catch(() => { this.loading = false })
|
})
|
||||||
|
.catch(() => {
|
||||||
|
this.loading = false
|
||||||
|
})
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
cancel() {
|
cancel() {
|
||||||
this.$refs['passwordForm'].resetFields()
|
this.$refs['passwordForm'].resetFields()
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
<style>
|
<style>
|
||||||
.reset-wrapper {
|
.reset-wrapper {
|
||||||
padding: 20px;
|
padding: 20px;
|
||||||
}
|
}
|
||||||
.reset-wrapper .el-page-header {
|
.reset-wrapper .el-page-header {
|
||||||
line-height: 50px;
|
line-height: 50px;
|
||||||
border: 1px solid #ebeef5;
|
border: 1px solid #ebeef5;
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
background-color: #fff;
|
background-color: #fff;
|
||||||
}
|
}
|
||||||
.reset-wrapper .box-wrapper {
|
.reset-wrapper .box-wrapper {
|
||||||
width: 60%;
|
width: 60%;
|
||||||
margin: 20px auto;
|
margin: 20px auto;
|
||||||
padding: 10px;
|
padding: 10px;
|
||||||
color: #303133;
|
color: #303133;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
<style scoped>
|
<style scoped>
|
||||||
::v-deep .is-error{
|
::v-deep .is-error {
|
||||||
margin-bottom: 40px;
|
margin-bottom: 40px;
|
||||||
}
|
}
|
||||||
input:-webkit-autofill {
|
input:-webkit-autofill {
|
||||||
-webkit-text-fill-color: #ededed !important;
|
-webkit-text-fill-color: #ededed !important;
|
||||||
box-shadow: 0 0 0px 1000px transparent inset !important;
|
box-shadow: 0 0 0px 1000px transparent inset !important;
|
||||||
background-color:transparent;
|
background-color: transparent;
|
||||||
background-image: none;
|
background-image: none;
|
||||||
transition: background-color 50000s ease-in-out 0s;
|
transition: background-color 50000s ease-in-out 0s;
|
||||||
}
|
}
|
||||||
input {
|
input {
|
||||||
background-color:transparent;
|
background-color: transparent;
|
||||||
caret-color: #fff;
|
caret-color: #fff;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
||||||
|
|
@ -41,8 +41,8 @@
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<!-- 阅片标准 -->
|
<!-- 阅片标准 -->
|
||||||
<el-form-item
|
<el-form-item
|
||||||
:label="$t('trials:trials-list:table:IR_ReadingCriterionList')"
|
|
||||||
v-if="hasPermi(['role:ir'])"
|
v-if="hasPermi(['role:ir'])"
|
||||||
|
:label="$t('trials:trials-list:table:IR_ReadingCriterionList')"
|
||||||
>
|
>
|
||||||
<el-select
|
<el-select
|
||||||
v-model="searchData.CriterionType"
|
v-model="searchData.CriterionType"
|
||||||
|
|
@ -59,8 +59,8 @@
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<!-- 联系人 -->
|
<!-- 联系人 -->
|
||||||
<el-form-item
|
<el-form-item
|
||||||
:label="$t('trials:trials-list:table:IR_PMEmailList')"
|
|
||||||
v-if="hasPermi(['role:ir'])"
|
v-if="hasPermi(['role:ir'])"
|
||||||
|
:label="$t('trials:trials-list:table:IR_PMEmailList')"
|
||||||
>
|
>
|
||||||
<el-input
|
<el-input
|
||||||
v-model="searchData.PM_EMail"
|
v-model="searchData.PM_EMail"
|
||||||
|
|
@ -293,9 +293,10 @@
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item>
|
<el-form-item>
|
||||||
<el-button type="primary" @click="handleSelectSearch"
|
<el-button
|
||||||
>Search</el-button
|
type="primary"
|
||||||
>
|
@click="handleSelectSearch"
|
||||||
|
>Search</el-button>
|
||||||
<el-button type="primary" @click="handleReset">Reset</el-button>
|
<el-button type="primary" @click="handleReset">Reset</el-button>
|
||||||
<el-button type="primary" @click="isShow = false">Back</el-button>
|
<el-button type="primary" @click="isShow = false">Back</el-button>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
@ -357,23 +358,19 @@
|
||||||
<el-tag
|
<el-tag
|
||||||
v-if="scope.row.TrialStatusStr === 'Initializing'"
|
v-if="scope.row.TrialStatusStr === 'Initializing'"
|
||||||
type="info"
|
type="info"
|
||||||
>{{ $fd("TrialStatusEnum", scope.row.TrialStatusStr) }}</el-tag
|
>{{ $fd("TrialStatusEnum", scope.row.TrialStatusStr) }}</el-tag>
|
||||||
>
|
|
||||||
<el-tag
|
<el-tag
|
||||||
v-if="scope.row.TrialStatusStr === 'Ongoing'"
|
v-if="scope.row.TrialStatusStr === 'Ongoing'"
|
||||||
type="primary"
|
type="primary"
|
||||||
>{{ $fd("TrialStatusEnum", scope.row.TrialStatusStr) }}</el-tag
|
>{{ $fd("TrialStatusEnum", scope.row.TrialStatusStr) }}</el-tag>
|
||||||
>
|
|
||||||
<el-tag
|
<el-tag
|
||||||
v-if="scope.row.TrialStatusStr === 'Completed'"
|
v-if="scope.row.TrialStatusStr === 'Completed'"
|
||||||
type="warning"
|
type="warning"
|
||||||
>{{ $fd("TrialStatusEnum", scope.row.TrialStatusStr) }}</el-tag
|
>{{ $fd("TrialStatusEnum", scope.row.TrialStatusStr) }}</el-tag>
|
||||||
>
|
|
||||||
<el-tag
|
<el-tag
|
||||||
v-if="scope.row.TrialStatusStr === 'Stopped'"
|
v-if="scope.row.TrialStatusStr === 'Stopped'"
|
||||||
type="danger"
|
type="danger"
|
||||||
>{{ $fd("TrialStatusEnum", scope.row.TrialStatusStr) }}</el-tag
|
>{{ $fd("TrialStatusEnum", scope.row.TrialStatusStr) }}</el-tag>
|
||||||
>
|
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column
|
<el-table-column
|
||||||
|
|
@ -582,7 +579,7 @@
|
||||||
:disabled="
|
:disabled="
|
||||||
(scope.row.TrialStatusStr === 'Initializing' &&
|
(scope.row.TrialStatusStr === 'Initializing' &&
|
||||||
!hasPermi(['role:pm'])) ||
|
!hasPermi(['role:pm'])) ||
|
||||||
scope.row.IsDeleted
|
scope.row.IsDeleted || ((scope.row.TrialStatusStr === 'Completed' || scope.row.TrialStatusStr === 'Stopped') && !(hasPermi(['role:qa']) || hasPermi(['role:ea']) || hasPermi(['role:pm'])))
|
||||||
"
|
"
|
||||||
:title="$t('trials:trials-list:action:panel')"
|
:title="$t('trials:trials-list:action:panel')"
|
||||||
@click.stop="handleDetail(scope.row)"
|
@click.stop="handleDetail(scope.row)"
|
||||||
|
|
@ -693,54 +690,54 @@
|
||||||
import {
|
import {
|
||||||
abandonTrial,
|
abandonTrial,
|
||||||
ifTrialCanOngoing,
|
ifTrialCanOngoing,
|
||||||
getTrialToBeDoneList,
|
getTrialToBeDoneList
|
||||||
} from "@/api/trials";
|
} from '@/api/trials'
|
||||||
import { getTrialList_Export } from "@/api/export";
|
import { getTrialList_Export } from '@/api/export'
|
||||||
import store from "@/store";
|
import store from '@/store'
|
||||||
import { mapGetters } from "vuex";
|
import { mapGetters } from 'vuex'
|
||||||
import BaseContainer from "@/components/BaseContainer";
|
import BaseContainer from '@/components/BaseContainer'
|
||||||
import Pagination from "@/components/Pagination";
|
import Pagination from '@/components/Pagination'
|
||||||
import TrialForm from "./components/TrialForm";
|
import TrialForm from './components/TrialForm'
|
||||||
import TrialStatusForm from "./components/TrialStatusForm";
|
import TrialStatusForm from './components/TrialStatusForm'
|
||||||
import DoneList from "./components/DoneList";
|
import DoneList from './components/DoneList'
|
||||||
const searchDataDefault = () => {
|
const searchDataDefault = () => {
|
||||||
return {
|
return {
|
||||||
Code: "",
|
Code: '',
|
||||||
CriterionIds: [],
|
CriterionIds: [],
|
||||||
SponsorId: "",
|
SponsorId: '',
|
||||||
ReviewTypeIds: [],
|
ReviewTypeIds: [],
|
||||||
CROId: "",
|
CROId: '',
|
||||||
Expedited: "",
|
Expedited: '',
|
||||||
Indication: "",
|
Indication: '',
|
||||||
Phase: "",
|
Phase: '',
|
||||||
ModalityIds: [],
|
ModalityIds: [],
|
||||||
BeginDate: "",
|
BeginDate: '',
|
||||||
EndDate: "",
|
EndDate: '',
|
||||||
AttendedReviewerType: "",
|
AttendedReviewerType: '',
|
||||||
ResearchProgramNo: "",
|
ResearchProgramNo: '',
|
||||||
ExperimentName: "",
|
ExperimentName: '',
|
||||||
PageIndex: 1,
|
PageIndex: 1,
|
||||||
PageSize: 20,
|
PageSize: 20,
|
||||||
Asc: false,
|
Asc: false,
|
||||||
SortField: "",
|
SortField: '',
|
||||||
CriterionType: null,
|
CriterionType: null,
|
||||||
PM_EMail: null,
|
PM_EMail: null
|
||||||
};
|
}
|
||||||
};
|
}
|
||||||
export default {
|
export default {
|
||||||
name: "Trials",
|
name: 'Trials',
|
||||||
components: {
|
components: {
|
||||||
Pagination,
|
Pagination,
|
||||||
BaseContainer,
|
BaseContainer,
|
||||||
TrialForm,
|
TrialForm,
|
||||||
TrialStatusForm,
|
TrialStatusForm,
|
||||||
DoneList,
|
DoneList
|
||||||
},
|
},
|
||||||
dicts: ["ReadingStandard", "ReviewType", "ReadingType"],
|
dicts: ['ReadingStandard', 'ReviewType', 'ReadingType'],
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
exportLoading: false,
|
exportLoading: false,
|
||||||
userTypeEnumInt: zzSessionStorage.getItem("userTypeEnumInt") * 1,
|
userTypeEnumInt: zzSessionStorage.getItem('userTypeEnumInt') * 1,
|
||||||
doneDialogVisible: false,
|
doneDialogVisible: false,
|
||||||
doneTitle: null,
|
doneTitle: null,
|
||||||
selectArr: [],
|
selectArr: [],
|
||||||
|
|
@ -750,26 +747,26 @@ export default {
|
||||||
total: 0,
|
total: 0,
|
||||||
isShow: false,
|
isShow: false,
|
||||||
dialogVisible: false,
|
dialogVisible: false,
|
||||||
title: "",
|
title: '',
|
||||||
currentId: "",
|
currentId: '',
|
||||||
statusVisible: false,
|
statusVisible: false,
|
||||||
currentRow: {},
|
currentRow: {},
|
||||||
currentUser: zzSessionStorage.getItem("userName"),
|
currentUser: zzSessionStorage.getItem('userName'),
|
||||||
phaseOptions: [
|
phaseOptions: [
|
||||||
{ value: "I" },
|
{ value: 'I' },
|
||||||
{ value: "II" },
|
{ value: 'II' },
|
||||||
{ value: "III" },
|
{ value: 'III' },
|
||||||
{ value: "IV" },
|
{ value: 'IV' }
|
||||||
],
|
],
|
||||||
expeditedOption: this.$d.TrialExpeditedState,
|
expeditedOption: this.$d.TrialExpeditedState,
|
||||||
beginPickerOption: {
|
beginPickerOption: {
|
||||||
disabledDate: (time) => {
|
disabledDate: (time) => {
|
||||||
if (this.searchData.EndDate) {
|
if (this.searchData.EndDate) {
|
||||||
return time.getTime() > new Date(this.searchData.EndDate).getTime();
|
return time.getTime() > new Date(this.searchData.EndDate).getTime()
|
||||||
} else {
|
} else {
|
||||||
return time.getTime() > Date.now();
|
return time.getTime() > Date.now()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
|
||||||
},
|
},
|
||||||
endpickerOption: {
|
endpickerOption: {
|
||||||
disabledDate: (time) => {
|
disabledDate: (time) => {
|
||||||
|
|
@ -777,306 +774,189 @@ export default {
|
||||||
return (
|
return (
|
||||||
time.getTime() > Date.now() ||
|
time.getTime() > Date.now() ||
|
||||||
time.getTime() <= new Date(this.searchData.BeginDate).getTime()
|
time.getTime() <= new Date(this.searchData.BeginDate).getTime()
|
||||||
);
|
)
|
||||||
} else {
|
} else {
|
||||||
return time.getTime() > Date.now();
|
return time.getTime() > Date.now()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
},
|
|
||||||
};
|
|
||||||
},
|
|
||||||
computed: {
|
computed: {
|
||||||
...mapGetters(["sponsorList", "croList"]),
|
...mapGetters(['sponsorList', 'croList'])
|
||||||
},
|
},
|
||||||
created() {
|
created() {
|
||||||
this.initPage();
|
this.initPage()
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
initPage() {
|
initPage() {
|
||||||
this.getList();
|
this.getList()
|
||||||
store.dispatch("global/getSponsorList");
|
store.dispatch('global/getSponsorList')
|
||||||
store.dispatch("global/getCROList");
|
store.dispatch('global/getCROList')
|
||||||
},
|
},
|
||||||
// 获取项目列表信息
|
// 获取项目列表信息
|
||||||
getList() {
|
getList() {
|
||||||
this.listLoading = true;
|
this.listLoading = true
|
||||||
getTrialToBeDoneList(this.searchData)
|
getTrialToBeDoneList(this.searchData)
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
this.list = res.Result.CurrentPageData;
|
this.list = res.Result.CurrentPageData
|
||||||
this.total = res.Result.TotalCount;
|
this.total = res.Result.TotalCount
|
||||||
this.listLoading = false;
|
this.listLoading = false
|
||||||
})
|
})
|
||||||
.catch(() => {
|
.catch(() => {
|
||||||
this.listLoading = false;
|
this.listLoading = false
|
||||||
});
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
// 查询
|
// 查询
|
||||||
handleSearch() {
|
handleSearch() {
|
||||||
this.searchData.PageIndex = 1;
|
this.searchData.PageIndex = 1
|
||||||
this.getList();
|
this.getList()
|
||||||
},
|
},
|
||||||
// 查询
|
// 查询
|
||||||
handleSelectSearch() {
|
handleSelectSearch() {
|
||||||
this.searchData.PageIndex = 1;
|
this.searchData.PageIndex = 1
|
||||||
this.getList();
|
this.getList()
|
||||||
this.isShow = false;
|
this.isShow = false
|
||||||
},
|
},
|
||||||
// 重置
|
// 重置
|
||||||
handleReset() {
|
handleReset() {
|
||||||
this.searchData = searchDataDefault();
|
this.searchData = searchDataDefault()
|
||||||
this.getList();
|
this.getList()
|
||||||
},
|
},
|
||||||
// 新增项目
|
// 新增项目
|
||||||
handleNew() {
|
handleNew() {
|
||||||
// this.$router.push({ name: 'CreateTrial' })
|
// this.$router.push({ name: 'CreateTrial' })
|
||||||
this.title = this.$t("trials:trials-list:dialogTitle:new");
|
this.title = this.$t('trials:trials-list:dialogTitle:new')
|
||||||
this.currentId = "";
|
this.currentId = ''
|
||||||
this.dialogVisible = true;
|
this.dialogVisible = true
|
||||||
},
|
},
|
||||||
// 编辑项目
|
// 编辑项目
|
||||||
handleEdit(row) {
|
handleEdit(row) {
|
||||||
this.title = this.$t("trials:trials-list:dialogTitle:edit");
|
this.title = this.$t('trials:trials-list:dialogTitle:edit')
|
||||||
this.currentId = row.Id;
|
this.currentId = row.Id
|
||||||
this.dialogVisible = true;
|
this.dialogVisible = true
|
||||||
},
|
},
|
||||||
handleCommission(row) {
|
handleCommission(row) {
|
||||||
this.doneTitle = this.$t("trials:trials-list:dialogTitle:doneTitle");
|
this.doneTitle = this.$t('trials:trials-list:dialogTitle:doneTitle')
|
||||||
this.currentId = row.Id;
|
this.currentId = row.Id
|
||||||
this.doneDialogVisible = true;
|
this.doneDialogVisible = true
|
||||||
},
|
},
|
||||||
closeDialog() {
|
closeDialog() {
|
||||||
this.dialogVisible = false;
|
this.dialogVisible = false
|
||||||
},
|
},
|
||||||
// 状态
|
// 状态
|
||||||
handleStatus(row) {
|
handleStatus(row) {
|
||||||
if (row.TrialStatusStr === "Initializing") {
|
if (row.TrialStatusStr === 'Initializing') {
|
||||||
this.listLoading = true;
|
this.listLoading = true
|
||||||
ifTrialCanOngoing(row.Id)
|
ifTrialCanOngoing(row.Id)
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
this.listLoading = false;
|
this.listLoading = false
|
||||||
if (res.Result) {
|
if (res.Result) {
|
||||||
this.currentRow = { ...row };
|
this.currentRow = { ...row }
|
||||||
this.statusVisible = true;
|
this.statusVisible = true
|
||||||
} else {
|
} else {
|
||||||
this.$confirm(res.ErrorMessage, {
|
this.$confirm(res.ErrorMessage, {
|
||||||
type: "warning",
|
type: 'warning',
|
||||||
showCancelButton: false,
|
showCancelButton: false,
|
||||||
callback: (action) => {},
|
callback: (action) => {}
|
||||||
});
|
})
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.catch(() => {
|
.catch(() => {
|
||||||
this.listLoading = false;
|
this.listLoading = false
|
||||||
});
|
})
|
||||||
} else {
|
} else {
|
||||||
this.currentRow = { ...row };
|
this.currentRow = { ...row }
|
||||||
this.statusVisible = true;
|
this.statusVisible = true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
closeStatusDialog() {
|
closeStatusDialog() {
|
||||||
this.statusVisible = false;
|
this.statusVisible = false
|
||||||
},
|
},
|
||||||
// 废除
|
// 废除
|
||||||
handleAbandon(row) {
|
handleAbandon(row) {
|
||||||
this.$confirm(this.$t("trials:trials-list:message:abolition"), {
|
this.$confirm(this.$t('trials:trials-list:message:abolition'), {
|
||||||
type: "warning",
|
type: 'warning',
|
||||||
distinguishCancelAndClose: true,
|
distinguishCancelAndClose: true
|
||||||
})
|
})
|
||||||
.then(() => {
|
.then(() => {
|
||||||
this.currentRow = { ...row };
|
this.currentRow = { ...row }
|
||||||
this.abandonTrial();
|
this.abandonTrial()
|
||||||
})
|
})
|
||||||
.catch(() => {});
|
.catch(() => {})
|
||||||
},
|
},
|
||||||
// 废除项目
|
// 废除项目
|
||||||
abandonTrial() {
|
abandonTrial() {
|
||||||
this.listLoading = true;
|
this.listLoading = true
|
||||||
abandonTrial(this.currentRow.Id, true)
|
abandonTrial(this.currentRow.Id, true)
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
this.listLoading = false;
|
this.listLoading = false
|
||||||
if (res.IsSuccess) {
|
if (res.IsSuccess) {
|
||||||
this.getList();
|
this.getList()
|
||||||
this.$message.success(
|
this.$message.success(
|
||||||
this.$t("trials:trials-list:message:abolitionSuccessfully")
|
this.$t('trials:trials-list:message:abolitionSuccessfully')
|
||||||
);
|
)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.catch(() => {
|
.catch(() => {
|
||||||
this.listLoading = false;
|
this.listLoading = false
|
||||||
});
|
})
|
||||||
},
|
},
|
||||||
rowClick(row, col) {
|
rowClick(row, col) {
|
||||||
if (
|
if ((row.TrialStatusStr === 'Initializing' && !this.hasPermi(['role:pm'])) || row.IsDeleted) {
|
||||||
(row.TrialStatusStr === "Initializing" &&
|
return
|
||||||
!this.hasPermi(["role:pm"])) ||
|
} else if ((row.TrialStatusStr === 'Completed' || row.TrialStatusStr === 'Stopped') && !(this.hasPermi(['role:qa']) || this.hasPermi(['role:ea']) || this.hasPermi(['role:pm']))) {
|
||||||
row.IsDeleted
|
return
|
||||||
)
|
}
|
||||||
return;
|
|
||||||
this.$router.push({
|
this.$router.push({
|
||||||
path: `/trials/trials-panel?trialId=${row.Id}&trialCode=${row.TrialCode}&researchProgramNo=${row.ResearchProgramNo}`,
|
path: `/trials/trials-panel?trialId=${row.Id}&trialCode=${row.TrialCode}&researchProgramNo=${row.ResearchProgramNo}`
|
||||||
});
|
})
|
||||||
},
|
},
|
||||||
// panel
|
// panel
|
||||||
handleDetail(row) {
|
handleDetail(row) {
|
||||||
this.$router.push({
|
this.$router.push({
|
||||||
path: `/trials/trials-panel?trialId=${row.Id}&trialCode=${row.TrialCode}&researchProgramNo=${row.ResearchProgramNo}`,
|
path: `/trials/trials-panel?trialId=${row.Id}&trialCode=${row.TrialCode}&researchProgramNo=${row.ResearchProgramNo}`
|
||||||
});
|
})
|
||||||
},
|
},
|
||||||
// 获取已勾选行数据
|
// 获取已勾选行数据
|
||||||
handleSelectChange(val) {
|
handleSelectChange(val) {
|
||||||
const arr = [];
|
const arr = []
|
||||||
for (let index = 0; index < val.length; index++) {
|
for (let index = 0; index < val.length; index++) {
|
||||||
arr.push(val[index]);
|
arr.push(val[index])
|
||||||
}
|
}
|
||||||
this.selectArr = arr;
|
this.selectArr = arr
|
||||||
},
|
},
|
||||||
// 排序
|
// 排序
|
||||||
handleSortChange(column) {
|
handleSortChange(column) {
|
||||||
if (column.order === "ascending") {
|
if (column.order === 'ascending') {
|
||||||
this.searchData.Asc = true;
|
this.searchData.Asc = true
|
||||||
} else {
|
} else {
|
||||||
this.searchData.Asc = false;
|
this.searchData.Asc = false
|
||||||
}
|
}
|
||||||
if (column.prop === "Criterion") {
|
if (column.prop === 'Criterion') {
|
||||||
this.searchData.SortField = "CriterionId";
|
this.searchData.SortField = 'CriterionId'
|
||||||
} else {
|
} else {
|
||||||
this.searchData.SortField = column.prop;
|
this.searchData.SortField = column.prop
|
||||||
}
|
}
|
||||||
this.searchData.PageIndex = 1;
|
this.searchData.PageIndex = 1
|
||||||
this.getList();
|
this.getList()
|
||||||
},
|
},
|
||||||
// 导出Excel表格
|
// 导出Excel表格
|
||||||
handleExportTrial() {
|
handleExportTrial() {
|
||||||
this.exportLoading = true;
|
this.exportLoading = true
|
||||||
let data = {
|
const data = {
|
||||||
...this.searchData,
|
...this.searchData
|
||||||
};
|
}
|
||||||
data.TrialIdList = this.selectArr.map((item) => item.Id);
|
data.TrialIdList = this.selectArr.map((item) => item.Id)
|
||||||
return getTrialList_Export(data)
|
return getTrialList_Export(data)
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
this.exportLoading = false;
|
this.exportLoading = false
|
||||||
})
|
})
|
||||||
.catch(() => {
|
.catch(() => {
|
||||||
this.exportLoading = false;
|
this.exportLoading = false
|
||||||
});
|
|
||||||
this.selectArr.forEach((element, index) => {
|
|
||||||
// element.ExpeditedStr = element.Expedited === 0 ? 'No' : element.Expedited === 1 ? '24H' : '48H'
|
|
||||||
// element.ModalityListStr = element.ModalityList.join(', ')
|
|
||||||
// element.CreateTimeStr = element.CreateTime
|
|
||||||
// element.Criterion = element.CriterionList.join(', ')
|
|
||||||
element.Deleted = element.IsDeleted ? "Yes" : "No";
|
|
||||||
element.Index = index + 1;
|
|
||||||
});
|
|
||||||
var workbook = new Excel.Workbook();
|
|
||||||
var sheet = workbook.addWorksheet("Trials");
|
|
||||||
|
|
||||||
sheet.properties.defaultRowHeight = 22;
|
|
||||||
// sheet.columns = [
|
|
||||||
// { key: 'Index', width: 5 },
|
|
||||||
// { key: 'Code', width: 15 },
|
|
||||||
// { key: 'ExpeditedStr', width: 13 },
|
|
||||||
// { key: 'TrialStatusStr', width: 10 },
|
|
||||||
// { key: 'Indication', width: 25 },
|
|
||||||
// { key: 'Phase', width: 10 },
|
|
||||||
// { key: 'ReviewType', width: 20 },
|
|
||||||
// { key: 'Criterion', width: 15 },
|
|
||||||
// { key: 'ModalityListStr', width: 30 },
|
|
||||||
// { key: 'CRO', width: 10 },
|
|
||||||
// { key: 'Sponsor', width: 20 },
|
|
||||||
// { key: 'CreateTimeStr', width: 18 }
|
|
||||||
// ]
|
|
||||||
sheet.columns = [
|
|
||||||
{ key: "Index", width: 5 },
|
|
||||||
{ key: "TrialCode", width: 25 },
|
|
||||||
{ key: "ExperimentName", width: 25 },
|
|
||||||
{ key: "ResearchProgramNo", width: 25 },
|
|
||||||
{ key: "Sponsor", width: 25 },
|
|
||||||
{ key: "Deleted", width: 10 },
|
|
||||||
{ key: "CreateTime", width: 25 },
|
|
||||||
];
|
|
||||||
|
|
||||||
// 处理标题
|
|
||||||
sheet.mergeCells("A1", "G2");
|
|
||||||
sheet.getCell("A1").value = "Trials";
|
|
||||||
sheet.getCell("A1").alignment = {
|
|
||||||
vertical: "middle",
|
|
||||||
horizontal: "center",
|
|
||||||
};
|
|
||||||
sheet.getCell("A1").font = {
|
|
||||||
name: "SimSun",
|
|
||||||
family: 4,
|
|
||||||
size: 13,
|
|
||||||
bold: true,
|
|
||||||
};
|
|
||||||
sheet.mergeCells("A3", "G3");
|
|
||||||
var now = new Date();
|
|
||||||
sheet.getCell("A3").value = now.toLocaleDateString();
|
|
||||||
sheet.getCell("A3").alignment = {
|
|
||||||
vertical: "middle",
|
|
||||||
horizontal: "right",
|
|
||||||
};
|
|
||||||
|
|
||||||
sheet.getRow(4).values = [
|
|
||||||
"NO.",
|
|
||||||
"Trial ID",
|
|
||||||
"试验名称",
|
|
||||||
"研究方案号",
|
|
||||||
"申办方",
|
|
||||||
"是否废除",
|
|
||||||
"Date Created",
|
|
||||||
];
|
|
||||||
sheet.getRow(4).font = {
|
|
||||||
name: "SimSun",
|
|
||||||
family: 4,
|
|
||||||
size: 11,
|
|
||||||
bold: true,
|
|
||||||
};
|
|
||||||
sheet.getRow(4).alignment = { vertical: "middle", horizontal: "left" };
|
|
||||||
|
|
||||||
sheet.addRows(this.selectArr);
|
|
||||||
|
|
||||||
sheet.eachRow((row, number) => {
|
|
||||||
if (number > 3) {
|
|
||||||
row.eachCell((cell, rowNumber) => {
|
|
||||||
cell.alignment = { vertical: "center", horizontal: "left" };
|
|
||||||
cell.border = {
|
|
||||||
top: { style: "thin" },
|
|
||||||
left: { style: "thin" },
|
|
||||||
bottom: { style: "thin" },
|
|
||||||
right: { style: "thin" },
|
|
||||||
};
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
workbook.xlsx
|
|
||||||
.writeBuffer({
|
|
||||||
base64: true,
|
|
||||||
})
|
})
|
||||||
.then(function (xls64) {
|
|
||||||
var data = new Blob([xls64], {
|
|
||||||
type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
|
|
||||||
});
|
|
||||||
|
|
||||||
if ("msSaveOrOpenBlob" in navigator) {
|
|
||||||
// ie使用的下载方式
|
|
||||||
window.navigator.msSaveOrOpenBlob(data, "Trials" + ".xlsx");
|
|
||||||
} else {
|
|
||||||
var a = document.createElement("a");
|
|
||||||
|
|
||||||
var url = URL.createObjectURL(data);
|
|
||||||
a.href = url;
|
|
||||||
a.download = "Trials" + ".xlsx";
|
|
||||||
document.body.appendChild(a);
|
|
||||||
a.click();
|
|
||||||
setTimeout(function () {
|
|
||||||
document.body.removeChild(a);
|
|
||||||
window.URL.revokeObjectURL(url);
|
|
||||||
}, 0);
|
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
},
|
}
|
||||||
},
|
|
||||||
};
|
|
||||||
</script>
|
</script>
|
||||||
|
|
|
||||||
|
|
@ -91,8 +91,7 @@
|
||||||
.JudgeQuestionList[i].Answer
|
.JudgeQuestionList[i].Answer
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
}}</span
|
}}</span>
|
||||||
>
|
|
||||||
<span v-else>{{
|
<span v-else>{{
|
||||||
scope.row.VisitTaskInfoList[j.index].JudgeQuestionList[i]
|
scope.row.VisitTaskInfoList[j.index].JudgeQuestionList[i]
|
||||||
.Answer
|
.Answer
|
||||||
|
|
@ -321,7 +320,7 @@
|
||||||
alt=""
|
alt=""
|
||||||
crossorigin="anonymous"
|
crossorigin="anonymous"
|
||||||
style="max-width: 100%; max-height: 100%"
|
style="max-width: 100%; max-height: 100%"
|
||||||
/>
|
>
|
||||||
<span class="el-upload-list__item-actions">
|
<span class="el-upload-list__item-actions">
|
||||||
<span
|
<span
|
||||||
class="el-upload-list__item-preview"
|
class="el-upload-list__item-preview"
|
||||||
|
|
@ -435,88 +434,87 @@ import {
|
||||||
// uploadJudgeTaskImage,
|
// uploadJudgeTaskImage,
|
||||||
saveJudgeVisitTaskResult,
|
saveJudgeVisitTaskResult,
|
||||||
submitJudgeVisitTaskResult,
|
submitJudgeVisitTaskResult,
|
||||||
getReadingPastResultList,
|
getReadingPastResultList
|
||||||
} from "@/api/trials";
|
} from '@/api/trials'
|
||||||
import { getAutoCutNextTask } from "@/api/user";
|
import { getAutoCutNextTask } from '@/api/user'
|
||||||
import { setSkipReadingCache } from "@/api/reading";
|
import { setSkipReadingCache } from '@/api/reading'
|
||||||
import const_ from "@/const/sign-code";
|
import const_ from '@/const/sign-code'
|
||||||
import { getToken } from "@/utils/auth";
|
import { getToken } from '@/utils/auth'
|
||||||
import SignForm from "@/views/trials/components/newSignForm";
|
import SignForm from '@/views/trials/components/newSignForm'
|
||||||
import DicomEvent from "@/views/trials/trials-panel/reading/dicoms/components/DicomEvent";
|
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";
|
import { changeURLStatic } from '@/utils/history.js'
|
||||||
import Viewer from "v-viewer";
|
|
||||||
export default {
|
export default {
|
||||||
name: "AdReview",
|
name: 'AdReview',
|
||||||
components: { SignForm },
|
components: { SignForm },
|
||||||
props: {
|
props: {
|
||||||
trialId: {
|
trialId: {
|
||||||
type: String,
|
type: String,
|
||||||
required: true,
|
required: true
|
||||||
},
|
},
|
||||||
subjectId: {
|
subjectId: {
|
||||||
type: String,
|
type: String,
|
||||||
required: true,
|
required: true
|
||||||
},
|
},
|
||||||
visitTaskId: {
|
visitTaskId: {
|
||||||
type: String,
|
type: String,
|
||||||
required: true,
|
required: true
|
||||||
},
|
},
|
||||||
readingCategory: {
|
readingCategory: {
|
||||||
type: Number,
|
type: Number,
|
||||||
required: true,
|
required: true
|
||||||
},
|
},
|
||||||
subjectCode: {
|
subjectCode: {
|
||||||
type: String,
|
type: String,
|
||||||
required: true,
|
required: true
|
||||||
},
|
},
|
||||||
taskBlindName: {
|
taskBlindName: {
|
||||||
type: String,
|
type: String,
|
||||||
required: true,
|
required: true
|
||||||
},
|
},
|
||||||
isReadingShowSubjectInfo: {
|
isReadingShowSubjectInfo: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
required: true,
|
required: true
|
||||||
},
|
},
|
||||||
isReadingShowPreviousResults: {
|
isReadingShowPreviousResults: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
required: true,
|
required: true
|
||||||
},
|
},
|
||||||
isExistsClinicalData: {
|
isExistsClinicalData: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
required: true,
|
required: true
|
||||||
},
|
}
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
adInfo: {},
|
adInfo: {},
|
||||||
judgeQuestion: [],
|
judgeQuestion: [],
|
||||||
adForm: {
|
adForm: {
|
||||||
visitTaskId: "",
|
visitTaskId: '',
|
||||||
judgeResultTaskId: "",
|
judgeResultTaskId: '',
|
||||||
judgeResultRemark: "",
|
judgeResultRemark: '',
|
||||||
// judgeResultImagePath: ''
|
// judgeResultImagePath: ''
|
||||||
judgeResultImagePathList: [],
|
judgeResultImagePathList: []
|
||||||
},
|
},
|
||||||
currentUser: zzSessionStorage.getItem("userName"),
|
currentUser: zzSessionStorage.getItem('userName'),
|
||||||
signVisible: false,
|
signVisible: false,
|
||||||
signCode: null,
|
signCode: null,
|
||||||
accept: ".png,.jpg,.jpeg",
|
accept: '.png,.jpg,.jpeg',
|
||||||
imgVisible: false,
|
imgVisible: false,
|
||||||
imageUrl: "",
|
imageUrl: '',
|
||||||
uploadDisabled: false,
|
uploadDisabled: false,
|
||||||
fileList: [],
|
fileList: [],
|
||||||
loading: false,
|
loading: false,
|
||||||
visitTaskArmList: [],
|
visitTaskArmList: [],
|
||||||
priorADList: [],
|
priorADList: [],
|
||||||
priorLoading: false,
|
priorLoading: false,
|
||||||
judgeResultArmEnum: "",
|
judgeResultArmEnum: '',
|
||||||
criterionType: null,
|
criterionType: null,
|
||||||
openWindow: null,
|
openWindow: null,
|
||||||
isFixed: false,
|
isFixed: false,
|
||||||
images: [],
|
images: [],
|
||||||
remark: "",
|
remark: ''
|
||||||
};
|
}
|
||||||
},
|
},
|
||||||
// watch: {
|
// watch: {
|
||||||
// visitTaskId: {
|
// visitTaskId: {
|
||||||
|
|
@ -532,261 +530,260 @@ export default {
|
||||||
// }
|
// }
|
||||||
// },
|
// },
|
||||||
mounted() {
|
mounted() {
|
||||||
this.initializeViewer();
|
this.criterionType = parseInt(this.$route.query.criterionType)
|
||||||
this.criterionType = parseInt(this.$route.query.criterionType);
|
this.getAdInfo()
|
||||||
this.getAdInfo();
|
|
||||||
if (this.isReadingShowPreviousResults) {
|
if (this.isReadingShowPreviousResults) {
|
||||||
this.getPriorAdList();
|
this.getPriorAdList()
|
||||||
}
|
}
|
||||||
DicomEvent.$on("resetOpenWindow", () => {
|
DicomEvent.$on('resetOpenWindow', () => {
|
||||||
if (this.openWindow) {
|
if (this.openWindow) {
|
||||||
this.openWindow.close();
|
this.openWindow.close()
|
||||||
}
|
}
|
||||||
});
|
})
|
||||||
},
|
},
|
||||||
beforeDestroy() {
|
beforeDestroy() {
|
||||||
DicomEvent.$off("resetOpenWindow");
|
DicomEvent.$off('resetOpenWindow')
|
||||||
if (this.openWindow) {
|
if (this.openWindow) {
|
||||||
this.openWindow.close();
|
this.openWindow.close()
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
async getAdInfo() {
|
async getAdInfo() {
|
||||||
this.loading = true;
|
this.loading = true
|
||||||
try {
|
try {
|
||||||
const res = await getJudgeReadingInfo({
|
const res = await getJudgeReadingInfo({
|
||||||
visitTaskId: this.visitTaskId,
|
visitTaskId: this.visitTaskId
|
||||||
});
|
})
|
||||||
if (res.IsSuccess) {
|
if (res.IsSuccess) {
|
||||||
var judgeQS = [];
|
var judgeQS = []
|
||||||
if (res.Result.VisitInfoList.length > 0) {
|
if (res.Result.VisitInfoList.length > 0) {
|
||||||
res.Result.VisitInfoList[0].VisitTaskInfoList.map((v, index) => {
|
res.Result.VisitInfoList[0].VisitTaskInfoList.map((v, index) => {
|
||||||
var qsObj = {
|
var qsObj = {
|
||||||
armEnum: v.ArmEnum,
|
armEnum: v.ArmEnum,
|
||||||
judgeQuestionList: [],
|
judgeQuestionList: [],
|
||||||
index: index,
|
index: index
|
||||||
};
|
}
|
||||||
v.JudgeQuestionList.map((q) => {
|
v.JudgeQuestionList.map((q) => {
|
||||||
if (q.QuestionType === 1) {
|
if (q.QuestionType === 1) {
|
||||||
qsObj.judgeQuestionList.push(q.QuestionName);
|
qsObj.judgeQuestionList.push(q.QuestionName)
|
||||||
} else if (q.QuestionType === 3 && this.criterionType === 10) {
|
} else if (q.QuestionType === 3 && this.criterionType === 10) {
|
||||||
qsObj.judgeQuestionList.push(
|
qsObj.judgeQuestionList.push(
|
||||||
this.$t("trials:globalReview:table:visitRemark")
|
this.$t('trials:globalReview:table:visitRemark')
|
||||||
);
|
)
|
||||||
} else {
|
} else {
|
||||||
qsObj.judgeQuestionList.push(
|
qsObj.judgeQuestionList.push(
|
||||||
this.$fd("JudgeReadingQuestionType", q.QuestionType)
|
this.$fd('JudgeReadingQuestionType', q.QuestionType)
|
||||||
);
|
)
|
||||||
}
|
}
|
||||||
});
|
})
|
||||||
judgeQS.push(qsObj);
|
judgeQS.push(qsObj)
|
||||||
});
|
})
|
||||||
}
|
}
|
||||||
this.judgeQuestion = judgeQS;
|
this.judgeQuestion = judgeQS
|
||||||
this.isFixed =
|
this.isFixed =
|
||||||
this.judgeQuestion.length > 0 &&
|
this.judgeQuestion.length > 0 &&
|
||||||
this.judgeQuestion[0].judgeQuestionList.length > 4;
|
this.judgeQuestion[0].judgeQuestionList.length > 4
|
||||||
this.adInfo = res.Result;
|
this.adInfo = res.Result
|
||||||
this.adForm.judgeResultTaskId = res.Result.JudgeResultTaskId;
|
this.adForm.judgeResultTaskId = res.Result.JudgeResultTaskId
|
||||||
|
|
||||||
this.fileList = [];
|
this.fileList = []
|
||||||
if (res.Result.JudgeResultImagePathList) {
|
if (res.Result.JudgeResultImagePathList) {
|
||||||
res.Result.JudgeResultImagePathList.map((url) => {
|
res.Result.JudgeResultImagePathList.map((url) => {
|
||||||
if (url) {
|
if (url) {
|
||||||
this.fileList.push({ name: "", url: url });
|
this.fileList.push({ name: '', url: url })
|
||||||
}
|
}
|
||||||
});
|
})
|
||||||
this.adForm.judgeResultImagePathList =
|
this.adForm.judgeResultImagePathList =
|
||||||
res.Result.JudgeResultImagePathList;
|
res.Result.JudgeResultImagePathList
|
||||||
}
|
}
|
||||||
this.visitTaskArmList = res.Result.VisitTaskArmList;
|
this.visitTaskArmList = res.Result.VisitTaskArmList
|
||||||
var i = this.visitTaskArmList.findIndex(
|
var i = this.visitTaskArmList.findIndex(
|
||||||
(i) => i.VisitTaskId === this.adForm.judgeResultTaskId
|
(i) => i.VisitTaskId === this.adForm.judgeResultTaskId
|
||||||
);
|
)
|
||||||
if (i > -1) {
|
if (i > -1) {
|
||||||
// 本人已完整查看两位独立阅片人的全部相关影像和评估数据,经过综合研判,更认同第一阅片人(R1)对该病例的整体评估,原因是:
|
// 本人已完整查看两位独立阅片人的全部相关影像和评估数据,经过综合研判,更认同第一阅片人(R1)对该病例的整体评估,原因是:
|
||||||
this.judgeResultArmEnum = this.visitTaskArmList[i].ArmEnum;
|
this.judgeResultArmEnum = this.visitTaskArmList[i].ArmEnum
|
||||||
var msg = "";
|
var msg = ''
|
||||||
if (this.judgeResultArmEnum === 1) {
|
if (this.judgeResultArmEnum === 1) {
|
||||||
msg = this.$t("trials:adReview:title:msg1");
|
msg = this.$t('trials:adReview:title:msg1')
|
||||||
} else if (this.judgeResultArmEnum === 2) {
|
} else if (this.judgeResultArmEnum === 2) {
|
||||||
msg = this.$t("trials:adReview:title:msg3");
|
msg = this.$t('trials:adReview:title:msg3')
|
||||||
}
|
}
|
||||||
this.remark = msg;
|
this.remark = msg
|
||||||
this.adForm.judgeResultRemark = res.Result.JudgeResultRemark;
|
this.adForm.judgeResultRemark = res.Result.JudgeResultRemark
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
this.loading = false;
|
this.loading = false
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
this.loading = false;
|
this.loading = false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
async getPriorAdList() {
|
async getPriorAdList() {
|
||||||
this.priorLoading = true;
|
this.priorLoading = true
|
||||||
try {
|
try {
|
||||||
const res = await getReadingPastResultList({
|
const res = await getReadingPastResultList({
|
||||||
visitTaskId: this.visitTaskId,
|
visitTaskId: this.visitTaskId
|
||||||
});
|
})
|
||||||
if (res.IsSuccess) {
|
if (res.IsSuccess) {
|
||||||
this.priorADList = res.Result;
|
this.priorADList = res.Result
|
||||||
}
|
}
|
||||||
this.priorLoading = false;
|
this.priorLoading = false
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
this.priorLoading = false;
|
this.priorLoading = false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
handleVisitTaskArmChange(v) {
|
handleVisitTaskArmChange(v) {
|
||||||
var i = this.visitTaskArmList.findIndex((i) => i.VisitTaskId === v);
|
var i = this.visitTaskArmList.findIndex((i) => i.VisitTaskId === v)
|
||||||
if (i > -1) {
|
if (i > -1) {
|
||||||
// 本人已完整查看两位独立阅片人的全部相关影像和评估数据,经过综合研判,更认同第一阅片人(R1)对该病例的整体评估,原因是:
|
// 本人已完整查看两位独立阅片人的全部相关影像和评估数据,经过综合研判,更认同第一阅片人(R1)对该病例的整体评估,原因是:
|
||||||
this.judgeResultArmEnum = this.visitTaskArmList[i].ArmEnum;
|
this.judgeResultArmEnum = this.visitTaskArmList[i].ArmEnum
|
||||||
var msg = "";
|
var msg = ''
|
||||||
if (this.judgeResultArmEnum === 1) {
|
if (this.judgeResultArmEnum === 1) {
|
||||||
msg = this.$t("trials:adReview:title:msg1");
|
msg = this.$t('trials:adReview:title:msg1')
|
||||||
} else {
|
} else {
|
||||||
msg = this.$t("trials:adReview:title:msg3");
|
msg = this.$t('trials:adReview:title:msg3')
|
||||||
}
|
}
|
||||||
// this.adForm.judgeResultRemark = `本人已完整查看两位独立阅片人的全部相关影像和评估数据,经过综合研判,更认同${this.$fd('ArmEnum', this.judgeResultArmEnum)}对该病例的整体评估,原因是:`
|
// this.adForm.judgeResultRemark = `本人已完整查看两位独立阅片人的全部相关影像和评估数据,经过综合研判,更认同${this.$fd('ArmEnum', this.judgeResultArmEnum)}对该病例的整体评估,原因是:`
|
||||||
this.remark = msg;
|
this.remark = msg
|
||||||
this.adForm.judgeResultRemark = "";
|
this.adForm.judgeResultRemark = ''
|
||||||
} else {
|
} else {
|
||||||
this.judgeResultArmEnum = "";
|
this.judgeResultArmEnum = ''
|
||||||
this.remark = "";
|
this.remark = ''
|
||||||
this.adForm.judgeResultRemark = "";
|
this.adForm.judgeResultRemark = ''
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
previewCD() {
|
previewCD() {
|
||||||
var token = getToken();
|
var token = getToken()
|
||||||
const routeData = this.$router.resolve({
|
const routeData = this.$router.resolve({
|
||||||
path: `/clinicalData?subjectId=${this.subjectId}&trialId=${this.trialId}&visitTaskId=${this.visitTaskId}&TokenKey=${token}`,
|
path: `/clinicalData?subjectId=${this.subjectId}&trialId=${this.trialId}&visitTaskId=${this.visitTaskId}&TokenKey=${token}`
|
||||||
});
|
})
|
||||||
window.open(routeData.href, "_blank");
|
window.open(routeData.href, '_blank')
|
||||||
},
|
},
|
||||||
async handleSave() {
|
async handleSave() {
|
||||||
const valid = await this.$refs["adForm"].validate();
|
const valid = await this.$refs['adForm'].validate()
|
||||||
if (!valid) return;
|
if (!valid) return
|
||||||
this.loading = true;
|
this.loading = true
|
||||||
var paths = [];
|
var paths = []
|
||||||
this.fileList.map((file) => {
|
this.fileList.map((file) => {
|
||||||
if (file.url) {
|
if (file.url) {
|
||||||
paths.push(file.url);
|
paths.push(file.url)
|
||||||
}
|
}
|
||||||
});
|
})
|
||||||
this.adForm.judgeResultImagePathList = paths;
|
this.adForm.judgeResultImagePathList = paths
|
||||||
this.adForm.visitTaskId = this.visitTaskId;
|
this.adForm.visitTaskId = this.visitTaskId
|
||||||
try {
|
try {
|
||||||
await saveJudgeVisitTaskResult(this.adForm);
|
await saveJudgeVisitTaskResult(this.adForm)
|
||||||
this.$message.success(this.$t("common:message:savedSuccessfully"));
|
this.$message.success(this.$t('common:message:savedSuccessfully'))
|
||||||
this.loading = false;
|
this.loading = false
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
this.loading = false;
|
this.loading = false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
async handleSubmit() {
|
async handleSubmit() {
|
||||||
const valid = await this.$refs["adForm"].validate();
|
const valid = await this.$refs['adForm'].validate()
|
||||||
if (!valid) return;
|
if (!valid) return
|
||||||
const { ImageAssessmentReportConfirmation } = const_.processSignature;
|
const { ImageAssessmentReportConfirmation } = const_.processSignature
|
||||||
this.signCode = ImageAssessmentReportConfirmation;
|
this.signCode = ImageAssessmentReportConfirmation
|
||||||
this.signVisible = true;
|
this.signVisible = true
|
||||||
},
|
},
|
||||||
// 关闭签名框
|
// 关闭签名框
|
||||||
closeSignDialog(isSign, signInfo) {
|
closeSignDialog(isSign, signInfo) {
|
||||||
if (isSign) {
|
if (isSign) {
|
||||||
this.signConfirm(signInfo);
|
this.signConfirm(signInfo)
|
||||||
} else {
|
} else {
|
||||||
this.signVisible = false;
|
this.signVisible = false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
// 签名并确认
|
// 签名并确认
|
||||||
async signConfirm(signInfo) {
|
async signConfirm(signInfo) {
|
||||||
this.loading = true;
|
this.loading = true
|
||||||
var paths = [];
|
var paths = []
|
||||||
this.fileList.map((file) => {
|
this.fileList.map((file) => {
|
||||||
paths.push(file.url);
|
paths.push(file.url)
|
||||||
});
|
})
|
||||||
var params = {
|
var params = {
|
||||||
data: {
|
data: {
|
||||||
visitTaskId: this.visitTaskId,
|
visitTaskId: this.visitTaskId,
|
||||||
judgeResultTaskId: this.adForm.judgeResultTaskId,
|
judgeResultTaskId: this.adForm.judgeResultTaskId,
|
||||||
judgeResultRemark: this.adForm.judgeResultRemark,
|
judgeResultRemark: this.adForm.judgeResultRemark,
|
||||||
judgeResultImagePathList: paths,
|
judgeResultImagePathList: paths
|
||||||
},
|
},
|
||||||
signInfo: signInfo,
|
signInfo: signInfo
|
||||||
};
|
}
|
||||||
try {
|
try {
|
||||||
const res = await submitJudgeVisitTaskResult(params);
|
const res = await submitJudgeVisitTaskResult(params)
|
||||||
if (res.IsSuccess) {
|
if (res.IsSuccess) {
|
||||||
this.$message.success(this.$t("common:message:savedSuccessfully"));
|
this.$message.success(this.$t('common:message:savedSuccessfully'))
|
||||||
this.isEdit = false;
|
this.isEdit = false
|
||||||
this.$refs["signForm"].btnLoading = false;
|
this.$refs['signForm'].btnLoading = false
|
||||||
this.signVisible = false;
|
this.signVisible = false
|
||||||
// window.location.reload()
|
// window.location.reload()
|
||||||
// window.opener.postMessage('refreshTaskList', window.location)
|
// window.opener.postMessage('refreshTaskList', window.location)
|
||||||
// 设置当前任务阅片状态为已读
|
// 设置当前任务阅片状态为已读
|
||||||
this.adInfo.ReadingTaskState = 2;
|
this.adInfo.ReadingTaskState = 2
|
||||||
const res = await getAutoCutNextTask();
|
const res = await getAutoCutNextTask()
|
||||||
var isAutoTask = res.Result.AutoCutNextTask;
|
var isAutoTask = res.Result.AutoCutNextTask
|
||||||
if (isAutoTask) {
|
if (isAutoTask) {
|
||||||
// store.dispatch('reading/resetVisitTasks')
|
// store.dispatch('reading/resetVisitTasks')
|
||||||
window.location.reload();
|
window.location.reload()
|
||||||
} else {
|
} else {
|
||||||
// '当前阅片任务已完成,是否进入下一个阅片任务?'
|
// '当前阅片任务已完成,是否进入下一个阅片任务?'
|
||||||
const confirm = await this.$confirm(
|
const confirm = await this.$confirm(
|
||||||
this.$t("trials:adReview:title:msg2"),
|
this.$t('trials:adReview:title:msg2'),
|
||||||
{
|
{
|
||||||
type: "warning",
|
type: 'warning',
|
||||||
distinguishCancelAndClose: true,
|
distinguishCancelAndClose: true
|
||||||
}
|
}
|
||||||
);
|
)
|
||||||
if (confirm === "confirm") {
|
if (confirm === 'confirm') {
|
||||||
// store.dispatch('reading/resetVisitTasks')
|
// store.dispatch('reading/resetVisitTasks')
|
||||||
// DicomEvent.$emit('getNextTask')
|
// DicomEvent.$emit('getNextTask')
|
||||||
window.location.reload();
|
window.location.reload()
|
||||||
} else {
|
} else {
|
||||||
changeURLStatic("visitTaskId", this.visitTaskId);
|
changeURLStatic('visitTaskId', this.visitTaskId)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
window.opener.postMessage("refreshTaskList", window.location);
|
window.opener.postMessage('refreshTaskList', window.location)
|
||||||
}
|
}
|
||||||
this.loading = false;
|
this.loading = false
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
this.loading = false;
|
this.loading = false
|
||||||
this.$refs["signForm"].btnLoading = false;
|
this.$refs['signForm'].btnLoading = false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
handleViewDetail(visitTaskId) {
|
handleViewDetail(visitTaskId) {
|
||||||
if (this.openWindow) {
|
if (this.openWindow) {
|
||||||
this.openWindow.close();
|
this.openWindow.close()
|
||||||
}
|
}
|
||||||
var token = getToken();
|
var token = getToken()
|
||||||
var criterionType = parseInt(localStorage.getItem("CriterionType"));
|
var criterionType = parseInt(localStorage.getItem('CriterionType'))
|
||||||
var readingTool = this.$router.currentRoute.query.readingTool;
|
var readingTool = this.$router.currentRoute.query.readingTool
|
||||||
readingTool = isNaN(parseInt(readingTool)) ? null : parseInt(readingTool);
|
readingTool = isNaN(parseInt(readingTool)) ? null : parseInt(readingTool)
|
||||||
var isReadingTaskViewInOrder =
|
var isReadingTaskViewInOrder =
|
||||||
this.$router.currentRoute.query.isReadingTaskViewInOrder;
|
this.$router.currentRoute.query.isReadingTaskViewInOrder
|
||||||
var trialReadingCriterionId =
|
var trialReadingCriterionId =
|
||||||
this.$router.currentRoute.query.TrialReadingCriterionId;
|
this.$router.currentRoute.query.TrialReadingCriterionId
|
||||||
|
|
||||||
var path = "";
|
var path = ''
|
||||||
if (readingTool === 0) {
|
if (readingTool === 0) {
|
||||||
path = `/readingDicoms?TrialReadingCriterionId=${trialReadingCriterionId}&trialId=${
|
path = `/readingDicoms?TrialReadingCriterionId=${trialReadingCriterionId}&trialId=${
|
||||||
this.trialId
|
this.trialId
|
||||||
}&subjectCode=${this.subjectCode}&subjectId=${
|
}&subjectCode=${this.subjectCode}&subjectId=${
|
||||||
this.subjectId
|
this.subjectId
|
||||||
}&visitTaskId=${visitTaskId}&isReadingTaskViewInOrder=${isReadingTaskViewInOrder}&criterionType=${criterionType}&readingTool=${readingTool}&TokenKey=${token}&key=${new Date().getTime()}`;
|
}&visitTaskId=${visitTaskId}&isReadingTaskViewInOrder=${isReadingTaskViewInOrder}&criterionType=${criterionType}&readingTool=${readingTool}&TokenKey=${token}&key=${new Date().getTime()}`
|
||||||
} else {
|
} else {
|
||||||
path = `/noneDicomReading?TrialReadingCriterionId=${trialReadingCriterionId}&trialId=${
|
path = `/noneDicomReading?TrialReadingCriterionId=${trialReadingCriterionId}&trialId=${
|
||||||
this.trialId
|
this.trialId
|
||||||
}&subjectCode=${this.subjectCode}&subjectId=${
|
}&subjectCode=${this.subjectCode}&subjectId=${
|
||||||
this.subjectId
|
this.subjectId
|
||||||
}&visitTaskId=${visitTaskId}&isReadingTaskViewInOrder=${isReadingTaskViewInOrder}&criterionType=${criterionType}&readingTool=${readingTool}&TokenKey=${token}&key=${new Date().getTime()}`;
|
}&visitTaskId=${visitTaskId}&isReadingTaskViewInOrder=${isReadingTaskViewInOrder}&criterionType=${criterionType}&readingTool=${readingTool}&TokenKey=${token}&key=${new Date().getTime()}`
|
||||||
}
|
}
|
||||||
var routeData = this.$router.resolve({ path });
|
var routeData = this.$router.resolve({ path })
|
||||||
this.openWindow = window.open(routeData.href, "_blank");
|
this.openWindow = window.open(routeData.href, '_blank')
|
||||||
},
|
},
|
||||||
handleView(row, armEnum) {
|
handleView(row, armEnum) {
|
||||||
if (this.openWindow) {
|
if (this.openWindow) {
|
||||||
this.openWindow.close();
|
this.openWindow.close()
|
||||||
}
|
}
|
||||||
// var token = getToken()
|
// var token = getToken()
|
||||||
// var task = row.VisitTaskInfoList.find(item => item.ArmEnum === armEnum)
|
// var task = row.VisitTaskInfoList.find(item => item.ArmEnum === armEnum)
|
||||||
|
|
@ -794,17 +791,17 @@ export default {
|
||||||
// path: `/readingPage?trialId=${this.trialId}&visitTaskId=${task.VisitTaskId}&TokenKey=${token}&isReadingShowPreviousResults=false`
|
// path: `/readingPage?trialId=${this.trialId}&visitTaskId=${task.VisitTaskId}&TokenKey=${token}&isReadingShowPreviousResults=false`
|
||||||
// })
|
// })
|
||||||
// window.open(routeData.href, '_blank')
|
// window.open(routeData.href, '_blank')
|
||||||
var token = getToken();
|
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 criterionType = this.$router.currentRoute.query.criterionType
|
||||||
var readingTool = this.$router.currentRoute.query.readingTool;
|
var readingTool = this.$router.currentRoute.query.readingTool
|
||||||
readingTool = isNaN(parseInt(readingTool)) ? null : parseInt(readingTool);
|
readingTool = isNaN(parseInt(readingTool)) ? null : parseInt(readingTool)
|
||||||
var isReadingTaskViewInOrder =
|
var isReadingTaskViewInOrder =
|
||||||
this.$router.currentRoute.query.isReadingTaskViewInOrder;
|
this.$router.currentRoute.query.isReadingTaskViewInOrder
|
||||||
var trialReadingCriterionId =
|
var trialReadingCriterionId =
|
||||||
this.$router.currentRoute.query.TrialReadingCriterionId;
|
this.$router.currentRoute.query.TrialReadingCriterionId
|
||||||
|
|
||||||
var path = "";
|
var path = ''
|
||||||
if (readingTool === 0) {
|
if (readingTool === 0) {
|
||||||
path = `/readingDicoms?TrialReadingCriterionId=${trialReadingCriterionId}&trialId=${
|
path = `/readingDicoms?TrialReadingCriterionId=${trialReadingCriterionId}&trialId=${
|
||||||
this.trialId
|
this.trialId
|
||||||
|
|
@ -812,7 +809,7 @@ export default {
|
||||||
this.subjectId
|
this.subjectId
|
||||||
}&visitTaskId=${
|
}&visitTaskId=${
|
||||||
task.VisitTaskId
|
task.VisitTaskId
|
||||||
}&isReadingTaskViewInOrder=${isReadingTaskViewInOrder}&criterionType=${criterionType}&readingTool=${readingTool}&TokenKey=${token}&key=${new Date().getTime()}`;
|
}&isReadingTaskViewInOrder=${isReadingTaskViewInOrder}&criterionType=${criterionType}&readingTool=${readingTool}&TokenKey=${token}&key=${new Date().getTime()}`
|
||||||
} else {
|
} else {
|
||||||
path = `/noneDicomReading?TrialReadingCriterionId=${trialReadingCriterionId}&trialId=${
|
path = `/noneDicomReading?TrialReadingCriterionId=${trialReadingCriterionId}&trialId=${
|
||||||
this.trialId
|
this.trialId
|
||||||
|
|
@ -820,26 +817,26 @@ export default {
|
||||||
this.subjectId
|
this.subjectId
|
||||||
}&visitTaskId=${
|
}&visitTaskId=${
|
||||||
task.VisitTaskId
|
task.VisitTaskId
|
||||||
}&isReadingTaskViewInOrder=${isReadingTaskViewInOrder}&criterionType=${criterionType}&readingTool=${readingTool}&TokenKey=${token}&key=${new Date().getTime()}`;
|
}&isReadingTaskViewInOrder=${isReadingTaskViewInOrder}&criterionType=${criterionType}&readingTool=${readingTool}&TokenKey=${token}&key=${new Date().getTime()}`
|
||||||
}
|
}
|
||||||
var routeData = this.$router.resolve({ path });
|
var routeData = this.$router.resolve({ path })
|
||||||
this.openWindow = window.open(routeData.href, "_blank");
|
this.openWindow = window.open(routeData.href, '_blank')
|
||||||
},
|
},
|
||||||
handleViewGl(row, armEnum) {
|
handleViewGl(row, armEnum) {
|
||||||
if (this.openWindow) {
|
if (this.openWindow) {
|
||||||
this.openWindow.close();
|
this.openWindow.close()
|
||||||
}
|
}
|
||||||
var token = getToken();
|
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 criterionType = this.$router.currentRoute.query.criterionType
|
||||||
var readingTool = this.$router.currentRoute.query.readingTool;
|
var readingTool = this.$router.currentRoute.query.readingTool
|
||||||
readingTool = isNaN(parseInt(readingTool)) ? null : parseInt(readingTool);
|
readingTool = isNaN(parseInt(readingTool)) ? null : parseInt(readingTool)
|
||||||
var isReadingTaskViewInOrder =
|
var isReadingTaskViewInOrder =
|
||||||
this.$router.currentRoute.query.isReadingTaskViewInOrder;
|
this.$router.currentRoute.query.isReadingTaskViewInOrder
|
||||||
var trialReadingCriterionId =
|
var trialReadingCriterionId =
|
||||||
this.$router.currentRoute.query.TrialReadingCriterionId;
|
this.$router.currentRoute.query.TrialReadingCriterionId
|
||||||
|
|
||||||
var path = "";
|
var path = ''
|
||||||
if (readingTool === 0) {
|
if (readingTool === 0) {
|
||||||
path = `/readingDicoms?TrialReadingCriterionId=${trialReadingCriterionId}&trialId=${
|
path = `/readingDicoms?TrialReadingCriterionId=${trialReadingCriterionId}&trialId=${
|
||||||
this.trialId
|
this.trialId
|
||||||
|
|
@ -847,7 +844,7 @@ export default {
|
||||||
this.subjectId
|
this.subjectId
|
||||||
}&visitTaskId=${
|
}&visitTaskId=${
|
||||||
task.GlobalVisitTaskId
|
task.GlobalVisitTaskId
|
||||||
}&isReadingTaskViewInOrder=${isReadingTaskViewInOrder}&criterionType=${criterionType}&readingTool=${readingTool}&TokenKey=${token}&key=${new Date().getTime()}`;
|
}&isReadingTaskViewInOrder=${isReadingTaskViewInOrder}&criterionType=${criterionType}&readingTool=${readingTool}&TokenKey=${token}&key=${new Date().getTime()}`
|
||||||
} else {
|
} else {
|
||||||
path = `/noneDicomReading?TrialReadingCriterionId=${trialReadingCriterionId}&trialId=${
|
path = `/noneDicomReading?TrialReadingCriterionId=${trialReadingCriterionId}&trialId=${
|
||||||
this.trialId
|
this.trialId
|
||||||
|
|
@ -855,10 +852,10 @@ export default {
|
||||||
this.subjectId
|
this.subjectId
|
||||||
}&visitTaskId=${
|
}&visitTaskId=${
|
||||||
task.GlobalVisitTaskId
|
task.GlobalVisitTaskId
|
||||||
}&isReadingTaskViewInOrder=${isReadingTaskViewInOrder}&criterionType=${criterionType}&readingTool=${readingTool}&TokenKey=${token}&key=${new Date().getTime()}`;
|
}&isReadingTaskViewInOrder=${isReadingTaskViewInOrder}&criterionType=${criterionType}&readingTool=${readingTool}&TokenKey=${token}&key=${new Date().getTime()}`
|
||||||
}
|
}
|
||||||
var routeData = this.$router.resolve({ path });
|
var routeData = this.$router.resolve({ path })
|
||||||
this.openWindow = window.open(routeData.href, "_blank");
|
this.openWindow = window.open(routeData.href, '_blank')
|
||||||
},
|
},
|
||||||
// uploadScreenshot(param) {
|
// uploadScreenshot(param) {
|
||||||
// this.loading = true
|
// this.loading = true
|
||||||
|
|
@ -876,105 +873,93 @@ export default {
|
||||||
// })
|
// })
|
||||||
// },
|
// },
|
||||||
async uploadScreenshot(param) {
|
async uploadScreenshot(param) {
|
||||||
this.loading = true;
|
this.loading = true
|
||||||
this.uploadDisabled = false;
|
this.uploadDisabled = false
|
||||||
var trialId = this.$route.query.trialId;
|
var trialId = this.$route.query.trialId
|
||||||
var file = await this.fileToBlob(param.file);
|
var file = await this.fileToBlob(param.file)
|
||||||
const res = await this.OSSclient.put(
|
const res = await this.OSSclient.put(
|
||||||
`/${trialId}/Read/${this.subjectId}/visit/${param.file.name}`,
|
`/${trialId}/Read/${this.subjectId}/visit/${param.file.name}`,
|
||||||
file
|
file
|
||||||
);
|
)
|
||||||
console.log(res);
|
console.log(res)
|
||||||
this.fileList.push({
|
this.fileList.push({
|
||||||
name: param.file.name,
|
name: param.file.name,
|
||||||
url: this.$getObjectName(res.url),
|
url: this.$getObjectName(res.url)
|
||||||
});
|
})
|
||||||
this.loading = false;
|
this.loading = false
|
||||||
this.uploadDisabled = true;
|
this.uploadDisabled = true
|
||||||
},
|
},
|
||||||
handleBeforeUpload(file) {
|
handleBeforeUpload(file) {
|
||||||
// 检测文件类型是否符合要求
|
// 检测文件类型是否符合要求
|
||||||
if (this.checkFileSuffix(file.name)) {
|
if (this.checkFileSuffix(file.name)) {
|
||||||
return true;
|
return true
|
||||||
} else {
|
} else {
|
||||||
const msg = this.$t("trials:adReview:title:msg4").replace(
|
const msg = this.$t('trials:adReview:title:msg4').replace(
|
||||||
"xxx",
|
'xxx',
|
||||||
this.accept
|
this.accept
|
||||||
);
|
)
|
||||||
this.$alert(msg);
|
this.$alert(msg)
|
||||||
return false;
|
return false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
checkFileSuffix(fileName) {
|
checkFileSuffix(fileName) {
|
||||||
var index = fileName.lastIndexOf(".");
|
var index = fileName.lastIndexOf('.')
|
||||||
var suffix = fileName.substring(index + 1, fileName.length);
|
var suffix = fileName.substring(index + 1, fileName.length)
|
||||||
if (
|
if (
|
||||||
this.accept.toLocaleLowerCase().search(suffix.toLocaleLowerCase()) ===
|
this.accept.toLocaleLowerCase().search(suffix.toLocaleLowerCase()) ===
|
||||||
-1
|
-1
|
||||||
) {
|
) {
|
||||||
return false;
|
return false
|
||||||
} else {
|
} else {
|
||||||
return true;
|
return true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
// 图片清空
|
// 图片清空
|
||||||
removeImage() {
|
removeImage() {
|
||||||
this.imageUrl = "";
|
this.imageUrl = ''
|
||||||
this.fileList = [];
|
this.fileList = []
|
||||||
this.adForm.judgeResultImagePath = "";
|
this.adForm.judgeResultImagePath = ''
|
||||||
},
|
},
|
||||||
// 预览图片
|
// 预览图片
|
||||||
handlePictureCardPreview(file) {
|
handlePictureCardPreview(file) {
|
||||||
this.images = this.fileList.map(
|
this.images = this.fileList.map(
|
||||||
(f) => this.OSSclientConfig.basePath + f.url
|
(f) => this.OSSclientConfig.basePath + f.url
|
||||||
);
|
)
|
||||||
// this.imageUrl = this.OSSclientConfig.basePath + file.url
|
// this.imageUrl = this.OSSclientConfig.basePath + file.url
|
||||||
this.$refs[file.url].$viewer.show();
|
this.$refs[file.url].$viewer.show()
|
||||||
},
|
},
|
||||||
// 删除图片
|
// 删除图片
|
||||||
handleRemove(file, fileList) {
|
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;
|
if (idx === -1) return
|
||||||
this.fileList.splice(idx, 1);
|
this.fileList.splice(idx, 1)
|
||||||
},
|
},
|
||||||
async skipTask() {
|
async skipTask() {
|
||||||
try {
|
try {
|
||||||
// 是否确认跳过?
|
// 是否确认跳过?
|
||||||
const confirm = await this.$confirm(
|
const confirm = await this.$confirm(
|
||||||
this.$t("trials:readingReport:message:skipConfirm"),
|
this.$t('trials:readingReport:message:skipConfirm'),
|
||||||
{
|
{
|
||||||
type: "warning",
|
type: 'warning',
|
||||||
distinguishCancelAndClose: true,
|
distinguishCancelAndClose: true
|
||||||
}
|
}
|
||||||
);
|
)
|
||||||
if (confirm !== "confirm") return;
|
if (confirm !== 'confirm') return
|
||||||
this.loading = true;
|
this.loading = true
|
||||||
const res = await setSkipReadingCache({
|
const res = await setSkipReadingCache({
|
||||||
visitTaskId: this.visitTaskId,
|
visitTaskId: this.visitTaskId
|
||||||
});
|
})
|
||||||
this.loading = false;
|
this.loading = false
|
||||||
if (res.IsSuccess) {
|
if (res.IsSuccess) {
|
||||||
window.location.reload();
|
window.location.reload()
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
this.loading = false;
|
this.loading = false
|
||||||
console.log(e);
|
console.log(e)
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
initializeViewer() {
|
}
|
||||||
Viewer.setDefaults({
|
}
|
||||||
toolbar: {
|
|
||||||
zoomIn: true,
|
|
||||||
zoomOut: true,
|
|
||||||
rotateLeft: true,
|
|
||||||
rotateRight: true,
|
|
||||||
flipHorizontal: true,
|
|
||||||
flipVertical: true,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
</script>
|
</script>
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
.adReview_wrapper {
|
.adReview_wrapper {
|
||||||
|
|
|
||||||
|
|
@ -1654,7 +1654,7 @@ export default {
|
||||||
resetWwwc() {
|
resetWwwc() {
|
||||||
this.toolState.viewportInvert = false
|
this.toolState.viewportInvert = false
|
||||||
var viewport = cornerstone.getViewport(this.canvas)
|
var viewport = cornerstone.getViewport(this.canvas)
|
||||||
viewport.invert = false
|
// viewport.invert = false
|
||||||
var image = cornerstone.getImage(this.canvas)
|
var image = cornerstone.getImage(this.canvas)
|
||||||
viewport.voi.windowWidth = image.windowWidth
|
viewport.voi.windowWidth = image.windowWidth
|
||||||
viewport.voi.windowCenter = image.windowCenter
|
viewport.voi.windowCenter = image.windowCenter
|
||||||
|
|
|
||||||
|
|
@ -352,7 +352,44 @@
|
||||||
<div class="text">{{ $t('trials:reading:button:reset') }}</div>
|
<div class="text">{{ $t('trials:reading:button:reset') }}</div>
|
||||||
</div>
|
</div>
|
||||||
</el-tooltip>
|
</el-tooltip>
|
||||||
|
<el-tooltip
|
||||||
|
v-if="trialCriterion.ImageUploadEnum > 0 && currentReadingTaskState < 2"
|
||||||
|
v-hasPermi="['role:ir']"
|
||||||
|
class="item"
|
||||||
|
effect="dark"
|
||||||
|
:content="$t('trials:reading:button:upload')"
|
||||||
|
placement="bottom"
|
||||||
|
>
|
||||||
|
<div class="tool-wrapper">
|
||||||
|
<div class="icon" @click.prevent="openUploadImage('upload')">
|
||||||
|
<i class="el-icon-upload2 svg-icon" />
|
||||||
|
</div>
|
||||||
|
<div class="text">{{ $t('trials:reading:button:upload') }}</div>
|
||||||
|
</div>
|
||||||
|
</el-tooltip>
|
||||||
|
<el-tooltip
|
||||||
|
v-if="trialCriterion.ImageDownloadEnum > 0"
|
||||||
|
v-hasPermi="[
|
||||||
|
'role:ir',
|
||||||
|
'role:mim',
|
||||||
|
'role:mc',
|
||||||
|
'role:pm',
|
||||||
|
'role:apm',
|
||||||
|
'role:ea',
|
||||||
|
'role:qa',
|
||||||
|
]"
|
||||||
|
class="item"
|
||||||
|
effect="dark"
|
||||||
|
:content="$t('trials:reading:button:download')"
|
||||||
|
placement="bottom"
|
||||||
|
>
|
||||||
|
<div class="tool-wrapper">
|
||||||
|
<div class="icon" @click.prevent="openUploadImage('download')">
|
||||||
|
<i class="el-icon-download svg-icon" />
|
||||||
|
</div>
|
||||||
|
<div class="text">{{ $t('trials:reading:button:download') }}</div>
|
||||||
|
</div>
|
||||||
|
</el-tooltip>
|
||||||
<div style="margin-left:auto;">
|
<div style="margin-left:auto;">
|
||||||
<div style="padding:5px">
|
<div style="padding:5px">
|
||||||
<!-- 手册 -->
|
<!-- 手册 -->
|
||||||
|
|
@ -433,13 +470,34 @@
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<RecistQuestionList
|
<RecistQuestionList
|
||||||
v-else-if="CriterionType !== 17"
|
v-else-if="CriterionType === 1"
|
||||||
ref="measurementList"
|
ref="measurementList"
|
||||||
:question-form-change-state="questionFormChangeState"
|
:question-form-change-state="questionFormChangeState"
|
||||||
:question-form-change-num="questionFormChangeNum"
|
:question-form-change-num="questionFormChangeNum"
|
||||||
:is-show="isShow"
|
:is-show="isShow"
|
||||||
:is-reading-show-subject-info="isReadingShowSubjectInfo"
|
:is-reading-show-subject-info="isReadingShowSubjectInfo"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
<IVUSList
|
||||||
|
v-else-if="CriterionType === 19"
|
||||||
|
ref="measurementList"
|
||||||
|
:question-form-change-state="questionFormChangeState"
|
||||||
|
:question-form-change-num="questionFormChangeNum"
|
||||||
|
:is-show="isShow"
|
||||||
|
:is-reading-show-subject-info="isReadingShowSubjectInfo"
|
||||||
|
/>
|
||||||
|
<OCTList
|
||||||
|
v-else-if="CriterionType === 20"
|
||||||
|
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>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
@ -655,6 +713,21 @@
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-form>
|
</el-form>
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
|
<upload-dicom-and-nonedicom
|
||||||
|
v-if="uploadImageVisible"
|
||||||
|
:SubjectId="uploadSubjectId"
|
||||||
|
:SubjectCode="uploadSubjectCode"
|
||||||
|
:Criterion="uploadTrialCriterion"
|
||||||
|
:visible.sync="uploadImageVisible"
|
||||||
|
/>
|
||||||
|
<download-dicom-and-nonedicom
|
||||||
|
v-if="downloadImageVisible"
|
||||||
|
:SubjectId="uploadSubjectId"
|
||||||
|
:SubjectCode="uploadSubjectCode"
|
||||||
|
:Criterion="uploadTrialCriterion"
|
||||||
|
:TaskId="taskId"
|
||||||
|
:visible.sync="downloadImageVisible"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script>
|
<script>
|
||||||
|
|
@ -677,6 +750,8 @@ import RecistBMQuestionList from './RecistBM/QuestionList'
|
||||||
import IRecistQuestionList from './IRecist/QuestionList'
|
import IRecistQuestionList from './IRecist/QuestionList'
|
||||||
import PCWGQuestionList from './PCWG/QuestionList'
|
import PCWGQuestionList from './PCWG/QuestionList'
|
||||||
import LuganoQuestionList from './Lugano/QuestionList'
|
import LuganoQuestionList from './Lugano/QuestionList'
|
||||||
|
import IVUSList from './IVUS/QuestionList'
|
||||||
|
import OCTList from './OCT/QuestionList'
|
||||||
import CustomWwwcForm from './CustomWwwcForm'
|
import CustomWwwcForm from './CustomWwwcForm'
|
||||||
import Manuals from './Manuals'
|
import Manuals from './Manuals'
|
||||||
import Hotkeys from './Hotkeys'
|
import Hotkeys from './Hotkeys'
|
||||||
|
|
@ -684,6 +759,9 @@ import WL from './WL'
|
||||||
import Others from './Others'
|
import Others from './Others'
|
||||||
import DicomEvent from './DicomEvent'
|
import DicomEvent from './DicomEvent'
|
||||||
import html2canvas from 'html2canvas'
|
import html2canvas from 'html2canvas'
|
||||||
|
import uploadDicomAndNonedicom from '@/components/uploadDicomAndNonedicom'
|
||||||
|
import downloadDicomAndNonedicom from '@/components/downloadDicomAndNonedicom'
|
||||||
|
import { getCriterionReadingInfo } from '@/api/trials'
|
||||||
export default {
|
export default {
|
||||||
name: 'DicomViewer',
|
name: 'DicomViewer',
|
||||||
components: {
|
components: {
|
||||||
|
|
@ -698,7 +776,12 @@ export default {
|
||||||
PCWGQuestionList,
|
PCWGQuestionList,
|
||||||
RecistBMQuestionList,
|
RecistBMQuestionList,
|
||||||
IRecistQuestionList,
|
IRecistQuestionList,
|
||||||
LuganoQuestionList },
|
LuganoQuestionList,
|
||||||
|
IVUSList,
|
||||||
|
OCTList,
|
||||||
|
'download-dicom-and-nonedicom': downloadDicomAndNonedicom,
|
||||||
|
'upload-dicom-and-nonedicom': uploadDicomAndNonedicom,
|
||||||
|
},
|
||||||
props: {
|
props: {
|
||||||
isShow: {
|
isShow: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
|
|
@ -839,7 +922,16 @@ export default {
|
||||||
activeCanvasWC: null,
|
activeCanvasWC: null,
|
||||||
activeTaskInfo: {},
|
activeTaskInfo: {},
|
||||||
clipPlaying: false,
|
clipPlaying: false,
|
||||||
fps: 15
|
fps: 15,
|
||||||
|
trialCriterion: {},
|
||||||
|
// 上传
|
||||||
|
downloadImageVisible: false,
|
||||||
|
uploadImageVisible: false,
|
||||||
|
uploadSubjectId: null,
|
||||||
|
uploadSubjectCode: null,
|
||||||
|
uploadTrialCriterion: {},
|
||||||
|
uploadStatus: 'upload',
|
||||||
|
taskId: ''
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
@ -912,6 +1004,7 @@ export default {
|
||||||
mounted() {
|
mounted() {
|
||||||
this.getHotKeys()
|
this.getHotKeys()
|
||||||
this.getWwcTpl()
|
this.getWwcTpl()
|
||||||
|
this.getTrialCriterion()
|
||||||
// cornerstone.imageCache.setMaximumSizeBytes(0)
|
// cornerstone.imageCache.setMaximumSizeBytes(0)
|
||||||
|
|
||||||
// const maximumSizeInBytes = 1024 * 1024 * 1024 // 1 GB
|
// const maximumSizeInBytes = 1024 * 1024 * 1024 // 1 GB
|
||||||
|
|
@ -923,6 +1016,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: '' }]
|
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) {
|
} else if (this.CriterionType === 17) {
|
||||||
this.measuredTools = [{ toolName: 'Length', text: this.$t('trials:reading:button:length'), icon: 'length', isDisabled: false, disabledReason: '' }, { toolName: 'RectangleRoi', text: this.$t('trials:reading:button:rectangle'), icon: 'rectangle', isDisabled: false, disabledReason: '' }, { toolName: 'ArrowAnnotate', text: this.$t('trials:reading:button:arrowAnnotate'), icon: 'arrow', isDisabled: false, disabledReason: '' }]
|
this.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.rotateList[0] = '1'
|
||||||
this.colorList[0] = ''
|
this.colorList[0] = ''
|
||||||
|
|
@ -1062,6 +1159,27 @@ export default {
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
getTrialCriterion() {
|
||||||
|
getCriterionReadingInfo({
|
||||||
|
TrialId: this.trialId || this.$route.query.trialId,
|
||||||
|
TrialReadingCriterionId: this.trialReadingCriterionId || this.$route.query.TrialReadingCriterionId,
|
||||||
|
})
|
||||||
|
.then((res) => {
|
||||||
|
this.trialCriterion = res.Result
|
||||||
|
})
|
||||||
|
.catch(() => {})
|
||||||
|
},
|
||||||
|
openUploadImage(status) {
|
||||||
|
const idx = this.visitTaskList.findIndex(i => i.IsCurrentTask)
|
||||||
|
if (idx > -1) {
|
||||||
|
this.taskId = this.visitTaskList[idx].VisitTaskId
|
||||||
|
}
|
||||||
|
this.uploadSubjectCode = this.$route.query.subjectCode
|
||||||
|
this.uploadSubjectId = this.$route.query.subjectId
|
||||||
|
this.uploadTrialCriterion = this.trialCriterion
|
||||||
|
this.uploadStatus = status
|
||||||
|
this[`${status}ImageVisible`] = true
|
||||||
|
},
|
||||||
async getWwcTpl() {
|
async getWwcTpl() {
|
||||||
// const loading = this.$loading({ fullscreen: true })
|
// const loading = this.$loading({ fullscreen: true })
|
||||||
try {
|
try {
|
||||||
|
|
@ -2072,15 +2190,15 @@ export default {
|
||||||
},
|
},
|
||||||
handleFusion() {
|
handleFusion() {
|
||||||
// https 或者 本地开发环境才是安全上下文
|
// https 或者 本地开发环境才是安全上下文
|
||||||
if (!window.isSecureContext) {
|
// if (!window.isSecureContext) {
|
||||||
this.$alert(this.$t('components:uploadvideo:message:xf3'))
|
// this.$alert(this.$t('components:uploadvideo:message:xf3'))
|
||||||
return
|
// return
|
||||||
}
|
// }
|
||||||
// 顶部文档是否开启跨源隔离
|
// // 顶部文档是否开启跨源隔离
|
||||||
if (!window.crossOriginIsolated) {
|
// if (!window.crossOriginIsolated) {
|
||||||
this.$alert(this.$t('components:uploadvideo:message:xf4'))
|
// this.$alert(this.$t('components:uploadvideo:message:xf4'))
|
||||||
return
|
// return
|
||||||
}
|
// }
|
||||||
if (this.imageQualityIssues && parseInt(this.imageQualityIssues) === 6) {
|
if (this.imageQualityIssues && parseInt(this.imageQualityIssues) === 6) {
|
||||||
this.$alert(this.$t('trials:lugano:message:fusionWarn'))
|
this.$alert(this.$t('trials:lugano:message:fusionWarn'))
|
||||||
return
|
return
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,506 @@
|
||||||
|
<template>
|
||||||
|
<el-form
|
||||||
|
v-if="isRender"
|
||||||
|
ref="measurementForm"
|
||||||
|
v-loading="loading"
|
||||||
|
:model="questionForm"
|
||||||
|
size="mini"
|
||||||
|
class="measurement-form"
|
||||||
|
>
|
||||||
|
<div class="base-dialog-body">
|
||||||
|
<div style="display: flex;justify-content: space-between;">
|
||||||
|
<h3 v-if="questionName" style="color: #ddd;padding: 5px 0px;margin: 0;">
|
||||||
|
<!-- {{ `${questionName} (${orderMark}${String(rowIndex).padStart(2, '0')})` }} -->
|
||||||
|
{{ lesionName }}
|
||||||
|
</h3>
|
||||||
|
<!-- 关闭 -->
|
||||||
|
<div>
|
||||||
|
<i class="el-icon-circle-close" style="font-size: 25px;cursor: pointer;" @click="handleClose" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<el-form-item
|
||||||
|
v-for="qs in questions"
|
||||||
|
v-show="qs.ShowQuestion!==2"
|
||||||
|
:key="qs.Id"
|
||||||
|
:label="`${qs.QuestionName}`"
|
||||||
|
:prop="qs.Id"
|
||||||
|
:rules="[
|
||||||
|
{ required: (qs.IsRequired === 0 || (qs.IsRequired ===1 && qs.RelevanceId && (questionForm[qs.RelevanceId] === qs.RelevanceValue))) && qs.Type!=='group' && qs.Type!=='summary',
|
||||||
|
message:['radio', 'select', 'checkbox'].includes(qs.Type) ? $t('common:ruleMessage:select') : $t('common:ruleMessage:specify'), trigger: ['blur','change']},
|
||||||
|
]"
|
||||||
|
>
|
||||||
|
|
||||||
|
<!-- 输入框 -->
|
||||||
|
<template v-if="qs.Type==='input'">
|
||||||
|
<el-input
|
||||||
|
v-model="questionForm[qs.Id]"
|
||||||
|
:disabled="!isCurrentTask || readingTaskState>=2 "
|
||||||
|
@change="((val)=>{formItemChange(val, qs)})"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
<!-- 数值类型 -->
|
||||||
|
<template v-if="qs.Type==='number'">
|
||||||
|
<el-input
|
||||||
|
v-model="questionForm[qs.Id]"
|
||||||
|
:disabled="!isCurrentTask || readingTaskState>=2 "
|
||||||
|
@change="((val)=>{formItemChange(val, qs)})"
|
||||||
|
@blur="limitBlur(qs.Id, qs.ValueType)"
|
||||||
|
>
|
||||||
|
<template v-if="qs.Unit" slot="append">
|
||||||
|
{{ $fd('ValueUnit', parseInt(qs.Unit)) }}
|
||||||
|
</template>
|
||||||
|
</el-input>
|
||||||
|
</template>
|
||||||
|
<!-- 自动计算 -->
|
||||||
|
<template v-if="qs.Type==='calculation'">
|
||||||
|
<el-input
|
||||||
|
v-model="questionForm[qs.Id]"
|
||||||
|
disabled
|
||||||
|
@change="((val)=>{formItemChange(val, qs)})"
|
||||||
|
>
|
||||||
|
<template v-if="qs.Unit" slot="append">
|
||||||
|
{{ $fd('ValueUnit', parseInt(qs.Unit)) }}
|
||||||
|
</template>
|
||||||
|
</el-input>
|
||||||
|
</template>
|
||||||
|
<!-- 多行文本输入框 -->
|
||||||
|
<el-input
|
||||||
|
v-if="qs.Type==='textarea'"
|
||||||
|
v-model="questionForm[qs.Id]"
|
||||||
|
type="textarea"
|
||||||
|
:autosize="{ minRows: 2, maxRows: 4}"
|
||||||
|
:disabled="!isCurrentTask || readingTaskState>=2"
|
||||||
|
@change="((val)=>{formItemChange(val, qs)})"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<el-select
|
||||||
|
v-if="qs.Type==='select'"
|
||||||
|
v-model="questionForm[qs.Id]"
|
||||||
|
filterable
|
||||||
|
:placeholder="$t('common:placeholder:select')"
|
||||||
|
:disabled="!isCurrentTask || readingTaskState>=2"
|
||||||
|
@change="((val)=>{formItemChange(val, qs)})"
|
||||||
|
>
|
||||||
|
<template v-if="qs.DictionaryCode">
|
||||||
|
<el-option
|
||||||
|
v-for="item of $d[qs.DictionaryCode]"
|
||||||
|
:key="item.id"
|
||||||
|
:value="item.value"
|
||||||
|
:label="item.label"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
<template v-else>
|
||||||
|
<el-option
|
||||||
|
v-for="val in qs.TypeValue.split('|')"
|
||||||
|
:key="val"
|
||||||
|
:label="val"
|
||||||
|
:value="val"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
</el-select>
|
||||||
|
<!-- 单选 -->
|
||||||
|
<el-radio-group
|
||||||
|
v-if="qs.Type==='radio'"
|
||||||
|
v-model="questionForm[qs.id]"
|
||||||
|
:disabled="!isCurrentTask || readingTaskState>=2"
|
||||||
|
>
|
||||||
|
<el-radio
|
||||||
|
v-for="val in qs.options.split('|')"
|
||||||
|
:key="val"
|
||||||
|
:label="val"
|
||||||
|
>
|
||||||
|
{{ val }}
|
||||||
|
</el-radio>
|
||||||
|
</el-radio-group>
|
||||||
|
</el-form-item>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div
|
||||||
|
v-if="isCurrentTask && readingTaskState<2"
|
||||||
|
class="base-dialog-footer"
|
||||||
|
style="text-align:right;margin-top:10px;"
|
||||||
|
>
|
||||||
|
<!-- 删除 -->
|
||||||
|
<el-button
|
||||||
|
v-if="isCurrentTaskAdd !== 'False'"
|
||||||
|
size="mini"
|
||||||
|
@click="handleDelete"
|
||||||
|
>
|
||||||
|
{{ $t('common:button:delete') }}
|
||||||
|
</el-button>
|
||||||
|
<!-- 保存 -->
|
||||||
|
<el-button
|
||||||
|
size="mini"
|
||||||
|
@click="handleSave"
|
||||||
|
>
|
||||||
|
{{ $t('common:button:save') }}
|
||||||
|
</el-button>
|
||||||
|
</div>
|
||||||
|
</el-form>
|
||||||
|
</template>
|
||||||
|
<script>
|
||||||
|
import { submitTableQuestion, deleteReadingRowAnswer } from '@/api/trials'
|
||||||
|
import DicomEvent from './../DicomEvent'
|
||||||
|
// import store from '@/store'
|
||||||
|
export default {
|
||||||
|
name: 'MeasurementForm',
|
||||||
|
props: {
|
||||||
|
questions: {
|
||||||
|
type: Array,
|
||||||
|
default() { return [] }
|
||||||
|
},
|
||||||
|
answers: {
|
||||||
|
type: Object,
|
||||||
|
default() { return {} }
|
||||||
|
},
|
||||||
|
lesionType: {
|
||||||
|
type: Number,
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
visitTaskId: {
|
||||||
|
type: String,
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
parentQsId: {
|
||||||
|
type: String,
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
isCurrentTask: {
|
||||||
|
type: Boolean,
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
readingTaskState: {
|
||||||
|
type: Number,
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
isBaseLineTask: {
|
||||||
|
type: Boolean,
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
orderMark: {
|
||||||
|
type: String,
|
||||||
|
default: ''
|
||||||
|
},
|
||||||
|
questionName: {
|
||||||
|
type: String,
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
rowIndex: {
|
||||||
|
type: String,
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
tableQuestions: {
|
||||||
|
type: Array,
|
||||||
|
default() { return [] }
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
questionForm: {},
|
||||||
|
loading: false,
|
||||||
|
trialId: '',
|
||||||
|
originalQuestionForm: {},
|
||||||
|
isRender: false,
|
||||||
|
toolType: '',
|
||||||
|
lesionName: '',
|
||||||
|
isCurrentTaskAdd: 'False',
|
||||||
|
lesionMark: '',
|
||||||
|
pictureBaseStr: '',
|
||||||
|
digitPlaces: 2
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this.trialId = this.$route.query.trialId
|
||||||
|
var digitPlaces = Number(localStorage.getItem('digitPlaces'))
|
||||||
|
this.digitPlaces = digitPlaces === -1 ? this.digitPlaces : digitPlaces
|
||||||
|
this.initForm()
|
||||||
|
DicomEvent.$on('handleImageQualityAbnormal', () => {
|
||||||
|
|
||||||
|
})
|
||||||
|
},
|
||||||
|
beforeDestroy() {
|
||||||
|
DicomEvent.$off('handleImageQualityAbnormal')
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
async initForm() {
|
||||||
|
const loading = this.$loading({ fullscreen: true })
|
||||||
|
this.questions.forEach(item => {
|
||||||
|
var val = this.answers[item.Id]
|
||||||
|
if (item.DictionaryCode) {
|
||||||
|
val = isNaN(parseInt(this.answers[item.Id])) ? this.answers[item.Id] : parseInt(this.answers[item.Id])
|
||||||
|
}
|
||||||
|
|
||||||
|
this.$set(this.questionForm, item.Id, val)
|
||||||
|
})
|
||||||
|
this.$set(this.questionForm, 'RowIndex', this.answers.RowIndex ? this.answers.RowIndex : '')
|
||||||
|
this.$set(this.questionForm, 'RowId', this.answers.RowId ? this.answers.RowId : '')
|
||||||
|
if (this.questionForm.RowId) {
|
||||||
|
this.$set(this.questionForm, 'saveTypeEnum', 2)
|
||||||
|
} else {
|
||||||
|
this.$set(this.questionForm, 'saveTypeEnum', 0)
|
||||||
|
}
|
||||||
|
this.$set(this.questionForm, 'IsDicomReading', this.answers.IsDicomReading !== 'False')
|
||||||
|
if (!this.questionForm.LesionType) {
|
||||||
|
this.$set(this.questionForm, 'LesionType', this.lesionType)
|
||||||
|
}
|
||||||
|
this.lesionName = this.getLesionInfo(this.orderMark, this.rowIndex)
|
||||||
|
this.isCurrentTaskAdd = this.answers.IsCurrentTaskAdd ? this.answers.IsCurrentTaskAdd : 'True'
|
||||||
|
this.lesionMark = this.getLesionName(this.orderMark, this.questionForm.RowIndex)
|
||||||
|
this.originalQuestionForm = { ...this.questionForm }
|
||||||
|
this.isRender = true
|
||||||
|
loading.close()
|
||||||
|
},
|
||||||
|
getLesionName(orderMark, rowIndex) {
|
||||||
|
var lessionName = ''
|
||||||
|
var rowIndexArr = rowIndex.split('.')
|
||||||
|
var x = parseInt(rowIndexArr[0])
|
||||||
|
var y = parseInt(rowIndexArr[1])
|
||||||
|
if (y > 0) {
|
||||||
|
y = String.fromCharCode(parseInt(rowIndexArr[1]) - 1 + 65 + 32)
|
||||||
|
lessionName = `${orderMark}${String(x).padStart(2, '0')}${y}`
|
||||||
|
} else {
|
||||||
|
lessionName = `${orderMark}${String(x).padStart(2, '0')}`
|
||||||
|
}
|
||||||
|
|
||||||
|
return lessionName
|
||||||
|
},
|
||||||
|
getLesionInfo(orderMark, rowIndex) {
|
||||||
|
var arr = []
|
||||||
|
var lessionName = ''
|
||||||
|
var rowIndexArr = rowIndex.split('.')
|
||||||
|
var x = parseInt(rowIndexArr[0])
|
||||||
|
var y = parseInt(rowIndexArr[1])
|
||||||
|
if (y > 0) {
|
||||||
|
y = String.fromCharCode(parseInt(rowIndexArr[1]) - 1 + 65 + 32)
|
||||||
|
lessionName = `${orderMark}${String(x).padStart(2, '0')}${y}`
|
||||||
|
arr.push(lessionName)
|
||||||
|
} else {
|
||||||
|
lessionName = `${orderMark}${String(x).padStart(2, '0')}`
|
||||||
|
arr.push(lessionName)
|
||||||
|
}
|
||||||
|
return arr.join(' ')
|
||||||
|
},
|
||||||
|
getQuestionId(questionMark) {
|
||||||
|
var idx = this.questions.findIndex(i => i.QuestionMark === questionMark)
|
||||||
|
if (idx > -1) {
|
||||||
|
return this.questions[idx].Id
|
||||||
|
} else {
|
||||||
|
return ''
|
||||||
|
}
|
||||||
|
},
|
||||||
|
async formItemChange(v, question) {
|
||||||
|
if (this.questionForm.RowId) {
|
||||||
|
this.$set(this.questionForm, 'saveTypeEnum', 1)
|
||||||
|
} else {
|
||||||
|
this.$set(this.questionForm, 'saveTypeEnum', 0)
|
||||||
|
}
|
||||||
|
if (question.QuestionMark === 1001 || question.QuestionMark === 1002) {
|
||||||
|
this.questionForm[this.getQuestionId(1003)] = this.calculate([1001, 1002], '-')
|
||||||
|
}
|
||||||
|
const area1 = this.getQuestionVal(1001)
|
||||||
|
const area2 = this.getQuestionVal(1002)
|
||||||
|
const diff = this.getQuestionVal(1003)
|
||||||
|
this.$emit('resetQuestions', { area1, area2, diff, saveTypeEnum: this.questionForm.saveTypeEnum, rowIndex: this.rowIndex, questionId: this.parentQsId, anwsers: this.questionForm })
|
||||||
|
},
|
||||||
|
calculate(qsMarkArr, type) {
|
||||||
|
var num = 0
|
||||||
|
for (let i = 0; i < qsMarkArr.length; i++) {
|
||||||
|
const mark = qsMarkArr[i]
|
||||||
|
const v = this.questionForm[this.getQuestionId(mark)]
|
||||||
|
if (isNaN(parseFloat(v))) {
|
||||||
|
num = null
|
||||||
|
break
|
||||||
|
}
|
||||||
|
if (i === 0) {
|
||||||
|
num = parseFloat(v)
|
||||||
|
} else {
|
||||||
|
switch (type) {
|
||||||
|
case '-':
|
||||||
|
num -= parseFloat(v)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return num === null ? num : num.toFixed(this.digitPlaces)
|
||||||
|
},
|
||||||
|
limitBlur(qId, valueType) {
|
||||||
|
const value = this.questionForm[qId]
|
||||||
|
if (isNaN(parseInt(value))) return
|
||||||
|
if (valueType === 0) {
|
||||||
|
this.$set(this.questionForm, qId, parseInt(value))
|
||||||
|
} else if (valueType === 3) {
|
||||||
|
this.$set(this.questionForm, qId, parseFloat(value))
|
||||||
|
} else {
|
||||||
|
this.$set(this.questionForm, qId, parseFloat(value).toFixed(this.digitPlaces))
|
||||||
|
}
|
||||||
|
},
|
||||||
|
returnFloat(num) {
|
||||||
|
if (num) return
|
||||||
|
var value = Math.round(parseFloat(num) * 100) / 100
|
||||||
|
var s = value.toString().split('.')
|
||||||
|
if (s.length === 1) {
|
||||||
|
value = value.toString() + '.00'
|
||||||
|
return value
|
||||||
|
}
|
||||||
|
if (s.length > 1) {
|
||||||
|
if (s[1].length < 2) {
|
||||||
|
value = value.toString() + '0'
|
||||||
|
}
|
||||||
|
return value
|
||||||
|
}
|
||||||
|
},
|
||||||
|
getQuestionVal(questionMark) {
|
||||||
|
const idx = this.questions.findIndex(i => i.QuestionMark === questionMark)
|
||||||
|
if (idx > -1) {
|
||||||
|
const questionId = this.questions[idx].Id
|
||||||
|
const answer = this.questionForm[questionId]
|
||||||
|
if (isNaN(parseFloat(answer))) {
|
||||||
|
return answer
|
||||||
|
} else {
|
||||||
|
return parseFloat(answer)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return ''
|
||||||
|
}
|
||||||
|
},
|
||||||
|
async handleSave() {
|
||||||
|
const valid = await this.$refs.measurementForm.validate()
|
||||||
|
if (!valid) return
|
||||||
|
const loading = this.$loading({ fullscreen: true })
|
||||||
|
try {
|
||||||
|
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}$/)
|
||||||
|
for (const k in this.questionForm) {
|
||||||
|
if (reg.test(k)) {
|
||||||
|
if (answers.findIndex(i => i.tableQuestionId === k) === -1) {
|
||||||
|
answers.push({ tableQuestionId: k, answer: this.questionForm[k] })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var params = {
|
||||||
|
questionId: this.parentQsId,
|
||||||
|
rowId: this.questionForm.RowId,
|
||||||
|
rowIndex: this.answers.RowIndex,
|
||||||
|
visitTaskId: this.visitTaskId,
|
||||||
|
trialId: this.trialId,
|
||||||
|
answerList: answers
|
||||||
|
}
|
||||||
|
const res = await submitTableQuestion(params)
|
||||||
|
if (res.IsSuccess) {
|
||||||
|
// 保存成功!
|
||||||
|
this.$message.success(this.$t('common:message:savedSuccessfully'))
|
||||||
|
this.$set(this.questionForm, 'saveTypeEnum', 2)
|
||||||
|
this.originalQuestionForm = { ...this.questionForm }
|
||||||
|
this.$set(this.questionForm, 'RowId', res.Result.RowId)
|
||||||
|
const area1 = this.getQuestionVal(1001)
|
||||||
|
const area2 = this.getQuestionVal(1002)
|
||||||
|
const diff = this.getQuestionVal(1003)
|
||||||
|
this.$emit('resetQuestions', { area1, area2, diff, saveTypeEnum: this.questionForm.saveTypeEnum, rowIndex: this.rowIndex, questionId: this.parentQsId, anwsers: this.questionForm })
|
||||||
|
this.$emit('close')
|
||||||
|
|
||||||
|
DicomEvent.$emit('refreshQuestions')
|
||||||
|
DicomEvent.$emit('getReportInfo', true)
|
||||||
|
}
|
||||||
|
loading.close()
|
||||||
|
} catch (e) {
|
||||||
|
console.log(e)
|
||||||
|
loading.close()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
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) {
|
||||||
|
this.$emit('close', { lesionType: this.lesionType, rowIndex: this.rowIndex, visitTaskId: this.visitTaskId })
|
||||||
|
DicomEvent.$emit('getReportInfo', true)
|
||||||
|
// '删除成功!'
|
||||||
|
this.$message.success(this.$t('common:message:deletedSuccessfully'))
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
this.$emit('close', { lesionType: this.lesionType, rowIndex: this.rowIndex, visitTaskId: this.visitTaskId })
|
||||||
|
}
|
||||||
|
loading.close()
|
||||||
|
} catch (e) {
|
||||||
|
loading.close()
|
||||||
|
console.log(e)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
async handleClose() {
|
||||||
|
if (!this.questionForm.RowId) {
|
||||||
|
// '当前数据未保存。如果关闭窗口,将会删除,是否继续?'
|
||||||
|
const confirm = await this.$confirm(
|
||||||
|
this.$t('trials:reading:warnning:msg60'),
|
||||||
|
{
|
||||||
|
type: 'warning',
|
||||||
|
distinguishCancelAndClose: true
|
||||||
|
}
|
||||||
|
)
|
||||||
|
if (confirm !== 'confirm') return
|
||||||
|
this.$emit('close', { lesionType: this.lesionType, rowIndex: this.rowIndex, visitTaskId: this.visitTaskId })
|
||||||
|
} else {
|
||||||
|
this.$emit('close')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.measurement-form{
|
||||||
|
/deep/ .el-form-item__label{
|
||||||
|
color: #c3c3c3;
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
/deep/ .el-input .el-input__inner{
|
||||||
|
background-color: transparent;
|
||||||
|
color: #ddd;
|
||||||
|
border: 1px solid #5e5e5e;
|
||||||
|
}
|
||||||
|
/deep/ .el-form-item{
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
justify-content: flex-start;
|
||||||
|
}
|
||||||
|
/deep/ .el-form-item__content{
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
/deep/ .el-input.is-disabled .el-input__inner{
|
||||||
|
background-color: #646464a1;
|
||||||
|
}
|
||||||
|
/deep/ .el-select.is-disabled .el-input__inner{
|
||||||
|
background-color: #646464a1;
|
||||||
|
}
|
||||||
|
/deep/ .el-button--mini, .el-button--mini.is-round {
|
||||||
|
padding: 7px 10px;
|
||||||
|
}
|
||||||
|
.el-form-item__content
|
||||||
|
.el-select{
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
.input-width1{
|
||||||
|
width: calc(100% -60px)!important;
|
||||||
|
}
|
||||||
|
.input-width2{
|
||||||
|
width: 100% !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
</style>
|
||||||
|
|
@ -0,0 +1,768 @@
|
||||||
|
<template>
|
||||||
|
<div class="measurement-wrapper" :style="{'height':height+10+'px'}">
|
||||||
|
|
||||||
|
<div class="container" :style="{'height':height+'px'}">
|
||||||
|
<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="true"
|
||||||
|
:question-form-change-num="0"
|
||||||
|
:is-qulity-issues="false"
|
||||||
|
:group-classify="1"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 测量问题 -->
|
||||||
|
<template v-if="questions.length > 0 && CriterionType !== 10">
|
||||||
|
<div v-for="(qs,index) in questions" :key="index" v-loading="loading" class="lesions lesions_wrapper">
|
||||||
|
<h4 v-if="qs.Type === 'group'" style="color: #ddd;padding: 5px 0px;margin: 0;">
|
||||||
|
{{ language==='en'?qs.GroupEnName:qs.GroupName }}
|
||||||
|
</h4>
|
||||||
|
<div class="lesion_list">
|
||||||
|
<el-form
|
||||||
|
v-if="questions.length > 0"
|
||||||
|
:ref="`questions${index}`"
|
||||||
|
size="small"
|
||||||
|
:model="questionForm"
|
||||||
|
>
|
||||||
|
<div class="base-dialog-body">
|
||||||
|
<div v-for="item in qs.Childrens" :key="item.Id">
|
||||||
|
<div v-if="item.Type === 'table'" class="flex-row" style="margin:3px 0;">
|
||||||
|
<div class="title">{{ item.QuestionName }}</div>
|
||||||
|
<div v-if="readingTaskState < 2" class="add-icon" @click.prevent="handleAdd(item)">
|
||||||
|
<i class="el-icon-plus" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<el-collapse
|
||||||
|
v-if="item.Type === 'table' && item.TableQuestions"
|
||||||
|
v-model="activeName"
|
||||||
|
accordion
|
||||||
|
style="margin-bottom: 10px;"
|
||||||
|
@change="handleCollapseChange"
|
||||||
|
>
|
||||||
|
<el-collapse-item
|
||||||
|
v-for="(q,i) in item.TableQuestions.Answers"
|
||||||
|
:key="`${item.Id}_${q.RowIndex}`"
|
||||||
|
:name="`${item.Id}_${q.RowIndex}`"
|
||||||
|
>
|
||||||
|
<template slot="title">
|
||||||
|
<div style="width:300px;position: relative;" :style="{color:(activeName===item.Id+q.RowIndex?'#ffeb3b':'#fff')}">
|
||||||
|
|
||||||
|
{{ getLesionName(item.OrderMark,q.RowIndex) }}
|
||||||
|
<!-- 未保存 -->
|
||||||
|
<el-tooltip v-if="readingTaskState<2 && parseInt(item.TableQuestions.Answers[i].saveTypeEnum) === 0" class="item" effect="dark" :content="$t('trials:reading:button:unsaved')" placement="bottom">
|
||||||
|
<i class="el-icon-warning" style="color:red" />
|
||||||
|
</el-tooltip>
|
||||||
|
<!-- 信息不完整 -->
|
||||||
|
<el-tooltip v-if="readingTaskState<2 && parseInt(item.TableQuestions.Answers[i].saveTypeEnum) ===1" class="item" effect="dark" :content="$t('trials:reading:button:incompleteInfor')" placement="bottom">
|
||||||
|
<i class="el-icon-warning" style="color:#ff9800" />
|
||||||
|
</el-tooltip>
|
||||||
|
<div style="position: absolute;left: 60px;top: 2px;">
|
||||||
|
<div style="display: flex;flex-direction: row;font-size: 11px;width:200px;height: 30px;">
|
||||||
|
<div style="margin-left:10px;">
|
||||||
|
{{ numberToFixed(item.TableQuestions.Answers[i].area1,'m㎡') }}
|
||||||
|
</div>
|
||||||
|
<div style="margin-left:10px;">
|
||||||
|
{{ numberToFixed(item.TableQuestions.Answers[i].area2,'m㎡') }}
|
||||||
|
</div>
|
||||||
|
<div style="margin-left:10px;margin-bottom:5px;">
|
||||||
|
{{ numberToFixed(item.TableQuestions.Answers[i].diff, 'm㎡') }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</template>
|
||||||
|
<QuestionForm
|
||||||
|
:ref="`${item.Id}_${q.RowIndex}`"
|
||||||
|
:questions="item.TableQuestions.Questions"
|
||||||
|
:answers="item.TableQuestions.Answers[i]"
|
||||||
|
:lesion-type="item.LesionType"
|
||||||
|
:order-mark="item.OrderMark"
|
||||||
|
:table-questions="tableQuestions"
|
||||||
|
:row-index="String(q.RowIndex)"
|
||||||
|
:question-name="item.QuestionName"
|
||||||
|
:parent-qs-id="item.Id"
|
||||||
|
:visit-task-id="visitTaskId"
|
||||||
|
:is-current-task="isCurrentTask"
|
||||||
|
:reading-task-state="readingTaskState"
|
||||||
|
:is-base-line-task="isBaseLineTask"
|
||||||
|
@getReadingQuestionAndAnswer="getReadingQuestionAndAnswer"
|
||||||
|
@resetQuestions="resetQuestions"
|
||||||
|
@close="close"
|
||||||
|
/>
|
||||||
|
</el-collapse-item>
|
||||||
|
|
||||||
|
</el-collapse>
|
||||||
|
<template v-else>
|
||||||
|
<!-- 数值 -->
|
||||||
|
<el-form-item
|
||||||
|
v-if="item.ShowQuestion!==2"
|
||||||
|
:key="item.Id"
|
||||||
|
:label="`${item.QuestionName}`"
|
||||||
|
:prop="item.Id"
|
||||||
|
:rules="[
|
||||||
|
{ required: (item.IsRequired === 0 || (item.IsRequired ===1 && item.RelevanceId && (item.RelevanceValue.includes(questionForm[item.RelevanceId])))) && item.Type!=='group' && item.Type!=='summary',
|
||||||
|
message:['radio', 'select', 'checkbox'].includes(item.Type) ? $t('common:ruleMessage:select') : $t('common:ruleMessage:specify'), trigger: ['blur','change']},
|
||||||
|
]"
|
||||||
|
>
|
||||||
|
<!-- 数值类型 -->
|
||||||
|
<template v-if="item.Type==='number'">
|
||||||
|
<el-input
|
||||||
|
v-model="questionForm[item.Id]"
|
||||||
|
:disabled="!isCurrentTask || readingTaskState>=2 "
|
||||||
|
@change="((val)=>{formItemChange(val, item)})"
|
||||||
|
@blur="limitBlur(item.Id, item.ValueType)"
|
||||||
|
>
|
||||||
|
<template v-if="item.Unit" slot="append">
|
||||||
|
{{ $fd('ValueUnit', parseInt(item.Unit)) }}
|
||||||
|
</template>
|
||||||
|
</el-input>
|
||||||
|
</template>
|
||||||
|
</el-form-item>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
v-if="isCurrentTask && readingTaskState<2"
|
||||||
|
class="base-dialog-footer"
|
||||||
|
style="text-align:right;margin-top:10px;"
|
||||||
|
>
|
||||||
|
<!-- 保存 -->
|
||||||
|
<el-button
|
||||||
|
type="primary"
|
||||||
|
size="mini"
|
||||||
|
:disabled="!formChanged"
|
||||||
|
@click="handleSave(index)"
|
||||||
|
>
|
||||||
|
{{ $t('common:button:save') }}
|
||||||
|
</el-button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</el-form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<!-- 计算值 -->
|
||||||
|
<Questions
|
||||||
|
ref="ecrf2"
|
||||||
|
:question-form-change-state="true"
|
||||||
|
:question-form-change-num="0"
|
||||||
|
:is-qulity-issues="false"
|
||||||
|
:group-classify="4"
|
||||||
|
style="margin-top:20px"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<!-- 评估结果 -->
|
||||||
|
<Questions
|
||||||
|
ref="ecrf3"
|
||||||
|
:question-form-change-state="true"
|
||||||
|
:question-form-change-num="0"
|
||||||
|
:is-qulity-issues="false"
|
||||||
|
:group-classify="5"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<script>
|
||||||
|
import { saveTaskQuestion } from '@/api/trials'
|
||||||
|
import { resetReadingTask } from '@/api/reading'
|
||||||
|
import DicomEvent from './../DicomEvent'
|
||||||
|
import store from '@/store'
|
||||||
|
import { mapGetters } from 'vuex'
|
||||||
|
import Questions from './../Questions'
|
||||||
|
import QuestionForm from './QuestionForm'
|
||||||
|
export default {
|
||||||
|
name: 'MeasurementList',
|
||||||
|
components: {
|
||||||
|
Questions,
|
||||||
|
QuestionForm
|
||||||
|
},
|
||||||
|
props: {
|
||||||
|
isShow: {
|
||||||
|
type: Boolean,
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
isReadingShowSubjectInfo: {
|
||||||
|
type: Boolean,
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
questionFormChangeState: {
|
||||||
|
type: Boolean,
|
||||||
|
default() {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
questionFormChangeNum: {
|
||||||
|
type: Number,
|
||||||
|
default() {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
height: window.innerHeight - 140,
|
||||||
|
questions: [],
|
||||||
|
activeName: '',
|
||||||
|
activeItem: {
|
||||||
|
activeRowIndex: null,
|
||||||
|
activeCollapseId: null
|
||||||
|
},
|
||||||
|
visitTaskId: '',
|
||||||
|
isCurrentTask: false,
|
||||||
|
loading: false,
|
||||||
|
unSaveTargets: [],
|
||||||
|
temporaryLesions: [],
|
||||||
|
readingTaskState: 2,
|
||||||
|
isBaseLineTask: false,
|
||||||
|
taskBlindName: '',
|
||||||
|
tableQuestions: [],
|
||||||
|
isFirstRender: false,
|
||||||
|
CriterionType: null,
|
||||||
|
subjectCode: '',
|
||||||
|
questionForm: {},
|
||||||
|
formChanged: false,
|
||||||
|
digitPlaces: 2
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
...mapGetters(['visitTaskList', 'language', 'lastCanvasTaskId', 'currentReadingTaskState'])
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
lastCanvasTaskId: {
|
||||||
|
immediate: true,
|
||||||
|
handler(val) {
|
||||||
|
if (val) {
|
||||||
|
this.initList()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
currentReadingTaskState: {
|
||||||
|
immediate: true,
|
||||||
|
handler(val) {
|
||||||
|
if (val) {
|
||||||
|
this.readingTaskState = val
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
// 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
|
||||||
|
window.addEventListener('message', this.receiveMsg)
|
||||||
|
this.CriterionType = parseInt(localStorage.getItem('CriterionType'))
|
||||||
|
DicomEvent.$on('setCollapseActive', measureData => {
|
||||||
|
this.setCollapseActive(measureData)
|
||||||
|
console.log('setCollapseActive')
|
||||||
|
})
|
||||||
|
DicomEvent.$on('getAllUnSaveLesions', (callback) => {
|
||||||
|
callback([])
|
||||||
|
})
|
||||||
|
DicomEvent.$on('refreshQuestions', _ => {
|
||||||
|
this.refreshQuestions()
|
||||||
|
})
|
||||||
|
|
||||||
|
window.addEventListener('resize', this.setHeight)
|
||||||
|
},
|
||||||
|
beforeDestroy() {
|
||||||
|
DicomEvent.$off('setCollapseActive')
|
||||||
|
DicomEvent.$off('getUnSaveTarget')
|
||||||
|
DicomEvent.$off('refreshQuestions')
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
async initList() {
|
||||||
|
var i = this.visitTaskList.findIndex(i => i.VisitTaskId === this.lastCanvasTaskId)
|
||||||
|
if (i > -1) {
|
||||||
|
this.visitTaskId = this.visitTaskList[i].VisitTaskId
|
||||||
|
this.taskBlindName = this.visitTaskList[i].TaskBlindName
|
||||||
|
this.readingTaskState = this.visitTaskList[i].ReadingTaskState
|
||||||
|
this.isBaseLineTask = this.visitTaskList[i].IsBaseLineTask
|
||||||
|
this.isCurrentTask = this.visitTaskList[i].IsCurrentTask
|
||||||
|
this.activeName = ''
|
||||||
|
this.activeItem.activeRowIndex = null
|
||||||
|
this.activeItem.activeCollapseId = null
|
||||||
|
if (!this.visitTaskList[i].IsInit) {
|
||||||
|
var loading = this.$loading({ fullscreen: true })
|
||||||
|
var triald = this.trialId = this.$router.currentRoute.query.trialId
|
||||||
|
if (!this.visitTaskList[i].studyListInit) {
|
||||||
|
await store.dispatch('reading/getStudyInfo', { trialId: triald, subjectVisitId: this.visitTaskList[i].VisitId, visitTaskId: this.visitTaskList[i].VisitTaskId, taskBlindName: this.visitTaskList[i].TaskBlindName })
|
||||||
|
}
|
||||||
|
if (!this.visitTaskList[i].readingQuestionsInit) {
|
||||||
|
await store.dispatch('reading/getReadingQuestionAndAnswer', { trialId: triald, visitTaskId: this.visitTaskList[i].VisitTaskId })
|
||||||
|
}
|
||||||
|
if (!this.visitTaskList[i].questionsInit) {
|
||||||
|
await store.dispatch('reading/getDicomReadingQuestionAnswer', { trialId: triald, visitTaskId: this.visitTaskList[i].VisitTaskId })
|
||||||
|
}
|
||||||
|
|
||||||
|
await store.dispatch('reading/setStatus', { visitTaskId: this.visitTaskList[i].VisitTaskId })
|
||||||
|
loading.close()
|
||||||
|
}
|
||||||
|
this.questions = this.visitTaskList[i].ReadingQuestions
|
||||||
|
this.setQuestionForm(this.questions)
|
||||||
|
this.$nextTick(() => {
|
||||||
|
this.$refs['ecrf'].getQuestions(this.visitTaskId)
|
||||||
|
this.$refs['ecrf2'].getQuestions(this.visitTaskId)
|
||||||
|
this.$refs['ecrf3'].getQuestions(this.visitTaskId)
|
||||||
|
this.getTableQuestions()
|
||||||
|
this.tableQuestions.forEach(item => {
|
||||||
|
item.TableQuestions.Answers.forEach(i => {
|
||||||
|
var refName = `${item.Id}_${i.RowIndex}`
|
||||||
|
this.$refs[refName] && this.$refs[refName][0].initForm()
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
},
|
||||||
|
setQuestionForm(questions) {
|
||||||
|
const type = ['number', 'radio', 'select', 'input', 'textarea', 'calculation']
|
||||||
|
questions.forEach(item => {
|
||||||
|
if (type.includes(item.Type)) {
|
||||||
|
const answer = item.Type === 'number' || item.Type === 'calculation' ? isNaN(parseFloat(item.Answer)) ? null : parseFloat(item.Answer) : item.Answer
|
||||||
|
this.$set(this.questionForm, item.Id, answer)
|
||||||
|
}
|
||||||
|
if (item.Childrens.length > 0) {
|
||||||
|
this.setQuestionForm(item.Childrens)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
async resetQuestions(obj) {
|
||||||
|
this.setQuestions(this.questions, obj)
|
||||||
|
await store.dispatch('reading/setReadingQuestionAndAnswer', { questions: this.questions, visitTaskId: this.visitTaskId })
|
||||||
|
|
||||||
|
this.getTableQuestions()
|
||||||
|
},
|
||||||
|
setQuestions(questions, obj) {
|
||||||
|
questions.forEach(item => {
|
||||||
|
if (item.Type === 'table' && item.Id === obj.questionId) {
|
||||||
|
var idx = item.TableQuestions.Answers.findIndex(i => i.RowIndex === obj.rowIndex)
|
||||||
|
item.TableQuestions.Answers[idx].saveTypeEnum = obj.saveTypeEnum
|
||||||
|
item.TableQuestions.Answers[idx].area1 = obj.area1
|
||||||
|
item.TableQuestions.Answers[idx].area2 = obj.area2
|
||||||
|
item.TableQuestions.Answers[idx].diff = obj.diff
|
||||||
|
for (const i in obj.anwsers) {
|
||||||
|
item.TableQuestions.Answers[idx][i] = String(obj.anwsers[i])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (item.Childrens.length > 0) {
|
||||||
|
this.setQuestions(item.Childrens, obj)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
getQuestions(questions) {
|
||||||
|
questions.forEach(item => {
|
||||||
|
if (item.Type === 'table' && item.TableQuestions && item.TableQuestions.Answers.length > 0) {
|
||||||
|
item.TableQuestions.Answers.forEach(answerObj => {
|
||||||
|
if (answerObj.RowId) {
|
||||||
|
var diffVal = this.getQuestionAnswer(item.TableQuestions.Questions, 1003, answerObj)
|
||||||
|
this.$set(answerObj, 'saveTypeEnum', isNaN(parseFloat(diffVal)) ? 1 : 2)
|
||||||
|
} else {
|
||||||
|
this.$set(answerObj, 'saveTypeEnum', 0)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
if (item.Childrens.length > 0) {
|
||||||
|
this.getQuestions(item.Childrens)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
return questions
|
||||||
|
},
|
||||||
|
getTableQuestions() {
|
||||||
|
this.tableQuestions = []
|
||||||
|
this.questions.map(item => {
|
||||||
|
if (item.Type === 'table') {
|
||||||
|
this.tableQuestions.push(item)
|
||||||
|
}
|
||||||
|
if (item.Childrens.length > 0) {
|
||||||
|
this.getTableQuestionsChild(item.Childrens)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
getTableQuestionsChild(obj) {
|
||||||
|
obj.map(item => {
|
||||||
|
if (item.Type === 'table') {
|
||||||
|
this.tableQuestions.push(item)
|
||||||
|
}
|
||||||
|
if (item.Childrens.length > 0) {
|
||||||
|
this.getTableQuestionsChild(item.Childrens)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
refreshReadingQuestionAndAnswer(type) {
|
||||||
|
if (type === 0) {
|
||||||
|
// 删除
|
||||||
|
this.activeName = ''
|
||||||
|
this.activeItem.activeRowIndex = null
|
||||||
|
this.activeItem.activeCollapseId = null
|
||||||
|
}
|
||||||
|
|
||||||
|
this.getReadingQuestionAndAnswer(this.visitTaskId)
|
||||||
|
},
|
||||||
|
getReadingQuestionAndAnswer() {
|
||||||
|
return new Promise(async resolve => {
|
||||||
|
try {
|
||||||
|
const loading = this.$loading({ fullscreen: true })
|
||||||
|
await store.dispatch('reading/refreshReadingQuestionAndAnswer', { trialId: this.$router.currentRoute.query.trialId, visitTaskId: this.visitTaskId }).then(() => {
|
||||||
|
var idx = this.visitTaskList.findIndex(i => i.VisitTaskId === this.visitTaskId)
|
||||||
|
if (idx > -1) {
|
||||||
|
if (this.visitTaskList[idx].ReadingQuestions.length > 0) {
|
||||||
|
this.questions = this.visitTaskList[idx].ReadingQuestions
|
||||||
|
this.setQuestionForm(this.questions)
|
||||||
|
}
|
||||||
|
this.readingTaskState = this.visitTaskList[idx].ReadingTaskState
|
||||||
|
this.isBaseLineTask = this.visitTaskList[idx].IsBaseLineTask
|
||||||
|
this.isCurrentTask = this.visitTaskList[idx].IsCurrentTask
|
||||||
|
}
|
||||||
|
this.getTableQuestions()
|
||||||
|
this.$nextTick(() => {
|
||||||
|
this.tableQuestions.forEach(item => {
|
||||||
|
item.TableQuestions.Answers.forEach(i => {
|
||||||
|
var refName = `${item.Id}_${i.RowIndex}`
|
||||||
|
this.$refs[refName] && this.$refs[refName][0].initForm()
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
loading.close()
|
||||||
|
resolve()
|
||||||
|
} 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) {
|
||||||
|
var questionId = questions[idx].Id
|
||||||
|
return answers[questionId]
|
||||||
|
} else {
|
||||||
|
return ''
|
||||||
|
}
|
||||||
|
},
|
||||||
|
isCanActiveTool(toolName) {
|
||||||
|
return { isCanActiveTool: true, reason: '' }
|
||||||
|
},
|
||||||
|
|
||||||
|
async handleAdd(qs) {
|
||||||
|
if (!!qs.MaxQuestionCount && qs.MaxQuestionCount <= qs.TableQuestions.Answers.length) {
|
||||||
|
let msg = this.$t('trials:reading:warnning:msg14')
|
||||||
|
// msg = msg.replace('xxx', qs.QuestionName)
|
||||||
|
msg = msg.replace('xxx', qs.MaxQuestionCount)
|
||||||
|
this.$confirm(msg, {
|
||||||
|
type: 'warning',
|
||||||
|
showCancelButton: false,
|
||||||
|
callback: action => {}
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
// saveTypeEnum: 0
|
||||||
|
var obj = { saveTypeEnum: 0 }
|
||||||
|
// var questions = qs.TableQuestions.Questions.find(item => item.QuestionMark === 3)
|
||||||
|
// if (questions) {
|
||||||
|
// console.log(questions)
|
||||||
|
// var maxIndex = this.getMaxRowIndex(qs.TableQuestions.Answers)
|
||||||
|
// obj.RowIndex = `${maxIndex + 1}.00`
|
||||||
|
// obj[questions.Id] = `${qs.OrderMark}${String(maxIndex + 1).padStart(2, '0')}`
|
||||||
|
// }
|
||||||
|
var maxIndex = this.getMaxRowIndex(qs.TableQuestions.Answers)
|
||||||
|
obj.RowIndex = `${maxIndex + 1}.00`
|
||||||
|
obj.IsDicomReading = true
|
||||||
|
await store.dispatch('reading/addReadingQuestionAndAnswer', { lesionType: qs.LesionType, visitTaskId: this.visitTaskId, lesionObj: obj })
|
||||||
|
|
||||||
|
this.activeItem.activeRowIndex = String(obj.RowIndex)
|
||||||
|
this.activeItem.activeCollapseId = qs.Id
|
||||||
|
this.activeName = `${this.activeItem.activeCollapseId}_${this.activeItem.activeRowIndex}`
|
||||||
|
}
|
||||||
|
},
|
||||||
|
getMaxRowIndex(answerList) {
|
||||||
|
if (answerList.length > 0) {
|
||||||
|
var arr = []
|
||||||
|
answerList.forEach(item => {
|
||||||
|
var rowIndex = item.RowIndex
|
||||||
|
arr.push(parseInt(rowIndex))
|
||||||
|
})
|
||||||
|
var max = Math.max.apply(null, arr)
|
||||||
|
return max
|
||||||
|
} else {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
},
|
||||||
|
getLesionName(orderMark, rowIndex) {
|
||||||
|
var lessionName = ''
|
||||||
|
var rowIndexArr = rowIndex.split('.')
|
||||||
|
var x = parseInt(rowIndexArr[0])
|
||||||
|
var y = parseInt(rowIndexArr[1])
|
||||||
|
if (y > 0) {
|
||||||
|
y = String.fromCharCode(parseInt(rowIndexArr[1]) - 1 + 65 + 32)
|
||||||
|
lessionName = `${orderMark}${String(x).padStart(2, '0')}${y}`
|
||||||
|
} else {
|
||||||
|
lessionName = `${orderMark}${String(x).padStart(2, '0')}`
|
||||||
|
}
|
||||||
|
|
||||||
|
return lessionName
|
||||||
|
},
|
||||||
|
handleCollapseChange(val) {
|
||||||
|
if (this.activeName) {
|
||||||
|
var arr = this.activeName.split('_')
|
||||||
|
this.activeItem.activeRowIndex = arr[1]
|
||||||
|
this.activeItem.activeCollapseId = arr[0]
|
||||||
|
} else {
|
||||||
|
this.activeItem.activeRowIndex = null
|
||||||
|
this.activeItem.activeCollapseId = null
|
||||||
|
}
|
||||||
|
},
|
||||||
|
collapseRightClick(e, obj, activeCollapseId, activeRowIndex) {
|
||||||
|
e.stopImmediatePropagation()
|
||||||
|
e.stopPropagation()
|
||||||
|
e.preventDefault()
|
||||||
|
},
|
||||||
|
setCollapseActive(measureData) {
|
||||||
|
|
||||||
|
},
|
||||||
|
modifyMeasuredData(measureObj) {
|
||||||
|
},
|
||||||
|
// 设置测量数据
|
||||||
|
setMeasuredData(measureData) {
|
||||||
|
|
||||||
|
},
|
||||||
|
formItemChange() {
|
||||||
|
this.formChanged = true
|
||||||
|
},
|
||||||
|
limitBlur(qId, valueType) {
|
||||||
|
const value = this.questionForm[qId]
|
||||||
|
if (isNaN(parseInt(value))) return
|
||||||
|
if (valueType === 0) {
|
||||||
|
this.$set(this.questionForm, qId, parseInt(value))
|
||||||
|
} else if (valueType === 3) {
|
||||||
|
this.$set(this.questionForm, qId, parseFloat(value))
|
||||||
|
} else {
|
||||||
|
this.$set(this.questionForm, qId, parseFloat(value).toFixed(this.digitPlaces))
|
||||||
|
}
|
||||||
|
},
|
||||||
|
numberToFixed(v, unit) {
|
||||||
|
return isNaN(parseFloat(v)) ? null : `${parseFloat(v).toFixed(this.digitPlaces)}${unit}`
|
||||||
|
},
|
||||||
|
async handleSave(index) {
|
||||||
|
const refName = `questions${index}`
|
||||||
|
const valid = await this.$refs[refName][0].validate()
|
||||||
|
if (!valid) return
|
||||||
|
const loading = this.$loading({ fullscreen: true })
|
||||||
|
var answers = []
|
||||||
|
for (const k in this.questionForm) {
|
||||||
|
answers.push({ id: k, answer: this.questionForm[k] })
|
||||||
|
}
|
||||||
|
var params = {
|
||||||
|
visitTaskId: this.visitTaskId,
|
||||||
|
answers: answers
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
await saveTaskQuestion(8, params)
|
||||||
|
this.$message.success(this.$t('common:message:savedSuccessfully'))
|
||||||
|
loading.close()
|
||||||
|
DicomEvent.$emit('getReportInfo', true)
|
||||||
|
this.refreshQuestions()
|
||||||
|
this.formChanged = false
|
||||||
|
} catch (e) {
|
||||||
|
console.log(e)
|
||||||
|
loading.close()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
async close(questionsObj) {
|
||||||
|
if (questionsObj) {
|
||||||
|
this.getReadingQuestionAndAnswer(questionsObj.visitTaskId)
|
||||||
|
this.refreshQuestions()
|
||||||
|
}
|
||||||
|
this.activeItem.activeRowIndex = null
|
||||||
|
this.activeItem.activeCollapseId = null
|
||||||
|
this.activeName = ''
|
||||||
|
},
|
||||||
|
getECRFQuestions(obj) {
|
||||||
|
this.$refs['ecrf'].getQuestions(obj.visitTaskId)
|
||||||
|
this.$refs['ecrf2'].getQuestions(obj.visitTaskId)
|
||||||
|
this.$refs['ecrf3'].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)
|
||||||
|
this.$refs['ecrf2'].getQuestions(this.visitTaskId, true)
|
||||||
|
this.$refs['ecrf3'].getQuestions(this.visitTaskId, true)
|
||||||
|
DicomEvent.$emit('getReportInfo', true)
|
||||||
|
}
|
||||||
|
loading.close()
|
||||||
|
} catch (e) {
|
||||||
|
loading.close()
|
||||||
|
console.log(e)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
async refreshQuestions() {
|
||||||
|
const triald = this.$router.currentRoute.query.trialId
|
||||||
|
await store.dispatch('reading/refreshDicomReadingQuestionAnswer', { trialId: triald, visitTaskId: this.visitTaskId })
|
||||||
|
this.$refs['ecrf'].getQuestions(this.visitTaskId, true)
|
||||||
|
this.$refs['ecrf2'].getQuestions(this.visitTaskId, true)
|
||||||
|
this.$refs['ecrf3'].getQuestions(this.visitTaskId, true)
|
||||||
|
},
|
||||||
|
receiveMsg(event) {
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.measurement-wrapper{
|
||||||
|
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;
|
||||||
|
font-weight: bold;
|
||||||
|
color: #ddd;
|
||||||
|
font-size: 15px;
|
||||||
|
|
||||||
|
}
|
||||||
|
.add-icon{
|
||||||
|
padding: 5px;
|
||||||
|
font-weight: bold;
|
||||||
|
color: #ddd;
|
||||||
|
font-size: 15px;
|
||||||
|
border: 1px solid #938b8b;
|
||||||
|
margin-bottom: 2px;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
.add-icon:hover{
|
||||||
|
background-color: #607d8b;
|
||||||
|
}
|
||||||
|
|
||||||
|
.flex-row{
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
justify-content: space-between;
|
||||||
|
background-color: #424242;
|
||||||
|
|
||||||
|
}
|
||||||
|
.lesion_list{
|
||||||
|
position: relative;
|
||||||
|
/deep/ .el-form-item__label{
|
||||||
|
color: #c3c3c3;
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
/deep/ .el-input .el-input__inner{
|
||||||
|
background-color: transparent;
|
||||||
|
color: #ddd;
|
||||||
|
border: 1px solid #5e5e5e;
|
||||||
|
}
|
||||||
|
/deep/ .el-form-item{
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: flex-start;
|
||||||
|
}
|
||||||
|
/deep/ .el-form-item__content{
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
/deep/ .el-input.is-disabled .el-input__inner{
|
||||||
|
background-color: #646464a1;
|
||||||
|
}
|
||||||
|
/deep/ .el-select.is-disabled .el-input__inner{
|
||||||
|
background-color: #646464a1;
|
||||||
|
}
|
||||||
|
/deep/ .el-button--mini, .el-button--mini.is-round {
|
||||||
|
padding: 7px 10px;
|
||||||
|
}
|
||||||
|
.el-form-item__content
|
||||||
|
.el-select{
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.el-collapse{
|
||||||
|
border-bottom:none;
|
||||||
|
border-top:none;
|
||||||
|
/deep/ .el-collapse-item{
|
||||||
|
background-color: #000!important;
|
||||||
|
color: #ddd;
|
||||||
|
|
||||||
|
}
|
||||||
|
/deep/ .el-collapse-item__header{
|
||||||
|
background-color: #000!important;
|
||||||
|
color: #ddd;
|
||||||
|
border-bottom-color:#5a5a5a;
|
||||||
|
padding-left: 5px;
|
||||||
|
height: 35px;
|
||||||
|
line-height: 35px;
|
||||||
|
}
|
||||||
|
/deep/ .el-collapse-item__wrap{
|
||||||
|
background-color: #000!important;
|
||||||
|
color: #ddd;
|
||||||
|
}
|
||||||
|
/deep/ .el-collapse-item__content{
|
||||||
|
width:260px;
|
||||||
|
position: absolute;
|
||||||
|
top: 0px;
|
||||||
|
right: 0px;
|
||||||
|
// border: 1px solid #ffeb3b;
|
||||||
|
border: 1px solid #fff;
|
||||||
|
z-index: 1;
|
||||||
|
color: #ddd;
|
||||||
|
padding: 5px;
|
||||||
|
background-color:#1e1e1e;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
@ -276,7 +276,6 @@ import { submitTableQuestion, deleteReadingRowAnswer, getIsSuvMaxLesion } from '
|
||||||
// import { uploadPrintscreen } from '@/api/reading'
|
// import { uploadPrintscreen } from '@/api/reading'
|
||||||
import DicomEvent from './../DicomEvent'
|
import DicomEvent from './../DicomEvent'
|
||||||
import store from '@/store'
|
import store from '@/store'
|
||||||
import Viewer from 'v-viewer'
|
|
||||||
export default {
|
export default {
|
||||||
name: 'MeasurementForm',
|
name: 'MeasurementForm',
|
||||||
props: {
|
props: {
|
||||||
|
|
@ -353,7 +352,6 @@ export default {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
this.initializeViewer()
|
|
||||||
this.trialId = this.$route.query.trialId
|
this.trialId = this.$route.query.trialId
|
||||||
this.initForm()
|
this.initForm()
|
||||||
DicomEvent.$on('handleImageQualityAbnormal', () => {
|
DicomEvent.$on('handleImageQualityAbnormal', () => {
|
||||||
|
|
@ -380,11 +378,6 @@ export default {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
initializeViewer() {
|
|
||||||
Viewer.setDefaults({
|
|
||||||
toolbar: { zoomIn: true, zoomOut: true, rotateLeft: true, rotateRight: true, flipHorizontal: true, flipVertical: true }
|
|
||||||
})
|
|
||||||
},
|
|
||||||
previewImage() {
|
previewImage() {
|
||||||
this.$refs.viewer[0].$viewer.show()
|
this.$refs.viewer[0].$viewer.show()
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,534 @@
|
||||||
|
<template>
|
||||||
|
<el-form
|
||||||
|
v-if="isRender"
|
||||||
|
ref="measurementForm"
|
||||||
|
v-loading="loading"
|
||||||
|
:model="questionForm"
|
||||||
|
size="mini"
|
||||||
|
class="measurement-form"
|
||||||
|
>
|
||||||
|
<div class="base-dialog-body">
|
||||||
|
<div style="display: flex;justify-content: space-between;">
|
||||||
|
<h3 v-if="questionName" style="color: #ddd;padding: 5px 0px;margin: 0;">
|
||||||
|
<!-- {{ `${questionName} (${orderMark}${String(rowIndex).padStart(2, '0')})` }} -->
|
||||||
|
{{ lesionName }}
|
||||||
|
</h3>
|
||||||
|
<!-- 关闭 -->
|
||||||
|
<div>
|
||||||
|
<i class="el-icon-circle-close" style="font-size: 25px;cursor: pointer;" @click="handleClose" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<el-form-item
|
||||||
|
v-for="qs in questions"
|
||||||
|
v-show="qs.ShowQuestion!==2"
|
||||||
|
:key="qs.Id"
|
||||||
|
:label="`${qs.QuestionName}`"
|
||||||
|
:prop="qs.Id"
|
||||||
|
:rules="[
|
||||||
|
{ required: (qs.IsRequired === 0 || (qs.IsRequired ===1 && qs.RelevanceId && (questionForm[qs.RelevanceId] === qs.RelevanceValue))) && qs.Type!=='group' && qs.Type!=='summary',
|
||||||
|
message:['radio', 'select', 'checkbox'].includes(qs.Type) ? $t('common:ruleMessage:select') : $t('common:ruleMessage:specify'), trigger: ['blur','change']},
|
||||||
|
]"
|
||||||
|
>
|
||||||
|
|
||||||
|
<!-- 输入框 -->
|
||||||
|
<template v-if="qs.Type==='input'">
|
||||||
|
<el-input
|
||||||
|
v-model="questionForm[qs.Id]"
|
||||||
|
:disabled="!isCurrentTask || readingTaskState>=2 "
|
||||||
|
@change="((val)=>{formItemChange(val, qs)})"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
<!-- 数值类型 -->
|
||||||
|
<template v-if="qs.Type==='number'">
|
||||||
|
<el-input
|
||||||
|
v-model="questionForm[qs.Id]"
|
||||||
|
:disabled="!isCurrentTask || readingTaskState>=2 "
|
||||||
|
@change="((val)=>{formItemChange(val, qs)})"
|
||||||
|
@blur="limitBlur(qs.Id, qs.ValueType)"
|
||||||
|
>
|
||||||
|
<template v-if="qs.Unit" slot="append">
|
||||||
|
{{ $fd('ValueUnit', parseInt(qs.Unit)) }}
|
||||||
|
</template>
|
||||||
|
</el-input>
|
||||||
|
</template>
|
||||||
|
<!-- 自动计算 -->
|
||||||
|
<template v-if="qs.Type==='calculation'">
|
||||||
|
<el-input
|
||||||
|
v-model="questionForm[qs.Id]"
|
||||||
|
disabled
|
||||||
|
@change="((val)=>{formItemChange(val, qs)})"
|
||||||
|
>
|
||||||
|
<template v-if="qs.Unit" slot="append">
|
||||||
|
{{ $fd('ValueUnit', parseInt(qs.Unit)) }}
|
||||||
|
</template>
|
||||||
|
</el-input>
|
||||||
|
</template>
|
||||||
|
<!-- 多行文本输入框 -->
|
||||||
|
<el-input
|
||||||
|
v-if="qs.Type==='textarea'"
|
||||||
|
v-model="questionForm[qs.Id]"
|
||||||
|
type="textarea"
|
||||||
|
:autosize="{ minRows: 2, maxRows: 4}"
|
||||||
|
:disabled="!isCurrentTask || readingTaskState>=2"
|
||||||
|
@change="((val)=>{formItemChange(val, qs)})"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<el-select
|
||||||
|
v-if="qs.Type==='select'"
|
||||||
|
v-model="questionForm[qs.Id]"
|
||||||
|
filterable
|
||||||
|
:placeholder="$t('common:placeholder:select')"
|
||||||
|
:disabled="!isCurrentTask || readingTaskState>=2"
|
||||||
|
@change="((val)=>{formItemChange(val, qs)})"
|
||||||
|
>
|
||||||
|
<template v-if="qs.DictionaryCode">
|
||||||
|
<el-option
|
||||||
|
v-for="item of $d[qs.DictionaryCode]"
|
||||||
|
:key="item.id"
|
||||||
|
:value="item.value"
|
||||||
|
:label="item.label"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
<template v-else>
|
||||||
|
<el-option
|
||||||
|
v-for="val in qs.TypeValue.split('|')"
|
||||||
|
:key="val"
|
||||||
|
:label="val"
|
||||||
|
:value="val"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
</el-select>
|
||||||
|
<!-- 单选 -->
|
||||||
|
<el-radio-group
|
||||||
|
v-if="qs.Type==='radio'"
|
||||||
|
v-model="questionForm[qs.id]"
|
||||||
|
:disabled="!isCurrentTask || readingTaskState>=2"
|
||||||
|
>
|
||||||
|
<el-radio
|
||||||
|
v-for="val in qs.options.split('|')"
|
||||||
|
:key="val"
|
||||||
|
:label="val"
|
||||||
|
>
|
||||||
|
{{ val }}
|
||||||
|
</el-radio>
|
||||||
|
</el-radio-group>
|
||||||
|
</el-form-item>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div
|
||||||
|
v-if="isCurrentTask && readingTaskState<2"
|
||||||
|
class="base-dialog-footer"
|
||||||
|
style="text-align:right;margin-top:10px;"
|
||||||
|
>
|
||||||
|
<!-- 删除 -->
|
||||||
|
<el-button
|
||||||
|
v-if="isCurrentTaskAdd !== 'False'"
|
||||||
|
size="mini"
|
||||||
|
@click="handleDelete"
|
||||||
|
>
|
||||||
|
{{ $t('common:button:delete') }}
|
||||||
|
</el-button>
|
||||||
|
<!-- 保存 -->
|
||||||
|
<el-button
|
||||||
|
size="mini"
|
||||||
|
@click="handleSave"
|
||||||
|
>
|
||||||
|
{{ $t('common:button:save') }}
|
||||||
|
</el-button>
|
||||||
|
</div>
|
||||||
|
</el-form>
|
||||||
|
</template>
|
||||||
|
<script>
|
||||||
|
import { submitTableQuestion, deleteReadingRowAnswer } from '@/api/trials'
|
||||||
|
import DicomEvent from './../DicomEvent'
|
||||||
|
// import store from '@/store'
|
||||||
|
export default {
|
||||||
|
name: 'MeasurementForm',
|
||||||
|
props: {
|
||||||
|
questions: {
|
||||||
|
type: Array,
|
||||||
|
default() { return [] }
|
||||||
|
},
|
||||||
|
answers: {
|
||||||
|
type: Object,
|
||||||
|
default() { return {} }
|
||||||
|
},
|
||||||
|
lesionType: {
|
||||||
|
type: Number,
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
visitTaskId: {
|
||||||
|
type: String,
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
parentQsId: {
|
||||||
|
type: String,
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
isCurrentTask: {
|
||||||
|
type: Boolean,
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
readingTaskState: {
|
||||||
|
type: Number,
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
isBaseLineTask: {
|
||||||
|
type: Boolean,
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
orderMark: {
|
||||||
|
type: String,
|
||||||
|
default: ''
|
||||||
|
},
|
||||||
|
questionName: {
|
||||||
|
type: String,
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
rowIndex: {
|
||||||
|
type: String,
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
tableQuestions: {
|
||||||
|
type: Array,
|
||||||
|
default() { return [] }
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
questionForm: {},
|
||||||
|
loading: false,
|
||||||
|
trialId: '',
|
||||||
|
originalQuestionForm: {},
|
||||||
|
isRender: false,
|
||||||
|
toolType: '',
|
||||||
|
lesionName: '',
|
||||||
|
isCurrentTaskAdd: 'False',
|
||||||
|
lesionMark: '',
|
||||||
|
pictureBaseStr: '',
|
||||||
|
digitPlaces: 2
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this.trialId = this.$route.query.trialId
|
||||||
|
var digitPlaces = Number(localStorage.getItem('digitPlaces'))
|
||||||
|
this.digitPlaces = digitPlaces === -1 ? this.digitPlaces : digitPlaces
|
||||||
|
this.initForm()
|
||||||
|
DicomEvent.$on('handleImageQualityAbnormal', () => {
|
||||||
|
|
||||||
|
})
|
||||||
|
},
|
||||||
|
beforeDestroy() {
|
||||||
|
DicomEvent.$off('handleImageQualityAbnormal')
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
async initForm() {
|
||||||
|
const loading = this.$loading({ fullscreen: true })
|
||||||
|
this.questions.forEach(item => {
|
||||||
|
var val = this.answers[item.Id]
|
||||||
|
if (item.DictionaryCode) {
|
||||||
|
val = isNaN(parseInt(this.answers[item.Id])) ? this.answers[item.Id] : parseInt(this.answers[item.Id])
|
||||||
|
}
|
||||||
|
|
||||||
|
this.$set(this.questionForm, item.Id, val)
|
||||||
|
})
|
||||||
|
this.$set(this.questionForm, 'RowIndex', this.answers.RowIndex ? this.answers.RowIndex : '')
|
||||||
|
this.$set(this.questionForm, 'RowId', this.answers.RowId ? this.answers.RowId : '')
|
||||||
|
if (this.questionForm.RowId) {
|
||||||
|
this.$set(this.questionForm, 'saveTypeEnum', 2)
|
||||||
|
} else {
|
||||||
|
this.$set(this.questionForm, 'saveTypeEnum', 0)
|
||||||
|
}
|
||||||
|
this.$set(this.questionForm, 'IsDicomReading', this.answers.IsDicomReading !== 'False')
|
||||||
|
if (!this.questionForm.LesionType) {
|
||||||
|
this.$set(this.questionForm, 'LesionType', this.lesionType)
|
||||||
|
}
|
||||||
|
this.lesionName = this.getLesionInfo(this.orderMark, this.rowIndex)
|
||||||
|
this.isCurrentTaskAdd = this.answers.IsCurrentTaskAdd ? this.answers.IsCurrentTaskAdd : 'True'
|
||||||
|
this.lesionMark = this.getLesionName(this.orderMark, this.questionForm.RowIndex)
|
||||||
|
this.originalQuestionForm = { ...this.questionForm }
|
||||||
|
this.isRender = true
|
||||||
|
loading.close()
|
||||||
|
},
|
||||||
|
getLesionName(orderMark, rowIndex) {
|
||||||
|
var lessionName = ''
|
||||||
|
var rowIndexArr = rowIndex.split('.')
|
||||||
|
var x = parseInt(rowIndexArr[0])
|
||||||
|
var y = parseInt(rowIndexArr[1])
|
||||||
|
if (y > 0) {
|
||||||
|
y = String.fromCharCode(parseInt(rowIndexArr[1]) - 1 + 65 + 32)
|
||||||
|
lessionName = `${orderMark}${String(x).padStart(2, '0')}${y}`
|
||||||
|
} else {
|
||||||
|
lessionName = `${orderMark}${String(x).padStart(2, '0')}`
|
||||||
|
}
|
||||||
|
|
||||||
|
return lessionName
|
||||||
|
},
|
||||||
|
getLesionInfo(orderMark, rowIndex) {
|
||||||
|
var arr = []
|
||||||
|
var lessionName = ''
|
||||||
|
var rowIndexArr = rowIndex.split('.')
|
||||||
|
var x = parseInt(rowIndexArr[0])
|
||||||
|
var y = parseInt(rowIndexArr[1])
|
||||||
|
if (y > 0) {
|
||||||
|
y = String.fromCharCode(parseInt(rowIndexArr[1]) - 1 + 65 + 32)
|
||||||
|
lessionName = `${orderMark}${String(x).padStart(2, '0')}${y}`
|
||||||
|
arr.push(lessionName)
|
||||||
|
} else {
|
||||||
|
lessionName = `${orderMark}${String(x).padStart(2, '0')}`
|
||||||
|
arr.push(lessionName)
|
||||||
|
}
|
||||||
|
return arr.join(' ')
|
||||||
|
},
|
||||||
|
getQuestionId(questionMark) {
|
||||||
|
var idx = this.questions.findIndex(i => i.QuestionMark === questionMark)
|
||||||
|
if (idx > -1) {
|
||||||
|
return this.questions[idx].Id
|
||||||
|
} else {
|
||||||
|
return ''
|
||||||
|
}
|
||||||
|
},
|
||||||
|
async formItemChange(v, question) {
|
||||||
|
if (this.questionForm.RowId) {
|
||||||
|
this.$set(this.questionForm, 'saveTypeEnum', 1)
|
||||||
|
} else {
|
||||||
|
this.$set(this.questionForm, 'saveTypeEnum', 0)
|
||||||
|
}
|
||||||
|
if (question.QuestionMark === 1011 || question.QuestionMark === 1012 || question.QuestionMark === 1013) {
|
||||||
|
// 最小值
|
||||||
|
this.questionForm[this.getQuestionId(1014)] = this.calculate([1011, 1012, 1013], 'min')
|
||||||
|
// 平均值
|
||||||
|
this.questionForm[this.getQuestionId(1015)] = this.calculate([1011, 1012, 1013], 'avg')
|
||||||
|
}
|
||||||
|
let l1, l2, l3, min, mean, angle
|
||||||
|
if (this.lesionType === 101) {
|
||||||
|
l1 = this.getQuestionVal(1011)
|
||||||
|
l2 = this.getQuestionVal(1012)
|
||||||
|
l3 = this.getQuestionVal(1013)
|
||||||
|
min = this.getQuestionVal(1014)
|
||||||
|
mean = this.getQuestionVal(1015)
|
||||||
|
} else if (this.lesionType === 103) {
|
||||||
|
angle = this.getQuestionVal(1016)
|
||||||
|
}
|
||||||
|
this.$emit('resetQuestions', { l1, l2, l3, min, mean, angle, saveTypeEnum: this.questionForm.saveTypeEnum, rowIndex: this.rowIndex, questionId: this.parentQsId, anwsers: this.questionForm })
|
||||||
|
},
|
||||||
|
calculate(qsMarkArr, type) {
|
||||||
|
var num = 0
|
||||||
|
const arr = []
|
||||||
|
for (let i = 0; i < qsMarkArr.length; i++) {
|
||||||
|
const mark = qsMarkArr[i]
|
||||||
|
let v = this.questionForm[this.getQuestionId(mark)]
|
||||||
|
if (isNaN(parseFloat(v))) {
|
||||||
|
num = null
|
||||||
|
break
|
||||||
|
}
|
||||||
|
v = parseFloat(v)
|
||||||
|
if (i === 0) {
|
||||||
|
num = v
|
||||||
|
arr.push(v)
|
||||||
|
} else {
|
||||||
|
switch (type) {
|
||||||
|
case 'min':
|
||||||
|
num = num > v ? v : num
|
||||||
|
break
|
||||||
|
case 'avg':
|
||||||
|
arr.push(v)
|
||||||
|
if (arr.length === qsMarkArr.length) {
|
||||||
|
num = arr.reduce((acc, curr) => {
|
||||||
|
return acc + curr
|
||||||
|
}, 0) / arr.length
|
||||||
|
}
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return num === null ? num : num.toFixed(this.digitPlaces)
|
||||||
|
},
|
||||||
|
limitBlur(qId, valueType) {
|
||||||
|
const value = this.questionForm[qId]
|
||||||
|
if (isNaN(parseInt(value))) return
|
||||||
|
if (valueType === 0) {
|
||||||
|
this.$set(this.questionForm, qId, parseInt(value))
|
||||||
|
} else if (valueType === 3) {
|
||||||
|
this.$set(this.questionForm, qId, parseFloat(value))
|
||||||
|
} else {
|
||||||
|
this.$set(this.questionForm, qId, parseFloat(value).toFixed(this.digitPlaces))
|
||||||
|
}
|
||||||
|
},
|
||||||
|
returnFloat(num) {
|
||||||
|
if (num) return
|
||||||
|
var value = Math.round(parseFloat(num) * 100) / 100
|
||||||
|
var s = value.toString().split('.')
|
||||||
|
if (s.length === 1) {
|
||||||
|
value = value.toString() + '.00'
|
||||||
|
return value
|
||||||
|
}
|
||||||
|
if (s.length > 1) {
|
||||||
|
if (s[1].length < 2) {
|
||||||
|
value = value.toString() + '0'
|
||||||
|
}
|
||||||
|
return value
|
||||||
|
}
|
||||||
|
},
|
||||||
|
getQuestionVal(questionMark) {
|
||||||
|
const idx = this.questions.findIndex(i => i.QuestionMark === questionMark)
|
||||||
|
if (idx > -1) {
|
||||||
|
const questionId = this.questions[idx].Id
|
||||||
|
const answer = this.questionForm[questionId]
|
||||||
|
if (isNaN(parseFloat(answer))) {
|
||||||
|
return answer
|
||||||
|
} else {
|
||||||
|
return parseFloat(answer)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return ''
|
||||||
|
}
|
||||||
|
},
|
||||||
|
async handleSave() {
|
||||||
|
const valid = await this.$refs.measurementForm.validate()
|
||||||
|
if (!valid) return
|
||||||
|
const loading = this.$loading({ fullscreen: true })
|
||||||
|
try {
|
||||||
|
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}$/)
|
||||||
|
for (const k in this.questionForm) {
|
||||||
|
if (reg.test(k)) {
|
||||||
|
if (answers.findIndex(i => i.tableQuestionId === k) === -1) {
|
||||||
|
answers.push({ tableQuestionId: k, answer: this.questionForm[k] })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var params = {
|
||||||
|
questionId: this.parentQsId,
|
||||||
|
rowId: this.questionForm.RowId,
|
||||||
|
rowIndex: this.answers.RowIndex,
|
||||||
|
visitTaskId: this.visitTaskId,
|
||||||
|
trialId: this.trialId,
|
||||||
|
answerList: answers
|
||||||
|
}
|
||||||
|
const res = await submitTableQuestion(params)
|
||||||
|
if (res.IsSuccess) {
|
||||||
|
// 保存成功!
|
||||||
|
this.$message.success(this.$t('common:message:savedSuccessfully'))
|
||||||
|
this.$set(this.questionForm, 'saveTypeEnum', 2)
|
||||||
|
this.originalQuestionForm = { ...this.questionForm }
|
||||||
|
this.$set(this.questionForm, 'RowId', res.Result.RowId)
|
||||||
|
let l1, l2, l3, min, mean, angle
|
||||||
|
if (this.lesionType === 101) {
|
||||||
|
l1 = this.getQuestionVal(1011)
|
||||||
|
l2 = this.getQuestionVal(1012)
|
||||||
|
l3 = this.getQuestionVal(1013)
|
||||||
|
min = this.getQuestionVal(1014)
|
||||||
|
mean = this.getQuestionVal(1015)
|
||||||
|
} else if (this.lesionType === 103) {
|
||||||
|
angle = this.getQuestionVal(1016)
|
||||||
|
}
|
||||||
|
this.$emit('resetQuestions', { l1, l2, l3, min, mean, angle, saveTypeEnum: this.questionForm.saveTypeEnum, rowIndex: this.rowIndex, questionId: this.parentQsId, anwsers: this.questionForm })
|
||||||
|
this.$emit('close')
|
||||||
|
|
||||||
|
DicomEvent.$emit('refreshQuestions')
|
||||||
|
DicomEvent.$emit('getReportInfo', true)
|
||||||
|
}
|
||||||
|
loading.close()
|
||||||
|
} catch (e) {
|
||||||
|
console.log(e)
|
||||||
|
loading.close()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
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) {
|
||||||
|
this.$emit('close', { lesionType: this.lesionType, rowIndex: this.rowIndex, visitTaskId: this.visitTaskId })
|
||||||
|
DicomEvent.$emit('getReportInfo', true)
|
||||||
|
// '删除成功!'
|
||||||
|
this.$message.success(this.$t('common:message:deletedSuccessfully'))
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
this.$emit('close', { lesionType: this.lesionType, rowIndex: this.rowIndex, visitTaskId: this.visitTaskId })
|
||||||
|
}
|
||||||
|
loading.close()
|
||||||
|
} catch (e) {
|
||||||
|
loading.close()
|
||||||
|
console.log(e)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
async handleClose() {
|
||||||
|
if (!this.questionForm.RowId) {
|
||||||
|
// '当前数据未保存。如果关闭窗口,将会删除,是否继续?'
|
||||||
|
const confirm = await this.$confirm(
|
||||||
|
this.$t('trials:reading:warnning:msg60'),
|
||||||
|
{
|
||||||
|
type: 'warning',
|
||||||
|
distinguishCancelAndClose: true
|
||||||
|
}
|
||||||
|
)
|
||||||
|
if (confirm !== 'confirm') return
|
||||||
|
this.$emit('close', { lesionType: this.lesionType, rowIndex: this.rowIndex, visitTaskId: this.visitTaskId })
|
||||||
|
} else {
|
||||||
|
this.$emit('close')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.measurement-form{
|
||||||
|
/deep/ .el-form-item__label{
|
||||||
|
color: #c3c3c3;
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
/deep/ .el-input .el-input__inner{
|
||||||
|
background-color: transparent;
|
||||||
|
color: #ddd;
|
||||||
|
border: 1px solid #5e5e5e;
|
||||||
|
}
|
||||||
|
/deep/ .el-form-item{
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
justify-content: flex-start;
|
||||||
|
}
|
||||||
|
/deep/ .el-form-item__content{
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
/deep/ .el-input.is-disabled .el-input__inner{
|
||||||
|
background-color: #646464a1;
|
||||||
|
}
|
||||||
|
/deep/ .el-select.is-disabled .el-input__inner{
|
||||||
|
background-color: #646464a1;
|
||||||
|
}
|
||||||
|
/deep/ .el-button--mini, .el-button--mini.is-round {
|
||||||
|
padding: 7px 10px;
|
||||||
|
}
|
||||||
|
.el-form-item__content
|
||||||
|
.el-select{
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
.input-width1{
|
||||||
|
width: calc(100% -60px)!important;
|
||||||
|
}
|
||||||
|
.input-width2{
|
||||||
|
width: 100% !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
</style>
|
||||||
|
|
@ -0,0 +1,780 @@
|
||||||
|
<template>
|
||||||
|
<div class="measurement-wrapper" :style="{'height':height+10+'px'}">
|
||||||
|
|
||||||
|
<div class="container" :style="{'height':height+'px'}">
|
||||||
|
<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="true"
|
||||||
|
:question-form-change-num="0"
|
||||||
|
:is-qulity-issues="false"
|
||||||
|
:group-classify="1"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 测量问题 -->
|
||||||
|
<template v-if="questions.length > 0 && CriterionType !== 10">
|
||||||
|
<div v-for="(qs,index) in questions" :key="index" v-loading="loading" class="lesions lesions_wrapper">
|
||||||
|
<h4 v-if="qs.Type === 'group'" style="color: #ddd;padding: 5px 0px;margin: 0;">
|
||||||
|
{{ language==='en'?qs.GroupEnName:qs.GroupName }}
|
||||||
|
</h4>
|
||||||
|
<div class="lesion_list">
|
||||||
|
<el-form
|
||||||
|
v-if="questions.length > 0"
|
||||||
|
:ref="`questions${index}`"
|
||||||
|
size="small"
|
||||||
|
:model="questionForm"
|
||||||
|
>
|
||||||
|
<div class="base-dialog-body">
|
||||||
|
<div v-for="item in qs.Childrens" :key="item.Id">
|
||||||
|
<div v-if="item.Type === 'table'" class="flex-row" style="margin:3px 0;">
|
||||||
|
<div class="title">{{ item.QuestionName }}</div>
|
||||||
|
<div v-if="readingTaskState < 2" class="add-icon" @click.prevent="handleAdd(item)">
|
||||||
|
<i class="el-icon-plus" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<el-collapse
|
||||||
|
v-if="item.Type === 'table' && item.TableQuestions"
|
||||||
|
v-model="activeName"
|
||||||
|
accordion
|
||||||
|
style="margin-bottom: 10px;"
|
||||||
|
@change="handleCollapseChange"
|
||||||
|
>
|
||||||
|
<el-collapse-item
|
||||||
|
v-for="(q,i) in item.TableQuestions.Answers"
|
||||||
|
:key="`${item.Id}_${q.RowIndex}`"
|
||||||
|
:name="`${item.Id}_${q.RowIndex}`"
|
||||||
|
>
|
||||||
|
<template slot="title">
|
||||||
|
<div style="width:300px;position: relative;" :style="{color:(activeName===item.Id+q.RowIndex?'#ffeb3b':'#fff')}">
|
||||||
|
|
||||||
|
{{ getLesionName(item.OrderMark,q.RowIndex) }}
|
||||||
|
<!-- 未保存 -->
|
||||||
|
<el-tooltip v-if="readingTaskState<2 && parseInt(item.TableQuestions.Answers[i].saveTypeEnum) === 0" class="item" effect="dark" :content="$t('trials:reading:button:unsaved')" placement="bottom">
|
||||||
|
<i class="el-icon-warning" style="color:red" />
|
||||||
|
</el-tooltip>
|
||||||
|
<!-- 信息不完整 -->
|
||||||
|
<el-tooltip v-if="readingTaskState<2 && parseInt(item.TableQuestions.Answers[i].saveTypeEnum) ===1" class="item" effect="dark" :content="$t('trials:reading:button:incompleteInfor')" placement="bottom">
|
||||||
|
<i class="el-icon-warning" style="color:#ff9800" />
|
||||||
|
</el-tooltip>
|
||||||
|
<div style="position: absolute;left: 60px;top: 2px;">
|
||||||
|
<div style="display: flex;flex-direction: row;font-size: 11px;width:200px;height: 30px;">
|
||||||
|
<div v-show="item.LesionType === 101" style="margin-left:10px;">
|
||||||
|
min: {{ numberToFixed(item.TableQuestions.Answers[i].min,'μm') }}
|
||||||
|
</div>
|
||||||
|
<div v-show="item.LesionType === 101" style="margin-left:10px;">
|
||||||
|
mean: {{ numberToFixed(item.TableQuestions.Answers[i].mean,'μm') }}
|
||||||
|
</div>
|
||||||
|
<div v-show="item.LesionType === 103" style="margin-left:10px;">
|
||||||
|
{{ numberToFixed(item.TableQuestions.Answers[i].angle,'°') }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</template>
|
||||||
|
<QuestionForm
|
||||||
|
:ref="`${item.Id}_${q.RowIndex}`"
|
||||||
|
:questions="item.TableQuestions.Questions"
|
||||||
|
:answers="item.TableQuestions.Answers[i]"
|
||||||
|
:lesion-type="item.LesionType"
|
||||||
|
:order-mark="item.OrderMark"
|
||||||
|
:table-questions="tableQuestions"
|
||||||
|
:row-index="String(q.RowIndex)"
|
||||||
|
:question-name="item.QuestionName"
|
||||||
|
:parent-qs-id="item.Id"
|
||||||
|
:visit-task-id="visitTaskId"
|
||||||
|
:is-current-task="isCurrentTask"
|
||||||
|
:reading-task-state="readingTaskState"
|
||||||
|
:is-base-line-task="isBaseLineTask"
|
||||||
|
@getReadingQuestionAndAnswer="getReadingQuestionAndAnswer"
|
||||||
|
@resetQuestions="resetQuestions"
|
||||||
|
@close="close"
|
||||||
|
/>
|
||||||
|
</el-collapse-item>
|
||||||
|
|
||||||
|
</el-collapse>
|
||||||
|
<template v-else>
|
||||||
|
<!-- 数值 -->
|
||||||
|
<el-form-item
|
||||||
|
v-if="item.ShowQuestion!==2"
|
||||||
|
:key="item.Id"
|
||||||
|
:label="`${item.QuestionName}`"
|
||||||
|
:prop="item.Id"
|
||||||
|
:rules="[
|
||||||
|
{ required: (item.IsRequired === 0 || (item.IsRequired ===1 && item.RelevanceId && (item.RelevanceValue.includes(questionForm[item.RelevanceId])))) && item.Type!=='group' && item.Type!=='summary',
|
||||||
|
message:['radio', 'select', 'checkbox'].includes(item.Type) ? $t('common:ruleMessage:select') : $t('common:ruleMessage:specify'), trigger: ['blur','change']},
|
||||||
|
]"
|
||||||
|
>
|
||||||
|
<!-- 数值类型 -->
|
||||||
|
<template v-if="item.Type==='number'">
|
||||||
|
<el-input
|
||||||
|
v-model="questionForm[item.Id]"
|
||||||
|
:disabled="!isCurrentTask || readingTaskState>=2 "
|
||||||
|
@change="((val)=>{formItemChange(val, item)})"
|
||||||
|
@blur="limitBlur(item.Id, item.ValueType)"
|
||||||
|
>
|
||||||
|
<template v-if="item.Unit" slot="append">
|
||||||
|
{{ $fd('ValueUnit', parseInt(item.Unit)) }}
|
||||||
|
</template>
|
||||||
|
</el-input>
|
||||||
|
</template>
|
||||||
|
</el-form-item>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
v-if="isCurrentTask && readingTaskState<2"
|
||||||
|
class="base-dialog-footer"
|
||||||
|
style="text-align:right;margin-top:10px;"
|
||||||
|
>
|
||||||
|
<!-- 保存 -->
|
||||||
|
<el-button
|
||||||
|
type="primary"
|
||||||
|
size="mini"
|
||||||
|
:disabled="!formChanged"
|
||||||
|
@click="handleSave(index)"
|
||||||
|
>
|
||||||
|
{{ $t('common:button:save') }}
|
||||||
|
</el-button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</el-form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<!-- 计算值 -->
|
||||||
|
<Questions
|
||||||
|
ref="ecrf2"
|
||||||
|
:question-form-change-state="true"
|
||||||
|
:question-form-change-num="0"
|
||||||
|
:is-qulity-issues="false"
|
||||||
|
:group-classify="4"
|
||||||
|
style="margin-top:20px"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<!-- 评估结果 -->
|
||||||
|
<Questions
|
||||||
|
ref="ecrf3"
|
||||||
|
:question-form-change-state="true"
|
||||||
|
:question-form-change-num="0"
|
||||||
|
:is-qulity-issues="false"
|
||||||
|
:group-classify="5"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<script>
|
||||||
|
// import { saveTaskQuestion } from '@/api/trials'
|
||||||
|
import { resetReadingTask } from '@/api/reading'
|
||||||
|
import DicomEvent from './../DicomEvent'
|
||||||
|
import store from '@/store'
|
||||||
|
import { mapGetters } from 'vuex'
|
||||||
|
import Questions from './../Questions'
|
||||||
|
import QuestionForm from './QuestionForm'
|
||||||
|
export default {
|
||||||
|
name: 'MeasurementList',
|
||||||
|
components: {
|
||||||
|
Questions,
|
||||||
|
QuestionForm
|
||||||
|
},
|
||||||
|
props: {
|
||||||
|
isShow: {
|
||||||
|
type: Boolean,
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
isReadingShowSubjectInfo: {
|
||||||
|
type: Boolean,
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
questionFormChangeState: {
|
||||||
|
type: Boolean,
|
||||||
|
default() {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
questionFormChangeNum: {
|
||||||
|
type: Number,
|
||||||
|
default() {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
height: window.innerHeight - 140,
|
||||||
|
questions: [],
|
||||||
|
activeName: '',
|
||||||
|
activeItem: {
|
||||||
|
activeRowIndex: null,
|
||||||
|
activeCollapseId: null
|
||||||
|
},
|
||||||
|
visitTaskId: '',
|
||||||
|
isCurrentTask: false,
|
||||||
|
loading: false,
|
||||||
|
unSaveTargets: [],
|
||||||
|
temporaryLesions: [],
|
||||||
|
readingTaskState: 2,
|
||||||
|
isBaseLineTask: false,
|
||||||
|
taskBlindName: '',
|
||||||
|
tableQuestions: [],
|
||||||
|
isFirstRender: false,
|
||||||
|
CriterionType: null,
|
||||||
|
subjectCode: '',
|
||||||
|
questionForm: {},
|
||||||
|
formChanged: false,
|
||||||
|
digitPlaces: 2
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
...mapGetters(['visitTaskList', 'language', 'lastCanvasTaskId', 'currentReadingTaskState'])
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
lastCanvasTaskId: {
|
||||||
|
immediate: true,
|
||||||
|
handler(val) {
|
||||||
|
if (val) {
|
||||||
|
this.initList()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
currentReadingTaskState: {
|
||||||
|
immediate: true,
|
||||||
|
handler(val) {
|
||||||
|
if (val) {
|
||||||
|
this.readingTaskState = val
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
// 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
|
||||||
|
window.addEventListener('message', this.receiveMsg)
|
||||||
|
this.CriterionType = parseInt(localStorage.getItem('CriterionType'))
|
||||||
|
DicomEvent.$on('setCollapseActive', measureData => {
|
||||||
|
this.setCollapseActive(measureData)
|
||||||
|
console.log('setCollapseActive')
|
||||||
|
})
|
||||||
|
DicomEvent.$on('getAllUnSaveLesions', (callback) => {
|
||||||
|
callback([])
|
||||||
|
})
|
||||||
|
DicomEvent.$on('refreshQuestions', _ => {
|
||||||
|
this.refreshQuestions()
|
||||||
|
})
|
||||||
|
|
||||||
|
window.addEventListener('resize', this.setHeight)
|
||||||
|
},
|
||||||
|
beforeDestroy() {
|
||||||
|
DicomEvent.$off('setCollapseActive')
|
||||||
|
DicomEvent.$off('getUnSaveTarget')
|
||||||
|
DicomEvent.$off('refreshQuestions')
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
async initList() {
|
||||||
|
var i = this.visitTaskList.findIndex(i => i.VisitTaskId === this.lastCanvasTaskId)
|
||||||
|
if (i > -1) {
|
||||||
|
this.visitTaskId = this.visitTaskList[i].VisitTaskId
|
||||||
|
this.taskBlindName = this.visitTaskList[i].TaskBlindName
|
||||||
|
this.readingTaskState = this.visitTaskList[i].ReadingTaskState
|
||||||
|
this.isBaseLineTask = this.visitTaskList[i].IsBaseLineTask
|
||||||
|
this.isCurrentTask = this.visitTaskList[i].IsCurrentTask
|
||||||
|
this.activeName = ''
|
||||||
|
this.activeItem.activeRowIndex = null
|
||||||
|
this.activeItem.activeCollapseId = null
|
||||||
|
if (!this.visitTaskList[i].IsInit) {
|
||||||
|
var loading = this.$loading({ fullscreen: true })
|
||||||
|
var triald = this.trialId = this.$router.currentRoute.query.trialId
|
||||||
|
if (!this.visitTaskList[i].studyListInit) {
|
||||||
|
await store.dispatch('reading/getStudyInfo', { trialId: triald, subjectVisitId: this.visitTaskList[i].VisitId, visitTaskId: this.visitTaskList[i].VisitTaskId, taskBlindName: this.visitTaskList[i].TaskBlindName })
|
||||||
|
}
|
||||||
|
if (!this.visitTaskList[i].readingQuestionsInit) {
|
||||||
|
await store.dispatch('reading/getReadingQuestionAndAnswer', { trialId: triald, visitTaskId: this.visitTaskList[i].VisitTaskId })
|
||||||
|
}
|
||||||
|
if (!this.visitTaskList[i].questionsInit) {
|
||||||
|
await store.dispatch('reading/getDicomReadingQuestionAnswer', { trialId: triald, visitTaskId: this.visitTaskList[i].VisitTaskId })
|
||||||
|
}
|
||||||
|
|
||||||
|
await store.dispatch('reading/setStatus', { visitTaskId: this.visitTaskList[i].VisitTaskId })
|
||||||
|
loading.close()
|
||||||
|
}
|
||||||
|
this.questions = this.visitTaskList[i].ReadingQuestions
|
||||||
|
this.setQuestionForm(this.questions)
|
||||||
|
this.$nextTick(() => {
|
||||||
|
this.$refs['ecrf'].getQuestions(this.visitTaskId)
|
||||||
|
this.$refs['ecrf2'].getQuestions(this.visitTaskId)
|
||||||
|
this.$refs['ecrf3'].getQuestions(this.visitTaskId)
|
||||||
|
this.getTableQuestions()
|
||||||
|
this.tableQuestions.forEach(item => {
|
||||||
|
item.TableQuestions.Answers.forEach(i => {
|
||||||
|
var refName = `${item.Id}_${i.RowIndex}`
|
||||||
|
this.$refs[refName] && this.$refs[refName][0].initForm()
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
},
|
||||||
|
setQuestionForm(questions) {
|
||||||
|
const type = ['number', 'radio', 'select', 'input', 'textarea', 'calculation']
|
||||||
|
questions.forEach(item => {
|
||||||
|
if (type.includes(item.Type)) {
|
||||||
|
const answer = item.Type === 'number' || item.Type === 'calculation' ? isNaN(parseFloat(item.Answer)) ? null : parseFloat(item.Answer) : item.Answer
|
||||||
|
this.$set(this.questionForm, item.Id, answer)
|
||||||
|
}
|
||||||
|
if (item.Childrens.length > 0) {
|
||||||
|
this.setQuestionForm(item.Childrens)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
async resetQuestions(obj) {
|
||||||
|
this.setQuestions(this.questions, obj)
|
||||||
|
await store.dispatch('reading/setReadingQuestionAndAnswer', { questions: this.questions, visitTaskId: this.visitTaskId })
|
||||||
|
|
||||||
|
this.getTableQuestions()
|
||||||
|
},
|
||||||
|
setQuestions(questions, obj) {
|
||||||
|
questions.forEach(item => {
|
||||||
|
if (item.Type === 'table' && item.Id === obj.questionId) {
|
||||||
|
var idx = item.TableQuestions.Answers.findIndex(i => i.RowIndex === obj.rowIndex)
|
||||||
|
item.TableQuestions.Answers[idx].saveTypeEnum = obj.saveTypeEnum
|
||||||
|
if (item.LesionType === 101) {
|
||||||
|
item.TableQuestions.Answers[idx].l1 = obj.l1
|
||||||
|
item.TableQuestions.Answers[idx].l2 = obj.l2
|
||||||
|
item.TableQuestions.Answers[idx].l3 = obj.l3
|
||||||
|
item.TableQuestions.Answers[idx].min = obj.min
|
||||||
|
item.TableQuestions.Answers[idx].mean = obj.mean
|
||||||
|
} else if (item.LesionType === 103) {
|
||||||
|
item.TableQuestions.Answers[idx].angle = obj.angle
|
||||||
|
}
|
||||||
|
for (const i in obj.anwsers) {
|
||||||
|
item.TableQuestions.Answers[idx][i] = String(obj.anwsers[i])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (item.Childrens.length > 0) {
|
||||||
|
this.setQuestions(item.Childrens, obj)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
getQuestions(questions) {
|
||||||
|
questions.forEach(item => {
|
||||||
|
if (item.Type === 'table' && item.TableQuestions && item.TableQuestions.Answers.length > 0) {
|
||||||
|
item.TableQuestions.Answers.forEach(answerObj => {
|
||||||
|
if (answerObj.RowId) {
|
||||||
|
if (item.LesionType === 101) {
|
||||||
|
var min = this.getQuestionAnswer(item.TableQuestions.Questions, 1014, answerObj)
|
||||||
|
var mean = this.getQuestionAnswer(item.TableQuestions.Questions, 1015, answerObj)
|
||||||
|
this.$set(answerObj, 'saveTypeEnum', (isNaN(parseFloat(min)) || isNaN(parseFloat(mean))) ? 1 : 2)
|
||||||
|
} else if (item.LesionType === 103) {
|
||||||
|
var angle = this.getQuestionAnswer(item.TableQuestions.Questions, 1016, answerObj)
|
||||||
|
this.$set(answerObj, 'saveTypeEnum', isNaN(parseFloat(angle)) ? 1 : 2)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
this.$set(answerObj, 'saveTypeEnum', 0)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
if (item.Childrens.length > 0) {
|
||||||
|
this.getQuestions(item.Childrens)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
return questions
|
||||||
|
},
|
||||||
|
getTableQuestions() {
|
||||||
|
this.tableQuestions = []
|
||||||
|
this.questions.map(item => {
|
||||||
|
if (item.Type === 'table') {
|
||||||
|
this.tableQuestions.push(item)
|
||||||
|
}
|
||||||
|
if (item.Childrens.length > 0) {
|
||||||
|
this.getTableQuestionsChild(item.Childrens)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
getTableQuestionsChild(obj) {
|
||||||
|
obj.map(item => {
|
||||||
|
if (item.Type === 'table') {
|
||||||
|
this.tableQuestions.push(item)
|
||||||
|
}
|
||||||
|
if (item.Childrens.length > 0) {
|
||||||
|
this.getTableQuestionsChild(item.Childrens)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
refreshReadingQuestionAndAnswer(type) {
|
||||||
|
if (type === 0) {
|
||||||
|
// 删除
|
||||||
|
this.activeName = ''
|
||||||
|
this.activeItem.activeRowIndex = null
|
||||||
|
this.activeItem.activeCollapseId = null
|
||||||
|
}
|
||||||
|
|
||||||
|
this.getReadingQuestionAndAnswer(this.visitTaskId)
|
||||||
|
},
|
||||||
|
getReadingQuestionAndAnswer() {
|
||||||
|
return new Promise(async resolve => {
|
||||||
|
try {
|
||||||
|
const loading = this.$loading({ fullscreen: true })
|
||||||
|
await store.dispatch('reading/refreshReadingQuestionAndAnswer', { trialId: this.$router.currentRoute.query.trialId, visitTaskId: this.visitTaskId }).then(() => {
|
||||||
|
var idx = this.visitTaskList.findIndex(i => i.VisitTaskId === this.visitTaskId)
|
||||||
|
if (idx > -1) {
|
||||||
|
if (this.visitTaskList[idx].ReadingQuestions.length > 0) {
|
||||||
|
this.questions = this.visitTaskList[idx].ReadingQuestions
|
||||||
|
this.setQuestionForm(this.questions)
|
||||||
|
}
|
||||||
|
this.readingTaskState = this.visitTaskList[idx].ReadingTaskState
|
||||||
|
this.isBaseLineTask = this.visitTaskList[idx].IsBaseLineTask
|
||||||
|
this.isCurrentTask = this.visitTaskList[idx].IsCurrentTask
|
||||||
|
}
|
||||||
|
this.getTableQuestions()
|
||||||
|
this.$nextTick(() => {
|
||||||
|
this.tableQuestions.forEach(item => {
|
||||||
|
item.TableQuestions.Answers.forEach(i => {
|
||||||
|
var refName = `${item.Id}_${i.RowIndex}`
|
||||||
|
this.$refs[refName] && this.$refs[refName][0].initForm()
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
loading.close()
|
||||||
|
resolve()
|
||||||
|
} 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) {
|
||||||
|
var questionId = questions[idx].Id
|
||||||
|
return answers[questionId]
|
||||||
|
} else {
|
||||||
|
return ''
|
||||||
|
}
|
||||||
|
},
|
||||||
|
isCanActiveTool(toolName) {
|
||||||
|
return { isCanActiveTool: true, reason: '' }
|
||||||
|
},
|
||||||
|
|
||||||
|
async handleAdd(qs) {
|
||||||
|
if (!!qs.MaxQuestionCount && qs.MaxQuestionCount <= qs.TableQuestions.Answers.length) {
|
||||||
|
let msg = this.$t('trials:reading:warnning:msg14')
|
||||||
|
// msg = msg.replace('xxx', qs.QuestionName)
|
||||||
|
msg = msg.replace('xxx', qs.MaxQuestionCount)
|
||||||
|
this.$confirm(msg, {
|
||||||
|
type: 'warning',
|
||||||
|
showCancelButton: false,
|
||||||
|
callback: action => {}
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
// saveTypeEnum: 0
|
||||||
|
var obj = { saveTypeEnum: 0 }
|
||||||
|
// var questions = qs.TableQuestions.Questions.find(item => item.QuestionMark === 3)
|
||||||
|
// if (questions) {
|
||||||
|
// console.log(questions)
|
||||||
|
// var maxIndex = this.getMaxRowIndex(qs.TableQuestions.Answers)
|
||||||
|
// obj.RowIndex = `${maxIndex + 1}.00`
|
||||||
|
// obj[questions.Id] = `${qs.OrderMark}${String(maxIndex + 1).padStart(2, '0')}`
|
||||||
|
// }
|
||||||
|
var maxIndex = this.getMaxRowIndex(qs.TableQuestions.Answers)
|
||||||
|
obj.RowIndex = `${maxIndex + 1}.00`
|
||||||
|
obj.IsDicomReading = true
|
||||||
|
await store.dispatch('reading/addReadingQuestionAndAnswer', { lesionType: qs.LesionType, visitTaskId: this.visitTaskId, lesionObj: obj })
|
||||||
|
|
||||||
|
this.activeItem.activeRowIndex = String(obj.RowIndex)
|
||||||
|
this.activeItem.activeCollapseId = qs.Id
|
||||||
|
this.activeName = `${this.activeItem.activeCollapseId}_${this.activeItem.activeRowIndex}`
|
||||||
|
}
|
||||||
|
},
|
||||||
|
getMaxRowIndex(answerList) {
|
||||||
|
if (answerList.length > 0) {
|
||||||
|
var arr = []
|
||||||
|
answerList.forEach(item => {
|
||||||
|
var rowIndex = item.RowIndex
|
||||||
|
arr.push(parseInt(rowIndex))
|
||||||
|
})
|
||||||
|
var max = Math.max.apply(null, arr)
|
||||||
|
return max
|
||||||
|
} else {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
},
|
||||||
|
getLesionName(orderMark, rowIndex) {
|
||||||
|
var lessionName = ''
|
||||||
|
var rowIndexArr = rowIndex.split('.')
|
||||||
|
var x = parseInt(rowIndexArr[0])
|
||||||
|
var y = parseInt(rowIndexArr[1])
|
||||||
|
if (y > 0) {
|
||||||
|
y = String.fromCharCode(parseInt(rowIndexArr[1]) - 1 + 65 + 32)
|
||||||
|
lessionName = `${orderMark}${String(x).padStart(2, '0')}${y}`
|
||||||
|
} else {
|
||||||
|
lessionName = `${orderMark}${String(x).padStart(2, '0')}`
|
||||||
|
}
|
||||||
|
|
||||||
|
return lessionName
|
||||||
|
},
|
||||||
|
handleCollapseChange(val) {
|
||||||
|
if (this.activeName) {
|
||||||
|
var arr = this.activeName.split('_')
|
||||||
|
this.activeItem.activeRowIndex = arr[1]
|
||||||
|
this.activeItem.activeCollapseId = arr[0]
|
||||||
|
} else {
|
||||||
|
this.activeItem.activeRowIndex = null
|
||||||
|
this.activeItem.activeCollapseId = null
|
||||||
|
}
|
||||||
|
},
|
||||||
|
collapseRightClick(e, obj, activeCollapseId, activeRowIndex) {
|
||||||
|
e.stopImmediatePropagation()
|
||||||
|
e.stopPropagation()
|
||||||
|
e.preventDefault()
|
||||||
|
},
|
||||||
|
setCollapseActive(measureData) {
|
||||||
|
|
||||||
|
},
|
||||||
|
modifyMeasuredData(measureObj) {
|
||||||
|
},
|
||||||
|
// 设置测量数据
|
||||||
|
setMeasuredData(measureData) {
|
||||||
|
|
||||||
|
},
|
||||||
|
formItemChange() {
|
||||||
|
this.formChanged = true
|
||||||
|
},
|
||||||
|
limitBlur(qId, valueType) {
|
||||||
|
const value = this.questionForm[qId]
|
||||||
|
if (isNaN(parseInt(value))) return
|
||||||
|
if (valueType === 0) {
|
||||||
|
this.$set(this.questionForm, qId, parseInt(value))
|
||||||
|
} else if (valueType === 3) {
|
||||||
|
this.$set(this.questionForm, qId, parseFloat(value))
|
||||||
|
} else {
|
||||||
|
this.$set(this.questionForm, qId, parseFloat(value).toFixed(this.digitPlaces))
|
||||||
|
}
|
||||||
|
},
|
||||||
|
numberToFixed(v, unit) {
|
||||||
|
return isNaN(parseFloat(v)) ? null : `${parseFloat(v).toFixed(this.digitPlaces)}${unit}`
|
||||||
|
},
|
||||||
|
async handleSave(index) {
|
||||||
|
// const refName = `questions${index}`
|
||||||
|
// const valid = await this.$refs[refName][0].validate()
|
||||||
|
// if (!valid) return
|
||||||
|
// const loading = this.$loading({ fullscreen: true })
|
||||||
|
// var answers = []
|
||||||
|
// for (const k in this.questionForm) {
|
||||||
|
// answers.push({ id: k, answer: this.questionForm[k] })
|
||||||
|
// }
|
||||||
|
// var params = {
|
||||||
|
// visitTaskId: this.visitTaskId,
|
||||||
|
// answers: answers
|
||||||
|
// }
|
||||||
|
// try {
|
||||||
|
// await saveTaskQuestion(8, params)
|
||||||
|
// this.$message.success(this.$t('common:message:savedSuccessfully'))
|
||||||
|
// loading.close()
|
||||||
|
// DicomEvent.$emit('getReportInfo', true)
|
||||||
|
// this.refreshQuestions()
|
||||||
|
// this.formChanged = false
|
||||||
|
// } catch (e) {
|
||||||
|
// console.log(e)
|
||||||
|
// loading.close()
|
||||||
|
// }
|
||||||
|
},
|
||||||
|
async close(questionsObj) {
|
||||||
|
if (questionsObj) {
|
||||||
|
this.getReadingQuestionAndAnswer(questionsObj.visitTaskId)
|
||||||
|
this.refreshQuestions()
|
||||||
|
}
|
||||||
|
this.activeItem.activeRowIndex = null
|
||||||
|
this.activeItem.activeCollapseId = null
|
||||||
|
this.activeName = ''
|
||||||
|
},
|
||||||
|
getECRFQuestions(obj) {
|
||||||
|
this.$refs['ecrf'].getQuestions(obj.visitTaskId)
|
||||||
|
this.$refs['ecrf2'].getQuestions(obj.visitTaskId)
|
||||||
|
this.$refs['ecrf3'].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)
|
||||||
|
this.$refs['ecrf2'].getQuestions(this.visitTaskId, true)
|
||||||
|
this.$refs['ecrf3'].getQuestions(this.visitTaskId, true)
|
||||||
|
DicomEvent.$emit('getReportInfo', true)
|
||||||
|
}
|
||||||
|
loading.close()
|
||||||
|
} catch (e) {
|
||||||
|
loading.close()
|
||||||
|
console.log(e)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
async refreshQuestions() {
|
||||||
|
const triald = this.$router.currentRoute.query.trialId
|
||||||
|
await store.dispatch('reading/refreshDicomReadingQuestionAnswer', { trialId: triald, visitTaskId: this.visitTaskId })
|
||||||
|
this.$refs['ecrf'].getQuestions(this.visitTaskId, true)
|
||||||
|
this.$refs['ecrf2'].getQuestions(this.visitTaskId, true)
|
||||||
|
this.$refs['ecrf3'].getQuestions(this.visitTaskId, true)
|
||||||
|
},
|
||||||
|
receiveMsg(event) {
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.measurement-wrapper{
|
||||||
|
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;
|
||||||
|
font-weight: bold;
|
||||||
|
color: #ddd;
|
||||||
|
font-size: 15px;
|
||||||
|
|
||||||
|
}
|
||||||
|
.add-icon{
|
||||||
|
padding: 5px;
|
||||||
|
font-weight: bold;
|
||||||
|
color: #ddd;
|
||||||
|
font-size: 15px;
|
||||||
|
border: 1px solid #938b8b;
|
||||||
|
margin-bottom: 2px;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
.add-icon:hover{
|
||||||
|
background-color: #607d8b;
|
||||||
|
}
|
||||||
|
|
||||||
|
.flex-row{
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
justify-content: space-between;
|
||||||
|
background-color: #424242;
|
||||||
|
|
||||||
|
}
|
||||||
|
.lesion_list{
|
||||||
|
position: relative;
|
||||||
|
/deep/ .el-form-item__label{
|
||||||
|
color: #c3c3c3;
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
/deep/ .el-input .el-input__inner{
|
||||||
|
background-color: transparent;
|
||||||
|
color: #ddd;
|
||||||
|
border: 1px solid #5e5e5e;
|
||||||
|
}
|
||||||
|
/deep/ .el-form-item{
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
justify-content: flex-start;
|
||||||
|
}
|
||||||
|
/deep/ .el-form-item__content{
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
/deep/ .el-input.is-disabled .el-input__inner{
|
||||||
|
background-color: #646464a1;
|
||||||
|
}
|
||||||
|
/deep/ .el-select.is-disabled .el-input__inner{
|
||||||
|
background-color: #646464a1;
|
||||||
|
}
|
||||||
|
/deep/ .el-button--mini, .el-button--mini.is-round {
|
||||||
|
padding: 7px 10px;
|
||||||
|
}
|
||||||
|
.el-form-item__content
|
||||||
|
.el-select{
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.el-collapse{
|
||||||
|
border-bottom:none;
|
||||||
|
border-top:none;
|
||||||
|
/deep/ .el-collapse-item{
|
||||||
|
background-color: #000!important;
|
||||||
|
color: #ddd;
|
||||||
|
|
||||||
|
}
|
||||||
|
/deep/ .el-collapse-item__header{
|
||||||
|
background-color: #000!important;
|
||||||
|
color: #ddd;
|
||||||
|
border-bottom-color:#5a5a5a;
|
||||||
|
padding-left: 5px;
|
||||||
|
height: 35px;
|
||||||
|
line-height: 35px;
|
||||||
|
}
|
||||||
|
/deep/ .el-collapse-item__wrap{
|
||||||
|
background-color: #000!important;
|
||||||
|
color: #ddd;
|
||||||
|
}
|
||||||
|
/deep/ .el-collapse-item__content{
|
||||||
|
width:260px;
|
||||||
|
position: absolute;
|
||||||
|
top: 0px;
|
||||||
|
right: 0px;
|
||||||
|
// border: 1px solid #ffeb3b;
|
||||||
|
border: 1px solid #fff;
|
||||||
|
z-index: 1;
|
||||||
|
color: #ddd;
|
||||||
|
padding: 5px;
|
||||||
|
background-color:#1e1e1e;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
@ -24,7 +24,7 @@
|
||||||
{ required: (question.IsRequired === 0 || (question.IsRequired ===1 && question.RelevanceId && (questionForm[question.RelevanceId] === question.RelevanceValue))) && question.Type!=='group' && question.Type!=='summary',
|
{ 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']},
|
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">
|
<template v-if="question.QuestionType === 60 || question.QuestionType === 61">
|
||||||
<div style="display: flex;flex-direction: row;justify-content: flex-start;align-items: center;">
|
<div style="display: flex;flex-direction: row;justify-content: flex-start;align-items: center;">
|
||||||
|
|
@ -211,16 +211,40 @@
|
||||||
</el-checkbox>
|
</el-checkbox>
|
||||||
</el-checkbox-group>
|
</el-checkbox-group>
|
||||||
<!-- 数值 -->
|
<!-- 数值 -->
|
||||||
<el-input-number
|
<!-- <el-input-number
|
||||||
v-else-if="question.Type==='number'"
|
v-else-if="question.Type==='number'"
|
||||||
v-model="questionForm[question.Id]"
|
v-model="questionForm[question.Id]"
|
||||||
:disabled="readingTaskState >= 2 || isFirstChangeTask"
|
: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
|
<el-input
|
||||||
v-else-if="question.Type==='calculation'"
|
v-else-if="question.Type==='calculation'"
|
||||||
v-model="questionForm[question.Id]"
|
v-model="questionForm[question.Id]"
|
||||||
disabled
|
disabled
|
||||||
/>
|
>
|
||||||
|
<template v-if="question.Unit" slot="append">
|
||||||
|
{{ $fd('ValueUnit', parseInt(question.Unit)) }}
|
||||||
|
</template>
|
||||||
|
</el-input>
|
||||||
<!-- 上传图像 -->
|
<!-- 上传图像 -->
|
||||||
<el-upload
|
<el-upload
|
||||||
v-else-if="question.Type==='upload'"
|
v-else-if="question.Type==='upload'"
|
||||||
|
|
@ -326,7 +350,8 @@ export default {
|
||||||
accept: '.png,.jpg,.jpeg',
|
accept: '.png,.jpg,.jpeg',
|
||||||
imgVisible: false,
|
imgVisible: false,
|
||||||
imageUrl: '',
|
imageUrl: '',
|
||||||
urls: []
|
urls: [],
|
||||||
|
digitPlaces: 2
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
|
|
@ -352,6 +377,8 @@ export default {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
var digitPlaces = Number(localStorage.getItem('digitPlaces'))
|
||||||
|
this.digitPlaces = digitPlaces === -1 ? this.digitPlaces : digitPlaces
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
formItemChange(v, question) {
|
formItemChange(v, question) {
|
||||||
|
|
@ -461,7 +488,7 @@ export default {
|
||||||
}
|
}
|
||||||
.uploadWrapper{
|
.uploadWrapper{
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column !important;
|
||||||
align-items: flex-start;
|
align-items: flex-start;
|
||||||
}
|
}
|
||||||
/deep/ .el-input.is-disabled .el-input__inner{
|
/deep/ .el-input.is-disabled .el-input__inner{
|
||||||
|
|
@ -470,6 +497,9 @@ export default {
|
||||||
/deep/ .el-input-group__append, .el-input-group__prepend{
|
/deep/ .el-input-group__append, .el-input-group__prepend{
|
||||||
padding: 0 10px;
|
padding: 0 10px;
|
||||||
}
|
}
|
||||||
|
/deep/ .el-form-item__content {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
/deep/ .el-select.is-disabled .el-input__inner{
|
/deep/ .el-select.is-disabled .el-input__inner{
|
||||||
background-color: #646464a1;
|
background-color: #646464a1;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -88,7 +88,7 @@ export default {
|
||||||
spleenInfo: null,
|
spleenInfo: null,
|
||||||
calculateSpleenStatus: '',
|
calculateSpleenStatus: '',
|
||||||
formChanged: false,
|
formChanged: false,
|
||||||
digitPlaces: null
|
digitPlaces: 2
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
|
|
@ -374,7 +374,8 @@ export default {
|
||||||
DicomEvent.$emit('getReportInfo', true)
|
DicomEvent.$emit('getReportInfo', true)
|
||||||
// DicomEvent.$emit('readingPageUpdate', {})
|
// DicomEvent.$emit('readingPageUpdate', {})
|
||||||
var idx = this.visitTaskList.findIndex(i => i.VisitTaskId === this.visitTaskId)
|
var idx = this.visitTaskList.findIndex(i => i.VisitTaskId === this.visitTaskId)
|
||||||
if (idx > -1 && !this.visitTaskList[idx].IsBaseLineTask) {
|
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) {
|
if (parseInt(imageQuality) === 2) {
|
||||||
this.$confirm(this.$t('trials:reading:warnning:unableEvaluate'), '', {
|
this.$confirm(this.$t('trials:reading:warnning:unableEvaluate'), '', {
|
||||||
type: 'warning'
|
type: 'warning'
|
||||||
|
|
@ -856,6 +857,7 @@ export default {
|
||||||
.ecrf-wrapper{
|
.ecrf-wrapper{
|
||||||
/deep/ .el-form-item__label{
|
/deep/ .el-form-item__label{
|
||||||
color: #c3c3c3;
|
color: #c3c3c3;
|
||||||
|
text-align: left;
|
||||||
}
|
}
|
||||||
/deep/ .el-input__inner{
|
/deep/ .el-input__inner{
|
||||||
background-color: transparent;
|
background-color: transparent;
|
||||||
|
|
|
||||||
|
|
@ -102,7 +102,7 @@
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<template slot-scope="scope">
|
<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) || scope.row.HighlightAnswerList.includes(`${scope.row.Answers[task.VisitTaskId]}`) ? '#f66' : '#fff'}" >
|
<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.VisitTaskId === visitTaskId && readingTaskState < 2 && [13,14,15,42].includes(scope.row.QuestionType)">
|
||||||
<!-- 是否存在疾病(基线时可修改) -->
|
<!-- 是否存在疾病(基线时可修改) -->
|
||||||
<template v-if="task.IsBaseLine && scope.row.QuestionType=== 15">
|
<template v-if="task.IsBaseLine && scope.row.QuestionType=== 15">
|
||||||
|
|
|
||||||
|
|
@ -77,7 +77,7 @@
|
||||||
>
|
>
|
||||||
<div>
|
<div>
|
||||||
<div>{{ instance.InstanceNumber }}</div>
|
<div>{{ instance.InstanceNumber }}</div>
|
||||||
<div>{{ `${instance.NumberOfFrames > 0 ? instance.NumberOfFrames : 1} frame` }}</div>
|
<div>{{ `${instance.NumberOfFrames > 0 ? instance.KeyFramesList.length > 0 ? instance.KeyFramesList.length : instance.NumberOfFrames : 1} frame` }}</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -294,7 +294,14 @@ export default {
|
||||||
store.dispatch('reading/setImageloadedInfo', item)
|
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) {
|
if (i > -1) {
|
||||||
var idx = this.visitTaskList.findIndex(i => i.VisitTaskId === this.visitTaskId)
|
var idx = this.visitTaskList.findIndex(i => i.VisitTaskId === this.visitTaskId)
|
||||||
if (idx > -1) {
|
if (idx > -1) {
|
||||||
|
|
@ -342,8 +349,9 @@ export default {
|
||||||
this.studyList = this.visitTaskList[idx].StudyList
|
this.studyList = this.visitTaskList[idx].StudyList
|
||||||
var sIdx = this.studyList.findIndex(s => s.IsDicom)
|
var sIdx = this.studyList.findIndex(s => s.IsDicom)
|
||||||
if (sIdx > -1) {
|
if (sIdx > -1) {
|
||||||
this.studyIndex = sIdx
|
console.log(this.studyIndex, this.studyIndex)
|
||||||
this.seriesIndex = 0
|
// this.studyIndex = sIdx
|
||||||
|
// c = 0
|
||||||
this.activeNames = [`${this.studyList[sIdx].StudyId}`]
|
this.activeNames = [`${this.studyList[sIdx].StudyId}`]
|
||||||
// 下载关键序列
|
// 下载关键序列
|
||||||
const i = this.studyList.findIndex(i => i.IsCriticalSequence)
|
const i = this.studyList.findIndex(i => i.IsCriticalSequence)
|
||||||
|
|
@ -377,8 +385,23 @@ export default {
|
||||||
var isReadingTaskViewInOrder = parseInt(this.$router.currentRoute.query.isReadingTaskViewInOrder)
|
var isReadingTaskViewInOrder = parseInt(this.$router.currentRoute.query.isReadingTaskViewInOrder)
|
||||||
var idx = this.visitTaskList.findIndex(i => i.VisitTaskId === this.visitTaskId)
|
var idx = this.visitTaskList.findIndex(i => i.VisitTaskId === this.visitTaskId)
|
||||||
this.studyList = this.visitTaskList[idx].StudyList
|
this.studyList = this.visitTaskList[idx].StudyList
|
||||||
if (this.visitTaskList[idx].IsBaseLineTask || isReadingTaskViewInOrder !== 1) {
|
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])
|
const obj = this.getFirstMarkedSeries(this.visitTaskList[idx].MeasureData, [...this.visitTaskList[idx].StudyList])
|
||||||
if (Object.keys(obj).length !== 0) {
|
if (Object.keys(obj).length !== 0) {
|
||||||
this.studyIndex = obj.studyIndex
|
this.studyIndex = obj.studyIndex
|
||||||
|
|
@ -668,7 +691,11 @@ export default {
|
||||||
this.currentSeriesIndex = seriesIndex
|
this.currentSeriesIndex = seriesIndex
|
||||||
var idx = this.visitTaskIdx
|
var idx = this.visitTaskIdx
|
||||||
const imageIds = []
|
const imageIds = []
|
||||||
if (instanceInfo.NumberOfFrames && instanceInfo.NumberOfFrames > 1) {
|
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++) {
|
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}`)
|
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}`)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1637,7 +1637,7 @@ export default {
|
||||||
resetWwwc() {
|
resetWwwc() {
|
||||||
this.toolState.viewportInvert = false
|
this.toolState.viewportInvert = false
|
||||||
var viewport = cornerstone.getViewport(this.canvas)
|
var viewport = cornerstone.getViewport(this.canvas)
|
||||||
viewport.invert = false
|
// viewport.invert = false
|
||||||
var image = cornerstone.getImage(this.canvas)
|
var image = cornerstone.getImage(this.canvas)
|
||||||
viewport.voi.windowWidth = image.windowWidth
|
viewport.voi.windowWidth = image.windowWidth
|
||||||
viewport.voi.windowCenter = image.windowCenter
|
viewport.voi.windowCenter = image.windowCenter
|
||||||
|
|
|
||||||
|
|
@ -106,7 +106,8 @@
|
||||||
v-if="item.val === 1"
|
v-if="item.val === 1"
|
||||||
class="divider"
|
class="divider"
|
||||||
content-position="center"
|
content-position="center"
|
||||||
>{{ ` ${$t("trials:reading:title:preset")}` }}</el-divider>
|
>{{ ` ${$t('trials:reading:title:preset')}` }}</el-divider
|
||||||
|
>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -163,7 +164,7 @@
|
||||||
<svg-icon icon-class="magnifier" class="svg-icon" />
|
<svg-icon icon-class="magnifier" class="svg-icon" />
|
||||||
</div>
|
</div>
|
||||||
<!-- 缩放 -->
|
<!-- 缩放 -->
|
||||||
<div class="text">{{ $t("trials:reading:button:zoom") }}</div>
|
<div class="text">{{ $t('trials:reading:button:zoom') }}</div>
|
||||||
</div>
|
</div>
|
||||||
</el-tooltip>
|
</el-tooltip>
|
||||||
|
|
||||||
|
|
@ -183,7 +184,7 @@
|
||||||
<svg-icon icon-class="move" class="svg-icon" />
|
<svg-icon icon-class="move" class="svg-icon" />
|
||||||
</div>
|
</div>
|
||||||
<!-- 移动 -->
|
<!-- 移动 -->
|
||||||
<div class="text">{{ $t("trials:reading:button:move") }}</div>
|
<div class="text">{{ $t('trials:reading:button:move') }}</div>
|
||||||
</div>
|
</div>
|
||||||
</el-tooltip>
|
</el-tooltip>
|
||||||
|
|
||||||
|
|
@ -210,7 +211,7 @@
|
||||||
</div>
|
</div>
|
||||||
<!-- 旋转 -->
|
<!-- 旋转 -->
|
||||||
<div class="text">
|
<div class="text">
|
||||||
{{ $t("trials:reading:button:rotate")
|
{{ $t('trials:reading:button:rotate')
|
||||||
}}<i class="el-icon-caret-bottom" />
|
}}<i class="el-icon-caret-bottom" />
|
||||||
</div>
|
</div>
|
||||||
<div class="dropdown-content">
|
<div class="dropdown-content">
|
||||||
|
|
@ -223,7 +224,8 @@
|
||||||
<a
|
<a
|
||||||
href="#"
|
href="#"
|
||||||
@click.prevent="setDicomCanvasRotate(rotate.val)"
|
@click.prevent="setDicomCanvasRotate(rotate.val)"
|
||||||
>{{ rotate.label }}</a>
|
>{{ rotate.label }}</a
|
||||||
|
>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -258,8 +260,8 @@
|
||||||
<div class="text">
|
<div class="text">
|
||||||
{{
|
{{
|
||||||
fitType === 1
|
fitType === 1
|
||||||
? $t("trials:reading:button:fitWindow")
|
? $t('trials:reading:button:fitWindow')
|
||||||
: $t("trials:reading:button:fitImage")
|
: $t('trials:reading:button:fitImage')
|
||||||
}}
|
}}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -282,7 +284,7 @@
|
||||||
</div>
|
</div>
|
||||||
<!-- 同步 -->
|
<!-- 同步 -->
|
||||||
<div class="text">
|
<div class="text">
|
||||||
{{ $t("trials:reading:button:imageIndexSync") }}
|
{{ $t('trials:reading:button:imageIndexSync') }}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</el-tooltip>
|
</el-tooltip>
|
||||||
|
|
@ -307,7 +309,7 @@
|
||||||
<svg-icon icon-class="image" class="svg-icon" />
|
<svg-icon icon-class="image" class="svg-icon" />
|
||||||
</div>
|
</div>
|
||||||
<!-- 截屏 -->
|
<!-- 截屏 -->
|
||||||
<div class="text">{{ $t("trials:reading:button:screenShot") }}</div>
|
<div class="text">{{ $t('trials:reading:button:screenShot') }}</div>
|
||||||
</div>
|
</div>
|
||||||
</el-tooltip>
|
</el-tooltip>
|
||||||
|
|
||||||
|
|
@ -316,7 +318,7 @@
|
||||||
<div slot="content">
|
<div slot="content">
|
||||||
<div v-if="tool.disabledReason">
|
<div v-if="tool.disabledReason">
|
||||||
<h4 style="margin: 0; padding-bottom: 2px">{{ tool.text }}</h4>
|
<h4 style="margin: 0; padding-bottom: 2px">{{ tool.text }}</h4>
|
||||||
<br>{{ tool.disabledReason }}
|
<br />{{ tool.disabledReason }}
|
||||||
</div>
|
</div>
|
||||||
<div v-else>{{ tool.text }}</div>
|
<div v-else>{{ tool.text }}</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -365,7 +367,7 @@
|
||||||
<svg-icon icon-class="clear" class="svg-icon" />
|
<svg-icon icon-class="clear" class="svg-icon" />
|
||||||
</div>
|
</div>
|
||||||
<!-- 缩放 -->
|
<!-- 缩放 -->
|
||||||
<div class="text">{{ $t("trials:dicom-show:Eraser") }}</div>
|
<div class="text">{{ $t('trials:dicom-show:Eraser') }}</div>
|
||||||
</div>
|
</div>
|
||||||
</el-tooltip>
|
</el-tooltip>
|
||||||
<div class="tool-frame">
|
<div class="tool-frame">
|
||||||
|
|
@ -467,11 +469,11 @@
|
||||||
<div class="icon" @click.prevent="resetViewport">
|
<div class="icon" @click.prevent="resetViewport">
|
||||||
<svg-icon icon-class="refresh" class="svg-icon" />
|
<svg-icon icon-class="refresh" class="svg-icon" />
|
||||||
</div>
|
</div>
|
||||||
<div class="text">{{ $t("trials:reading:button:reset") }}</div>
|
<div class="text">{{ $t('trials:reading:button:reset') }}</div>
|
||||||
</div>
|
</div>
|
||||||
</el-tooltip>
|
</el-tooltip>
|
||||||
<el-tooltip
|
<el-tooltip
|
||||||
v-if="trialCriterion.ImageUploadEnum > 0"
|
v-if="trialCriterion.ImageUploadEnum > 0 && currentReadingTaskState < 2"
|
||||||
v-hasPermi="['role:ir']"
|
v-hasPermi="['role:ir']"
|
||||||
class="item"
|
class="item"
|
||||||
effect="dark"
|
effect="dark"
|
||||||
|
|
@ -482,7 +484,7 @@
|
||||||
<div class="icon" @click.prevent="openUploadImage('upload')">
|
<div class="icon" @click.prevent="openUploadImage('upload')">
|
||||||
<i class="el-icon-upload2 svg-icon" />
|
<i class="el-icon-upload2 svg-icon" />
|
||||||
</div>
|
</div>
|
||||||
<div class="text">{{ $t("trials:reading:button:upload") }}</div>
|
<div class="text">{{ $t('trials:reading:button:upload') }}</div>
|
||||||
</div>
|
</div>
|
||||||
</el-tooltip>
|
</el-tooltip>
|
||||||
<el-tooltip
|
<el-tooltip
|
||||||
|
|
@ -505,7 +507,7 @@
|
||||||
<div class="icon" @click.prevent="openUploadImage('download')">
|
<div class="icon" @click.prevent="openUploadImage('download')">
|
||||||
<i class="el-icon-download svg-icon" />
|
<i class="el-icon-download svg-icon" />
|
||||||
</div>
|
</div>
|
||||||
<div class="text">{{ $t("trials:reading:button:download") }}</div>
|
<div class="text">{{ $t('trials:reading:button:download') }}</div>
|
||||||
</div>
|
</div>
|
||||||
</el-tooltip>
|
</el-tooltip>
|
||||||
|
|
||||||
|
|
@ -515,17 +517,19 @@
|
||||||
v-if="isExistsManual"
|
v-if="isExistsManual"
|
||||||
type="text"
|
type="text"
|
||||||
@click="previewManuals"
|
@click="previewManuals"
|
||||||
>{{ $t("trials:reading:button:handbooks") }}</el-button>
|
>{{ $t('trials:reading:button:handbooks') }}</el-button
|
||||||
|
>
|
||||||
<!-- 临床数据 -->
|
<!-- 临床数据 -->
|
||||||
<el-button
|
<el-button
|
||||||
v-if="isExistsClinicalData"
|
v-if="isExistsClinicalData"
|
||||||
type="text"
|
type="text"
|
||||||
@click="previewCD"
|
@click="previewCD"
|
||||||
>{{ $t("trials:reading:button:clinicalData") }}</el-button>
|
>{{ $t('trials:reading:button:clinicalData') }}</el-button
|
||||||
|
>
|
||||||
<!-- <el-button v-if="isExistsNoDicomFile" type="text" @click="previewNoneDicoms">非Dicom文件</el-button> -->
|
<!-- <el-button v-if="isExistsNoDicomFile" type="text" @click="previewNoneDicoms">非Dicom文件</el-button> -->
|
||||||
|
|
||||||
<el-button type="text" @click="previewConfig">{{
|
<el-button type="text" @click="previewConfig">{{
|
||||||
$t("trials:reading:button:customCfg")
|
$t('trials:reading:button:customCfg')
|
||||||
}}</el-button>
|
}}</el-button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -625,7 +629,7 @@
|
||||||
:fullscreen="isFullscreen"
|
:fullscreen="isFullscreen"
|
||||||
>
|
>
|
||||||
<span slot="title" class="dialog-footer">
|
<span slot="title" class="dialog-footer">
|
||||||
<span>{{ $t("trials:reading:button:handbooks") }}</span>
|
<span>{{ $t('trials:reading:button:handbooks') }}</span>
|
||||||
<span style="position: absolute; right: 20px; font-size: 20px">
|
<span style="position: absolute; right: 20px; font-size: 20px">
|
||||||
<svg-icon
|
<svg-icon
|
||||||
:icon-class="isFullscreen ? 'exit-fullscreen' : 'fullscreen'"
|
:icon-class="isFullscreen ? 'exit-fullscreen' : 'fullscreen'"
|
||||||
|
|
@ -646,12 +650,27 @@
|
||||||
<!-- <button :title="$t('trials:dicom-show:Eraser')" class="btn-link" data-tool="Eraser" @click="setToolActive($event,'Eraser')">-->
|
<!-- <button :title="$t('trials:dicom-show:Eraser')" class="btn-link" data-tool="Eraser" @click="setToolActive($event,'Eraser')">-->
|
||||||
<!-- <svg-icon icon-class="clear" style="font-size:20px;" />-->
|
<!-- <svg-icon icon-class="clear" style="font-size:20px;" />-->
|
||||||
<!-- </button>-->
|
<!-- </button>-->
|
||||||
<upload-image
|
<!-- <upload-image
|
||||||
v-if="uploadImageVisible"
|
v-if="uploadImageVisible"
|
||||||
:visible.sync="uploadImageVisible"
|
:visible.sync="uploadImageVisible"
|
||||||
:subject-id="subjectId"
|
:subject-id="subjectId"
|
||||||
:criterion="trialCriterion"
|
:criterion="trialCriterion"
|
||||||
:status="uploadStatus"
|
:status="uploadStatus"
|
||||||
|
/> -->
|
||||||
|
<upload-dicom-and-nonedicom
|
||||||
|
v-if="uploadImageVisible"
|
||||||
|
:SubjectId="uploadSubjectId"
|
||||||
|
:SubjectCode="uploadSubjectCode"
|
||||||
|
:Criterion="uploadTrialCriterion"
|
||||||
|
:visible.sync="uploadImageVisible"
|
||||||
|
/>
|
||||||
|
<download-dicom-and-nonedicom
|
||||||
|
v-if="downloadImageVisible"
|
||||||
|
:SubjectId="uploadSubjectId"
|
||||||
|
:SubjectCode="uploadSubjectCode"
|
||||||
|
:Criterion="uploadTrialCriterion"
|
||||||
|
:TaskId="taskId"
|
||||||
|
:visible.sync="downloadImageVisible"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
@ -676,7 +695,8 @@ import DicomEvent from './../components/DicomEvent'
|
||||||
import { mapGetters } from 'vuex'
|
import { mapGetters } from 'vuex'
|
||||||
import store from '@/store'
|
import store from '@/store'
|
||||||
import { getDoctorShortcutKey, getUserWLTemplateList } from '@/api/user'
|
import { getDoctorShortcutKey, getUserWLTemplateList } from '@/api/user'
|
||||||
import uploadImage from '@/components/uploadImage'
|
import uploadDicomAndNonedicom from '@/components/uploadDicomAndNonedicom'
|
||||||
|
import downloadDicomAndNonedicom from '@/components/downloadDicomAndNonedicom'
|
||||||
import { getCriterionReadingInfo } from '@/api/trials'
|
import { getCriterionReadingInfo } from '@/api/trials'
|
||||||
export default {
|
export default {
|
||||||
name: 'DicomViewer',
|
name: 'DicomViewer',
|
||||||
|
|
@ -688,48 +708,49 @@ export default {
|
||||||
Others,
|
Others,
|
||||||
Manuals,
|
Manuals,
|
||||||
MeasurementList,
|
MeasurementList,
|
||||||
'upload-image': uploadImage
|
'download-dicom-and-nonedicom': downloadDicomAndNonedicom,
|
||||||
|
'upload-dicom-and-nonedicom': uploadDicomAndNonedicom,
|
||||||
},
|
},
|
||||||
props: {
|
props: {
|
||||||
isExistsClinicalData: {
|
isExistsClinicalData: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: false
|
default: false,
|
||||||
},
|
},
|
||||||
isExistsNoDicomFile: {
|
isExistsNoDicomFile: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: false
|
default: false,
|
||||||
},
|
},
|
||||||
isExistsManual: {
|
isExistsManual: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
required: true
|
required: true,
|
||||||
},
|
},
|
||||||
isReadingShowSubjectInfo: {
|
isReadingShowSubjectInfo: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
required: true
|
required: true,
|
||||||
},
|
},
|
||||||
isReadingTaskViewInOrder: {
|
isReadingTaskViewInOrder: {
|
||||||
type: Number,
|
type: Number,
|
||||||
required: true
|
required: true,
|
||||||
},
|
},
|
||||||
IseCRFShowInDicomReading: {
|
IseCRFShowInDicomReading: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
required: true
|
required: true,
|
||||||
},
|
},
|
||||||
subjectId: {
|
subjectId: {
|
||||||
type: String,
|
type: String,
|
||||||
required: true,
|
required: true,
|
||||||
default: ''
|
default: '',
|
||||||
},
|
},
|
||||||
trialReadingCriterionId: {
|
trialReadingCriterionId: {
|
||||||
type: String,
|
type: String,
|
||||||
required: true,
|
required: true,
|
||||||
default: ''
|
default: '',
|
||||||
},
|
},
|
||||||
trialId: {
|
trialId: {
|
||||||
type: String,
|
type: String,
|
||||||
required: true,
|
required: true,
|
||||||
default: ''
|
default: '',
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
|
|
@ -738,7 +759,7 @@ export default {
|
||||||
{ index: 0, row: 1, col: 1, name: 'A' },
|
{ index: 0, row: 1, col: 1, name: 'A' },
|
||||||
{ index: 1, row: 1, col: 2, name: 'A|A' },
|
{ index: 1, row: 1, col: 2, name: 'A|A' },
|
||||||
{ index: 2, row: 1, col: 2, name: 'A|B' },
|
{ index: 2, row: 1, col: 2, name: 'A|B' },
|
||||||
{ index: 3, row: 2, col: 2, name: 'A|A|A|A' }
|
{ index: 3, row: 2, col: 2, name: 'A|A|A|A' },
|
||||||
// { index: 2, row: 2, col: 1 },
|
// { index: 2, row: 2, col: 1 },
|
||||||
// { index: 3, row: 2, col: 2 }
|
// { index: 3, row: 2, col: 2 }
|
||||||
],
|
],
|
||||||
|
|
@ -747,7 +768,7 @@ export default {
|
||||||
{ label: this.$t('trials:reading:button:rotateVertical'), val: 2 }, // 垂直翻转
|
{ label: this.$t('trials:reading:button:rotateVertical'), val: 2 }, // 垂直翻转
|
||||||
{ label: this.$t('trials:reading:button:rotateHorizontal'), val: 3 }, // 水平翻转
|
{ label: this.$t('trials:reading:button:rotateHorizontal'), val: 3 }, // 水平翻转
|
||||||
{ label: this.$t('trials:reading:button:rotateTurnLeft'), val: 4 }, // 左转90度
|
{ label: this.$t('trials:reading:button:rotateTurnLeft'), val: 4 }, // 左转90度
|
||||||
{ label: this.$t('trials:reading:button:rotateTurnRight'), val: 5 } // 右转90度
|
{ label: this.$t('trials:reading:button:rotateTurnRight'), val: 5 }, // 右转90度
|
||||||
],
|
],
|
||||||
maxCanvas: 1,
|
maxCanvas: 1,
|
||||||
layoutRow: 1,
|
layoutRow: 1,
|
||||||
|
|
@ -755,8 +776,8 @@ export default {
|
||||||
currentDicomCanvasIndex: 0,
|
currentDicomCanvasIndex: 0,
|
||||||
currentDicomCanvas: {
|
currentDicomCanvas: {
|
||||||
toolState: {
|
toolState: {
|
||||||
clipPlaying: false
|
clipPlaying: false,
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
colormapsList: [],
|
colormapsList: [],
|
||||||
rotateList: [],
|
rotateList: [],
|
||||||
|
|
@ -773,7 +794,7 @@ export default {
|
||||||
text: this.$t('trials:reading:button:length'),
|
text: this.$t('trials:reading:button:length'),
|
||||||
icon: 'length',
|
icon: 'length',
|
||||||
isDisabled: false,
|
isDisabled: false,
|
||||||
disabledReason: ''
|
disabledReason: '',
|
||||||
},
|
},
|
||||||
// 长短径测量
|
// 长短径测量
|
||||||
{
|
{
|
||||||
|
|
@ -781,7 +802,7 @@ export default {
|
||||||
text: this.$t('trials:reading:button:bidirectional'),
|
text: this.$t('trials:reading:button:bidirectional'),
|
||||||
icon: 'bidirection',
|
icon: 'bidirection',
|
||||||
isDisabled: false,
|
isDisabled: false,
|
||||||
disabledReason: ''
|
disabledReason: '',
|
||||||
},
|
},
|
||||||
// 矩形工具
|
// 矩形工具
|
||||||
{
|
{
|
||||||
|
|
@ -789,7 +810,7 @@ export default {
|
||||||
text: this.$t('trials:reading:button:rectangle'),
|
text: this.$t('trials:reading:button:rectangle'),
|
||||||
icon: 'rectangle',
|
icon: 'rectangle',
|
||||||
isDisabled: false,
|
isDisabled: false,
|
||||||
disabledReason: ''
|
disabledReason: '',
|
||||||
},
|
},
|
||||||
// 圆形工具
|
// 圆形工具
|
||||||
{
|
{
|
||||||
|
|
@ -797,7 +818,7 @@ export default {
|
||||||
text: this.$t('trials:reading:button:elliptical'),
|
text: this.$t('trials:reading:button:elliptical'),
|
||||||
icon: 'oval',
|
icon: 'oval',
|
||||||
isDisabled: false,
|
isDisabled: false,
|
||||||
disabledReason: ''
|
disabledReason: '',
|
||||||
},
|
},
|
||||||
// 箭头工具
|
// 箭头工具
|
||||||
{
|
{
|
||||||
|
|
@ -805,8 +826,8 @@ export default {
|
||||||
text: this.$t('trials:reading:button:arrowAnnotate'),
|
text: this.$t('trials:reading:button:arrowAnnotate'),
|
||||||
icon: 'arrow',
|
icon: 'arrow',
|
||||||
isDisabled: false,
|
isDisabled: false,
|
||||||
disabledReason: ''
|
disabledReason: '',
|
||||||
}
|
},
|
||||||
],
|
],
|
||||||
|
|
||||||
fitType: 0,
|
fitType: 0,
|
||||||
|
|
@ -818,25 +839,25 @@ export default {
|
||||||
label: this.$t('trials:reading:button:wwwcDefault'),
|
label: this.$t('trials:reading:button:wwwcDefault'),
|
||||||
val: -1,
|
val: -1,
|
||||||
ww: null,
|
ww: null,
|
||||||
wc: null
|
wc: null,
|
||||||
}, // 默认值
|
}, // 默认值
|
||||||
{
|
{
|
||||||
label: this.$t('trials:reading:button:wwwcCustom'),
|
label: this.$t('trials:reading:button:wwwcCustom'),
|
||||||
val: 0,
|
val: 0,
|
||||||
ww: null,
|
ww: null,
|
||||||
wc: null
|
wc: null,
|
||||||
}, // 自定义
|
}, // 自定义
|
||||||
{
|
{
|
||||||
label: this.$t('trials:reading:button:wwwcRegion'),
|
label: this.$t('trials:reading:button:wwwcRegion'),
|
||||||
val: 1,
|
val: 1,
|
||||||
ww: null,
|
ww: null,
|
||||||
wc: null
|
wc: null,
|
||||||
}, // 区域窗宽
|
}, // 区域窗宽
|
||||||
{ label: 'CT Brain', wc: 40, ww: 80 },
|
{ label: 'CT Brain', wc: 40, ww: 80 },
|
||||||
{ label: 'CT Lungs', wc: -400, ww: 1500 },
|
{ label: 'CT Lungs', wc: -400, ww: 1500 },
|
||||||
{ label: 'CT Abdomen', wc: 60, ww: 400 },
|
{ label: 'CT Abdomen', wc: 60, ww: 400 },
|
||||||
{ label: 'CT Liver', wc: 40, ww: 400 },
|
{ label: 'CT Liver', wc: 40, ww: 400 },
|
||||||
{ label: 'CT Bone', wc: 300, ww: 1500 }
|
{ label: 'CT Bone', wc: 300, ww: 1500 },
|
||||||
],
|
],
|
||||||
activeSeries: {},
|
activeSeries: {},
|
||||||
seriesStack: [],
|
seriesStack: [],
|
||||||
|
|
@ -844,13 +865,13 @@ export default {
|
||||||
isScrollSync: false,
|
isScrollSync: false,
|
||||||
imageIndexSync: {
|
imageIndexSync: {
|
||||||
sourceCanvas: '',
|
sourceCanvas: '',
|
||||||
targetCanvas: []
|
targetCanvas: [],
|
||||||
},
|
},
|
||||||
isFirstRender: false,
|
isFirstRender: false,
|
||||||
customWwc: { visible: false, title: null }, // 自定义调窗
|
customWwc: { visible: false, title: null }, // 自定义调窗
|
||||||
personalConfigDialog: {
|
personalConfigDialog: {
|
||||||
visible: false,
|
visible: false,
|
||||||
title: this.$t('trials:reading:button:customCfg')
|
title: this.$t('trials:reading:button:customCfg'),
|
||||||
}, // 个性化配置
|
}, // 个性化配置
|
||||||
layout: '',
|
layout: '',
|
||||||
isFirstNotLinked: false,
|
isFirstNotLinked: false,
|
||||||
|
|
@ -861,15 +882,20 @@ export default {
|
||||||
manualsDialog: { visible: false },
|
manualsDialog: { visible: false },
|
||||||
clipPlaying: false,
|
clipPlaying: false,
|
||||||
fps: 15,
|
fps: 15,
|
||||||
// 上传
|
|
||||||
uploadImageVisible: false,
|
|
||||||
trialCriterion: {},
|
trialCriterion: {},
|
||||||
uploadStatus: 'upload'
|
// 上传
|
||||||
|
downloadImageVisible: false,
|
||||||
|
uploadImageVisible: false,
|
||||||
|
uploadSubjectId: null,
|
||||||
|
uploadSubjectCode: null,
|
||||||
|
uploadTrialCriterion: {},
|
||||||
|
uploadStatus: 'upload',
|
||||||
|
taskId: ''
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
computed: {
|
computed: {
|
||||||
...mapGetters(['visitTaskList', 'currentReadingTaskState'])
|
...mapGetters(['visitTaskList', 'currentReadingTaskState']),
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
currentReadingTaskState: {
|
currentReadingTaskState: {
|
||||||
|
|
@ -888,7 +914,7 @@ export default {
|
||||||
this.activeTool = ''
|
this.activeTool = ''
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
currentDicomCanvasIndex: {
|
currentDicomCanvasIndex: {
|
||||||
immediate: true,
|
immediate: true,
|
||||||
|
|
@ -905,8 +931,8 @@ export default {
|
||||||
this.clipPlaying = false
|
this.clipPlaying = false
|
||||||
this.fps = 15
|
this.fps = 15
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
this.getTrialCriterion()
|
this.getTrialCriterion()
|
||||||
|
|
@ -919,7 +945,7 @@ export default {
|
||||||
// cornerstone.imageCache.setMaximumSizeBytes(maximumSizeInBytes)
|
// cornerstone.imageCache.setMaximumSizeBytes(maximumSizeInBytes)
|
||||||
this.customWwc = {
|
this.customWwc = {
|
||||||
visible: false,
|
visible: false,
|
||||||
title: this.$t('trials:reading:dagTitle:wwwcCustom')
|
title: this.$t('trials:reading:dagTitle:wwwcCustom'),
|
||||||
}
|
}
|
||||||
this.CriterionType = parseInt(localStorage.getItem('CriterionType'))
|
this.CriterionType = parseInt(localStorage.getItem('CriterionType'))
|
||||||
if (this.CriterionType === 10) {
|
if (this.CriterionType === 10) {
|
||||||
|
|
@ -929,15 +955,15 @@ export default {
|
||||||
text: this.$t('trials:reading:button:arrowAnnotate'),
|
text: this.$t('trials:reading:button:arrowAnnotate'),
|
||||||
icon: 'arrow',
|
icon: 'arrow',
|
||||||
isDisabled: false,
|
isDisabled: false,
|
||||||
disabledReason: ''
|
disabledReason: '',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
toolName: 'RectangleRoi',
|
toolName: 'RectangleRoi',
|
||||||
text: this.$t('trials:reading:button:rectangle'),
|
text: this.$t('trials:reading:button:rectangle'),
|
||||||
icon: 'rectangle',
|
icon: 'rectangle',
|
||||||
isDisabled: false,
|
isDisabled: false,
|
||||||
disabledReason: ''
|
disabledReason: '',
|
||||||
}
|
},
|
||||||
]
|
]
|
||||||
} else if (this.CriterionType === 17) {
|
} else if (this.CriterionType === 17) {
|
||||||
this.measuredTools = [
|
this.measuredTools = [
|
||||||
|
|
@ -946,22 +972,22 @@ export default {
|
||||||
text: this.$t('trials:reading:button:length'),
|
text: this.$t('trials:reading:button:length'),
|
||||||
icon: 'length',
|
icon: 'length',
|
||||||
isDisabled: false,
|
isDisabled: false,
|
||||||
disabledReason: ''
|
disabledReason: '',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
toolName: 'RectangleRoi',
|
toolName: 'RectangleRoi',
|
||||||
text: this.$t('trials:reading:button:rectangle'),
|
text: this.$t('trials:reading:button:rectangle'),
|
||||||
icon: 'rectangle',
|
icon: 'rectangle',
|
||||||
isDisabled: false,
|
isDisabled: false,
|
||||||
disabledReason: ''
|
disabledReason: '',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
toolName: 'ArrowAnnotate',
|
toolName: 'ArrowAnnotate',
|
||||||
text: this.$t('trials:reading:button:arrowAnnotate'),
|
text: this.$t('trials:reading:button:arrowAnnotate'),
|
||||||
icon: 'arrow',
|
icon: 'arrow',
|
||||||
isDisabled: false,
|
isDisabled: false,
|
||||||
disabledReason: ''
|
disabledReason: '',
|
||||||
}
|
},
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
this.rotateList[0] = '1'
|
this.rotateList[0] = '1'
|
||||||
|
|
@ -1041,7 +1067,7 @@ export default {
|
||||||
getTrialCriterion() {
|
getTrialCriterion() {
|
||||||
getCriterionReadingInfo({
|
getCriterionReadingInfo({
|
||||||
TrialId: this.trialId,
|
TrialId: this.trialId,
|
||||||
TrialReadingCriterionId: this.trialReadingCriterionId
|
TrialReadingCriterionId: this.trialReadingCriterionId,
|
||||||
})
|
})
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
this.trialCriterion = res.Result
|
this.trialCriterion = res.Result
|
||||||
|
|
@ -1049,8 +1075,15 @@ export default {
|
||||||
.catch(() => {})
|
.catch(() => {})
|
||||||
},
|
},
|
||||||
openUploadImage(status) {
|
openUploadImage(status) {
|
||||||
|
const idx = this.visitTaskList.findIndex(i => i.IsCurrentTask)
|
||||||
|
if (idx > -1) {
|
||||||
|
this.taskId = this.visitTaskList[idx].VisitTaskId
|
||||||
|
}
|
||||||
|
this.uploadSubjectCode = this.$route.query.subjectCode
|
||||||
|
this.uploadSubjectId = this.$route.query.subjectId
|
||||||
|
this.uploadTrialCriterion = this.trialCriterion
|
||||||
this.uploadStatus = status
|
this.uploadStatus = status
|
||||||
this.uploadImageVisible = true
|
this[`${status}ImageVisible`] = true
|
||||||
},
|
},
|
||||||
async getWwcTpl() {
|
async getWwcTpl() {
|
||||||
// const loading = this.$loading({ fullscreen: true })
|
// const loading = this.$loading({ fullscreen: true })
|
||||||
|
|
@ -1061,14 +1094,13 @@ export default {
|
||||||
this.customWwcTpl.push({
|
this.customWwcTpl.push({
|
||||||
label: i.TemplateName,
|
label: i.TemplateName,
|
||||||
wc: i.WL,
|
wc: i.WL,
|
||||||
ww: i.WW
|
ww: i.WW,
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
this.wwwcArr = [...this.defaultWwwc, ...this.customWwcTpl]
|
this.wwwcArr = [...this.defaultWwwc, ...this.customWwcTpl]
|
||||||
} catch(e) {
|
} catch (e) {
|
||||||
console.log(e)
|
console.log(e)
|
||||||
}
|
}
|
||||||
|
|
||||||
},
|
},
|
||||||
async getHotKeys() {
|
async getHotKeys() {
|
||||||
// const loading = this.$loading({ fullscreen: true })
|
// const loading = this.$loading({ fullscreen: true })
|
||||||
|
|
@ -1084,11 +1116,11 @@ export default {
|
||||||
key: item.Keyboardkey,
|
key: item.Keyboardkey,
|
||||||
code: item.Code,
|
code: item.Code,
|
||||||
text: item.Text,
|
text: item.Text,
|
||||||
shortcutKeyEnum: item.ShortcutKeyEnum
|
shortcutKeyEnum: item.ShortcutKeyEnum,
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
this.bindHotKey()
|
this.bindHotKey()
|
||||||
} catch(e) {
|
} catch (e) {
|
||||||
console.log(e)
|
console.log(e)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
@ -1105,7 +1137,7 @@ export default {
|
||||||
key: item.keys.controlKey.key,
|
key: item.keys.controlKey.key,
|
||||||
code: item.keys.controlKey.code,
|
code: item.keys.controlKey.code,
|
||||||
text: item.keys.text,
|
text: item.keys.text,
|
||||||
shortcutKeyEnum: item.label
|
shortcutKeyEnum: item.label,
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
@ -1148,7 +1180,7 @@ export default {
|
||||||
DicomEvent.$emit('selectSeries', {
|
DicomEvent.$emit('selectSeries', {
|
||||||
seriesId: series.seriesId,
|
seriesId: series.seriesId,
|
||||||
studyId: series.studyId,
|
studyId: series.studyId,
|
||||||
offset: -1
|
offset: -1,
|
||||||
})
|
})
|
||||||
} else if (shortcutKeyEnum === 4) {
|
} else if (shortcutKeyEnum === 4) {
|
||||||
// 下一个序列
|
// 下一个序列
|
||||||
|
|
@ -1157,7 +1189,7 @@ export default {
|
||||||
DicomEvent.$emit('selectSeries', {
|
DicomEvent.$emit('selectSeries', {
|
||||||
seriesId: series.seriesId,
|
seriesId: series.seriesId,
|
||||||
studyId: series.studyId,
|
studyId: series.studyId,
|
||||||
offset: 1
|
offset: 1,
|
||||||
})
|
})
|
||||||
} else if (shortcutKeyEnum === 5) {
|
} else if (shortcutKeyEnum === 5) {
|
||||||
// 上一张图像
|
// 上一张图像
|
||||||
|
|
@ -1287,7 +1319,7 @@ export default {
|
||||||
top: '72px',
|
top: '72px',
|
||||||
left: '205px',
|
left: '205px',
|
||||||
right: '350px',
|
right: '350px',
|
||||||
zIndex: 10
|
zIndex: 10,
|
||||||
}
|
}
|
||||||
this.canvasW = window.innerWidth - 570 + 'px'
|
this.canvasW = window.innerWidth - 570 + 'px'
|
||||||
this.canvasH = window.innerHeight - 130 + 'px'
|
this.canvasH = window.innerHeight - 130 + 'px'
|
||||||
|
|
@ -1387,10 +1419,7 @@ export default {
|
||||||
// this.$refs['measurementList'].initPage(dicomSeries)
|
// this.$refs['measurementList'].initPage(dicomSeries)
|
||||||
store.dispatch('reading/setActiveSeries', dicomSeries)
|
store.dispatch('reading/setActiveSeries', dicomSeries)
|
||||||
if (this.currentDicomCanvasIndex === this.maxCanvas - 1) {
|
if (this.currentDicomCanvasIndex === this.maxCanvas - 1) {
|
||||||
store.dispatch(
|
store.dispatch('reading/setLastCanvasTaskId', dicomSeries.visitTaskId)
|
||||||
'reading/setLastCanvasTaskId',
|
|
||||||
dicomSeries.visitTaskId
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
@ -1421,10 +1450,7 @@ export default {
|
||||||
|
|
||||||
store.dispatch('reading/setActiveSeries', dicomSeries)
|
store.dispatch('reading/setActiveSeries', dicomSeries)
|
||||||
if (this.currentDicomCanvasIndex === this.maxCanvas - 1) {
|
if (this.currentDicomCanvasIndex === this.maxCanvas - 1) {
|
||||||
store.dispatch(
|
store.dispatch('reading/setLastCanvasTaskId', dicomSeries.visitTaskId)
|
||||||
'reading/setLastCanvasTaskId',
|
|
||||||
dicomSeries.visitTaskId
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
@ -1474,7 +1500,7 @@ export default {
|
||||||
visitTaskId = this.visitTaskList[i].VisitTaskId
|
visitTaskId = this.visitTaskList[i].VisitTaskId
|
||||||
}
|
}
|
||||||
this.getFirstSeries(activeSeries, visitTaskId).then(
|
this.getFirstSeries(activeSeries, visitTaskId).then(
|
||||||
async(baseSerires) => {
|
async (baseSerires) => {
|
||||||
this.seriesStack = [baseSerires, activeSeries]
|
this.seriesStack = [baseSerires, activeSeries]
|
||||||
this.currentDicomCanvasIndex = 1
|
this.currentDicomCanvasIndex = 1
|
||||||
store.dispatch(
|
store.dispatch(
|
||||||
|
|
@ -1502,7 +1528,7 @@ export default {
|
||||||
activeSeries,
|
activeSeries,
|
||||||
activeSeries,
|
activeSeries,
|
||||||
activeSeries,
|
activeSeries,
|
||||||
activeSeries
|
activeSeries,
|
||||||
]
|
]
|
||||||
this.currentDicomCanvasIndex = 3
|
this.currentDicomCanvasIndex = 3
|
||||||
store.dispatch(
|
store.dispatch(
|
||||||
|
|
@ -1521,9 +1547,7 @@ export default {
|
||||||
for (let i = 0; i < this.maxCanvas && i < seriesStack.length; i++) {
|
for (let i = 0; i < this.maxCanvas && i < seriesStack.length; i++) {
|
||||||
this.canvasObj[i] = seriesStack[i]
|
this.canvasObj[i] = seriesStack[i]
|
||||||
let s = Object.assign({}, seriesStack[i])
|
let s = Object.assign({}, seriesStack[i])
|
||||||
promiseArr.push(
|
promiseArr.push(this.$refs[`dicomCanvas${i}`][0].loadImageStack(s))
|
||||||
this.$refs[`dicomCanvas${i}`][0].loadImageStack(s)
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
Promise.all(promiseArr)
|
Promise.all(promiseArr)
|
||||||
.then(() => {
|
.then(() => {
|
||||||
|
|
@ -1585,24 +1609,24 @@ export default {
|
||||||
trialId: this.trialId,
|
trialId: this.trialId,
|
||||||
subjectVisitId: this.visitTaskList[taskIdx].VisitId,
|
subjectVisitId: this.visitTaskList[taskIdx].VisitId,
|
||||||
visitTaskId: this.visitTaskList[taskIdx].VisitTaskId,
|
visitTaskId: this.visitTaskList[taskIdx].VisitTaskId,
|
||||||
taskBlindName: this.visitTaskList[taskIdx].TaskBlindName
|
taskBlindName: this.visitTaskList[taskIdx].TaskBlindName,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
if (!this.visitTaskList[taskIdx].readingQuestionsInit) {
|
if (!this.visitTaskList[taskIdx].readingQuestionsInit) {
|
||||||
await store.dispatch('reading/getReadingQuestionAndAnswer', {
|
await store.dispatch('reading/getReadingQuestionAndAnswer', {
|
||||||
trialId: this.trialId,
|
trialId: this.trialId,
|
||||||
visitTaskId: this.visitTaskList[taskIdx].VisitTaskId
|
visitTaskId: this.visitTaskList[taskIdx].VisitTaskId,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
if (!this.visitTaskList[taskIdx].questionsInit) {
|
if (!this.visitTaskList[taskIdx].questionsInit) {
|
||||||
await store.dispatch('reading/getDicomReadingQuestionAnswer', {
|
await store.dispatch('reading/getDicomReadingQuestionAnswer', {
|
||||||
trialId: this.trialId,
|
trialId: this.trialId,
|
||||||
visitTaskId: this.visitTaskList[taskIdx].VisitTaskId
|
visitTaskId: this.visitTaskList[taskIdx].VisitTaskId,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
await store.dispatch('reading/setStatus', {
|
await store.dispatch('reading/setStatus', {
|
||||||
visitTaskId: this.visitTaskList[taskIdx].VisitTaskId
|
visitTaskId: this.visitTaskList[taskIdx].VisitTaskId,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
firstAddSeries = this.getSeriesInfoByMark(firstAddVisitTaskId, obj)
|
firstAddSeries = this.getSeriesInfoByMark(firstAddVisitTaskId, obj)
|
||||||
|
|
@ -1696,8 +1720,7 @@ export default {
|
||||||
var studyList = this.visitTaskList[index].StudyList
|
var studyList = this.visitTaskList[index].StudyList
|
||||||
var studyId = this.visitTaskList[index].MeasureData[idx].StudyId
|
var studyId = this.visitTaskList[index].MeasureData[idx].StudyId
|
||||||
var seriesId = this.visitTaskList[index].MeasureData[idx].SeriesId
|
var seriesId = this.visitTaskList[index].MeasureData[idx].SeriesId
|
||||||
var instanceId =
|
var instanceId = this.visitTaskList[index].MeasureData[idx].InstanceId
|
||||||
this.visitTaskList[index].MeasureData[idx].InstanceId
|
|
||||||
var studyIdx = studyList.findIndex(
|
var studyIdx = studyList.findIndex(
|
||||||
(study) => study.StudyId === studyId
|
(study) => study.StudyId === studyId
|
||||||
)
|
)
|
||||||
|
|
@ -1706,10 +1729,15 @@ export default {
|
||||||
(s) => s.seriesId === seriesId
|
(s) => s.seriesId === seriesId
|
||||||
)
|
)
|
||||||
if (seriesIdx > -1) {
|
if (seriesIdx > -1) {
|
||||||
var series = studyList[studyIdx].SeriesList[seriesIdx];
|
var series = studyList[studyIdx].SeriesList[seriesIdx]
|
||||||
let frame = this.visitTaskList[index].MeasureData[idx].MeasureData.frame
|
let frame =
|
||||||
let filterStr = series.isExistMutiFrames ? `frame=${frame}&instanceId=${instanceId}` : `instanceId=${instanceId}`
|
this.visitTaskList[index].MeasureData[idx].MeasureData.frame
|
||||||
var instanceIdx = series.imageIds.findIndex(imageId => imageId.includes(filterStr))
|
let filterStr = series.isExistMutiFrames
|
||||||
|
? `frame=${frame}&instanceId=${instanceId}`
|
||||||
|
: `instanceId=${instanceId}`
|
||||||
|
var instanceIdx = series.imageIds.findIndex((imageId) =>
|
||||||
|
imageId.includes(filterStr)
|
||||||
|
)
|
||||||
// var instanceIdx = series.instanceList.findIndex(
|
// var instanceIdx = series.instanceList.findIndex(
|
||||||
// (imageId) => !!~imageId.indexOf(instanceId)
|
// (imageId) => !!~imageId.indexOf(instanceId)
|
||||||
// );
|
// );
|
||||||
|
|
@ -1738,16 +1766,14 @@ export default {
|
||||||
i.description,
|
i.description,
|
||||||
baseSeries.description
|
baseSeries.description
|
||||||
),
|
),
|
||||||
index
|
index,
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
similarArr = similarArr.sort((a, b) => {
|
similarArr = similarArr.sort((a, b) => {
|
||||||
return b.similar - a.similar
|
return b.similar - a.similar
|
||||||
})
|
})
|
||||||
const i =
|
const i =
|
||||||
similarArr[0] && similarArr[0].similar > 0.85
|
similarArr[0] && similarArr[0].similar > 0.85 ? similarArr[0].index : -1
|
||||||
? similarArr[0].index
|
|
||||||
: -1
|
|
||||||
if (i > -1) {
|
if (i > -1) {
|
||||||
obj = seriesList[i]
|
obj = seriesList[i]
|
||||||
}
|
}
|
||||||
|
|
@ -1822,7 +1848,7 @@ export default {
|
||||||
trialId: this.trialId,
|
trialId: this.trialId,
|
||||||
subjectVisitId: this.visitTaskList[index].VisitId,
|
subjectVisitId: this.visitTaskList[index].VisitId,
|
||||||
visitTaskId: this.visitTaskList[index].VisitTaskId,
|
visitTaskId: this.visitTaskList[index].VisitTaskId,
|
||||||
taskBlindName: this.visitTaskList[index].TaskBlindName
|
taskBlindName: this.visitTaskList[index].TaskBlindName,
|
||||||
})
|
})
|
||||||
|
|
||||||
await store.dispatch(
|
await store.dispatch(
|
||||||
|
|
@ -1841,16 +1867,14 @@ export default {
|
||||||
i.description,
|
i.description,
|
||||||
baseSeries.description
|
baseSeries.description
|
||||||
),
|
),
|
||||||
index
|
index,
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
similarArr = similarArr.sort((a, b) => {
|
similarArr = similarArr.sort((a, b) => {
|
||||||
return b.similar - a.similar
|
return b.similar - a.similar
|
||||||
})
|
})
|
||||||
const i =
|
const i =
|
||||||
similarArr[0] && similarArr[0].similar > 0.85
|
similarArr[0] && similarArr[0].similar > 0.85 ? similarArr[0].index : -1
|
||||||
? similarArr[0].index
|
|
||||||
: -1
|
|
||||||
if (i > -1) {
|
if (i > -1) {
|
||||||
obj = seriesList[i]
|
obj = seriesList[i]
|
||||||
}
|
}
|
||||||
|
|
@ -2025,9 +2049,7 @@ export default {
|
||||||
},
|
},
|
||||||
// 鼠标移入测量工具时,判断工具是否可激活
|
// 鼠标移入测量工具时,判断工具是否可激活
|
||||||
enter(e, toolName) {
|
enter(e, toolName) {
|
||||||
var i = this.measuredTools.findIndex(
|
var i = this.measuredTools.findIndex((item) => item.toolName === toolName)
|
||||||
(item) => item.toolName === toolName
|
|
||||||
)
|
|
||||||
if (i === -1) return
|
if (i === -1) return
|
||||||
var isCurrentTask =
|
var isCurrentTask =
|
||||||
this.$refs[`dicomCanvas${this.currentDicomCanvasIndex}`][0]
|
this.$refs[`dicomCanvas${this.currentDicomCanvasIndex}`][0]
|
||||||
|
|
@ -2089,8 +2111,11 @@ export default {
|
||||||
`dicomCanvas${this.currentDicomCanvasIndex}`
|
`dicomCanvas${this.currentDicomCanvasIndex}`
|
||||||
][0].setToolActive(toolName)
|
][0].setToolActive(toolName)
|
||||||
}
|
}
|
||||||
} else if (dicomSeries.isCurrentTask &&
|
} else if (
|
||||||
isMeasuredTool && dicomSeries.readingTaskState >= 2) {
|
dicomSeries.isCurrentTask &&
|
||||||
|
isMeasuredTool &&
|
||||||
|
dicomSeries.readingTaskState >= 2
|
||||||
|
) {
|
||||||
if (this.activeTool === toolName) {
|
if (this.activeTool === toolName) {
|
||||||
this.$refs[
|
this.$refs[
|
||||||
`dicomCanvas${this.currentDicomCanvasIndex}`
|
`dicomCanvas${this.currentDicomCanvasIndex}`
|
||||||
|
|
@ -2162,9 +2187,7 @@ export default {
|
||||||
][0].fitToWindow()
|
][0].fitToWindow()
|
||||||
} else if (toolName === 'fitToImage') {
|
} else if (toolName === 'fitToImage') {
|
||||||
this.fitType = 1
|
this.fitType = 1
|
||||||
this.$refs[
|
this.$refs[`dicomCanvas${this.currentDicomCanvasIndex}`][0].fitToImage()
|
||||||
`dicomCanvas${this.currentDicomCanvasIndex}`
|
|
||||||
][0].fitToImage()
|
|
||||||
}
|
}
|
||||||
this.activeTool = toolName
|
this.activeTool = toolName
|
||||||
},
|
},
|
||||||
|
|
@ -2181,7 +2204,9 @@ export default {
|
||||||
const isLoaded = this.getSeriesLoadStatus()
|
const isLoaded = this.getSeriesLoadStatus()
|
||||||
if (!isLoaded) return
|
if (!isLoaded) return
|
||||||
this.clipPlaying = isPlay
|
this.clipPlaying = isPlay
|
||||||
this.$refs[`dicomCanvas${this.currentDicomCanvasIndex}`][0].setFps(this.fps)
|
this.$refs[`dicomCanvas${this.currentDicomCanvasIndex}`][0].setFps(
|
||||||
|
this.fps
|
||||||
|
)
|
||||||
this.$refs[
|
this.$refs[
|
||||||
`dicomCanvas${this.currentDicomCanvasIndex}`
|
`dicomCanvas${this.currentDicomCanvasIndex}`
|
||||||
][0].toggleClipPlay(isPlay)
|
][0].toggleClipPlay(isPlay)
|
||||||
|
|
@ -2297,8 +2322,8 @@ export default {
|
||||||
previewManuals() {
|
previewManuals() {
|
||||||
this.isFullscreen = false
|
this.isFullscreen = false
|
||||||
this.manualsDialog.visible = true
|
this.manualsDialog.visible = true
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
|
|
|
||||||
|
|
@ -244,6 +244,7 @@ export default {
|
||||||
params.StudyId = params.questionInfo.StudyId
|
params.StudyId = params.questionInfo.StudyId
|
||||||
params.SeriesId = params.questionInfo.SeriesId
|
params.SeriesId = params.questionInfo.SeriesId
|
||||||
params.InstanceId = params.questionInfo.InstanceId
|
params.InstanceId = params.questionInfo.InstanceId
|
||||||
|
params.NumberOfFrames = measureData.frame
|
||||||
submitCustomTag(params).then(() => {
|
submitCustomTag(params).then(() => {
|
||||||
this.measuredDataVisible = false
|
this.measuredDataVisible = false
|
||||||
DicomEvent.$emit('updateImage')
|
DicomEvent.$emit('updateImage')
|
||||||
|
|
@ -282,6 +283,7 @@ export default {
|
||||||
} else {
|
} else {
|
||||||
let params = JSON.parse(JSON.stringify(this.measureData))
|
let params = JSON.parse(JSON.stringify(this.measureData))
|
||||||
params.measureData = JSON.stringify(this.measureData)
|
params.measureData = JSON.stringify(this.measureData)
|
||||||
|
params.NumberOfFrames = this.measureData.frame
|
||||||
submitCustomTag(params).then(async (res) => {
|
submitCustomTag(params).then(async (res) => {
|
||||||
this.measuredDataVisible = false
|
this.measuredDataVisible = false
|
||||||
this.form.measuredDataName = ''
|
this.form.measuredDataName = ''
|
||||||
|
|
|
||||||
|
|
@ -239,7 +239,7 @@
|
||||||
<!-- </span>-->
|
<!-- </span>-->
|
||||||
<!-- </div>-->
|
<!-- </div>-->
|
||||||
</el-upload>
|
</el-upload>
|
||||||
<el-dialog
|
<!-- <el-dialog
|
||||||
v-if="question.Type==='upload'"
|
v-if="question.Type==='upload'"
|
||||||
append-to-body
|
append-to-body
|
||||||
:visible.sync="imgVisible"
|
:visible.sync="imgVisible"
|
||||||
|
|
@ -250,7 +250,20 @@
|
||||||
加载中<span class="dot">...</span>
|
加载中<span class="dot">...</span>
|
||||||
</div>
|
</div>
|
||||||
</el-image>
|
</el-image>
|
||||||
</el-dialog>
|
</el-dialog> -->
|
||||||
|
<viewer
|
||||||
|
v-if="question.Type==='upload' && imgVisible"
|
||||||
|
:ref="imageUrl"
|
||||||
|
style="margin:0 10px;"
|
||||||
|
:images="[imageUrl]"
|
||||||
|
>
|
||||||
|
<img
|
||||||
|
v-show="false"
|
||||||
|
crossorigin="anonymous"
|
||||||
|
:src="imageUrl"
|
||||||
|
alt="Image"
|
||||||
|
>
|
||||||
|
</viewer>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|
@ -801,6 +814,9 @@ export default {
|
||||||
}else{
|
}else{
|
||||||
this.imageUrl = this.OSSclientConfig.basePath + file.url
|
this.imageUrl = this.OSSclientConfig.basePath + file.url
|
||||||
this.imgVisible = true
|
this.imgVisible = true
|
||||||
|
this.$nextTick(()=>{
|
||||||
|
this.$refs[this.imageUrl].$viewer.show()
|
||||||
|
})
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
// 删除图片
|
// 删除图片
|
||||||
|
|
|
||||||
|
|
@ -138,11 +138,24 @@
|
||||||
>
|
>
|
||||||
<i slot="default" class="el-icon-plus" />
|
<i slot="default" class="el-icon-plus" />
|
||||||
<div slot="file" slot-scope="{file}">
|
<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
|
<img
|
||||||
class="el-upload-list__item-thumbnail"
|
class="el-upload-list__item-thumbnail"
|
||||||
:src="OSSclientConfig.basePath + file.url"
|
:src="OSSclientConfig.basePath + file.url"
|
||||||
|
crossOrigin="anonymous"
|
||||||
alt=""
|
alt=""
|
||||||
>
|
style="max-width: 100%; max-height: 100%"
|
||||||
|
/>
|
||||||
<span class="el-upload-list__item-actions">
|
<span class="el-upload-list__item-actions">
|
||||||
<span
|
<span
|
||||||
class="el-upload-list__item-preview"
|
class="el-upload-list__item-preview"
|
||||||
|
|
@ -159,6 +172,7 @@
|
||||||
<i class="el-icon-delete" />
|
<i class="el-icon-delete" />
|
||||||
</span>
|
</span>
|
||||||
</span>
|
</span>
|
||||||
|
</viewer>
|
||||||
</div>
|
</div>
|
||||||
</el-upload>
|
</el-upload>
|
||||||
<el-dialog
|
<el-dialog
|
||||||
|
|
@ -308,7 +322,7 @@ export default {
|
||||||
window.open(this.OSSclientConfig.basePath + file.url,'_blank')
|
window.open(this.OSSclientConfig.basePath + file.url,'_blank')
|
||||||
}else{
|
}else{
|
||||||
this.imageUrl = this.OSSclientConfig.basePath + file.url
|
this.imageUrl = this.OSSclientConfig.basePath + file.url
|
||||||
this.imgVisible = true
|
this.$refs[file.url].$viewer.show();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
// 删除图片
|
// 删除图片
|
||||||
|
|
|
||||||
|
|
@ -148,11 +148,24 @@
|
||||||
>
|
>
|
||||||
<i slot="default" class="el-icon-plus" />
|
<i slot="default" class="el-icon-plus" />
|
||||||
<div slot="file" slot-scope="{file}">
|
<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
|
<img
|
||||||
class="el-upload-list__item-thumbnail"
|
class="el-upload-list__item-thumbnail"
|
||||||
:src="OSSclientConfig.basePath + file.url"
|
:src="OSSclientConfig.basePath + file.url"
|
||||||
|
crossOrigin="anonymous"
|
||||||
alt=""
|
alt=""
|
||||||
>
|
style="max-width: 100%; max-height: 100%"
|
||||||
|
/>
|
||||||
<span class="el-upload-list__item-actions">
|
<span class="el-upload-list__item-actions">
|
||||||
<span
|
<span
|
||||||
class="el-upload-list__item-preview"
|
class="el-upload-list__item-preview"
|
||||||
|
|
@ -169,6 +182,7 @@
|
||||||
<i class="el-icon-delete" />
|
<i class="el-icon-delete" />
|
||||||
</span>
|
</span>
|
||||||
</span>
|
</span>
|
||||||
|
</viewer>
|
||||||
</div>
|
</div>
|
||||||
</el-upload>
|
</el-upload>
|
||||||
<el-dialog
|
<el-dialog
|
||||||
|
|
@ -492,7 +506,8 @@ export default {
|
||||||
window.open(this.OSSclientConfig.basePath + file.url,'_blank')
|
window.open(this.OSSclientConfig.basePath + file.url,'_blank')
|
||||||
}else{
|
}else{
|
||||||
this.imageUrl = this.OSSclientConfig.basePath + file.url
|
this.imageUrl = this.OSSclientConfig.basePath + file.url
|
||||||
this.imgVisible = true
|
// this.imgVisible = true
|
||||||
|
this.$refs[file.url].$viewer.show()
|
||||||
}
|
}
|
||||||
|
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -14,12 +14,24 @@
|
||||||
>
|
>
|
||||||
<i slot="default" class="el-icon-plus" />
|
<i slot="default" class="el-icon-plus" />
|
||||||
<div slot="file" slot-scope="{file}">
|
<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
|
<img
|
||||||
class="el-upload-list__item-thumbnail"
|
class="el-upload-list__item-thumbnail"
|
||||||
crossOrigin="Anonymous"
|
|
||||||
:src="OSSclientConfig.basePath + file.url"
|
:src="OSSclientConfig.basePath + file.url"
|
||||||
|
crossOrigin="anonymous"
|
||||||
alt=""
|
alt=""
|
||||||
>
|
style="max-width: 100%; max-height: 100%"
|
||||||
|
/>
|
||||||
<span class="el-upload-list__item-actions">
|
<span class="el-upload-list__item-actions">
|
||||||
<span
|
<span
|
||||||
class="el-upload-list__item-preview"
|
class="el-upload-list__item-preview"
|
||||||
|
|
@ -36,19 +48,9 @@
|
||||||
<i class="el-icon-delete" />
|
<i class="el-icon-delete" />
|
||||||
</span>
|
</span>
|
||||||
</span>
|
</span>
|
||||||
|
</viewer>
|
||||||
</div>
|
</div>
|
||||||
</el-upload>
|
</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>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|
@ -142,7 +144,8 @@ name: "CustomizeReportPageUpload",
|
||||||
window.open(this.OSSclientConfig.basePath + file.url,'_blank')
|
window.open(this.OSSclientConfig.basePath + file.url,'_blank')
|
||||||
}else{
|
}else{
|
||||||
this.imageUrl = this.OSSclientConfig.basePath + file.url
|
this.imageUrl = this.OSSclientConfig.basePath + file.url
|
||||||
this.imgVisible = true
|
// this.imgVisible = true
|
||||||
|
this.$refs[file.url].$viewer.show()
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
// 删除图片
|
// 删除图片
|
||||||
|
|
|
||||||
|
|
@ -87,7 +87,7 @@
|
||||||
</div> -->
|
</div> -->
|
||||||
<div>
|
<div>
|
||||||
<div>{{ instance.InstanceNumber }}</div>
|
<div>{{ instance.InstanceNumber }}</div>
|
||||||
<div>{{ `${instance.NumberOfFrames > 0 ? instance.NumberOfFrames : 1} frame` }}</div>
|
<div>{{ `${instance.NumberOfFrames > 0 ? instance.KeyFramesList.length > 0 ? instance.KeyFramesList.length : instance.NumberOfFrames : 1} frame` }}</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -279,7 +279,14 @@ export default {
|
||||||
store.dispatch('reading/setImageloadedInfo', item)
|
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) {
|
if (i > -1) {
|
||||||
var idx = this.visitTaskList.findIndex(i => i.VisitTaskId === this.visitTaskId)
|
var idx = this.visitTaskList.findIndex(i => i.VisitTaskId === this.visitTaskId)
|
||||||
if (idx > -1) {
|
if (idx > -1) {
|
||||||
|
|
@ -356,7 +363,22 @@ export default {
|
||||||
var isReadingTaskViewInOrder = JSON.parse(this.$router.currentRoute.query.isReadingTaskViewInOrder)
|
var isReadingTaskViewInOrder = JSON.parse(this.$router.currentRoute.query.isReadingTaskViewInOrder)
|
||||||
var idx = this.visitTaskList.findIndex(i => i.VisitTaskId === this.visitTaskId)
|
var idx = this.visitTaskList.findIndex(i => i.VisitTaskId === this.visitTaskId)
|
||||||
this.studyList = this.visitTaskList[idx].StudyList
|
this.studyList = this.visitTaskList[idx].StudyList
|
||||||
if (this.visitTaskList[idx].IsBaseLineTask || isReadingTaskViewInOrder !== 1) {
|
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])
|
const obj = this.getFirstMarkedSeries(this.visitTaskList[idx].MeasureData, [...this.visitTaskList[idx].StudyList])
|
||||||
if (Object.keys(obj).length !== 0) {
|
if (Object.keys(obj).length !== 0) {
|
||||||
|
|
@ -652,7 +674,11 @@ export default {
|
||||||
this.studyList[studyIndex].SeriesList[seriesIndex].measureData = this.measureData
|
this.studyList[studyIndex].SeriesList[seriesIndex].measureData = this.measureData
|
||||||
var dicomStatck = Object.assign({},this.studyList[studyIndex].SeriesList[seriesIndex])
|
var dicomStatck = Object.assign({},this.studyList[studyIndex].SeriesList[seriesIndex])
|
||||||
const imageIds = []
|
const imageIds = []
|
||||||
if (instanceInfo.NumberOfFrames && instanceInfo.NumberOfFrames > 1) {
|
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++) {
|
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}`)
|
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}`)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -267,7 +267,7 @@ export default {
|
||||||
// this.readingTool = this.$router.currentRoute.query.readingTool
|
// this.readingTool = this.$router.currentRoute.query.readingTool
|
||||||
this.TrialReadingCriterionId = this.$router.currentRoute.query.TrialReadingCriterionId
|
this.TrialReadingCriterionId = this.$router.currentRoute.query.TrialReadingCriterionId
|
||||||
// this.isNewSubject = this.$router.currentRoute.query.isNewSubject
|
// this.isNewSubject = this.$router.currentRoute.query.isNewSubject
|
||||||
localStorage.setItem('isReadingTaskViewInOrder', this.isReadingTaskViewInOrder)
|
|
||||||
// if (this.isNewSubject && this.isReadingTaskViewInOrder !== 0) {
|
// if (this.isNewSubject && this.isReadingTaskViewInOrder !== 0) {
|
||||||
// // 已开始受试者${this.subjectCode}阅片任务
|
// // 已开始受试者${this.subjectCode}阅片任务
|
||||||
// var msg = this.$t('trials:reading:warnning:msg1')
|
// var msg = this.$t('trials:reading:warnning:msg1')
|
||||||
|
|
@ -332,6 +332,7 @@ export default {
|
||||||
this.digitPlaces = res.Result.DigitPlaces
|
this.digitPlaces = res.Result.DigitPlaces
|
||||||
this.IseCRFShowInDicomReading = res.Result.IseCRFShowInDicomReading
|
this.IseCRFShowInDicomReading = res.Result.IseCRFShowInDicomReading
|
||||||
this.isReadingTaskViewInOrder = res.Result.IsReadingTaskViewInOrder
|
this.isReadingTaskViewInOrder = res.Result.IsReadingTaskViewInOrder
|
||||||
|
localStorage.setItem('isReadingTaskViewInOrder', this.isReadingTaskViewInOrder)
|
||||||
localStorage.setItem('CriterionType', res.Result.CriterionType)
|
localStorage.setItem('CriterionType', res.Result.CriterionType)
|
||||||
localStorage.setItem('digitPlaces', res.Result.DigitPlaces)
|
localStorage.setItem('digitPlaces', res.Result.DigitPlaces)
|
||||||
this.readingCategory = res.Result.ReadingCategory
|
this.readingCategory = res.Result.ReadingCategory
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@
|
||||||
</div>
|
</div>
|
||||||
<!-- 文件层级 -->
|
<!-- 文件层级 -->
|
||||||
<div v-if="study.NoneDicomStudyFileList.length === 0" class="empty-text">
|
<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>
|
||||||
<div v-else id="imgList" style="height:100%;">
|
<div v-else id="imgList" style="height:100%;">
|
||||||
<div
|
<div
|
||||||
|
|
@ -28,8 +28,15 @@
|
||||||
class="img-box"
|
class="img-box"
|
||||||
@click="selected(item,i,j,true)"
|
@click="selected(item,i,j,true)"
|
||||||
>
|
>
|
||||||
|
<div v-if="item.FileName.length < 15" class="img-text">
|
||||||
{{ `${j+1}. ${item.FileName}` }}
|
{{ `${j+1}. ${item.FileName}` }}
|
||||||
</div>
|
</div>
|
||||||
|
<el-tooltip v-else :content="item.FileName" placement="bottom">
|
||||||
|
<div class="img-text">
|
||||||
|
{{ `${j+1}. ${item.FileName}` }}
|
||||||
|
</div>
|
||||||
|
</el-tooltip>
|
||||||
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -96,7 +103,7 @@ export default {
|
||||||
visistTaskId: '',
|
visistTaskId: '',
|
||||||
taskBlindName: '',
|
taskBlindName: '',
|
||||||
readingTaskState: 2,
|
readingTaskState: 2,
|
||||||
bp:[]
|
bp: []
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
async mounted() {
|
async mounted() {
|
||||||
|
|
@ -188,7 +195,7 @@ export default {
|
||||||
}
|
}
|
||||||
var arr = bodyPart.split(separator)
|
var arr = bodyPart.split(separator)
|
||||||
var newArr = arr.map(i => {
|
var newArr = arr.map(i => {
|
||||||
return this.$fd('Bodypart', i.trim(),'Code',{Bodypart:this.bp},'Name')
|
return this.$fd('Bodypart', i.trim(), 'Code', { Bodypart: this.bp }, 'Name')
|
||||||
})
|
})
|
||||||
return newArr.join(' | ')
|
return newArr.join(' | ')
|
||||||
}
|
}
|
||||||
|
|
@ -265,13 +272,19 @@ export default {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
border-bottom: 2px solid #f3f3f3;
|
border-bottom: 2px solid #f3f3f3;
|
||||||
width: 180px;
|
|
||||||
height: 50px;
|
|
||||||
line-height: 50px;
|
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
// margin-bottom: 5px;
|
// margin-bottom: 5px;
|
||||||
padding-left: 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){
|
.img-box:nth-last-child(1){
|
||||||
margin-bottom: 0px;
|
margin-bottom: 0px;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -143,7 +143,6 @@ import { getMedicalReviewDialog } from '@/api/trials'
|
||||||
import FeedbackForm from './FeedbackForm'
|
import FeedbackForm from './FeedbackForm'
|
||||||
import mimAvatar from '@/assets/MIM.png'
|
import mimAvatar from '@/assets/MIM.png'
|
||||||
import irAvatar from '@/assets/IR.png'
|
import irAvatar from '@/assets/IR.png'
|
||||||
import Viewer from 'v-viewer'
|
|
||||||
export default {
|
export default {
|
||||||
name: 'ChatForm',
|
name: 'ChatForm',
|
||||||
components: { FeedbackForm },
|
components: { FeedbackForm },
|
||||||
|
|
@ -177,7 +176,6 @@ export default {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
this.initializeViewer()
|
|
||||||
this.getMessageList()
|
this.getMessageList()
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
|
@ -213,11 +211,6 @@ export default {
|
||||||
this.imagePath = `${this.OSSclientConfig.basePath}${path}`
|
this.imagePath = `${this.OSSclientConfig.basePath}${path}`
|
||||||
this.previewDialog = true
|
this.previewDialog = true
|
||||||
this.$refs[path][0].$viewer.show()
|
this.$refs[path][0].$viewer.show()
|
||||||
},
|
|
||||||
initializeViewer() {
|
|
||||||
Viewer.setDefaults({
|
|
||||||
toolbar: { zoomIn: true, zoomOut: true, rotateLeft: true, rotateRight: true, flipHorizontal: true, flipVertical: true }
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -171,7 +171,6 @@ import { getMedicalReviewDialog, sendMedicalReviewDialog } from '@/api/trials'
|
||||||
import FeedbackForm from '@/views/trials/trials-panel/reading/medical-feedback/components/FeedbackForm'
|
import FeedbackForm from '@/views/trials/trials-panel/reading/medical-feedback/components/FeedbackForm'
|
||||||
import mimAvatar from '@/assets/MIM.png'
|
import mimAvatar from '@/assets/MIM.png'
|
||||||
import irAvatar from '@/assets/IR.png'
|
import irAvatar from '@/assets/IR.png'
|
||||||
import Viewer from 'v-viewer'
|
|
||||||
export default {
|
export default {
|
||||||
name: 'ChatForm',
|
name: 'ChatForm',
|
||||||
components: {
|
components: {
|
||||||
|
|
@ -207,7 +206,6 @@ export default {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
this.initializeViewer()
|
|
||||||
this.getMessageList()
|
this.getMessageList()
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
|
@ -261,11 +259,6 @@ export default {
|
||||||
this.irFeedbackForm.title = this.$t('trials:medicalFeedback:title:feedback')
|
this.irFeedbackForm.title = this.$t('trials:medicalFeedback:title:feedback')
|
||||||
|
|
||||||
this.irFeedbackForm.visible = true
|
this.irFeedbackForm.visible = true
|
||||||
},
|
|
||||||
initializeViewer() {
|
|
||||||
Viewer.setDefaults({
|
|
||||||
toolbar: { zoomIn: true, zoomOut: true, rotateLeft: true, rotateRight: true, flipHorizontal: true, flipVertical: true }
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -197,7 +197,6 @@
|
||||||
import { saveMedicalReviewInfo } from "@/api/trials";
|
import { saveMedicalReviewInfo } from "@/api/trials";
|
||||||
import ChatForm from "./ChatForm";
|
import ChatForm from "./ChatForm";
|
||||||
import CloseQC from "./CloseQC";
|
import CloseQC from "./CloseQC";
|
||||||
import Viewer from "v-viewer";
|
|
||||||
export default {
|
export default {
|
||||||
name: "AuditConclusions",
|
name: "AuditConclusions",
|
||||||
components: {
|
components: {
|
||||||
|
|
@ -253,7 +252,6 @@ export default {
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
this.initializeViewer();
|
|
||||||
this.initForm();
|
this.initForm();
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
|
@ -435,21 +433,9 @@ export default {
|
||||||
var idx = this.fileList.findIndex((i) => i.url === file.url);
|
var idx = this.fileList.findIndex((i) => i.url === file.url);
|
||||||
if (idx === -1) return;
|
if (idx === -1) return;
|
||||||
this.fileList.splice(idx, 1);
|
this.fileList.splice(idx, 1);
|
||||||
},
|
}
|
||||||
initializeViewer() {
|
}
|
||||||
Viewer.setDefaults({
|
}
|
||||||
toolbar: {
|
|
||||||
zoomIn: true,
|
|
||||||
zoomOut: true,
|
|
||||||
rotateLeft: true,
|
|
||||||
rotateRight: true,
|
|
||||||
flipHorizontal: true,
|
|
||||||
flipVertical: true,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
</script>
|
</script>
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
.conclusions {
|
.conclusions {
|
||||||
|
|
|
||||||
|
|
@ -1,17 +1,15 @@
|
||||||
<template>
|
<template>
|
||||||
<!-- <el-tabs v-model="activeName" v-loading="loading" style="min-height:500px">-->
|
<div style="min-height:500px">
|
||||||
<!-- <el-tab-pane-->
|
<h3 v-if="isReadingShowSubjectInfo" style="padding: 5px 0px;margin: 0;">
|
||||||
<!-- v-for="criterion in criterions"-->
|
<span v-if="subjectCode">{{ subjectCode }} </span>
|
||||||
<!-- :key="criterion.ReadingQuestionCriterionTrialId"-->
|
<span style="margin-left:5px;">{{ taskBlindName }}</span>
|
||||||
<!-- :label="criterion.ReadingQuestionCriterionTrialName"-->
|
</h3>
|
||||||
<!-- :name="criterion.ReadingQuestionCriterionTrialId"-->
|
|
||||||
<!-- >-->
|
|
||||||
<div v-loading="loading" style="min-height:500px">
|
|
||||||
<ECRF
|
<ECRF
|
||||||
:trial-id="trialId"
|
:trial-id="trialId"
|
||||||
:subject-id="subjectId"
|
:subject-id="subjectId"
|
||||||
:criterion-id="criterionId"
|
:criterion-id="criterionId"
|
||||||
:visit-task-id="visitTaskId"
|
:visit-task-id="visitTaskId"
|
||||||
|
:iseCRFShowInDicomReading="iseCRFShowInDicomReading"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
@ -43,6 +41,22 @@ export default {
|
||||||
criterionId: {
|
criterionId: {
|
||||||
type: String,
|
type: String,
|
||||||
required: true
|
required: true
|
||||||
|
},
|
||||||
|
subjectCode: {
|
||||||
|
type: String,
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
taskBlindName: {
|
||||||
|
type: String,
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
isReadingShowSubjectInfo: {
|
||||||
|
type: Boolean,
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
iseCRFShowInDicomReading: {
|
||||||
|
type: Boolean,
|
||||||
|
required: true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
|
|
|
||||||
|
|
@ -77,13 +77,13 @@
|
||||||
|
|
||||||
<el-form-item v-if="readingTaskState < 2">
|
<el-form-item v-if="readingTaskState < 2">
|
||||||
<div style="text-align:center;">
|
<div style="text-align:center;">
|
||||||
<el-button type="primary" @click="skipTask">
|
<el-button type="primary" @click="skipTask" v-if="iseCRFShowInDicomReading">
|
||||||
{{ $t('trials:readingReport:button:skip') }}
|
{{ $t('trials:readingReport:button:skip') }}
|
||||||
</el-button>
|
</el-button>
|
||||||
<el-button type="primary" @click="handleSave">
|
<el-button type="primary" @click="handleSave">
|
||||||
{{ $t('common:button:save') }}
|
{{ $t('common:button:save') }}
|
||||||
</el-button>
|
</el-button>
|
||||||
<el-button type="primary" @click="handleSubmit">
|
<el-button type="primary" @click="handleSubmit" v-if="iseCRFShowInDicomReading">
|
||||||
{{ $t('common:button:submit') }}
|
{{ $t('common:button:submit') }}
|
||||||
</el-button>
|
</el-button>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -116,7 +116,7 @@ import const_ from '@/const/sign-code'
|
||||||
import FormItem from './FormItem'
|
import FormItem from './FormItem'
|
||||||
import SignForm from '@/views/trials/components/newSignForm'
|
import SignForm from '@/views/trials/components/newSignForm'
|
||||||
// import { getToken } from '@/utils/auth'
|
// import { getToken } from '@/utils/auth'
|
||||||
// import DicomEvent from '@/views/trials/trials-panel/reading/dicoms/components/DicomEvent'
|
import DicomEvent from '@/views/trials/trials-panel/reading/dicoms/components/DicomEvent'
|
||||||
export default {
|
export default {
|
||||||
name: 'ECRF',
|
name: 'ECRF',
|
||||||
components: {
|
components: {
|
||||||
|
|
@ -139,6 +139,10 @@ export default {
|
||||||
visitTaskId: {
|
visitTaskId: {
|
||||||
type: String,
|
type: String,
|
||||||
required: true
|
required: true
|
||||||
|
},
|
||||||
|
iseCRFShowInDicomReading: {
|
||||||
|
type: Boolean,
|
||||||
|
required: true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
|
|
@ -158,6 +162,9 @@ export default {
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
this.getQuestions()
|
this.getQuestions()
|
||||||
|
DicomEvent.$on('refreshQuestionAnswer', _ => {
|
||||||
|
this.getQuestions()
|
||||||
|
})
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
async getQuestions() {
|
async getQuestions() {
|
||||||
|
|
@ -243,6 +250,7 @@ export default {
|
||||||
try {
|
try {
|
||||||
const res = await saveVisitTaskQuestions(params)
|
const res = await saveVisitTaskQuestions(params)
|
||||||
if (res.IsSuccess) {
|
if (res.IsSuccess) {
|
||||||
|
DicomEvent.$emit('getReportInfo', true)
|
||||||
this.$message.success(this.$t('common:message:savedSuccessfully'))
|
this.$message.success(this.$t('common:message:savedSuccessfully'))
|
||||||
}
|
}
|
||||||
this.loading = false
|
this.loading = false
|
||||||
|
|
@ -285,6 +293,7 @@ export default {
|
||||||
const res = await submitVisitTaskQuestionsInDto(params)
|
const res = await submitVisitTaskQuestionsInDto(params)
|
||||||
this.loading = false
|
this.loading = false
|
||||||
if (res.IsSuccess) {
|
if (res.IsSuccess) {
|
||||||
|
DicomEvent.$emit('getReportInfo', true)
|
||||||
this.$message.success(this.$t('common:message:savedSuccessfully'))
|
this.$message.success(this.$t('common:message:savedSuccessfully'))
|
||||||
this.isEdit = false
|
this.isEdit = false
|
||||||
this.$refs['signForm'].btnLoading = false
|
this.$refs['signForm'].btnLoading = false
|
||||||
|
|
|
||||||
|
|
@ -120,11 +120,26 @@
|
||||||
</el-checkbox-group>
|
</el-checkbox-group>
|
||||||
<!-- 数值 -->
|
<!-- 数值 -->
|
||||||
<!-- :precision="2" :step="0.1" :max="10" -->
|
<!-- :precision="2" :step="0.1" :max="10" -->
|
||||||
|
<template v-if="question.Type==='number'">
|
||||||
<el-input-number
|
<el-input-number
|
||||||
v-if="question.Type==='number'"
|
v-if="question.ValueType === 0"
|
||||||
|
v-model="questionForm[question.Id]"
|
||||||
|
precision="0"
|
||||||
|
:disabled="readingTaskState >= 2"
|
||||||
|
/>
|
||||||
|
<el-input-number
|
||||||
|
v-else-if="question.ValueType === 3"
|
||||||
v-model="questionForm[question.Id]"
|
v-model="questionForm[question.Id]"
|
||||||
:disabled="readingTaskState >= 2"
|
:disabled="readingTaskState >= 2"
|
||||||
/>
|
/>
|
||||||
|
<el-input-number
|
||||||
|
v-else-if="question.ValueType === 1 || question.ValueType === 2"
|
||||||
|
v-model="questionForm[question.Id]"
|
||||||
|
:precision="digitPlaces"
|
||||||
|
:disabled="readingTaskState >= 2"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
|
||||||
<!-- 上传图像 -->
|
<!-- 上传图像 -->
|
||||||
<el-upload
|
<el-upload
|
||||||
v-if="question.Type==='upload'"
|
v-if="question.Type==='upload'"
|
||||||
|
|
@ -222,7 +237,8 @@ export default {
|
||||||
accept: '.png,.jpg,.jpeg',
|
accept: '.png,.jpg,.jpeg',
|
||||||
imgVisible: false,
|
imgVisible: false,
|
||||||
imageUrl: '',
|
imageUrl: '',
|
||||||
urls: []
|
urls: [],
|
||||||
|
digitPlaces: null
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
|
|
@ -245,6 +261,7 @@ export default {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
this.digitPlaces = parseInt(localStorage.getItem('digitPlaces'))
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
formItemChange(v, question) {
|
formItemChange(v, question) {
|
||||||
|
|
|
||||||
|
|
@ -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,167 @@
|
||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<el-upload
|
||||||
|
:action="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>
|
<template>
|
||||||
<div v-loading="loading" class="img-container">
|
<div class="img-container">
|
||||||
<el-card class="box-card left">
|
<el-card v-loading="loading" class="box-card left">
|
||||||
<div v-if="otherInfo && otherInfo.IsReadingShowSubjectInfo" class="title">
|
<div v-if="isReadingShowSubjectInfo" class="title">
|
||||||
<span>{{ $t('trials:auditRecord:table:subject') }}:{{ otherInfo.SubjectCode }} </span>
|
<h4>{{ subjectCode }} </h4>
|
||||||
<span>({{ otherInfo.TaskBlindName }})</span>
|
<h4>{{ taskBlindName }}</h4>
|
||||||
</div>
|
</div>
|
||||||
<el-tabs v-model="activeName" @tab-click="handleClick">
|
<el-tabs v-model="activeName" @tab-click="handleClick">
|
||||||
<el-tab-pane :label="$t('trials:clinicaldara:title:currentTask')" name="first" class="left-content">
|
<el-tab-pane :label="$t('trials:clinicaldara:title:currentTask')" name="first" class="left-content">
|
||||||
|
|
@ -30,8 +30,15 @@
|
||||||
class="img-box"
|
class="img-box"
|
||||||
@click="selected(item,i,j,true)"
|
@click="selected(item,i,j,true)"
|
||||||
>
|
>
|
||||||
|
<div v-if="item.FileName.length < 15" class="img-text">
|
||||||
{{ `${j+1}. ${item.FileName}` }}
|
{{ `${j+1}. ${item.FileName}` }}
|
||||||
</div>
|
</div>
|
||||||
|
<el-tooltip v-else :content="item.FileName" placement="bottom">
|
||||||
|
<div class="img-text">
|
||||||
|
{{ `${j+1}. ${item.FileName}` }}
|
||||||
|
</div>
|
||||||
|
</el-tooltip>
|
||||||
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -53,9 +60,15 @@
|
||||||
class="img-box"
|
class="img-box"
|
||||||
@click="handleImageRead(task)"
|
@click="handleImageRead(task)"
|
||||||
>
|
>
|
||||||
|
<div v-if="task.TaskBlindName.length < 15" class="img-text">
|
||||||
{{ `${j+1}. ${task.TaskBlindName}` }}
|
{{ `${j+1}. ${task.TaskBlindName}` }}
|
||||||
</div>
|
</div>
|
||||||
|
<el-tooltip v-else :content="task.TaskBlindName" placement="bottom">
|
||||||
|
<div class="img-text">
|
||||||
|
{{ `${j+1}. ${task.TaskBlindName}` }}
|
||||||
|
</div>
|
||||||
|
</el-tooltip>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</el-tab-pane>
|
</el-tab-pane>
|
||||||
|
|
@ -63,7 +76,7 @@
|
||||||
|
|
||||||
</el-card>
|
</el-card>
|
||||||
<!-- 预览图像 -->
|
<!-- 预览图像 -->
|
||||||
<el-card class="box-card right">
|
<el-card v-loading="loading" class="box-card right">
|
||||||
<div style="width:100%;height: 100%;">
|
<div style="width:100%;height: 100%;">
|
||||||
<Preview
|
<Preview
|
||||||
v-if="previewImage.imgList.length > 0"
|
v-if="previewImage.imgList.length > 0"
|
||||||
|
|
@ -93,6 +106,10 @@
|
||||||
:subject-id="subjectId"
|
:subject-id="subjectId"
|
||||||
:visit-task-id="visitTaskId"
|
:visit-task-id="visitTaskId"
|
||||||
:criterion-id="otherInfo.TrialCriterionId"
|
: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>
|
</el-card>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -127,9 +144,33 @@ export default {
|
||||||
type: String,
|
type: String,
|
||||||
required: true
|
required: true
|
||||||
},
|
},
|
||||||
|
taskBlindName: {
|
||||||
|
type: String,
|
||||||
|
required: true
|
||||||
|
},
|
||||||
readingCategory: {
|
readingCategory: {
|
||||||
type: Number,
|
type: Number,
|
||||||
required: true
|
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() {
|
data() {
|
||||||
|
|
@ -156,7 +197,8 @@ export default {
|
||||||
currentTaskId: '',
|
currentTaskId: '',
|
||||||
otherInfo: null,
|
otherInfo: null,
|
||||||
isReadingShowPreviousResults: false,
|
isReadingShowPreviousResults: false,
|
||||||
bp: []
|
bp: [],
|
||||||
|
openWindow: null
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
|
|
@ -170,6 +212,11 @@ export default {
|
||||||
|
|
||||||
this.getNoneDicomList(this.isReadingShowPreviousResults)
|
this.getNoneDicomList(this.isReadingShowPreviousResults)
|
||||||
},
|
},
|
||||||
|
beforeDestroy() {
|
||||||
|
if (this.openWindow) {
|
||||||
|
this.openWindow.close()
|
||||||
|
}
|
||||||
|
},
|
||||||
methods: {
|
methods: {
|
||||||
// 获取非Dicom检查信息
|
// 获取非Dicom检查信息
|
||||||
getNoneDicomList() {
|
getNoneDicomList() {
|
||||||
|
|
@ -250,18 +297,21 @@ export default {
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
handleImageRead(task) {
|
handleImageRead(task) {
|
||||||
|
if (this.openWindow) {
|
||||||
|
this.openWindow.close()
|
||||||
|
}
|
||||||
this.currentTaskId = task.VisitTaskId
|
this.currentTaskId = task.VisitTaskId
|
||||||
var criterionType = this.$router.currentRoute.query.criterionType
|
var criterionType = this.criterionType
|
||||||
var readingTool = this.$router.currentRoute.query.readingTool
|
var readingTool = this.readingTool
|
||||||
var isReadingTaskViewInOrder = this.$router.currentRoute.query.isReadingTaskViewInOrder
|
var isReadingTaskViewInOrder = this.isReadingTaskViewInOrder
|
||||||
var trialReadingCriterionId = this.$router.currentRoute.query.TrialReadingCriterionId
|
var trialReadingCriterionId = this.$router.currentRoute.query.TrialReadingCriterionId
|
||||||
var token = getToken()
|
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({
|
// const routeData = this.$router.resolve({
|
||||||
// path: `/readingPage?subjectId=${this.subjectId}&trialId=${this.trialId}&visitTaskId=${task.VisitTaskId}&TokenKey=${token}`
|
// path: `/readingPage?subjectId=${this.subjectId}&trialId=${this.trialId}&visitTaskId=${task.VisitTaskId}&TokenKey=${token}`
|
||||||
// })
|
// })
|
||||||
const routeData = this.$router.resolve({ path })
|
const routeData = this.$router.resolve({ path })
|
||||||
window.open(routeData.href, '_blank')
|
this.openWindow = window.open(routeData.href, '_blank')
|
||||||
},
|
},
|
||||||
previewCD() {
|
previewCD() {
|
||||||
var token = getToken()
|
var token = getToken()
|
||||||
|
|
@ -295,7 +345,7 @@ export default {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
padding: 10px;
|
padding-bottom: 10px;
|
||||||
display: flex;
|
display: flex;
|
||||||
::-webkit-scrollbar {
|
::-webkit-scrollbar {
|
||||||
width: 7px;
|
width: 7px;
|
||||||
|
|
@ -326,13 +376,19 @@ export default {
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
}
|
}
|
||||||
.title{
|
.title{
|
||||||
height: 40px;
|
// height: 40px;
|
||||||
line-height: 40px;
|
// line-height: 40px;
|
||||||
border: 1ppx solid;
|
border: 1ppx solid;
|
||||||
border: 1px solid #ebe7e7;
|
border: 1px solid #ebe7e7;
|
||||||
padding-left: 10px;
|
// padding-left: 10px;
|
||||||
background-color: #4e4e4e;
|
background-color: #4e4e4e;
|
||||||
color: #ffffff;
|
color: #ffffff;
|
||||||
|
h4{
|
||||||
|
padding: 5px 0px;
|
||||||
|
margin: 0;
|
||||||
|
text-align: center;
|
||||||
|
background-color: #4c4c4c;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
.left-content{
|
.left-content{
|
||||||
flex: 1;
|
flex: 1;
|
||||||
|
|
@ -359,13 +415,19 @@ export default {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
border-bottom: 2px solid #f3f3f3;
|
border-bottom: 2px solid #f3f3f3;
|
||||||
width: 180px;
|
|
||||||
height: 50px;
|
|
||||||
line-height: 50px;
|
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
// margin-bottom: 5px;
|
// margin-bottom: 5px;
|
||||||
padding-left: 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){
|
.img-box:nth-last-child(1){
|
||||||
margin-bottom: 0px;
|
margin-bottom: 0px;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,15 +1,40 @@
|
||||||
<template>
|
<template>
|
||||||
<div ref="container" v-loading="loading" class="none-dicom-reading-container">
|
<div ref="container" v-loading="loading" class="none-dicom-reading-container">
|
||||||
<!-- 访视阅片 -->
|
<!-- 访视阅片 -->
|
||||||
|
<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
|
<VisitReview
|
||||||
v-if="isShow && readingCategory && readingCategory=== 1"
|
|
||||||
:trial-id="trialId"
|
:trial-id="trialId"
|
||||||
:subject-id="subjectId"
|
:subject-id="subjectId"
|
||||||
:subject-code="subjectCode"
|
:subject-code="subjectCode"
|
||||||
:visit-task-id="visitTaskId"
|
:visit-task-id="visitTaskId"
|
||||||
|
:task-blind-name="taskBlindName"
|
||||||
:reading-category="readingCategory"
|
:reading-category="readingCategory"
|
||||||
:is-exists-clinical-data="isExistsClinicalData"
|
: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
|
<GlobalReview
|
||||||
v-else-if="isShow && readingCategory && readingCategory === 2"
|
v-else-if="isShow && readingCategory && readingCategory === 2"
|
||||||
|
|
@ -83,6 +108,7 @@ import { getNextTask, readClinicalData } from '@/api/trials'
|
||||||
import store from '@/store'
|
import store from '@/store'
|
||||||
import { changeURLStatic } from '@/utils/history.js'
|
import { changeURLStatic } from '@/utils/history.js'
|
||||||
import DicomEvent from '@/views/trials/trials-panel/reading/dicoms/components/DicomEvent'
|
import DicomEvent from '@/views/trials/trials-panel/reading/dicoms/components/DicomEvent'
|
||||||
|
import Report from './components/Report'
|
||||||
import VisitReview from './components/VisitReview'
|
import VisitReview from './components/VisitReview'
|
||||||
import GlobalReview from '@/views/trials/trials-panel/reading/global-review'
|
import GlobalReview from '@/views/trials/trials-panel/reading/global-review'
|
||||||
import AdReview from '@/views/trials/trials-panel/reading/ad-review'
|
import AdReview from '@/views/trials/trials-panel/reading/ad-review'
|
||||||
|
|
@ -93,6 +119,7 @@ export default {
|
||||||
name: 'NoneDicomReading',
|
name: 'NoneDicomReading',
|
||||||
components: {
|
components: {
|
||||||
VisitReview,
|
VisitReview,
|
||||||
|
Report,
|
||||||
AdReview,
|
AdReview,
|
||||||
GlobalReview,
|
GlobalReview,
|
||||||
OncologyReview,
|
OncologyReview,
|
||||||
|
|
@ -113,12 +140,15 @@ export default {
|
||||||
isExistsClinicalData: false,
|
isExistsClinicalData: false,
|
||||||
isNeedReadClinicalData: false,
|
isNeedReadClinicalData: false,
|
||||||
isReadClinicalData: false,
|
isReadClinicalData: false,
|
||||||
|
iseCRFShowInDicomReading: false,
|
||||||
criterionType: null,
|
criterionType: null,
|
||||||
readingTool: null,
|
readingTool: null,
|
||||||
isNewSubject: null,
|
isNewSubject: null,
|
||||||
dialogVisible: false,
|
dialogVisible: false,
|
||||||
dialogH: 0,
|
dialogH: 0,
|
||||||
isShow: false
|
isShow: false,
|
||||||
|
activeName:'',
|
||||||
|
tabs: []
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
|
|
@ -169,6 +199,10 @@ export default {
|
||||||
// var token = getToken()
|
// 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}`
|
// 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.subjectId = res.Result.SubjectId
|
||||||
this.visitTaskId = res.Result.VisitTaskId
|
this.visitTaskId = res.Result.VisitTaskId
|
||||||
this.subjectCode = res.Result.SubjectCode
|
this.subjectCode = res.Result.SubjectCode
|
||||||
|
|
@ -176,7 +210,8 @@ export default {
|
||||||
this.isExistsClinicalData = res.Result.IsExistsClinicalData
|
this.isExistsClinicalData = res.Result.IsExistsClinicalData
|
||||||
this.isReadClinicalData = res.Result.IsReadClinicalData
|
this.isReadClinicalData = res.Result.IsReadClinicalData
|
||||||
this.isNeedReadClinicalData = res.Result.IsNeedReadClinicalData
|
this.isNeedReadClinicalData = res.Result.IsNeedReadClinicalData
|
||||||
|
this.iseCRFShowInDicomReading = res.Result.IseCRFShowInDicomReading
|
||||||
|
this.isReadingTaskViewInOrder = res.Result.IsReadingTaskViewInOrder
|
||||||
this.isReadingShowSubjectInfo = res.Result.IsReadingShowSubjectInfo
|
this.isReadingShowSubjectInfo = res.Result.IsReadingShowSubjectInfo
|
||||||
this.isReadingShowPreviousResults = res.Result.IsReadingShowPreviousResults
|
this.isReadingShowPreviousResults = res.Result.IsReadingShowPreviousResults
|
||||||
this.digitPlaces = res.Result.DigitPlaces
|
this.digitPlaces = res.Result.DigitPlaces
|
||||||
|
|
@ -201,7 +236,21 @@ export default {
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
this.loading = false
|
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>
|
</script>
|
||||||
|
|
@ -221,7 +270,38 @@ export default {
|
||||||
padding: 10px;
|
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%;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
/deep/ .dialog-container{
|
/deep/ .dialog-container{
|
||||||
margin-top: 50px !important;
|
margin-top: 50px !important;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -41,7 +41,7 @@
|
||||||
icon="el-icon-search"
|
icon="el-icon-search"
|
||||||
@click="handleSearch"
|
@click="handleSearch"
|
||||||
>
|
>
|
||||||
{{ $t("common:button:search") }}
|
{{ $t('common:button:search') }}
|
||||||
</el-button>
|
</el-button>
|
||||||
<!-- 重置 -->
|
<!-- 重置 -->
|
||||||
<el-button
|
<el-button
|
||||||
|
|
@ -49,7 +49,7 @@
|
||||||
icon="el-icon-refresh-left"
|
icon="el-icon-refresh-left"
|
||||||
@click="handleReset"
|
@click="handleReset"
|
||||||
>
|
>
|
||||||
{{ $t("common:button:reset") }}
|
{{ $t('common:button:reset') }}
|
||||||
</el-button>
|
</el-button>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-form>
|
</el-form>
|
||||||
|
|
@ -78,7 +78,8 @@
|
||||||
? 'warning'
|
? 'warning'
|
||||||
: 'primary'
|
: 'primary'
|
||||||
"
|
"
|
||||||
>{{ $fd("YesOrNo", scope.row.IsUrgent) }}</el-tag>
|
>{{ $fd('YesOrNo', scope.row.IsUrgent) }}</el-tag
|
||||||
|
>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<!-- 受试者编号 -->
|
<!-- 受试者编号 -->
|
||||||
|
|
@ -116,7 +117,8 @@
|
||||||
? '#E6A23C'
|
? '#E6A23C'
|
||||||
: '#409EFF',
|
: '#409EFF',
|
||||||
}"
|
}"
|
||||||
>{{ scope.row.UrgentCount }}</span>
|
>{{ scope.row.UrgentCount }}</span
|
||||||
|
>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<!-- 建议完成时间 -->
|
<!-- 建议完成时间 -->
|
||||||
|
|
@ -130,7 +132,7 @@
|
||||||
sortable="custom"
|
sortable="custom"
|
||||||
>
|
>
|
||||||
<template slot-scope="scope">
|
<template slot-scope="scope">
|
||||||
{{ scope.row.SuggesteFinishedTime.split(":")[0] + ":00:00" }}
|
{{ scope.row.SuggesteFinishedTime.split(':')[0] + ':00:00' }}
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column
|
<el-table-column
|
||||||
|
|
@ -156,9 +158,9 @@
|
||||||
<!-- 上传 -->
|
<!-- 上传 -->
|
||||||
<el-button
|
<el-button
|
||||||
v-if="
|
v-if="
|
||||||
item.CriterionType === 0 &&
|
|
||||||
item.ImageUploadEnum > 0 &&
|
item.ImageUploadEnum > 0 &&
|
||||||
item.IsReadingTaskViewInOrder > 0
|
item.IsReadingTaskViewInOrder > 0 &&
|
||||||
|
!scope.row.IsSubjectJudge
|
||||||
"
|
"
|
||||||
v-hasPermi="['role:ir']"
|
v-hasPermi="['role:ir']"
|
||||||
circle
|
circle
|
||||||
|
|
@ -169,9 +171,9 @@
|
||||||
<!-- 下载 -->
|
<!-- 下载 -->
|
||||||
<el-button
|
<el-button
|
||||||
v-if="
|
v-if="
|
||||||
item.CriterionType === 0 &&
|
item.ImageDownloadEnum > 0 &&
|
||||||
item.ImageDownloadEnum === 1 &&
|
item.IsReadingTaskViewInOrder > 0 &&
|
||||||
item.IsReadingTaskViewInOrder > 0
|
!scope.row.IsSubjectJudge
|
||||||
"
|
"
|
||||||
v-hasPermi="['role:ir']"
|
v-hasPermi="['role:ir']"
|
||||||
circle
|
circle
|
||||||
|
|
@ -252,44 +254,61 @@
|
||||||
"
|
"
|
||||||
@click="handleOutOfOrderReading"
|
@click="handleOutOfOrderReading"
|
||||||
>
|
>
|
||||||
{{ $t("trials:pendingReadingTasks:button:beginRandomReview") }}
|
{{ $t('trials:pendingReadingTasks:button:beginRandomReview') }}
|
||||||
</el-button>
|
</el-button>
|
||||||
</el-descriptions-item>
|
</el-descriptions-item>
|
||||||
</el-descriptions>
|
</el-descriptions>
|
||||||
</div>
|
</div>
|
||||||
</el-tab-pane>
|
</el-tab-pane>
|
||||||
</el-tabs>
|
</el-tabs>
|
||||||
<upload-image
|
<!-- <upload-image
|
||||||
v-if="uploadImageVisible"
|
v-if="uploadImageVisible"
|
||||||
:visible.sync="uploadImageVisible"
|
:visible.sync="uploadImageVisible"
|
||||||
:subject-id="uploadSubjectId"
|
:subject-id="uploadSubjectId"
|
||||||
:criterion="uploadTrialCriterion"
|
:criterion="uploadTrialCriterion"
|
||||||
:status="uploadStatus"
|
:status="uploadStatus"
|
||||||
@getList="getList"
|
@getList="getList"
|
||||||
|
/> -->
|
||||||
|
<upload-dicom-and-nonedicom
|
||||||
|
v-if="uploadImageVisible"
|
||||||
|
:SubjectId="uploadSubjectId"
|
||||||
|
:SubjectCode="uploadSubjectCode"
|
||||||
|
:Criterion="uploadTrialCriterion"
|
||||||
|
:visible.sync="uploadImageVisible"
|
||||||
|
/>
|
||||||
|
<download-dicom-and-nonedicom
|
||||||
|
v-if="downloadImageVisible"
|
||||||
|
:SubjectId="uploadSubjectId"
|
||||||
|
:SubjectCode="uploadSubjectCode"
|
||||||
|
:Criterion="uploadTrialCriterion"
|
||||||
|
:visible.sync="downloadImageVisible"
|
||||||
/>
|
/>
|
||||||
</BaseContainer>
|
</BaseContainer>
|
||||||
</template>
|
</template>
|
||||||
<script>
|
<script>
|
||||||
import {
|
import { getIRUnReadSubjectTaskList, verifyReadingRestTime } from '@/api/trials'
|
||||||
getIRUnReadSubjectTaskList,
|
|
||||||
verifyReadingRestTime
|
|
||||||
} from '@/api/trials'
|
|
||||||
import { getTrialCriterionList } from '@/api/trials/reading'
|
import { getTrialCriterionList } from '@/api/trials/reading'
|
||||||
import { clearSkipReadingCache } from '@/api/reading'
|
import { clearSkipReadingCache } from '@/api/reading'
|
||||||
import BaseContainer from '@/components/BaseContainer'
|
import BaseContainer from '@/components/BaseContainer'
|
||||||
import uploadImage from '@/components/uploadImage'
|
import uploadDicomAndNonedicom from '@/components/uploadDicomAndNonedicom'
|
||||||
|
import downloadDicomAndNonedicom from '@/components/downloadDicomAndNonedicom'
|
||||||
import Pagination from '@/components/Pagination'
|
import Pagination from '@/components/Pagination'
|
||||||
import { getToken } from '@/utils/auth'
|
import { getToken } from '@/utils/auth'
|
||||||
const searchDataDefault = () => {
|
const searchDataDefault = () => {
|
||||||
return {
|
return {
|
||||||
SubjectCode: '',
|
SubjectCode: '',
|
||||||
PageIndex: 1,
|
PageIndex: 1,
|
||||||
PageSize: 20
|
PageSize: 20,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
export default {
|
export default {
|
||||||
name: 'ReadingTaskList',
|
name: 'ReadingTaskList',
|
||||||
components: { BaseContainer, Pagination, 'upload-image': uploadImage },
|
components: {
|
||||||
|
BaseContainer,
|
||||||
|
Pagination,
|
||||||
|
'upload-dicom-and-nonedicom': uploadDicomAndNonedicom,
|
||||||
|
'download-dicom-and-nonedicom': downloadDicomAndNonedicom,
|
||||||
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
searchData: searchDataDefault(),
|
searchData: searchDataDefault(),
|
||||||
|
|
@ -308,10 +327,12 @@ export default {
|
||||||
openWindow: null,
|
openWindow: null,
|
||||||
|
|
||||||
// 上传
|
// 上传
|
||||||
|
downloadImageVisible: false,
|
||||||
uploadImageVisible: false,
|
uploadImageVisible: false,
|
||||||
uploadSubjectId: null,
|
uploadSubjectId: null,
|
||||||
|
uploadSubjectCode: null,
|
||||||
uploadTrialCriterion: {},
|
uploadTrialCriterion: {},
|
||||||
uploadStatus: 'upload'
|
uploadStatus: 'upload',
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
|
|
@ -319,7 +340,7 @@ export default {
|
||||||
if (v) {
|
if (v) {
|
||||||
this.getList()
|
this.getList()
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
window.addEventListener('message', this.receiveMsg)
|
window.addEventListener('message', this.receiveMsg)
|
||||||
|
|
@ -335,10 +356,11 @@ export default {
|
||||||
methods: {
|
methods: {
|
||||||
// 打开上传下载弹框
|
// 打开上传下载弹框
|
||||||
openUploadImage(item, trialCriterion, status) {
|
openUploadImage(item, trialCriterion, status) {
|
||||||
|
this.uploadSubjectCode = item.SubjectCode
|
||||||
this.uploadSubjectId = item.SubjectId
|
this.uploadSubjectId = item.SubjectId
|
||||||
this.uploadTrialCriterion = trialCriterion
|
this.uploadTrialCriterion = trialCriterion
|
||||||
this.uploadStatus = status
|
this.uploadStatus = status
|
||||||
this.uploadImageVisible = true
|
this[`${status}ImageVisible`] = true
|
||||||
},
|
},
|
||||||
async getTrialCriterionList() {
|
async getTrialCriterionList() {
|
||||||
try {
|
try {
|
||||||
|
|
@ -360,8 +382,7 @@ export default {
|
||||||
this.isRender = false
|
this.isRender = false
|
||||||
const res = await getIRUnReadSubjectTaskList(this.searchData)
|
const res = await getIRUnReadSubjectTaskList(this.searchData)
|
||||||
if (res.IsSuccess) {
|
if (res.IsSuccess) {
|
||||||
this.isReadingTaskViewInOrder =
|
this.isReadingTaskViewInOrder = res.OtherInfo.IsReadingTaskViewInOrder
|
||||||
res.OtherInfo.IsReadingTaskViewInOrder
|
|
||||||
this.readingTool = res.OtherInfo.ReadingTool
|
this.readingTool = res.OtherInfo.ReadingTool
|
||||||
this.criterionType = res.OtherInfo.CriterionType
|
this.criterionType = res.OtherInfo.CriterionType
|
||||||
if (res.OtherInfo.IsReadingTaskViewInOrder) {
|
if (res.OtherInfo.IsReadingTaskViewInOrder) {
|
||||||
|
|
@ -395,7 +416,10 @@ export default {
|
||||||
await clearSkipReadingCache()
|
await clearSkipReadingCache()
|
||||||
await verifyReadingRestTime()
|
await verifyReadingRestTime()
|
||||||
this.loading = false
|
this.loading = false
|
||||||
window.localStorage.setItem('TrialReadingCriterionId', this.TrialReadingCriterionId)
|
window.localStorage.setItem(
|
||||||
|
'TrialReadingCriterionId',
|
||||||
|
this.TrialReadingCriterionId
|
||||||
|
)
|
||||||
var token = getToken()
|
var token = getToken()
|
||||||
var path = ''
|
var path = ''
|
||||||
if (this.readingTool === 0) {
|
if (this.readingTool === 0) {
|
||||||
|
|
@ -420,7 +444,10 @@ export default {
|
||||||
await clearSkipReadingCache()
|
await clearSkipReadingCache()
|
||||||
await verifyReadingRestTime()
|
await verifyReadingRestTime()
|
||||||
this.loading = false
|
this.loading = false
|
||||||
window.localStorage.setItem('TrialReadingCriterionId', this.TrialReadingCriterionId)
|
window.localStorage.setItem(
|
||||||
|
'TrialReadingCriterionId',
|
||||||
|
this.TrialReadingCriterionId
|
||||||
|
)
|
||||||
var token = getToken()
|
var token = getToken()
|
||||||
var path = ''
|
var path = ''
|
||||||
if (this.readingTool === 0) {
|
if (this.readingTool === 0) {
|
||||||
|
|
@ -450,7 +477,7 @@ export default {
|
||||||
this.searchData.SortField = column.prop
|
this.searchData.SortField = column.prop
|
||||||
this.searchData.PageIndex = 1
|
this.searchData.PageIndex = 1
|
||||||
this.getList()
|
this.getList()
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
|
||||||
|
|
@ -381,7 +381,7 @@
|
||||||
/>
|
/>
|
||||||
<!-- 退回 -->
|
<!-- 退回 -->
|
||||||
<el-button
|
<el-button
|
||||||
:disabled="scope.row.ReadingTaskState === 2 || scope.row.ReadingCategory !== 1 || scope.row.TaskState !== 0"
|
:disabled="scope.row.ReadingTaskState === 2 || scope.row.ReadingCategory !== 1 || scope.row.TaskState !== 0 || scope.row.IsManualGeneration"
|
||||||
v-if="hasPermi(['trials:trials-panel:readingTracking:edit'])"
|
v-if="hasPermi(['trials:trials-panel:readingTracking:edit'])"
|
||||||
icon="el-icon-back"
|
icon="el-icon-back"
|
||||||
circle
|
circle
|
||||||
|
|
|
||||||
|
|
@ -84,7 +84,7 @@
|
||||||
</el-button>
|
</el-button>
|
||||||
<!-- 预览 -->
|
<!-- 预览 -->
|
||||||
<el-button
|
<el-button
|
||||||
:disabled="otherInfo.QuestionCount===0"
|
:disabled="!otherInfo.IsHaveQuestion"
|
||||||
type="primary"
|
type="primary"
|
||||||
icon="el-icon-view"
|
icon="el-icon-view"
|
||||||
@click="preview.visible = true"
|
@click="preview.visible = true"
|
||||||
|
|
@ -118,7 +118,7 @@
|
||||||
</el-button>
|
</el-button>
|
||||||
<el-button
|
<el-button
|
||||||
v-if="!otherInfo.IsConfirmMedicineQuestion && hasPermi(['trials:trials-panel:setting:medical-audit:confirm'])"
|
v-if="!otherInfo.IsConfirmMedicineQuestion && hasPermi(['trials:trials-panel:setting:medical-audit:confirm'])"
|
||||||
:disabled="otherInfo.QuestionCount===0"
|
:disabled="!otherInfo.IsHaveQuestion"
|
||||||
type="danger"
|
type="danger"
|
||||||
icon="el-icon-circle-check"
|
icon="el-icon-circle-check"
|
||||||
@click="handleConfirm"
|
@click="handleConfirm"
|
||||||
|
|
@ -443,7 +443,7 @@ export default {
|
||||||
this.list = res.Result.CurrentPageData
|
this.list = res.Result.CurrentPageData
|
||||||
this.total = res.Result.TotalCount
|
this.total = res.Result.TotalCount
|
||||||
this.isShow = true
|
this.isShow = true
|
||||||
this.otherInfo.IsConfirmMedicineQuestion = false
|
// this.otherInfo.IsConfirmMedicineQuestion = false
|
||||||
this.otherInfo = res.OtherInfo
|
this.otherInfo = res.OtherInfo
|
||||||
}).catch(() => { this.loading = false })
|
}).catch(() => { this.loading = false })
|
||||||
},
|
},
|
||||||
|
|
@ -503,7 +503,7 @@ export default {
|
||||||
|
|
||||||
// 确认前签名
|
// 确认前签名
|
||||||
handleConfirm() {
|
handleConfirm() {
|
||||||
if (this.otherInfo.QuestionCount === 0) {
|
if (!this.otherInfo.IsHaveQuestion) {
|
||||||
// '请先配置医学审核问题再进行确认!'
|
// '请先配置医学审核问题再进行确认!'
|
||||||
this.$alert(this.$t('trials:medicalFeedbackCfg:message:msg1'))
|
this.$alert(this.$t('trials:medicalFeedbackCfg:message:msg1'))
|
||||||
return
|
return
|
||||||
|
|
|
||||||
|
|
@ -103,6 +103,7 @@
|
||||||
<el-button
|
<el-button
|
||||||
circle
|
circle
|
||||||
icon="el-icon-delete"
|
icon="el-icon-delete"
|
||||||
|
:disabled="scope.row.IsJoin"
|
||||||
:title="$t('trials:externalStaff:button:delete')"
|
:title="$t('trials:externalStaff:button:delete')"
|
||||||
@click="deleteTrialExternalUser(scope.row)"
|
@click="deleteTrialExternalUser(scope.row)"
|
||||||
/>
|
/>
|
||||||
|
|
|
||||||
|
|
@ -41,7 +41,7 @@
|
||||||
type="primary"
|
type="primary"
|
||||||
:disabled="OtherInfo.IsSign"
|
:disabled="OtherInfo.IsSign"
|
||||||
@click="apply(item.ReadingQuestionTrialId, index)"
|
@click="apply(item.ReadingQuestionTrialId, index)"
|
||||||
>{{ $t("common:button:save") }}</el-button
|
>{{ $t('common:button:save') }}</el-button
|
||||||
>
|
>
|
||||||
<el-button
|
<el-button
|
||||||
v-hasPermi="['trials:trials-panel:setting:reading-unit:edit']"
|
v-hasPermi="['trials:trials-panel:setting:reading-unit:edit']"
|
||||||
|
|
@ -50,7 +50,7 @@
|
||||||
type="primary"
|
type="primary"
|
||||||
:disabled="OtherInfo.IsSign"
|
:disabled="OtherInfo.IsSign"
|
||||||
@click="reset(item.ReadingQuestionTrialId, index)"
|
@click="reset(item.ReadingQuestionTrialId, index)"
|
||||||
>{{ $t("common:button:reset") }}</el-button
|
>{{ $t('common:button:reset') }}</el-button
|
||||||
>
|
>
|
||||||
<!-- 产生裁判阅片的条件 -->
|
<!-- 产生裁判阅片的条件 -->
|
||||||
<el-form-item
|
<el-form-item
|
||||||
|
|
@ -71,13 +71,16 @@
|
||||||
:label="item.value"
|
:label="item.value"
|
||||||
v-if="
|
v-if="
|
||||||
(JudgyInfo.ArbitrationRule === 1 &&
|
(JudgyInfo.ArbitrationRule === 1 &&
|
||||||
QuestionList[index].Type === 'number' &&
|
(QuestionList[index].Type === 'number' ||
|
||||||
|
QuestionList[index].Type === 'calculation') &&
|
||||||
item.value !== 2 &&
|
item.value !== 2 &&
|
||||||
item.value !== 3) ||
|
item.value !== 3) ||
|
||||||
(JudgyInfo.ArbitrationRule === 2 &&
|
(JudgyInfo.ArbitrationRule === 2 &&
|
||||||
QuestionList[index].Type === 'number' &&
|
(QuestionList[index].Type === 'number' ||
|
||||||
|
QuestionList[index].Type === 'calculation') &&
|
||||||
item.value === 1) ||
|
item.value === 1) ||
|
||||||
(QuestionList[index].Type !== 'number' &&
|
((QuestionList[index].Type === 'number' ||
|
||||||
|
QuestionList[index].Type === 'calculation') &&
|
||||||
item.value !== 4 &&
|
item.value !== 4 &&
|
||||||
item.value !== 5)
|
item.value !== 5)
|
||||||
"
|
"
|
||||||
|
|
@ -98,7 +101,7 @@
|
||||||
type="primary"
|
type="primary"
|
||||||
:disabled="OtherInfo.IsSign"
|
:disabled="OtherInfo.IsSign"
|
||||||
@click="addGroup(index, null)"
|
@click="addGroup(index, null)"
|
||||||
>{{ $t("trials:adRules:button:addRule") }}</el-button
|
>{{ $t('trials:adRules:button:addRule') }}</el-button
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
<el-table
|
<el-table
|
||||||
|
|
@ -211,14 +214,14 @@
|
||||||
</el-checkbox-group>
|
</el-checkbox-group>
|
||||||
<div style="margin-top: 20px">
|
<div style="margin-top: 20px">
|
||||||
<!-- 当前选择答案分组: -->
|
<!-- 当前选择答案分组: -->
|
||||||
{{ $t("trials:adRules:title:selectAnswerGroup") }}
|
{{ $t('trials:adRules:title:selectAnswerGroup') }}
|
||||||
<el-tag
|
<el-tag
|
||||||
v-if="
|
v-if="
|
||||||
QuestionList[index].grouping.length > 0 &&
|
QuestionList[index].grouping.length > 0 &&
|
||||||
QuestionList[index].QuestionGenre !== 3
|
QuestionList[index].QuestionGenre !== 3
|
||||||
"
|
"
|
||||||
>{{
|
>{{
|
||||||
QuestionList[index].grouping.toString().replaceAll(",", "|")
|
QuestionList[index].grouping.toString().replaceAll(',', '|')
|
||||||
}}</el-tag
|
}}</el-tag
|
||||||
>
|
>
|
||||||
<el-tag
|
<el-tag
|
||||||
|
|
@ -235,7 +238,7 @@
|
||||||
).label
|
).label
|
||||||
)
|
)
|
||||||
.toString()
|
.toString()
|
||||||
.replaceAll(",", "|")
|
.replaceAll(',', '|')
|
||||||
}}</el-tag
|
}}</el-tag
|
||||||
>
|
>
|
||||||
<el-button
|
<el-button
|
||||||
|
|
@ -245,7 +248,7 @@
|
||||||
@click="addGroup2(index)"
|
@click="addGroup2(index)"
|
||||||
>
|
>
|
||||||
<!-- 添加分组 -->
|
<!-- 添加分组 -->
|
||||||
{{ $t("trials:adRules:title:addGroup") }}
|
{{ $t('trials:adRules:title:addGroup') }}
|
||||||
</el-button>
|
</el-button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -253,7 +256,7 @@
|
||||||
v-if="QuestionList[index].QuestionGenre !== 3"
|
v-if="QuestionList[index].QuestionGenre !== 3"
|
||||||
style="margin-top: 20px"
|
style="margin-top: 20px"
|
||||||
>
|
>
|
||||||
{{ $t("trials:adRules:title:group") }}
|
{{ $t('trials:adRules:title:group') }}
|
||||||
<el-tag
|
<el-tag
|
||||||
v-for="itemA of QuestionList[index].AnswerGroup2List"
|
v-for="itemA of QuestionList[index].AnswerGroup2List"
|
||||||
:key="itemA"
|
:key="itemA"
|
||||||
|
|
@ -261,7 +264,7 @@
|
||||||
style="margin-right: 10px"
|
style="margin-right: 10px"
|
||||||
@close="
|
@close="
|
||||||
() => {
|
() => {
|
||||||
return tagClose2(index, indexA);
|
return tagClose2(index, indexA)
|
||||||
}
|
}
|
||||||
"
|
"
|
||||||
>{{ itemA }}</el-tag
|
>{{ itemA }}</el-tag
|
||||||
|
|
@ -272,7 +275,7 @@
|
||||||
style="margin-top: 20px"
|
style="margin-top: 20px"
|
||||||
>
|
>
|
||||||
<!-- 分组: -->
|
<!-- 分组: -->
|
||||||
{{ $t("trials:adRules:title:group") }}
|
{{ $t('trials:adRules:title:group') }}
|
||||||
<el-tag
|
<el-tag
|
||||||
v-for="itemA of QuestionList[index].AnswerGroup2List"
|
v-for="itemA of QuestionList[index].AnswerGroup2List"
|
||||||
:key="itemA"
|
:key="itemA"
|
||||||
|
|
@ -280,17 +283,17 @@
|
||||||
style="margin-right: 10px"
|
style="margin-right: 10px"
|
||||||
@close="
|
@close="
|
||||||
() => {
|
() => {
|
||||||
return tagClose2(index, indexA);
|
return tagClose2(index, indexA)
|
||||||
}
|
}
|
||||||
"
|
"
|
||||||
>
|
>
|
||||||
{{
|
{{
|
||||||
itemA
|
itemA
|
||||||
.split("|")
|
.split('|')
|
||||||
.map((v) =>
|
.map((v) =>
|
||||||
$fd(QuestionList[index].DictionaryCode, parseInt(v))
|
$fd(QuestionList[index].DictionaryCode, parseInt(v))
|
||||||
)
|
)
|
||||||
.join("|")
|
.join('|')
|
||||||
}}
|
}}
|
||||||
</el-tag>
|
</el-tag>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -340,11 +343,16 @@
|
||||||
"
|
"
|
||||||
prop="JudgeDifferenceValue"
|
prop="JudgeDifferenceValue"
|
||||||
>
|
>
|
||||||
|
<div style="display: flex">
|
||||||
<el-input
|
<el-input
|
||||||
v-model="QuestionList[index].JudgeDifferenceValue"
|
v-model="QuestionList[index].JudgeDifferenceValue"
|
||||||
clearable
|
clearable
|
||||||
:disabled="OtherInfo.IsSign"
|
:disabled="OtherInfo.IsSign"
|
||||||
></el-input>
|
></el-input>
|
||||||
|
<span style="margin-left: 10px">{{
|
||||||
|
$fd('ValueUnit', QuestionList[index].Unit)
|
||||||
|
}}</span>
|
||||||
|
</div>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-form>
|
</el-form>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -457,12 +465,12 @@
|
||||||
size="small"
|
size="small"
|
||||||
type="primary"
|
type="primary"
|
||||||
@click="
|
@click="
|
||||||
QuestionVisible = false;
|
QuestionVisible = false
|
||||||
$set(QuestionList[selectIndex], 'groupingA', []);
|
$set(QuestionList[selectIndex], 'groupingA', [])
|
||||||
$set(QuestionList[selectIndex], 'groupingB', []);
|
$set(QuestionList[selectIndex], 'groupingB', [])
|
||||||
"
|
"
|
||||||
>
|
>
|
||||||
{{ $t("common:button:cancel") }}
|
{{ $t('common:button:cancel') }}
|
||||||
</el-button>
|
</el-button>
|
||||||
<el-button
|
<el-button
|
||||||
v-hasPermi="['trials:trials-panel:setting:reading-unit:edit']"
|
v-hasPermi="['trials:trials-panel:setting:reading-unit:edit']"
|
||||||
|
|
@ -471,7 +479,7 @@
|
||||||
type="primary"
|
type="primary"
|
||||||
@click="save"
|
@click="save"
|
||||||
>
|
>
|
||||||
{{ $t("common:button:save") }}
|
{{ $t('common:button:save') }}
|
||||||
</el-button>
|
</el-button>
|
||||||
</div>
|
</div>
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
|
|
@ -482,13 +490,13 @@ import {
|
||||||
getTrialConfirmCriterionList,
|
getTrialConfirmCriterionList,
|
||||||
getTrialCriterionJudgeQuestionList,
|
getTrialCriterionJudgeQuestionList,
|
||||||
setTrialCriterionJudgeQuestionAnswerGroup,
|
setTrialCriterionJudgeQuestionAnswerGroup,
|
||||||
} from "@/api/trials/reading";
|
} from '@/api/trials/reading'
|
||||||
import { setTrialJudgyInfo, getTrialJudgyInfo } from "@/api/trials/setting";
|
import { setTrialJudgyInfo, getTrialJudgyInfo } from '@/api/trials/setting'
|
||||||
export default {
|
export default {
|
||||||
props: {
|
props: {
|
||||||
trialReadingCriterionId: {
|
trialReadingCriterionId: {
|
||||||
type: String,
|
type: String,
|
||||||
default: "",
|
default: '',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
|
|
@ -512,23 +520,23 @@ export default {
|
||||||
{
|
{
|
||||||
required: true,
|
required: true,
|
||||||
message: this.$t(
|
message: this.$t(
|
||||||
"trials:trials-list:setitng:JudgeDifferenceTypeRequired"
|
'trials:trials-list:setitng:JudgeDifferenceTypeRequired'
|
||||||
),
|
),
|
||||||
trigger: "blur",
|
trigger: 'blur',
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
JudgeDifferenceValue: [
|
JudgeDifferenceValue: [
|
||||||
{
|
{
|
||||||
required: true,
|
required: true,
|
||||||
message: this.$t(
|
message: this.$t(
|
||||||
"trials:trials-list:setitng:JudgeDifferenceValueRequired"
|
'trials:trials-list:setitng:JudgeDifferenceValueRequired'
|
||||||
),
|
),
|
||||||
trigger: "blur",
|
trigger: 'blur',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
pattern: /^[0-9]+(.[0-9]{2})?$/,
|
pattern: /^[0-9]+(.[0-9]{2})?$/,
|
||||||
message: this.$t("trials:trials-list:setitng:JudgeDifferenceValue"),
|
message: this.$t('trials:trials-list:setitng:JudgeDifferenceValue'),
|
||||||
trigger: "blur",
|
trigger: 'blur',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
validator: (rule, value, callback) => {
|
validator: (rule, value, callback) => {
|
||||||
|
|
@ -536,115 +544,115 @@ export default {
|
||||||
callback(
|
callback(
|
||||||
new Error(
|
new Error(
|
||||||
this.$t(
|
this.$t(
|
||||||
"trials:trials-list:setitng:JudgeDifferenceValueMin"
|
'trials:trials-list:setitng:JudgeDifferenceValueMin'
|
||||||
|
)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
);
|
|
||||||
} else {
|
} else {
|
||||||
callback();
|
callback()
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
trigger: "blur",
|
trigger: 'blur',
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
};
|
}
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
TrialReadingCriterionId(v) {
|
TrialReadingCriterionId(v) {
|
||||||
if (v === null) return;
|
if (v === null) return
|
||||||
this.loading = true;
|
this.loading = true
|
||||||
getTrialCriterionJudgeQuestionList({
|
getTrialCriterionJudgeQuestionList({
|
||||||
TrialId: this.$route.query.trialId,
|
TrialId: this.$route.query.trialId,
|
||||||
// ReadingQuestionCriterionTrialId: v,
|
// ReadingQuestionCriterionTrialId: v,
|
||||||
TrialReadingCriterionId: this.trialReadingCriterionId,
|
TrialReadingCriterionId: this.trialReadingCriterionId,
|
||||||
})
|
})
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
this.loading = false;
|
this.loading = false
|
||||||
this.QuestionList = res.Result;
|
this.QuestionList = res.Result
|
||||||
this.OtherInfo = res.OtherInfo;
|
this.OtherInfo = res.OtherInfo
|
||||||
this.activeNames = this.QuestionList.map(
|
this.activeNames = this.QuestionList.map(
|
||||||
(v) => v.ReadingQuestionTrialId
|
(v) => v.ReadingQuestionTrialId
|
||||||
);
|
)
|
||||||
this.QuestionList.forEach((v) => {
|
this.QuestionList.forEach((v) => {
|
||||||
this.$set(v, "grouping", []);
|
this.$set(v, 'grouping', [])
|
||||||
this.$set(v, "groupingA", []);
|
this.$set(v, 'groupingA', [])
|
||||||
this.$set(v, "groupingB", []);
|
this.$set(v, 'groupingB', [])
|
||||||
this.$set(
|
this.$set(
|
||||||
v,
|
v,
|
||||||
"AnswerGroupList",
|
'AnswerGroupList',
|
||||||
Object.assign([], v.AnswerCombination)
|
Object.assign([], v.AnswerCombination)
|
||||||
);
|
)
|
||||||
this.$set(v, "AnswerGroup2List", Object.assign([], v.AnswerGroup));
|
this.$set(v, 'AnswerGroup2List', Object.assign([], v.AnswerGroup))
|
||||||
});
|
})
|
||||||
})
|
})
|
||||||
.catch(() => {
|
.catch(() => {
|
||||||
this.btnLoading = false;
|
this.btnLoading = false
|
||||||
this.loading = false;
|
this.loading = false
|
||||||
});
|
})
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
this.getList();
|
this.getList()
|
||||||
this.getTrialJudgyInfo();
|
this.getTrialJudgyInfo()
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
// 修改仲裁规则
|
// 修改仲裁规则
|
||||||
changeArbitrationRule(value) {
|
changeArbitrationRule(value) {
|
||||||
if (value !== 1) {
|
if (value !== 1) {
|
||||||
this.QuestionList.forEach((item) => {
|
this.QuestionList.forEach((item) => {
|
||||||
item.JudgeDifferenceValue = 0;
|
item.JudgeDifferenceValue = 0
|
||||||
item.JudgeDifferenceType = 0;
|
item.JudgeDifferenceType = 0
|
||||||
});
|
})
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
JudgeTypeChange(value, index) {
|
JudgeTypeChange(value, index) {
|
||||||
this.$nextTick(() => {
|
this.$nextTick(() => {
|
||||||
if (value === 4 || value === 5) {
|
if (value === 4 || value === 5) {
|
||||||
if (this.$refs["JudgeDifferenceValue" + value + index][0]) {
|
if (this.$refs['JudgeDifferenceValue' + value + index][0]) {
|
||||||
this.$refs["JudgeDifferenceValue" + value + index][0].resetFields();
|
this.$refs['JudgeDifferenceValue' + value + index][0].resetFields()
|
||||||
// this.QuestionList[index].JudgeDifferenceValue = 0;
|
// this.QuestionList[index].JudgeDifferenceValue = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
})
|
||||||
},
|
},
|
||||||
saveAllSync() {
|
saveAllSync() {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
var arr = [];
|
var arr = []
|
||||||
this.QuestionList.forEach((v, i) => {
|
this.QuestionList.forEach((v, i) => {
|
||||||
arr.push(this.applySync(v.ReadingQuestionTrialId, i));
|
arr.push(this.applySync(v.ReadingQuestionTrialId, i))
|
||||||
});
|
})
|
||||||
Promise.all(arr)
|
Promise.all(arr)
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
console.log(res);
|
console.log(res)
|
||||||
resolve(true);
|
resolve(true)
|
||||||
})
|
})
|
||||||
.catch((res) => {
|
.catch((res) => {
|
||||||
console.log("进入catch");
|
console.log('进入catch')
|
||||||
resolve(false);
|
resolve(false)
|
||||||
});
|
})
|
||||||
});
|
})
|
||||||
},
|
},
|
||||||
applySync(ReadingQuestionTrialId, index) {
|
applySync(ReadingQuestionTrialId, index) {
|
||||||
return new Promise(async (resolve, reject) => {
|
return new Promise(async (resolve, reject) => {
|
||||||
console.log(this.QuestionList[index].JudgeType);
|
console.log(this.QuestionList[index].JudgeType)
|
||||||
if (this.QuestionList[index].JudgeType === 0) {
|
if (this.QuestionList[index].JudgeType === 0) {
|
||||||
reject(false);
|
reject(false)
|
||||||
return;
|
return
|
||||||
}
|
}
|
||||||
if (
|
if (
|
||||||
this.QuestionList[index].JudgeType === 2 &&
|
this.QuestionList[index].JudgeType === 2 &&
|
||||||
this.QuestionList[index].AnswerGroup2List.length === 0
|
this.QuestionList[index].AnswerGroup2List.length === 0
|
||||||
) {
|
) {
|
||||||
reject(false);
|
reject(false)
|
||||||
return;
|
return
|
||||||
}
|
}
|
||||||
if (
|
if (
|
||||||
this.QuestionList[index].JudgeType === 3 &&
|
this.QuestionList[index].JudgeType === 3 &&
|
||||||
this.QuestionList[index].AnswerGroupList.length === 0
|
this.QuestionList[index].AnswerGroupList.length === 0
|
||||||
) {
|
) {
|
||||||
reject(false);
|
reject(false)
|
||||||
return;
|
return
|
||||||
}
|
}
|
||||||
if (
|
if (
|
||||||
this.QuestionList[index].JudgeType === 4 ||
|
this.QuestionList[index].JudgeType === 4 ||
|
||||||
|
|
@ -652,17 +660,17 @@ export default {
|
||||||
) {
|
) {
|
||||||
try {
|
try {
|
||||||
let validate = await this.$refs[
|
let validate = await this.$refs[
|
||||||
"JudgeDifferenceValue" +
|
'JudgeDifferenceValue' +
|
||||||
this.QuestionList[index].JudgeType +
|
this.QuestionList[index].JudgeType +
|
||||||
index
|
index
|
||||||
][0].validate();
|
][0].validate()
|
||||||
if (!validate) return reject(false);
|
if (!validate) return reject(false)
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
return reject(false);
|
return reject(false)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
this.btnLoading = true;
|
this.btnLoading = true
|
||||||
this.loading = true;
|
this.loading = true
|
||||||
setTrialCriterionJudgeQuestionAnswerGroup({
|
setTrialCriterionJudgeQuestionAnswerGroup({
|
||||||
ReadingQuestionTrialId: ReadingQuestionTrialId,
|
ReadingQuestionTrialId: ReadingQuestionTrialId,
|
||||||
AnswerGroup: this.QuestionList[index].AnswerGroup2List,
|
AnswerGroup: this.QuestionList[index].AnswerGroup2List,
|
||||||
|
|
@ -676,126 +684,126 @@ export default {
|
||||||
),
|
),
|
||||||
})
|
})
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
resolve();
|
resolve()
|
||||||
this.btnLoading = false;
|
this.btnLoading = false
|
||||||
this.loading = false;
|
this.loading = false
|
||||||
})
|
})
|
||||||
.catch(() => {
|
.catch(() => {
|
||||||
reject(false);
|
reject(false)
|
||||||
this.btnLoading = false;
|
this.btnLoading = false
|
||||||
this.loading = false;
|
this.loading = false
|
||||||
});
|
})
|
||||||
});
|
})
|
||||||
},
|
},
|
||||||
setTrialJudgyInfo() {
|
setTrialJudgyInfo() {
|
||||||
this.loading = true;
|
this.loading = true
|
||||||
setTrialJudgyInfo({
|
setTrialJudgyInfo({
|
||||||
TrialId: this.$route.query.trialId,
|
TrialId: this.$route.query.trialId,
|
||||||
ArbitrationRule: this.JudgyInfo.ArbitrationRule,
|
ArbitrationRule: this.JudgyInfo.ArbitrationRule,
|
||||||
TrialReadingCriterionId: this.trialReadingCriterionId,
|
TrialReadingCriterionId: this.trialReadingCriterionId,
|
||||||
})
|
})
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
this.loading = false;
|
this.loading = false
|
||||||
this.$message.success(this.$t("common:message:savedSuccessfully")); // '保存成功'
|
this.$message.success(this.$t('common:message:savedSuccessfully')) // '保存成功'
|
||||||
})
|
})
|
||||||
.catch(() => {
|
.catch(() => {
|
||||||
this.loading = false;
|
this.loading = false
|
||||||
});
|
})
|
||||||
},
|
},
|
||||||
getTrialJudgyInfo() {
|
getTrialJudgyInfo() {
|
||||||
this.loading = true;
|
this.loading = true
|
||||||
getTrialJudgyInfo({
|
getTrialJudgyInfo({
|
||||||
TrialId: this.$route.query.trialId,
|
TrialId: this.$route.query.trialId,
|
||||||
TrialReadingCriterionId: this.trialReadingCriterionId,
|
TrialReadingCriterionId: this.trialReadingCriterionId,
|
||||||
})
|
})
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
this.JudgyInfo = res.Result;
|
this.JudgyInfo = res.Result
|
||||||
this.loading = false;
|
this.loading = false
|
||||||
})
|
})
|
||||||
.catch((v) => {
|
.catch((v) => {
|
||||||
this.loading = false;
|
this.loading = false
|
||||||
});
|
})
|
||||||
},
|
},
|
||||||
tagClose2(index, indexA) {
|
tagClose2(index, indexA) {
|
||||||
// '删除该规则组?'
|
// '删除该规则组?'
|
||||||
this.$confirm(this.$t("trials:adRules:message:msg1")).then(() => {
|
this.$confirm(this.$t('trials:adRules:message:msg1')).then(() => {
|
||||||
this.QuestionList[index].AnswerGroup2List.splice(indexA, 1);
|
this.QuestionList[index].AnswerGroup2List.splice(indexA, 1)
|
||||||
});
|
})
|
||||||
},
|
},
|
||||||
tagClose(index, indexA) {
|
tagClose(index, indexA) {
|
||||||
// '删除该规则组?'
|
// '删除该规则组?'
|
||||||
this.$confirm(this.$t("trials:adRules:message:msg1")).then(() => {
|
this.$confirm(this.$t('trials:adRules:message:msg1')).then(() => {
|
||||||
this.QuestionList[index].AnswerGroupList.splice(indexA, 1);
|
this.QuestionList[index].AnswerGroupList.splice(indexA, 1)
|
||||||
});
|
})
|
||||||
},
|
},
|
||||||
save() {
|
save() {
|
||||||
var index = this.selectIndex;
|
var index = this.selectIndex
|
||||||
var indexA = this.indexA;
|
var indexA = this.indexA
|
||||||
if (this.QuestionList[index].groupingA.length === 0) {
|
if (this.QuestionList[index].groupingA.length === 0) {
|
||||||
this.$alert(this.$t("trials:adRules:message:msg2")); // '请先选择答案A'
|
this.$alert(this.$t('trials:adRules:message:msg2')) // '请先选择答案A'
|
||||||
return;
|
return
|
||||||
}
|
}
|
||||||
if (this.QuestionList[index].groupingB.length === 0) {
|
if (this.QuestionList[index].groupingB.length === 0) {
|
||||||
this.$alert(this.$t("trials:adRules:message:msg3")); // '请先选择答案B'
|
this.$alert(this.$t('trials:adRules:message:msg3')) // '请先选择答案B'
|
||||||
return;
|
return
|
||||||
}
|
}
|
||||||
if (this.type === "add") {
|
if (this.type === 'add') {
|
||||||
this.QuestionList[index].AnswerGroupList.push({
|
this.QuestionList[index].AnswerGroupList.push({
|
||||||
AnswerGroupA: this.QuestionList[index].groupingA,
|
AnswerGroupA: this.QuestionList[index].groupingA,
|
||||||
AnswerGroupB: this.QuestionList[index].groupingB,
|
AnswerGroupB: this.QuestionList[index].groupingB,
|
||||||
});
|
})
|
||||||
} else {
|
} else {
|
||||||
this.$set(
|
this.$set(
|
||||||
this.QuestionList[index].AnswerGroupList[indexA],
|
this.QuestionList[index].AnswerGroupList[indexA],
|
||||||
"AnswerGroupA",
|
'AnswerGroupA',
|
||||||
this.QuestionList[index].groupingA
|
this.QuestionList[index].groupingA
|
||||||
);
|
)
|
||||||
this.$set(
|
this.$set(
|
||||||
this.QuestionList[index].AnswerGroupList[indexA],
|
this.QuestionList[index].AnswerGroupList[indexA],
|
||||||
"AnswerGroupB",
|
'AnswerGroupB',
|
||||||
this.QuestionList[index].groupingB
|
this.QuestionList[index].groupingB
|
||||||
);
|
)
|
||||||
}
|
}
|
||||||
this.$set(this.QuestionList[index], "groupingA", []);
|
this.$set(this.QuestionList[index], 'groupingA', [])
|
||||||
this.$set(this.QuestionList[index], "groupingB", []);
|
this.$set(this.QuestionList[index], 'groupingB', [])
|
||||||
this.$message.success(this.$t("trials:adRules:message:msg4")); // '成功新增答案规则'
|
this.$message.success(this.$t('trials:adRules:message:msg4')) // '成功新增答案规则'
|
||||||
this.QuestionVisible = false;
|
this.QuestionVisible = false
|
||||||
},
|
},
|
||||||
addGroup2(index) {
|
addGroup2(index) {
|
||||||
if (this.QuestionList[index].grouping.length === 0) {
|
if (this.QuestionList[index].grouping.length === 0) {
|
||||||
this.$alert(this.$t("trials:adRules:message:msg5")); // '请先选择答案,再添加分组'
|
this.$alert(this.$t('trials:adRules:message:msg5')) // '请先选择答案,再添加分组'
|
||||||
return;
|
return
|
||||||
}
|
}
|
||||||
var grouping = this.QuestionList[index].grouping
|
var grouping = this.QuestionList[index].grouping
|
||||||
.toString()
|
.toString()
|
||||||
.replaceAll(",", "|");
|
.replaceAll(',', '|')
|
||||||
this.QuestionList[index].AnswerGroup2List.push(`|${grouping}|`);
|
this.QuestionList[index].AnswerGroup2List.push(`|${grouping}|`)
|
||||||
this.$set(this.QuestionList[index], "grouping", []);
|
this.$set(this.QuestionList[index], 'grouping', [])
|
||||||
},
|
},
|
||||||
addGroup(index, indexA) {
|
addGroup(index, indexA) {
|
||||||
this.selectIndex = index;
|
this.selectIndex = index
|
||||||
this.type = "add";
|
this.type = 'add'
|
||||||
if (indexA !== null) {
|
if (indexA !== null) {
|
||||||
this.indexA = indexA;
|
this.indexA = indexA
|
||||||
this.type = "edit";
|
this.type = 'edit'
|
||||||
this.$set(
|
this.$set(
|
||||||
this.QuestionList[index],
|
this.QuestionList[index],
|
||||||
"groupingA",
|
'groupingA',
|
||||||
this.QuestionList[index].AnswerGroupList[indexA].AnswerGroupA
|
this.QuestionList[index].AnswerGroupList[indexA].AnswerGroupA
|
||||||
);
|
)
|
||||||
this.$set(
|
this.$set(
|
||||||
this.QuestionList[index],
|
this.QuestionList[index],
|
||||||
"groupingB",
|
'groupingB',
|
||||||
this.QuestionList[index].AnswerGroupList[indexA].AnswerGroupB
|
this.QuestionList[index].AnswerGroupList[indexA].AnswerGroupB
|
||||||
);
|
)
|
||||||
}
|
}
|
||||||
this.QuestionVisible = true;
|
this.QuestionVisible = true
|
||||||
},
|
},
|
||||||
reset(ReadingQuestionTrialId, index) {
|
reset(ReadingQuestionTrialId, index) {
|
||||||
// '确定重置当前设置的裁判任务生成规则吗?'
|
// '确定重置当前设置的裁判任务生成规则吗?'
|
||||||
this.$confirm(this.$t("trials:adRules:message:msg6")).then(() => {
|
this.$confirm(this.$t('trials:adRules:message:msg6')).then(() => {
|
||||||
this.btnLoading = true;
|
this.btnLoading = true
|
||||||
this.loading = true;
|
this.loading = true
|
||||||
setTrialCriterionJudgeQuestionAnswerGroup({
|
setTrialCriterionJudgeQuestionAnswerGroup({
|
||||||
ReadingQuestionTrialId: ReadingQuestionTrialId,
|
ReadingQuestionTrialId: ReadingQuestionTrialId,
|
||||||
AnswerGroup: [],
|
AnswerGroup: [],
|
||||||
|
|
@ -805,39 +813,39 @@ export default {
|
||||||
JudgeDifferenceType: 0,
|
JudgeDifferenceType: 0,
|
||||||
})
|
})
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
this.$set(this.QuestionList[index], "AnswerGroup2List", []);
|
this.$set(this.QuestionList[index], 'AnswerGroup2List', [])
|
||||||
this.$set(this.QuestionList[index], "AnswerGroupList", []);
|
this.$set(this.QuestionList[index], 'AnswerGroupList', [])
|
||||||
this.$set(this.QuestionList[index], "JudgeType", 0);
|
this.$set(this.QuestionList[index], 'JudgeType', 0)
|
||||||
this.$set(this.QuestionList[index], "JudgeDifferenceValue", 0);
|
this.$set(this.QuestionList[index], 'JudgeDifferenceValue', 0)
|
||||||
this.$set(this.QuestionList[index], "JudgeDifferenceType", 0);
|
this.$set(this.QuestionList[index], 'JudgeDifferenceType', 0)
|
||||||
this.$message.success(this.$t("trials:adRules:message:msg7")); // '重置成功'
|
this.$message.success(this.$t('trials:adRules:message:msg7')) // '重置成功'
|
||||||
this.btnLoading = false;
|
this.btnLoading = false
|
||||||
this.loading = false;
|
this.loading = false
|
||||||
})
|
})
|
||||||
.catch(() => {
|
.catch(() => {
|
||||||
this.btnLoading = false;
|
this.btnLoading = false
|
||||||
this.loading = false;
|
this.loading = false
|
||||||
});
|
})
|
||||||
});
|
})
|
||||||
},
|
},
|
||||||
async apply(ReadingQuestionTrialId, index) {
|
async apply(ReadingQuestionTrialId, index) {
|
||||||
if (this.QuestionList[index].JudgeType === 0) {
|
if (this.QuestionList[index].JudgeType === 0) {
|
||||||
this.$alert(this.$t("trials:adRules:message:msg8")); // '请先配置规则才能应用'
|
this.$alert(this.$t('trials:adRules:message:msg8')) // '请先配置规则才能应用'
|
||||||
return;
|
return
|
||||||
}
|
}
|
||||||
if (
|
if (
|
||||||
this.QuestionList[index].JudgeType === 2 &&
|
this.QuestionList[index].JudgeType === 2 &&
|
||||||
this.QuestionList[index].AnswerGroup2List.length === 0
|
this.QuestionList[index].AnswerGroup2List.length === 0
|
||||||
) {
|
) {
|
||||||
this.$alert(this.$t("trials:adRules:message:msg8")); // '请先配置规则才能应用'
|
this.$alert(this.$t('trials:adRules:message:msg8')) // '请先配置规则才能应用'
|
||||||
return;
|
return
|
||||||
}
|
}
|
||||||
if (
|
if (
|
||||||
this.QuestionList[index].JudgeType === 3 &&
|
this.QuestionList[index].JudgeType === 3 &&
|
||||||
this.QuestionList[index].AnswerGroupList.length === 0
|
this.QuestionList[index].AnswerGroupList.length === 0
|
||||||
) {
|
) {
|
||||||
this.$alert(this.$t("trials:adRules:message:msg8"));
|
this.$alert(this.$t('trials:adRules:message:msg8'))
|
||||||
return;
|
return
|
||||||
}
|
}
|
||||||
if (
|
if (
|
||||||
this.QuestionList[index].JudgeType === 4 ||
|
this.QuestionList[index].JudgeType === 4 ||
|
||||||
|
|
@ -845,15 +853,15 @@ export default {
|
||||||
) {
|
) {
|
||||||
try {
|
try {
|
||||||
let validate = await this.$refs[
|
let validate = await this.$refs[
|
||||||
"JudgeDifferenceValue" + this.QuestionList[index].JudgeType + index
|
'JudgeDifferenceValue' + this.QuestionList[index].JudgeType + index
|
||||||
][0].validate();
|
][0].validate()
|
||||||
if (!validate) return;
|
if (!validate) return
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
return;
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
this.btnLoading = true;
|
this.btnLoading = true
|
||||||
this.loading = true;
|
this.loading = true
|
||||||
setTrialCriterionJudgeQuestionAnswerGroup({
|
setTrialCriterionJudgeQuestionAnswerGroup({
|
||||||
ReadingQuestionTrialId: ReadingQuestionTrialId,
|
ReadingQuestionTrialId: ReadingQuestionTrialId,
|
||||||
AnswerGroup: this.QuestionList[index].AnswerGroup2List,
|
AnswerGroup: this.QuestionList[index].AnswerGroup2List,
|
||||||
|
|
@ -867,49 +875,49 @@ export default {
|
||||||
),
|
),
|
||||||
})
|
})
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
this.$message.success(this.$t("trials:adRules:message:msg9")); // '应用成功'
|
this.$message.success(this.$t('trials:adRules:message:msg9')) // '应用成功'
|
||||||
this.btnLoading = false;
|
this.btnLoading = false
|
||||||
this.loading = false;
|
this.loading = false
|
||||||
})
|
})
|
||||||
.catch(() => {
|
.catch(() => {
|
||||||
this.btnLoading = false;
|
this.btnLoading = false
|
||||||
this.loading = false;
|
this.loading = false
|
||||||
});
|
})
|
||||||
},
|
},
|
||||||
tabClick(v) {
|
tabClick(v) {
|
||||||
this.ReadingQuestionCriterionTrialId =
|
this.ReadingQuestionCriterionTrialId =
|
||||||
this.CriterionList[this.index].ReadingQuestionCriterionTrialId;
|
this.CriterionList[this.index].ReadingQuestionCriterionTrialId
|
||||||
},
|
},
|
||||||
getList() {
|
getList() {
|
||||||
this.loading = true;
|
this.loading = true
|
||||||
getTrialCriterionJudgeQuestionList({
|
getTrialCriterionJudgeQuestionList({
|
||||||
TrialId: this.$route.query.trialId,
|
TrialId: this.$route.query.trialId,
|
||||||
TrialReadingCriterionId: this.trialReadingCriterionId,
|
TrialReadingCriterionId: this.trialReadingCriterionId,
|
||||||
})
|
})
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
this.loading = false;
|
this.loading = false
|
||||||
this.QuestionList = res.Result;
|
this.QuestionList = res.Result
|
||||||
this.OtherInfo = res.OtherInfo;
|
this.OtherInfo = res.OtherInfo
|
||||||
this.activeNames = this.QuestionList.map(
|
this.activeNames = this.QuestionList.map(
|
||||||
(v) => v.ReadingQuestionTrialId
|
(v) => v.ReadingQuestionTrialId
|
||||||
);
|
)
|
||||||
this.QuestionList.forEach((v) => {
|
this.QuestionList.forEach((v) => {
|
||||||
this.$set(v, "grouping", []);
|
this.$set(v, 'grouping', [])
|
||||||
this.$set(v, "groupingA", []);
|
this.$set(v, 'groupingA', [])
|
||||||
this.$set(v, "groupingB", []);
|
this.$set(v, 'groupingB', [])
|
||||||
this.$set(
|
this.$set(
|
||||||
v,
|
v,
|
||||||
"AnswerGroupList",
|
'AnswerGroupList',
|
||||||
Object.assign([], v.AnswerCombination)
|
Object.assign([], v.AnswerCombination)
|
||||||
);
|
)
|
||||||
this.$set(v, "AnswerGroup2List", Object.assign([], v.AnswerGroup));
|
this.$set(v, 'AnswerGroup2List', Object.assign([], v.AnswerGroup))
|
||||||
});
|
})
|
||||||
})
|
})
|
||||||
.catch(() => {
|
.catch(() => {
|
||||||
this.btnLoading = false;
|
this.btnLoading = false
|
||||||
this.loading = false;
|
this.loading = false
|
||||||
});
|
})
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,7 @@
|
||||||
<!-- '表单问题' -->
|
<!-- '表单问题' -->
|
||||||
<el-form-item :label="$t('trials:readingUnit:readingCriterion:title:formQs')">
|
<el-form-item :label="$t('trials:readingUnit:readingCriterion:title:formQs')">
|
||||||
<QuestionsList
|
<QuestionsList
|
||||||
|
:ref="`questionList${trialReadingCriterionId}`"
|
||||||
v-if="form.FormType===1"
|
v-if="form.FormType===1"
|
||||||
:trial-reading-criterion-id="trialReadingCriterionId"
|
:trial-reading-criterion-id="trialReadingCriterionId"
|
||||||
:list="readingInfo.TrialQuestionList"
|
:list="readingInfo.TrialQuestionList"
|
||||||
|
|
@ -170,6 +171,9 @@ export default {
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
getQuestionLength() {
|
||||||
|
return this.$refs['questionList' + this.trialReadingCriterionId].tblList.length
|
||||||
|
},
|
||||||
reloadArbitrationRules() {
|
reloadArbitrationRules() {
|
||||||
this.$emit('reloadArbitrationRules')
|
this.$emit('reloadArbitrationRules')
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -103,7 +103,13 @@
|
||||||
@click.stop="handleCheckAllChange"
|
@click.stop="handleCheckAllChange"
|
||||||
type="success"
|
type="success"
|
||||||
>{{
|
>{{
|
||||||
$t("trials:readingUnit:readingRules:title:CriterionModalitysAll")
|
CriterionModalitys.length === modalityList.length
|
||||||
|
? $t(
|
||||||
|
'trials:readingUnit:readingRules:title:CriterionModalitysCancel'
|
||||||
|
)
|
||||||
|
: $t(
|
||||||
|
'trials:readingUnit:readingRules:title:CriterionModalitysAll'
|
||||||
|
)
|
||||||
}}</el-button
|
}}</el-button
|
||||||
>
|
>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
@ -131,6 +137,7 @@
|
||||||
<el-form-item
|
<el-form-item
|
||||||
:label="$t('trials:processCfg:form:IsAdditionalAssessment')"
|
:label="$t('trials:processCfg:form:IsAdditionalAssessment')"
|
||||||
prop="IsAdditionalAssessment"
|
prop="IsAdditionalAssessment"
|
||||||
|
v-if="CriterionType === 1"
|
||||||
>
|
>
|
||||||
<el-radio-group
|
<el-radio-group
|
||||||
v-model="form.IsAdditionalAssessment"
|
v-model="form.IsAdditionalAssessment"
|
||||||
|
|
@ -182,7 +189,7 @@
|
||||||
"
|
"
|
||||||
@change="
|
@change="
|
||||||
() => {
|
() => {
|
||||||
form.IsArbitrationReading = false;
|
form.IsArbitrationReading = false
|
||||||
}
|
}
|
||||||
"
|
"
|
||||||
>
|
>
|
||||||
|
|
@ -232,8 +239,8 @@
|
||||||
@change="
|
@change="
|
||||||
(v) => {
|
(v) => {
|
||||||
if (!v) {
|
if (!v) {
|
||||||
form.IsGlobalReading = v;
|
form.IsGlobalReading = v
|
||||||
form.IsOncologyReading = v;
|
form.IsOncologyReading = v
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
"
|
"
|
||||||
|
|
@ -306,15 +313,15 @@
|
||||||
"
|
"
|
||||||
@change="
|
@change="
|
||||||
(v) => {
|
(v) => {
|
||||||
form.ImageDownloadEnum = 0;
|
form.ImageDownloadEnum = 0
|
||||||
form.ImageUploadEnum = 0;
|
form.ImageUploadEnum = 0
|
||||||
if (v) {
|
if (v) {
|
||||||
form.IsReadingShowSubjectInfo = true;
|
form.IsReadingShowSubjectInfo = true
|
||||||
form.IsReadingShowPreviousResults = true;
|
form.IsReadingShowPreviousResults = true
|
||||||
form.ReadingTaskViewEnum = 0;
|
form.ReadingTaskViewEnum = 0
|
||||||
form.IseCRFShowInDicomReading = false;
|
form.IseCRFShowInDicomReading = false
|
||||||
} else {
|
} else {
|
||||||
form.ReadingTaskViewEnum = 2;
|
form.ReadingTaskViewEnum = 2
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
"
|
"
|
||||||
|
|
@ -351,11 +358,10 @@
|
||||||
</el-radio>
|
</el-radio>
|
||||||
</el-radio-group>
|
</el-radio-group>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<!--支持影像下载-->
|
<!--支持影像下载v-if="CriterionType === 0"-->
|
||||||
<el-form-item
|
<el-form-item
|
||||||
:label="$t('trials:processCfg:form:ImageDownloadEnum')"
|
:label="$t('trials:processCfg:form:ImageDownloadEnum')"
|
||||||
prop="ImageDownloadEnum"
|
prop="ImageDownloadEnum"
|
||||||
v-if="CriterionType === 0"
|
|
||||||
>
|
>
|
||||||
<el-radio-group
|
<el-radio-group
|
||||||
v-model="form.ImageDownloadEnum"
|
v-model="form.ImageDownloadEnum"
|
||||||
|
|
@ -379,7 +385,6 @@
|
||||||
<el-form-item
|
<el-form-item
|
||||||
:label="$t('trials:processCfg:form:ImageUploadEnum')"
|
:label="$t('trials:processCfg:form:ImageUploadEnum')"
|
||||||
prop="ImageUploadEnum"
|
prop="ImageUploadEnum"
|
||||||
v-if="CriterionType === 0"
|
|
||||||
>
|
>
|
||||||
<el-radio-group
|
<el-radio-group
|
||||||
v-model="form.ImageUploadEnum"
|
v-model="form.ImageUploadEnum"
|
||||||
|
|
@ -442,7 +447,7 @@
|
||||||
@change="
|
@change="
|
||||||
(v) => {
|
(v) => {
|
||||||
if (!v) {
|
if (!v) {
|
||||||
form.IseCRFShowInDicomReading = true;
|
form.IseCRFShowInDicomReading = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
"
|
"
|
||||||
|
|
@ -541,7 +546,7 @@
|
||||||
"
|
"
|
||||||
@change="
|
@change="
|
||||||
(v) => {
|
(v) => {
|
||||||
$set(form, 'AdditionalAssessmentType' + item.Id, v);
|
$set(form, 'AdditionalAssessmentType' + item.Id, v)
|
||||||
}
|
}
|
||||||
"
|
"
|
||||||
>
|
>
|
||||||
|
|
@ -563,21 +568,21 @@
|
||||||
>
|
>
|
||||||
<!-- 保存 -->
|
<!-- 保存 -->
|
||||||
<el-button type="primary" @click="handleSave(true)">
|
<el-button type="primary" @click="handleSave(true)">
|
||||||
{{ $t("common:button:save") }}
|
{{ $t('common:button:save') }}
|
||||||
</el-button>
|
</el-button>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-form>
|
</el-form>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script>
|
<script>
|
||||||
import { getCriterionReadingInfo, setCriterionReadingInfo } from "@/api/trials";
|
import { getCriterionReadingInfo, setCriterionReadingInfo } from '@/api/trials'
|
||||||
export default {
|
export default {
|
||||||
name: "ReadingRules",
|
name: 'ReadingRules',
|
||||||
props: {
|
props: {
|
||||||
trialReadingCriterionId: {
|
trialReadingCriterionId: {
|
||||||
type: String,
|
type: String,
|
||||||
default() {
|
default() {
|
||||||
return "";
|
return ''
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
CriterionType: {
|
CriterionType: {
|
||||||
|
|
@ -589,7 +594,7 @@ export default {
|
||||||
return {
|
return {
|
||||||
additionalAssessmentOptionList: [],
|
additionalAssessmentOptionList: [],
|
||||||
form: {
|
form: {
|
||||||
TrialId: "",
|
TrialId: '',
|
||||||
ImagePlatform: null,
|
ImagePlatform: null,
|
||||||
ReadingTool: 0,
|
ReadingTool: 0,
|
||||||
ReadingTaskViewEnum: null,
|
ReadingTaskViewEnum: null,
|
||||||
|
|
@ -624,151 +629,151 @@ export default {
|
||||||
IsAutoCreate: [
|
IsAutoCreate: [
|
||||||
{
|
{
|
||||||
required: true,
|
required: true,
|
||||||
message: this.$t("common:ruleMessage:select"),
|
message: this.$t('common:ruleMessage:select'),
|
||||||
trigger: ["blur", "change"],
|
trigger: ['blur', 'change'],
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
IsAdditionalAssessment: [
|
IsAdditionalAssessment: [
|
||||||
{
|
{
|
||||||
required: true,
|
required: true,
|
||||||
message: this.$t("common:ruleMessage:select"),
|
message: this.$t('common:ruleMessage:select'),
|
||||||
trigger: ["blur", "change"],
|
trigger: ['blur', 'change'],
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
ImagePlatform: [
|
ImagePlatform: [
|
||||||
{
|
{
|
||||||
required: true,
|
required: true,
|
||||||
message: this.$t("common:ruleMessage:select"),
|
message: this.$t('common:ruleMessage:select'),
|
||||||
trigger: ["blur", "change"],
|
trigger: ['blur', 'change'],
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
ReadingTool: [
|
ReadingTool: [
|
||||||
{
|
{
|
||||||
required: true,
|
required: true,
|
||||||
message: this.$t("common:ruleMessage:select"),
|
message: this.$t('common:ruleMessage:select'),
|
||||||
trigger: ["blur", "change"],
|
trigger: ['blur', 'change'],
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
ImageDownloadEnum: [
|
ImageDownloadEnum: [
|
||||||
{
|
{
|
||||||
required: true,
|
required: true,
|
||||||
message: this.$t("common:ruleMessage:select"),
|
message: this.$t('common:ruleMessage:select'),
|
||||||
trigger: ["blur", "change"],
|
trigger: ['blur', 'change'],
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
ImageUploadEnum: [
|
ImageUploadEnum: [
|
||||||
{
|
{
|
||||||
required: true,
|
required: true,
|
||||||
message: this.$t("common:ruleMessage:select"),
|
message: this.$t('common:ruleMessage:select'),
|
||||||
trigger: ["blur", "change"],
|
trigger: ['blur', 'change'],
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
IsImageFilter: [
|
IsImageFilter: [
|
||||||
{
|
{
|
||||||
required: true,
|
required: true,
|
||||||
message: this.$t("common:ruleMessage:select"),
|
message: this.$t('common:ruleMessage:select'),
|
||||||
trigger: ["blur", "change"],
|
trigger: ['blur', 'change'],
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
ReadingTaskViewEnum: [
|
ReadingTaskViewEnum: [
|
||||||
{
|
{
|
||||||
required: true,
|
required: true,
|
||||||
message: this.$t("common:ruleMessage:select"),
|
message: this.$t('common:ruleMessage:select'),
|
||||||
trigger: ["blur", "change"],
|
trigger: ['blur', 'change'],
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
IsImageLabeled: [
|
IsImageLabeled: [
|
||||||
{
|
{
|
||||||
required: true,
|
required: true,
|
||||||
message: this.$t("common:ruleMessage:select"),
|
message: this.$t('common:ruleMessage:select'),
|
||||||
trigger: ["blur", "change"],
|
trigger: ['blur', 'change'],
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
IsReadingShowSubjectInfo: [
|
IsReadingShowSubjectInfo: [
|
||||||
{
|
{
|
||||||
required: true,
|
required: true,
|
||||||
message: this.$t("common:ruleMessage:select"),
|
message: this.$t('common:ruleMessage:select'),
|
||||||
trigger: ["blur", "change"],
|
trigger: ['blur', 'change'],
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
IsReadingShowPreviousResults: [
|
IsReadingShowPreviousResults: [
|
||||||
{
|
{
|
||||||
required: true,
|
required: true,
|
||||||
message: this.$t("common:ruleMessage:select"),
|
message: this.$t('common:ruleMessage:select'),
|
||||||
trigger: ["blur", "change"],
|
trigger: ['blur', 'change'],
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
ReadingType: [
|
ReadingType: [
|
||||||
{
|
{
|
||||||
required: true,
|
required: true,
|
||||||
message: this.$t("common:ruleMessage:select"),
|
message: this.$t('common:ruleMessage:select'),
|
||||||
trigger: ["blur", "change"],
|
trigger: ['blur', 'change'],
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
IsReadingTaskViewInOrder: [
|
IsReadingTaskViewInOrder: [
|
||||||
{
|
{
|
||||||
required: true,
|
required: true,
|
||||||
message: this.$t("common:ruleMessage:select"),
|
message: this.$t('common:ruleMessage:select'),
|
||||||
trigger: ["blur", "change"],
|
trigger: ['blur', 'change'],
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
IsGlobalReading: [
|
IsGlobalReading: [
|
||||||
{
|
{
|
||||||
required: true,
|
required: true,
|
||||||
message: this.$t("common:ruleMessage:select"),
|
message: this.$t('common:ruleMessage:select'),
|
||||||
trigger: ["blur", "change"],
|
trigger: ['blur', 'change'],
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
IsArbitrationReading: [
|
IsArbitrationReading: [
|
||||||
{
|
{
|
||||||
required: true,
|
required: true,
|
||||||
message: this.$t("common:ruleMessage:select"),
|
message: this.$t('common:ruleMessage:select'),
|
||||||
trigger: ["blur", "change"],
|
trigger: ['blur', 'change'],
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
IsOncologyReading: [
|
IsOncologyReading: [
|
||||||
{
|
{
|
||||||
required: true,
|
required: true,
|
||||||
message: this.$t("common:ruleMessage:select"),
|
message: this.$t('common:ruleMessage:select'),
|
||||||
trigger: ["blur", "change"],
|
trigger: ['blur', 'change'],
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
DigitPlaces: [
|
DigitPlaces: [
|
||||||
{
|
{
|
||||||
required: true,
|
required: true,
|
||||||
message: this.$t("common:ruleMessage:select"),
|
message: this.$t('common:ruleMessage:select'),
|
||||||
trigger: ["blur", "change"],
|
trigger: ['blur', 'change'],
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
IseCRFShowInDicomReading: [
|
IseCRFShowInDicomReading: [
|
||||||
{
|
{
|
||||||
required: true,
|
required: true,
|
||||||
message: this.$t("common:ruleMessage:select"),
|
message: this.$t('common:ruleMessage:select'),
|
||||||
trigger: ["blur", "change"],
|
trigger: ['blur', 'change'],
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
IsReadingPeriod: [
|
IsReadingPeriod: [
|
||||||
{
|
{
|
||||||
required: true,
|
required: true,
|
||||||
message: this.$t("common:ruleMessage:select"),
|
message: this.$t('common:ruleMessage:select'),
|
||||||
trigger: ["blur", "change"],
|
trigger: ['blur', 'change'],
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
CriterionModalitys: [
|
CriterionModalitys: [
|
||||||
{
|
{
|
||||||
required: true,
|
required: true,
|
||||||
message: this.$t("common:ruleMessage:select"),
|
message: this.$t('common:ruleMessage:select'),
|
||||||
trigger: ["blur", "change"],
|
trigger: ['blur', 'change'],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
validator: (rule, value, callback) => {
|
validator: (rule, value, callback) => {
|
||||||
if (value && Array.isArray(value) && value.length < 0) {
|
if (value && Array.isArray(value) && value.length < 0) {
|
||||||
callback(new Error(this.$t("common:ruleMessage:select")));
|
callback(new Error(this.$t('common:ruleMessage:select')))
|
||||||
} else {
|
} else {
|
||||||
callback();
|
callback()
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
trigger: ["blur", "change"],
|
trigger: ['blur', 'change'],
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
// IsReadingTaskViewInOrder: [
|
// IsReadingTaskViewInOrder: [
|
||||||
|
|
@ -785,15 +790,15 @@ export default {
|
||||||
modalityList: [],
|
modalityList: [],
|
||||||
CriterionModalitys: [],
|
CriterionModalitys: [],
|
||||||
modalityIsCheck: false, // 是否允许影像筛选
|
modalityIsCheck: false, // 是否允许影像筛选
|
||||||
};
|
}
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
this.initPage();
|
this.initPage()
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
CriterionModalitys: {
|
CriterionModalitys: {
|
||||||
handler() {
|
handler() {
|
||||||
this.form.CriterionModalitys = this.CriterionModalitys.join("|");
|
this.form.CriterionModalitys = this.CriterionModalitys.join('|')
|
||||||
},
|
},
|
||||||
deep: true,
|
deep: true,
|
||||||
},
|
},
|
||||||
|
|
@ -802,19 +807,19 @@ export default {
|
||||||
// 检查类型筛选值变更
|
// 检查类型筛选值变更
|
||||||
IsImageFilterChange(data) {
|
IsImageFilterChange(data) {
|
||||||
if (data) {
|
if (data) {
|
||||||
this.CriterionModalitys = this.modalityList;
|
this.CriterionModalitys = this.modalityList
|
||||||
} else {
|
} else {
|
||||||
this.CriterionModalitys = [];
|
this.CriterionModalitys = []
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
// 影像模态全选
|
// 影像模态全选
|
||||||
handleCheckAllChange() {
|
handleCheckAllChange() {
|
||||||
this.CriterionModalitys =
|
this.CriterionModalitys =
|
||||||
this.CriterionModalitys.length <= 0 ? this.modalityList : [];
|
this.CriterionModalitys.length <= 0 ? this.modalityList : []
|
||||||
},
|
},
|
||||||
initPage() {
|
initPage() {
|
||||||
this.loading = true;
|
this.loading = true
|
||||||
const trialId = this.$route.query.trialId;
|
const trialId = this.$route.query.trialId
|
||||||
// getTrialCriterionAdditionalAssessmentOptionList(this.trialReadingCriterionId).then(res => {
|
// getTrialCriterionAdditionalAssessmentOptionList(this.trialReadingCriterionId).then(res => {
|
||||||
// this.additionalAssessmentOptionList = res.Result
|
// this.additionalAssessmentOptionList = res.Result
|
||||||
// if (this.additionalAssessmentOptionList.length > 0) {
|
// if (this.additionalAssessmentOptionList.length > 0) {
|
||||||
|
|
@ -827,46 +832,46 @@ export default {
|
||||||
TrialReadingCriterionId: this.trialReadingCriterionId,
|
TrialReadingCriterionId: this.trialReadingCriterionId,
|
||||||
})
|
})
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
this.loading = false;
|
this.loading = false
|
||||||
this.modalityList = res.Result.TrialModalitys.split("|").filter(
|
this.modalityList = res.Result.TrialModalitys.split('|').filter(
|
||||||
(item) => item && item.trim()
|
(item) => item && item.trim()
|
||||||
);
|
)
|
||||||
for (const k in this.form) {
|
for (const k in this.form) {
|
||||||
if (res.Result.hasOwnProperty(k)) {
|
if (res.Result.hasOwnProperty(k)) {
|
||||||
this.form[k] = res.Result[k];
|
this.form[k] = res.Result[k]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
this.CriterionModalitys = this.form.CriterionModalitys
|
this.CriterionModalitys = this.form.CriterionModalitys
|
||||||
? this.form.CriterionModalitys.split("|")
|
? this.form.CriterionModalitys.split('|')
|
||||||
: [];
|
: []
|
||||||
this.form.TrialCriterionAdditionalAssessmentTypeList.forEach((v) => {
|
this.form.TrialCriterionAdditionalAssessmentTypeList.forEach((v) => {
|
||||||
this.$set(v, "IsSelected", v.IsSelected || false);
|
this.$set(v, 'IsSelected', v.IsSelected || false)
|
||||||
this.$set(
|
this.$set(
|
||||||
this.form,
|
this.form,
|
||||||
"AdditionalAssessmentType" + v.Id,
|
'AdditionalAssessmentType' + v.Id,
|
||||||
v.IsSelected
|
v.IsSelected
|
||||||
);
|
)
|
||||||
});
|
})
|
||||||
this.isReadingTaskViewInOrder = res.Result.IsReadingTaskViewInOrder;
|
this.isReadingTaskViewInOrder = res.Result.IsReadingTaskViewInOrder
|
||||||
this.isConfirm = res.Result.IsSign;
|
this.isConfirm = res.Result.IsSign
|
||||||
this.IsMustGlobalReading = res.Result.IsMustGlobalReading;
|
this.IsMustGlobalReading = res.Result.IsMustGlobalReading
|
||||||
this.$emit("setConfirm", res.Result.IsSign);
|
this.$emit('setConfirm', res.Result.IsSign)
|
||||||
this.$emit("setArbitrationReading", res.Result.IsArbitrationReading);
|
this.$emit('setArbitrationReading', res.Result.IsArbitrationReading)
|
||||||
this.$emit(
|
this.$emit(
|
||||||
"setAdditionalAssessment",
|
'setAdditionalAssessment',
|
||||||
this.form.IsAdditionalAssessment
|
this.form.IsAdditionalAssessment
|
||||||
);
|
)
|
||||||
this.$emit("setIsClinicalReading", res.Result.IsClinicalReading);
|
this.$emit('setIsClinicalReading', res.Result.IsClinicalReading)
|
||||||
this.$emit("setGlobalReading", res.Result.IsGlobalReading);
|
this.$emit('setGlobalReading', res.Result.IsGlobalReading)
|
||||||
this.$emit("setOncologyReading", res.Result.IsOncologyReading);
|
this.$emit('setOncologyReading', res.Result.IsOncologyReading)
|
||||||
this.$emit("setDigitPlaces", res.Result.DigitPlaces);
|
this.$emit('setDigitPlaces', res.Result.DigitPlaces)
|
||||||
if (res.Result.ReadingType === 1) {
|
if (res.Result.ReadingType === 1) {
|
||||||
this.$emit("setArbitrationReading", false);
|
this.$emit('setArbitrationReading', false)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.catch(() => {
|
.catch(() => {
|
||||||
this.loading = false;
|
this.loading = false
|
||||||
});
|
})
|
||||||
// }).catch(() => {
|
// }).catch(() => {
|
||||||
// this.loading = false
|
// this.loading = false
|
||||||
// })
|
// })
|
||||||
|
|
@ -874,52 +879,52 @@ export default {
|
||||||
// 配置信息保存
|
// 配置信息保存
|
||||||
handleSave(isPrompt = true) {
|
handleSave(isPrompt = true) {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
this.$refs["readingRulesForm"].validate((valid) => {
|
this.$refs['readingRulesForm'].validate((valid) => {
|
||||||
if (!valid) {
|
if (!valid) {
|
||||||
resolve(false);
|
resolve(false)
|
||||||
} else {
|
} else {
|
||||||
this.loading = true;
|
this.loading = true
|
||||||
if (this.form.ReadingType === 1) {
|
if (this.form.ReadingType === 1) {
|
||||||
this.form.IsArbitrationReading = false;
|
this.form.IsArbitrationReading = false
|
||||||
}
|
}
|
||||||
// 保存配置信息
|
// 保存配置信息
|
||||||
this.form.TrialReadingCriterionId = this.trialReadingCriterionId;
|
this.form.TrialReadingCriterionId = this.trialReadingCriterionId
|
||||||
setCriterionReadingInfo(this.form)
|
setCriterionReadingInfo(this.form)
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
this.loading = false;
|
this.loading = false
|
||||||
this.$emit("reloadArbitrationRules");
|
this.$emit('reloadArbitrationRules')
|
||||||
this.$emit(
|
this.$emit(
|
||||||
"setArbitrationReading",
|
'setArbitrationReading',
|
||||||
this.form.IsArbitrationReading
|
this.form.IsArbitrationReading
|
||||||
);
|
)
|
||||||
this.$emit(
|
this.$emit(
|
||||||
"setAdditionalAssessment",
|
'setAdditionalAssessment',
|
||||||
this.form.IsAdditionalAssessment
|
this.form.IsAdditionalAssessment
|
||||||
);
|
)
|
||||||
this.$emit("setIsClinicalReading", this.form.IsClinicalReading);
|
this.$emit('setIsClinicalReading', this.form.IsClinicalReading)
|
||||||
this.$emit("setGlobalReading", this.form.IsGlobalReading);
|
this.$emit('setGlobalReading', this.form.IsGlobalReading)
|
||||||
this.$emit("setOncologyReading", this.form.IsOncologyReading);
|
this.$emit('setOncologyReading', this.form.IsOncologyReading)
|
||||||
this.$emit("setDigitPlaces", this.form.DigitPlaces);
|
this.$emit('setDigitPlaces', this.form.DigitPlaces)
|
||||||
if (this.form.ReadingType === 1) {
|
if (this.form.ReadingType === 1) {
|
||||||
this.$emit("setArbitrationReading", false);
|
this.$emit('setArbitrationReading', false)
|
||||||
}
|
}
|
||||||
if (res.IsSuccess && isPrompt) {
|
if (res.IsSuccess && isPrompt) {
|
||||||
this.$message.success(
|
this.$message.success(
|
||||||
this.$t("common:message:savedSuccessfully")
|
this.$t('common:message:savedSuccessfully')
|
||||||
);
|
)
|
||||||
}
|
}
|
||||||
resolve(true);
|
resolve(true)
|
||||||
})
|
})
|
||||||
.catch((_) => {
|
.catch((_) => {
|
||||||
this.loading = false;
|
this.loading = false
|
||||||
resolve(false);
|
resolve(false)
|
||||||
});
|
})
|
||||||
}
|
}
|
||||||
});
|
})
|
||||||
});
|
})
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
}
|
||||||
</script>
|
</script>
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
.reading-rule-config-form {
|
.reading-rule-config-form {
|
||||||
|
|
|
||||||
|
|
@ -370,11 +370,11 @@ export default {
|
||||||
isCheck: readingRules,
|
isCheck: readingRules,
|
||||||
msg: this.$t("trials:readingUnit:readingRules"), // '阅片规则'
|
msg: this.$t("trials:readingUnit:readingRules"), // '阅片规则'
|
||||||
});
|
});
|
||||||
// var readingCriterions = await this.$refs['readingCriterions' + this.TrialReadingCriterionId][0].handleSave(false)
|
var qsLength = this.$refs['readingCriterions' + this.TrialReadingCriterionId][0].getQuestionLength()
|
||||||
// isCheckList.push({
|
isCheckList.push({
|
||||||
// isCheck: readingCriterions,
|
isCheck: qsLength > 0,
|
||||||
// msg: '阅片标准'
|
msg: this.$t('trials:readingUnit:readingCriterion')
|
||||||
// })
|
})
|
||||||
if (
|
if (
|
||||||
this.$refs["globalReading" + this.TrialReadingCriterionId] &&
|
this.$refs["globalReading" + this.TrialReadingCriterionId] &&
|
||||||
this.$refs["globalReading" + this.TrialReadingCriterionId]
|
this.$refs["globalReading" + this.TrialReadingCriterionId]
|
||||||
|
|
@ -497,12 +497,16 @@ export default {
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
reloadArbitrationRules() {
|
reloadArbitrationRules() {
|
||||||
|
if (this.$refs[
|
||||||
|
"arbitrationRules" + this.TrialReadingCriterionId
|
||||||
|
]) {
|
||||||
this.$refs[
|
this.$refs[
|
||||||
"arbitrationRules" + this.TrialReadingCriterionId
|
"arbitrationRules" + this.TrialReadingCriterionId
|
||||||
][0].getList();
|
][0].getList();
|
||||||
this.$refs[
|
this.$refs[
|
||||||
"arbitrationRules" + this.TrialReadingCriterionId
|
"arbitrationRules" + this.TrialReadingCriterionId
|
||||||
][0].getTrialJudgyInfo();
|
][0].getTrialJudgyInfo();
|
||||||
|
}
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -34,7 +34,7 @@
|
||||||
type="text"
|
type="text"
|
||||||
@click="handleDownloadTpl"
|
@click="handleDownloadTpl"
|
||||||
>
|
>
|
||||||
{{ $t("trials:readingPeriod:cd:title:downloadTpl") }}
|
{{ $t('trials:readingPeriod:cd:title:downloadTpl') }}
|
||||||
</el-button>
|
</el-button>
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
@ -53,7 +53,7 @@
|
||||||
"
|
"
|
||||||
>
|
>
|
||||||
<el-button type="primary" style="width: 56px" size="small">
|
<el-button type="primary" style="width: 56px" size="small">
|
||||||
{{ $t("trials:uploadClinicalData:button:selectFile") }}
|
{{ $t('trials:uploadClinicalData:button:selectFile') }}
|
||||||
</el-button>
|
</el-button>
|
||||||
<input
|
<input
|
||||||
type="file"
|
type="file"
|
||||||
|
|
@ -72,7 +72,7 @@
|
||||||
@change="beginScanFiles($event)"
|
@change="beginScanFiles($event)"
|
||||||
/>
|
/>
|
||||||
<span style="margin-left: 10px">{{
|
<span style="margin-left: 10px">{{
|
||||||
$t("trials:attachment:message:pdf")
|
$t('trials:attachment:message:pdf')
|
||||||
}}</span>
|
}}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -139,7 +139,7 @@
|
||||||
type="primary"
|
type="primary"
|
||||||
@click="close"
|
@click="close"
|
||||||
>
|
>
|
||||||
{{ $t("common:button:cancel") }}
|
{{ $t('common:button:cancel') }}
|
||||||
</el-button>
|
</el-button>
|
||||||
<!-- 保存 -->
|
<!-- 保存 -->
|
||||||
<el-button
|
<el-button
|
||||||
|
|
@ -148,7 +148,7 @@
|
||||||
:loading="btnLoading"
|
:loading="btnLoading"
|
||||||
@click="save"
|
@click="save"
|
||||||
>
|
>
|
||||||
{{ $t("common:button:save") }}
|
{{ $t('common:button:save') }}
|
||||||
</el-button>
|
</el-button>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -159,23 +159,23 @@ import {
|
||||||
getTrialClinicalDataSelect,
|
getTrialClinicalDataSelect,
|
||||||
addOrUpdateReadingClinicalData,
|
addOrUpdateReadingClinicalData,
|
||||||
addOrUpdateConsistencyAnalysisReadingClinicalData,
|
addOrUpdateConsistencyAnalysisReadingClinicalData,
|
||||||
} from "@/api/trials";
|
} from '@/api/trials'
|
||||||
import { fileDownload } from "@/utils/uploadZip.js";
|
import { downLoadFile } from '@/utils/stream.js'
|
||||||
export default {
|
export default {
|
||||||
name: "AddOrUpdateClinicalData",
|
name: 'AddOrUpdateClinicalData',
|
||||||
props: {
|
props: {
|
||||||
trialReadingCriterionId: {
|
trialReadingCriterionId: {
|
||||||
type: String,
|
type: String,
|
||||||
default: "",
|
default: '',
|
||||||
},
|
},
|
||||||
data: {
|
data: {
|
||||||
type: Object,
|
type: Object,
|
||||||
default() {
|
default() {
|
||||||
return {};
|
return {}
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
type: {
|
type: {
|
||||||
default: "readingPeriod",
|
default: 'readingPeriod',
|
||||||
},
|
},
|
||||||
option: {
|
option: {
|
||||||
default: () => [],
|
default: () => [],
|
||||||
|
|
@ -185,13 +185,13 @@ export default {
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
fileList: [],
|
fileList: [],
|
||||||
faccept: [".pdf"],
|
faccept: ['.pdf'],
|
||||||
form: {
|
form: {
|
||||||
Id: "",
|
Id: '',
|
||||||
TrialId: "",
|
TrialId: '',
|
||||||
SubjectId: "",
|
SubjectId: '',
|
||||||
ReadingId: "",
|
ReadingId: '',
|
||||||
ClinicalDataTrialSetId: "",
|
ClinicalDataTrialSetId: '',
|
||||||
IsVisist: true,
|
IsVisist: true,
|
||||||
AddFileList: [],
|
AddFileList: [],
|
||||||
DeleteFileIds: [],
|
DeleteFileIds: [],
|
||||||
|
|
@ -201,8 +201,8 @@ export default {
|
||||||
ClinicalDataTrialSetId: [
|
ClinicalDataTrialSetId: [
|
||||||
{
|
{
|
||||||
required: true,
|
required: true,
|
||||||
message: this.$t("common:ruleMessage:select"),
|
message: this.$t('common:ruleMessage:select'),
|
||||||
trigger: ["blur", "change"],
|
trigger: ['blur', 'change'],
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
|
@ -211,194 +211,190 @@ export default {
|
||||||
clinicalDatas: [],
|
clinicalDatas: [],
|
||||||
pendingUploadList: [],
|
pendingUploadList: [],
|
||||||
pendingDeleteList: [],
|
pendingDeleteList: [],
|
||||||
currentTpl: { id: "", isExist: false },
|
currentTpl: { id: '', isExist: false },
|
||||||
};
|
}
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
this.initForm();
|
this.initForm()
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
// 下载临床数据
|
// 下载临床数据
|
||||||
handleUploadFile(row) {
|
handleUploadFile(row) {
|
||||||
let href = this.OSSclientConfig.basePath + row.Path;
|
let href = this.OSSclientConfig.basePath + row.Path
|
||||||
let name = row.FileName;
|
let name = row.FileName
|
||||||
fileDownload(href, name);
|
downLoadFile(href, name)
|
||||||
},
|
},
|
||||||
async initForm() {
|
async initForm() {
|
||||||
if (this.type === "readingPeriod") {
|
if (this.type === 'readingPeriod') {
|
||||||
await this.getClinicalDatas();
|
await this.getClinicalDatas()
|
||||||
} else {
|
} else {
|
||||||
this.clinicalDatas = this.option;
|
this.clinicalDatas = this.option
|
||||||
}
|
}
|
||||||
if (Object.keys(this.data).length > 0) {
|
if (Object.keys(this.data).length > 0) {
|
||||||
for (const k in this.form) {
|
for (const k in this.form) {
|
||||||
if (this.data.hasOwnProperty(k)) {
|
if (this.data.hasOwnProperty(k)) {
|
||||||
this.form[k] = this.data[k];
|
this.form[k] = this.data[k]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
this.handleClinicalDataSetChange(this.form.ClinicalDataTrialSetId);
|
this.handleClinicalDataSetChange(this.form.ClinicalDataTrialSetId)
|
||||||
this.fileList = this.form.FileList.concat();
|
this.fileList = this.form.FileList.concat()
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
save() {
|
save() {
|
||||||
this.$refs.clinicalDataForm.validate((valid) => {
|
this.$refs.clinicalDataForm.validate((valid) => {
|
||||||
if (!valid) return;
|
if (!valid) return
|
||||||
if (this.fileList.length === 0) {
|
if (this.fileList.length === 0) {
|
||||||
// 请上传文件!
|
// 请上传文件!
|
||||||
this.$alert(this.$t("trials:readingPeriod:cd:message:uploadFile"));
|
this.$alert(this.$t('trials:readingPeriod:cd:message:uploadFile'))
|
||||||
return;
|
return
|
||||||
}
|
}
|
||||||
this.pendingUploadList = [];
|
this.pendingUploadList = []
|
||||||
for (let i = 0; i < this.fileList.length; ++i) {
|
for (let i = 0; i < this.fileList.length; ++i) {
|
||||||
if (this.fileList[i].Status === 0) {
|
if (this.fileList[i].Status === 0) {
|
||||||
this.pendingUploadList.push(this.fileList[i].Files);
|
this.pendingUploadList.push(this.fileList[i].Files)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (this.pendingUploadList.length > 0) {
|
if (this.pendingUploadList.length > 0) {
|
||||||
this.uploadFilesAndSave();
|
this.uploadFilesAndSave()
|
||||||
} else {
|
} else {
|
||||||
this.saveClinicalData();
|
this.saveClinicalData()
|
||||||
}
|
}
|
||||||
});
|
})
|
||||||
},
|
},
|
||||||
uploadFilesAndSave() {
|
uploadFilesAndSave() {
|
||||||
return new Promise(async (resolve, reject) => {
|
return new Promise(async (resolve, reject) => {
|
||||||
this.form.AddFileList = [];
|
this.form.AddFileList = []
|
||||||
for (var i = 0; i < this.pendingUploadList.length; ++i) {
|
for (var i = 0; i < this.pendingUploadList.length; ++i) {
|
||||||
// const file = await this.convertBase64ToBlob(this.pendingUploadList[i])
|
// const file = await this.convertBase64ToBlob(this.pendingUploadList[i])
|
||||||
const file = await this.fileToBlob(this.pendingUploadList[i]);
|
const file = await this.fileToBlob(this.pendingUploadList[i])
|
||||||
const res = await this.OSSclient.put(
|
const res = await this.OSSclient.put(
|
||||||
`/${this.data.TrialId}/ClinicalData/${this.pendingUploadList[i].name}`,
|
`/${this.data.TrialId}/ClinicalData/${this.pendingUploadList[i].name}`,
|
||||||
file
|
file
|
||||||
);
|
)
|
||||||
this.form.AddFileList.push({
|
this.form.AddFileList.push({
|
||||||
fileName: this.pendingUploadList[i].name,
|
fileName: this.pendingUploadList[i].name,
|
||||||
path: this.$getObjectName(res.url),
|
path: this.$getObjectName(res.url),
|
||||||
size: this.pendingUploadList[i].size,
|
size: this.pendingUploadList[i].size,
|
||||||
type: this.pendingUploadList[i].type,
|
type: this.pendingUploadList[i].type,
|
||||||
});
|
})
|
||||||
}
|
}
|
||||||
this.saveClinicalData(this.form.AddFileList);
|
this.saveClinicalData(this.form.AddFileList)
|
||||||
resolve();
|
resolve()
|
||||||
});
|
})
|
||||||
},
|
},
|
||||||
saveClinicalData() {
|
saveClinicalData() {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
this.btnLoading = true;
|
this.btnLoading = true
|
||||||
this.form.DeleteFileIds = this.pendingDeleteList;
|
this.form.DeleteFileIds = this.pendingDeleteList
|
||||||
if (this.type === "consistencyAnalysis") {
|
if (this.type === 'consistencyAnalysis') {
|
||||||
addOrUpdateConsistencyAnalysisReadingClinicalData(this.form)
|
addOrUpdateConsistencyAnalysisReadingClinicalData(this.form)
|
||||||
.then((response) => {
|
.then((response) => {
|
||||||
this.btnLoading = false;
|
this.btnLoading = false
|
||||||
this.$emit("getList");
|
this.$emit('getList')
|
||||||
this.$emit("close");
|
this.$emit('close')
|
||||||
this.$message.success(
|
this.$message.success(this.$t('common:message:savedSuccessfully'))
|
||||||
this.$t("common:message:savedSuccessfully")
|
resolve()
|
||||||
);
|
|
||||||
resolve();
|
|
||||||
})
|
})
|
||||||
.catch(() => {
|
.catch(() => {
|
||||||
this.btnLoading = false;
|
this.btnLoading = false
|
||||||
reject();
|
reject()
|
||||||
});
|
})
|
||||||
} else {
|
} else {
|
||||||
addOrUpdateReadingClinicalData(this.form)
|
addOrUpdateReadingClinicalData(this.form)
|
||||||
.then((response) => {
|
.then((response) => {
|
||||||
this.btnLoading = false;
|
this.btnLoading = false
|
||||||
this.$emit("getList");
|
this.$emit('getList')
|
||||||
this.$emit("close");
|
this.$emit('close')
|
||||||
this.$message.success(
|
this.$message.success(this.$t('common:message:savedSuccessfully'))
|
||||||
this.$t("common:message:savedSuccessfully")
|
resolve()
|
||||||
);
|
|
||||||
resolve();
|
|
||||||
})
|
})
|
||||||
.catch(() => {
|
.catch(() => {
|
||||||
this.btnLoading = false;
|
this.btnLoading = false
|
||||||
reject();
|
reject()
|
||||||
});
|
})
|
||||||
}
|
}
|
||||||
});
|
})
|
||||||
},
|
},
|
||||||
getClinicalDatas() {
|
getClinicalDatas() {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
this.loading = true;
|
this.loading = true
|
||||||
var param = {
|
var param = {
|
||||||
trialId: this.data.TrialId,
|
trialId: this.data.TrialId,
|
||||||
IsVisit: this.data.IsVisit,
|
IsVisit: this.data.IsVisit,
|
||||||
ReadingId: this.data.ReadingId,
|
ReadingId: this.data.ReadingId,
|
||||||
SubjectId: this.data.SubjectId,
|
SubjectId: this.data.SubjectId,
|
||||||
ReadingClinicalDataId: this.data.Id ? this.data.Id : "",
|
ReadingClinicalDataId: this.data.Id ? this.data.Id : '',
|
||||||
IsBaseLine: this.data.IsBaseLine,
|
IsBaseLine: this.data.IsBaseLine,
|
||||||
TrialReadingCriterionId: this.trialReadingCriterionId,
|
TrialReadingCriterionId: this.trialReadingCriterionId,
|
||||||
};
|
}
|
||||||
getTrialClinicalDataSelect(param)
|
getTrialClinicalDataSelect(param)
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
this.clinicalDatas = res.Result;
|
this.clinicalDatas = res.Result
|
||||||
this.loading = false;
|
this.loading = false
|
||||||
resolve();
|
resolve()
|
||||||
})
|
})
|
||||||
.catch(() => {
|
.catch(() => {
|
||||||
this.loading = false;
|
this.loading = false
|
||||||
reject();
|
reject()
|
||||||
});
|
})
|
||||||
});
|
})
|
||||||
},
|
},
|
||||||
handleDeleteFile(index, row) {
|
handleDeleteFile(index, row) {
|
||||||
this.$confirm(this.$t("trials:readingPeriod:cd:message:delete"), {
|
this.$confirm(this.$t('trials:readingPeriod:cd:message:delete'), {
|
||||||
type: "warning",
|
type: 'warning',
|
||||||
distinguishCancelAndClose: true,
|
distinguishCancelAndClose: true,
|
||||||
})
|
})
|
||||||
.then(() => {
|
.then(() => {
|
||||||
if (row.Id) {
|
if (row.Id) {
|
||||||
this.pendingDeleteList.push(row.Id);
|
this.pendingDeleteList.push(row.Id)
|
||||||
}
|
}
|
||||||
this.fileList.splice(index, 1);
|
this.fileList.splice(index, 1)
|
||||||
})
|
})
|
||||||
.catch(() => {});
|
.catch(() => {})
|
||||||
},
|
},
|
||||||
beginScanFiles(e) {
|
beginScanFiles(e) {
|
||||||
var files = e.target.files;
|
var files = e.target.files
|
||||||
for (var i = 0; i < files.length; ++i) {
|
for (var i = 0; i < files.length; ++i) {
|
||||||
const fileName = files[i].name;
|
const fileName = files[i].name
|
||||||
var extendName = fileName
|
var extendName = fileName
|
||||||
.substring(fileName.lastIndexOf("."))
|
.substring(fileName.lastIndexOf('.'))
|
||||||
.toLocaleLowerCase();
|
.toLocaleLowerCase()
|
||||||
if (this.faccept.indexOf(extendName) !== -1) {
|
if (this.faccept.indexOf(extendName) !== -1) {
|
||||||
this.fileList.push({
|
this.fileList.push({
|
||||||
FileName: fileName,
|
FileName: fileName,
|
||||||
Path: "",
|
Path: '',
|
||||||
Status: 0,
|
Status: 0,
|
||||||
Files: files[i],
|
Files: files[i],
|
||||||
size: files[i].size,
|
size: files[i].size,
|
||||||
type: fileName.split(".")[1],
|
type: fileName.split('.')[1],
|
||||||
});
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
handleClinicalDataSetChange(v) {
|
handleClinicalDataSetChange(v) {
|
||||||
var index = this.clinicalDatas.findIndex((item) => item.Id === v);
|
var index = this.clinicalDatas.findIndex((item) => item.Id === v)
|
||||||
if (index > -1) {
|
if (index > -1) {
|
||||||
this.currentTpl.id = this.clinicalDatas[index].Id;
|
this.currentTpl.id = this.clinicalDatas[index].Id
|
||||||
this.currentTpl.path = this.clinicalDatas[index].Path;
|
this.currentTpl.path = this.clinicalDatas[index].Path
|
||||||
this.currentTpl.isExist = !!this.clinicalDatas[index].FileName;
|
this.currentTpl.isExist = !!this.clinicalDatas[index].FileName
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
handleDownloadTpl() {
|
handleDownloadTpl() {
|
||||||
this.loading = true;
|
this.loading = true
|
||||||
window.open(
|
window.open(
|
||||||
this.OSSclientConfig.basePath + this.currentTpl.path,
|
this.OSSclientConfig.basePath + this.currentTpl.path,
|
||||||
"_blank"
|
'_blank'
|
||||||
);
|
)
|
||||||
this.loading = false;
|
this.loading = false
|
||||||
// DownloadTrialClinicalFile(this.currentTpl.id).then(data => {
|
// DownloadTrialClinicalFile(this.currentTpl.id).then(data => {
|
||||||
// this.loading = false
|
// this.loading = false
|
||||||
// }).catch(() => { this.loading = false })
|
// }).catch(() => { this.loading = false })
|
||||||
},
|
},
|
||||||
close() {
|
close() {
|
||||||
this.$emit("close");
|
this.$emit('close')
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
}
|
||||||
</script>
|
</script>
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
</style>
|
</style>
|
||||||
|
|
|
||||||
|
|
@ -347,9 +347,9 @@
|
||||||
<a v-else-if="(scope.row.DataType === 'Link' || scope.row.DataType === 'Router') && scope.row.oldValue && scope.row.oldValue !== '--'" target="_blank" :href="scope.row.oldValue" style="color:#409eff;">
|
<a v-else-if="(scope.row.DataType === 'Link' || scope.row.DataType === 'Router') && scope.row.oldValue && scope.row.oldValue !== '--'" target="_blank" :href="scope.row.oldValue" style="color:#409eff;">
|
||||||
{{$t('trials:auditRecord:title:viewDetail')}}
|
{{$t('trials:auditRecord:title:viewDetail')}}
|
||||||
</a>
|
</a>
|
||||||
<viewer v-else-if="(scope.row.DataType === 'Image' || scope.row.DataType === 'ImageList') && scope.row.oldValue && scope.row.oldValue !== '--'" :ref="scope.row.oldValue instanceof Array ? scope.row.oldValue[0] : scope.row.oldValue" :images="imagesList">
|
<viewer v-else-if="(scope.row.DataType === 'Image' || scope.row.DataType === 'ImageList') && scope.row.oldValue && scope.row.oldValue !== '--'" :ref="`${scope.row.oldValue instanceof Array ? scope.row.oldValue[0] : scope.row.oldValue}_modelCfg`" :images="imagesList">
|
||||||
<!-- 查看图片 -->
|
<!-- 查看图片 -->
|
||||||
<span style="color:#409eff;cursor: pointer" @click="openImage(scope.row.oldValue)">{{$t('trials:auditRecord:title:viewImage')}}{{scope.row.oldValue instanceof Array ? `(${scope.row.oldValue.length})` : ''}}</span>
|
<span style="color:#409eff;cursor: pointer" @click="openImage(scope.row.oldValue, 'modelCfg')">{{$t('trials:auditRecord:title:viewImage')}}{{scope.row.oldValue instanceof Array ? `(${scope.row.oldValue.length})` : ''}}</span>
|
||||||
<template v-for="item of scope.row.oldValue">
|
<template v-for="item of scope.row.oldValue">
|
||||||
<img v-if="scope.row.DataType === 'ImageList'" :key="item" :src="OSSclientConfig.basePath + item" v-show="false" crossorigin="anonymous" alt="">
|
<img v-if="scope.row.DataType === 'ImageList'" :key="item" :src="OSSclientConfig.basePath + item" v-show="false" crossorigin="anonymous" alt="">
|
||||||
</template>
|
</template>
|
||||||
|
|
@ -378,9 +378,9 @@
|
||||||
<a v-else-if="(scope.row.DataType === 'Link' || scope.row.DataType === 'Router') && scope.row.newValue && scope.row.newValue !== '--'" target="_blank" :href="scope.row.newValue" style="color:#409eff;">
|
<a v-else-if="(scope.row.DataType === 'Link' || scope.row.DataType === 'Router') && scope.row.newValue && scope.row.newValue !== '--'" target="_blank" :href="scope.row.newValue" style="color:#409eff;">
|
||||||
{{$t('trials:auditRecord:title:viewDetail')}}
|
{{$t('trials:auditRecord:title:viewDetail')}}
|
||||||
</a>
|
</a>
|
||||||
<viewer v-else-if="(scope.row.DataType === 'Image' || scope.row.DataType === 'ImageList') && scope.row.newValue && scope.row.newValue !== '--'" :ref="scope.row.newValue instanceof Array ? scope.row.newValue[0] : scope.row.newValue" :images="imagesList">
|
<viewer v-else-if="(scope.row.DataType === 'Image' || scope.row.DataType === 'ImageList') && scope.row.newValue && scope.row.newValue !== '--'" :ref="`${scope.row.newValue instanceof Array ? scope.row.newValue[0] : scope.row.newValue}_modelcfg`" :images="imagesList">
|
||||||
<!-- 查看图片 -->
|
<!-- 查看图片 -->
|
||||||
<span style="color:#409eff;cursor: pointer" @click="openImage(scope.row.newValue)">{{$t('trials:auditRecord:title:viewImage')}}{{scope.row.newValue instanceof Array ? `(${scope.row.newValue.length})` : ''}}</span>
|
<span style="color:#409eff;cursor: pointer" @click="openImage(scope.row.newValue, 'modelcfg')">{{$t('trials:auditRecord:title:viewImage')}}{{scope.row.newValue instanceof Array ? `(${scope.row.newValue.length})` : ''}}</span>
|
||||||
<template v-for="item of scope.row.newValue">
|
<template v-for="item of scope.row.newValue">
|
||||||
<img v-if="scope.row.DataType === 'ImageList'" :key="item" :src="OSSclientConfig.basePath + item" v-show="false" crossorigin="anonymous" alt="">
|
<img v-if="scope.row.DataType === 'ImageList'" :key="item" :src="OSSclientConfig.basePath + item" v-show="false" crossorigin="anonymous" alt="">
|
||||||
</template>
|
</template>
|
||||||
|
|
@ -409,9 +409,9 @@
|
||||||
:key="'tableList' + index"
|
:key="'tableList' + index"
|
||||||
>
|
>
|
||||||
<template v-if="!item.IsMerge" slot-scope="scope">
|
<template v-if="!item.IsMerge" slot-scope="scope">
|
||||||
<viewer v-if="item.IsPicture" :images="imagesList" :ref="scope.row[item.ColumnValue]">
|
<viewer v-if="item.IsPicture" :images="imagesList" :ref="`${scope.row[item.ColumnValue]}_modelcfg`">
|
||||||
<!-- 查看图片 -->
|
<!-- 查看图片 -->
|
||||||
<span style="color:#409eff;cursor: pointer" @click="openImage(scope.row[item.ColumnValue])">{{$t('trials:auditRecord:title:viewImage')}}</span>
|
<span style="color:#409eff;cursor: pointer" @click="openImage(scope.row[item.ColumnValue],'modelcfg')">{{$t('trials:auditRecord:title:viewImage')}}</span>
|
||||||
<img :src="OSSclientConfig.basePath + scope.row[item.ColumnValue]" v-show="false" crossorigin="anonymous" alt="">
|
<img :src="OSSclientConfig.basePath + scope.row[item.ColumnValue]" v-show="false" crossorigin="anonymous" alt="">
|
||||||
</viewer>
|
</viewer>
|
||||||
<span v-else>{{scope.row[item.ColumnValue]}}</span>
|
<span v-else>{{scope.row[item.ColumnValue]}}</span>
|
||||||
|
|
@ -426,9 +426,9 @@
|
||||||
:key="'ChildrenList' + index"
|
:key="'ChildrenList' + index"
|
||||||
>
|
>
|
||||||
<template slot-scope="scope">
|
<template slot-scope="scope">
|
||||||
<viewer v-if="item.IsPicture" :images="imagesList" :ref="scope.row[ite.ListName ? ite.ListName + ite.ColumnValue + index : ite.ColumnValue]">
|
<viewer v-if="item.IsPicture" :images="imagesList" :ref="`${scope.row[ite.ListName ? ite.ListName + ite.ColumnValue + index : ite.ColumnValue]}_modelcfg`">
|
||||||
<!-- 查看图片 -->
|
<!-- 查看图片 -->
|
||||||
<span style="color:#409eff;cursor: pointer" @click="openImage(scope.row[ite.ListName ? ite.ListName + ite.ColumnValue + index : ite.ColumnValue])">
|
<span style="color:#409eff;cursor: pointer" @click="openImage(scope.row[ite.ListName ? ite.ListName + ite.ColumnValue + index : ite.ColumnValue], 'modelcfg')">
|
||||||
{{$t('trials:auditRecord:title:viewImage')}}
|
{{$t('trials:auditRecord:title:viewImage')}}
|
||||||
</span>
|
</span>
|
||||||
<img :src="OSSclientConfig.basePath + scope.row[ite.ListName ? ite.ListName + ite.ColumnValue + index : ite.ColumnValue]" v-show="false" crossorigin="anonymous" alt="">
|
<img :src="OSSclientConfig.basePath + scope.row[ite.ListName ? ite.ListName + ite.ColumnValue + index : ite.ColumnValue]" v-show="false" crossorigin="anonymous" alt="">
|
||||||
|
|
@ -652,9 +652,9 @@
|
||||||
/>
|
/>
|
||||||
<!-- OptType === 'Add' ? '值' : OptType === 'Delete' ? '删除前' : '修改前' -->
|
<!-- OptType === 'Add' ? '值' : OptType === 'Delete' ? '删除前' : '修改前' -->
|
||||||
<el-table-column
|
<el-table-column
|
||||||
v-if="OptType !== 'Add' && OptType !== 'Upload' && OptType !== 'Init'"
|
v-if="OptType2 !== 'Add' && OptType2 !== 'Upload' && OptType2 !== 'Init'"
|
||||||
prop="oldValue"
|
prop="oldValue"
|
||||||
:label="OptType === 'Add' ? $t('trials:auditRecord:title:fieldValue') : OptType === 'Delete' ? $t('trials:auditRecord:title:beforeDeletion') : $t('trials:auditRecord:title:beforeModification')"
|
:label="OptType2 === 'Add' ? $t('trials:auditRecord:title:fieldValue') : OptType2 === 'Delete' ? $t('trials:auditRecord:title:beforeDeletion') : $t('trials:auditRecord:title:beforeModification')"
|
||||||
show-overflow-tooltip
|
show-overflow-tooltip
|
||||||
>
|
>
|
||||||
<!-- <template slot-scope="scope">
|
<!-- <template slot-scope="scope">
|
||||||
|
|
@ -692,7 +692,7 @@
|
||||||
<!-- OptType === 'Add' || OptType === 'Init' ? '值' : OptType === 'Delete' ? '删除后' : '修改后' -->
|
<!-- OptType === 'Add' || OptType === 'Init' ? '值' : OptType === 'Delete' ? '删除后' : '修改后' -->
|
||||||
<el-table-column
|
<el-table-column
|
||||||
prop="newValue"
|
prop="newValue"
|
||||||
:label="OptType === 'Add' || OptType === 'Init' ? $t('trials:auditRecord:title:fieldValue') : OptType === 'Delete' ? $t('trials:auditRecord:title:afterDeletion') : $t('trials:auditRecord:title:afterModification')"
|
:label="OptType2 === 'Add' || OptType2 === 'Init' ? $t('trials:auditRecord:title:fieldValue') : OptType2 === 'Delete' ? $t('trials:auditRecord:title:afterDeletion') : $t('trials:auditRecord:title:afterModification')"
|
||||||
show-overflow-tooltip
|
show-overflow-tooltip
|
||||||
>
|
>
|
||||||
<!-- <template slot-scope="scope">
|
<!-- <template slot-scope="scope">
|
||||||
|
|
@ -876,6 +876,7 @@ export default {
|
||||||
siteOptions: [],
|
siteOptions: [],
|
||||||
visitPlanOptions: [],
|
visitPlanOptions: [],
|
||||||
OptType: null,
|
OptType: null,
|
||||||
|
OptType2: null,
|
||||||
trialId: this.$route.query.trialId,
|
trialId: this.$route.query.trialId,
|
||||||
configList2: [],
|
configList2: [],
|
||||||
otherData2: [],
|
otherData2: [],
|
||||||
|
|
@ -896,19 +897,22 @@ export default {
|
||||||
this.getList()
|
this.getList()
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
openImage(url) {
|
openImage(url, type) {
|
||||||
console.log(url)
|
console.log(url)
|
||||||
|
|
||||||
this.$nextTick(()=>{
|
this.$nextTick(()=>{
|
||||||
if (url instanceof Array) {
|
if (url instanceof Array) {
|
||||||
this.imagesList = url.map(v => this.OSSclientConfig.basePath + v)
|
this.imagesList = url.map(v => this.OSSclientConfig.basePath + v)
|
||||||
this.$refs[url[0]].$viewer.show()
|
let refName = type ? `${url[0]}_${type}` : url[0]
|
||||||
|
this.$refs[refName].$viewer.show()
|
||||||
} else {
|
} else {
|
||||||
this.imagesList = [this.OSSclientConfig.basePath + url]
|
this.imagesList = [this.OSSclientConfig.basePath + url]
|
||||||
if(this.$refs[url] instanceof Array){
|
if(this.$refs[url] instanceof Array){
|
||||||
this.$refs[url][0].$viewer.show()
|
let refName = type ? `${url}_${type}` : url
|
||||||
|
this.$refs[refName][0].$viewer.show()
|
||||||
}else{
|
}else{
|
||||||
this.$refs[url].$viewer.show()
|
let refName = type ? `${url}_${type}` : url
|
||||||
|
this.$refs[refName].$viewer.show()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
@ -978,6 +982,8 @@ export default {
|
||||||
this.tableListData = []
|
this.tableListData = []
|
||||||
this[auditData] = []
|
this[auditData] = []
|
||||||
config.forEach(v => {
|
config.forEach(v => {
|
||||||
|
v.Code = this.$i18n.locale === 'zh' ? v.Code : v.CodeEn ? v.CodeEn : v.Code
|
||||||
|
|
||||||
var item
|
var item
|
||||||
if (!v.IsEnable) return
|
if (!v.IsEnable) return
|
||||||
if (v.IsShowByTrialConfig) {
|
if (v.IsShowByTrialConfig) {
|
||||||
|
|
@ -989,18 +995,18 @@ export default {
|
||||||
let uo = upObj[v.TableFiledName][i]
|
let uo = upObj[v.TableFiledName][i]
|
||||||
if (row.OptType === 'Add' || row.OptType === 'Init') {
|
if (row.OptType === 'Add' || row.OptType === 'Init') {
|
||||||
item = {
|
item = {
|
||||||
newValue: o[v.Code] ? (o[v.Code] ? o[v.Code] : '--') : '--',
|
newValue: o[v.Code] ? o[v.Code] : '--',
|
||||||
oldValue: ''
|
oldValue: ''
|
||||||
}
|
}
|
||||||
} else if (row.OptType === 'Delete') {
|
} else if (row.OptType === 'Delete') {
|
||||||
item = {
|
item = {
|
||||||
oldValue: o[v.Code] ? (o[v.Code] ? o[v.Code] : '--') : '--',
|
oldValue: o[v.Code] ? o[v.Code] : '--',
|
||||||
newValue: '--'
|
newValue: '--'
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
item = {
|
item = {
|
||||||
newValue: o[v.Code] ? (o[v.Code] ? o[v.Code] : '--') : '--',
|
newValue: o[v.Code] ? o[v.Code] : '--',
|
||||||
oldValue: uo ? uo[v.Code] : '--'
|
oldValue: uo ? uo[v.Code] ? uo[v.Code] : '--' : '--'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
item.key = o ? ((o[v.Code] && o[v.Code] !== null && o[v.Code] !== '' || o[v.Code] !== 0) ? o[v.Code] : '--') : '--'
|
item.key = o ? ((o[v.Code] && o[v.Code] !== null && o[v.Code] !== '' || o[v.Code] !== 0) ? o[v.Code] : '--') : '--'
|
||||||
|
|
@ -1019,21 +1025,21 @@ export default {
|
||||||
if (row.OptType === 'Add' || row.OptType === 'Init') {
|
if (row.OptType === 'Add' || row.OptType === 'Init') {
|
||||||
item = {
|
item = {
|
||||||
key: v.Code,
|
key: v.Code,
|
||||||
Enum: v.ValueCN,
|
Enum: this.$i18n.locale === 'zh' ? v.ValueCN : v.Value,
|
||||||
newValue: obj[v.Code] ? obj[v.Code] : '--',
|
newValue: obj[v.Code] ? obj[v.Code] : '--',
|
||||||
oldValue: ''
|
oldValue: ''
|
||||||
}
|
}
|
||||||
} else if (row.OptType === 'Delete') {
|
} else if (row.OptType === 'Delete') {
|
||||||
item = {
|
item = {
|
||||||
key: v.Code,
|
key: v.Code,
|
||||||
Enum: v.ValueCN,
|
Enum: this.$i18n.locale === 'zh' ? v.ValueCN : v.Value,
|
||||||
oldValue: obj[v.Code] ? obj[v.Code] : '--',
|
oldValue: obj[v.Code] ? obj[v.Code] : '--',
|
||||||
newValue: '--'
|
newValue: '--'
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
item = {
|
item = {
|
||||||
key: v.Code,
|
key: v.Code,
|
||||||
Enum: v.ValueCN,
|
Enum: this.$i18n.locale === 'zh' ? v.ValueCN : v.Value,
|
||||||
newValue: obj[v.Code] ? obj[v.Code] : '--',
|
newValue: obj[v.Code] ? obj[v.Code] : '--',
|
||||||
oldValue: upObj[v.Code].length > 0 ? upObj[v.Code] : '--'
|
oldValue: upObj[v.Code].length > 0 ? upObj[v.Code] : '--'
|
||||||
}
|
}
|
||||||
|
|
@ -1051,23 +1057,23 @@ export default {
|
||||||
if (row.OptType === 'Add' || row.OptType === 'Init') {
|
if (row.OptType === 'Add' || row.OptType === 'Init') {
|
||||||
item = {
|
item = {
|
||||||
key: o[v.ChildDataLabel],
|
key: o[v.ChildDataLabel],
|
||||||
Enum: o[v.ChildDataLabel],
|
Enum: this.$i18n.locale === 'zh' ? o[v.ChildDataLabel] : o[v.ChildDataEnLabel] ? o[v.ChildDataEnLabel] : o[v.ChildDataLabel],
|
||||||
newValue: o[v.ChildDataValue] ? (o[v.ChildDataValue] ? o[v.ChildDataValue] : '--') : '--',
|
newValue: o[v.ChildDataValue] ? o[v.ChildDataValue] : '--',
|
||||||
oldValue: ''
|
oldValue: ''
|
||||||
}
|
}
|
||||||
} else if (row.OptType === 'Delete') {
|
} else if (row.OptType === 'Delete') {
|
||||||
item = {
|
item = {
|
||||||
key: o[v.ChildDataLabel],
|
key: o[v.ChildDataLabel],
|
||||||
Enum: o[v.ChildDataLabel],
|
Enum: this.$i18n.locale === 'zh' ? o[v.ChildDataLabel] : o[v.ChildDataEnLabel] ? o[v.ChildDataEnLabel] : o[v.ChildDataLabel],
|
||||||
oldValue: o[v.ChildDataValue] ? (o[v.ChildDataValue] ? o[v.ChildDataValue] : '--') : '--',
|
oldValue: o[v.ChildDataValue] ? o[v.ChildDataValue] : '--',
|
||||||
newValue: '--'
|
newValue: '--'
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
item = {
|
item = {
|
||||||
key: o[v.ChildDataLabel],
|
key: o[v.ChildDataLabel],
|
||||||
Enum: o[v.ChildDataLabel],
|
Enum: this.$i18n.locale === 'zh' ? o[v.ChildDataLabel] : o[v.ChildDataEnLabel] ? o[v.ChildDataEnLabel] : o[v.ChildDataLabel],
|
||||||
newValue: o[v.ChildDataValue] ? (o[v.ChildDataValue] ? o[v.ChildDataValue] : '--') : '--',
|
newValue: o[v.ChildDataValue] ? o[v.ChildDataValue] : '--',
|
||||||
oldValue: uo ? uo[v.ChildDataValue] : '--'
|
oldValue: uo ? uo[v.ChildDataValue] ? uo[v.ChildDataValue] : '--' : '--'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
this[auditData].push(item)
|
this[auditData].push(item)
|
||||||
|
|
@ -1084,7 +1090,7 @@ export default {
|
||||||
a = getToken()
|
a = getToken()
|
||||||
}
|
}
|
||||||
return v.UrlParameterName + '=' + a + '&'
|
return v.UrlParameterName + '=' + a + '&'
|
||||||
}).toString().replaceAll(',', '') : v.UrlConfig.RoutePath,
|
}).toString().replaceAll(',', '') + 'zh='+this.$i18n.locale : v.UrlConfig.RoutePath,
|
||||||
newValue: v.UrlConfig.IsHaveParameters ? v.UrlConfig.RoutePath + '?' +
|
newValue: v.UrlConfig.IsHaveParameters ? v.UrlConfig.RoutePath + '?' +
|
||||||
v.UrlConfig.ParameterList.map((v) => {
|
v.UrlConfig.ParameterList.map((v) => {
|
||||||
let a = obj[v.UrlParameterValueName] ? obj[v.UrlParameterValueName] : parentRow[v.UrlParameterValueName]
|
let a = obj[v.UrlParameterValueName] ? obj[v.UrlParameterValueName] : parentRow[v.UrlParameterValueName]
|
||||||
|
|
@ -1092,7 +1098,7 @@ export default {
|
||||||
a = getToken()
|
a = getToken()
|
||||||
}
|
}
|
||||||
return v.UrlParameterName + '=' + a + '&'
|
return v.UrlParameterName + '=' + a + '&'
|
||||||
}).toString().replaceAll(',', '') : v.UrlConfig.RoutePath
|
}).toString().replaceAll(',', '') + 'zh='+this.$i18n.locale : v.UrlConfig.RoutePath
|
||||||
}
|
}
|
||||||
console.log(item)
|
console.log(item)
|
||||||
item.IsTableFiled = v.IsTableFiled
|
item.IsTableFiled = v.IsTableFiled
|
||||||
|
|
@ -1111,10 +1117,10 @@ export default {
|
||||||
} else {
|
} else {
|
||||||
if (j.ListName) {
|
if (j.ListName) {
|
||||||
obj[v.Code][0][j.ListName].forEach((x, o) => {
|
obj[v.Code][0][j.ListName].forEach((x, o) => {
|
||||||
head.push({IsPicture: j.IsPicture, headName: x[j.ColumnName], IsMerge: j.IsMerge, ColumnName: j.ColumnName, ColumnValue: j.ColumnValue, ListName: j.ListName, MergeColumnName: j.IsMerge ? this.$i18n.locale === 'zh' ? j.MergeColumnName : j.MergeColumnEnName : null, ChildrenList: []})
|
head.push({IsPicture: j.IsPicture, headName: x[this.$i18n.locale === 'zh' ? j.ColumnName : j.ColumnEnName ? j.ColumnEnName : j.ColumnName], IsMerge: j.IsMerge, ColumnName: j.ColumnName, ColumnValue: j.ColumnValue, ListName: j.ListName, MergeColumnName: j.IsMerge ? this.$i18n.locale === 'zh' ? j.MergeColumnName : j.MergeColumnEnName : null, ChildrenList: []})
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
head.push({IsPicture: j.IsPicture, headName: j.ColumnName, IsMerge: j.IsMerge, ColumnName: j.ColumnName, ColumnValue: j.ColumnValue, ListName: j.ListName, MergeColumnName: j.IsMerge ? this.$i18n.locale === 'zh' ? j.MergeColumnName : j.MergeColumnEnName : null, ChildrenList: []})
|
head.push({IsPicture: j.IsPicture, headName: this.$i18n.locale === 'zh' ? j.ColumnName : j.ColumnEnName ? j.ColumnEnName : j.ColumnName, IsMerge: j.IsMerge, ColumnName: j.ColumnName, ColumnValue: j.ColumnValue, ListName: j.ListName, MergeColumnName: j.IsMerge ? this.$i18n.locale === 'zh' ? j.MergeColumnName : j.MergeColumnEnName : null, ChildrenList: []})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
@ -1254,6 +1260,7 @@ export default {
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
async lookDetails2(row) {
|
async lookDetails2(row) {
|
||||||
|
this.OptType2 = row.OptType
|
||||||
var Json = await this.getJSON(row)
|
var Json = await this.getJSON(row)
|
||||||
var JsonDetail = Json[0] ? JSON.parse(Json[0]) : null
|
var JsonDetail = Json[0] ? JSON.parse(Json[0]) : null
|
||||||
var ParentJson = Json[1] ? JSON.parse(Json[1]) : null
|
var ParentJson = Json[1] ? JSON.parse(Json[1]) : null
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@
|
||||||
<el-upload
|
<el-upload
|
||||||
class="upload-demo"
|
class="upload-demo"
|
||||||
action
|
action
|
||||||
accept=".xlsx,.xls,.csv"
|
accept=".xlsx,.xls"
|
||||||
:before-upload="beforeUpload"
|
:before-upload="beforeUpload"
|
||||||
:http-request="handleUploadFile"
|
:http-request="handleUploadFile"
|
||||||
:on-preview="handlePreview"
|
:on-preview="handlePreview"
|
||||||
|
|
@ -72,7 +72,7 @@ export default {
|
||||||
this.$message.warning(this.$t('trials:consistencyCheck:message:onlyOneFile'))
|
this.$message.warning(this.$t('trials:consistencyCheck:message:onlyOneFile'))
|
||||||
},
|
},
|
||||||
checkFileSuffix(fileName) {
|
checkFileSuffix(fileName) {
|
||||||
var typeArr = ['xls', 'xlsx', 'csv']
|
var typeArr = ['xls', 'xlsx']
|
||||||
var extendName = fileName.substring(fileName.lastIndexOf('.') + 1).toLocaleLowerCase()
|
var extendName = fileName.substring(fileName.lastIndexOf('.') + 1).toLocaleLowerCase()
|
||||||
if (typeArr.indexOf(extendName) !== -1) {
|
if (typeArr.indexOf(extendName) !== -1) {
|
||||||
return true
|
return true
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@
|
||||||
<span style="font-weight:700;">{{ record.CreateUserName }} </span>
|
<span style="font-weight:700;">{{ record.CreateUserName }} </span>
|
||||||
<span>({{ record.CreateTime }}) </span>
|
<span>({{ record.CreateTime }}) </span>
|
||||||
</p>
|
</p>
|
||||||
<div class="info-content" v-html="record.TalkContent" />
|
<div class="info-content" v-html="formattedText(record.TalkContent)" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
@ -23,7 +23,7 @@
|
||||||
<span style="font-weight:700;">{{ record.CreateUserName }} </span>
|
<span style="font-weight:700;">{{ record.CreateUserName }} </span>
|
||||||
<span>({{ record.CreateTime }}) </span>
|
<span>({{ record.CreateTime }}) </span>
|
||||||
</p>
|
</p>
|
||||||
<div class="info-content" v-html="record.TalkContent" />
|
<div class="info-content" v-html="formattedText(record.TalkContent)" />
|
||||||
</div>
|
</div>
|
||||||
<!-- <img :src="record.headUrl"> -->
|
<!-- <img :src="record.headUrl"> -->
|
||||||
<img v-if="record.UserTypeEnum*1 === 8" :src="adminAvatar" alt="Admin">
|
<img v-if="record.UserTypeEnum*1 === 8" :src="adminAvatar" alt="Admin">
|
||||||
|
|
@ -231,6 +231,9 @@ export default {
|
||||||
this.getMessageList()
|
this.getMessageList()
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
formattedText(text) {
|
||||||
|
return text.replace(/\n/g, '<br>')
|
||||||
|
},
|
||||||
// 初始化聊天信息
|
// 初始化聊天信息
|
||||||
getMessageList() {
|
getMessageList() {
|
||||||
var recordContent = []
|
var recordContent = []
|
||||||
|
|
|
||||||
|
|
@ -252,7 +252,7 @@
|
||||||
</div>
|
</div>
|
||||||
<!-- PDF录入 -->
|
<!-- PDF录入 -->
|
||||||
<div v-if="cd.ClinicalUploadType === 1">
|
<div v-if="cd.ClinicalUploadType === 1">
|
||||||
<div v-if="allowAddOrEdit" style="text-align: right">
|
<div v-if="allowAddOrEdit" style="display:flex;align-items:center;justify-content: flex-end;">
|
||||||
<!-- 下载模板 -->
|
<!-- 下载模板 -->
|
||||||
<el-button
|
<el-button
|
||||||
v-if="cd.Path"
|
v-if="cd.Path"
|
||||||
|
|
@ -271,6 +271,7 @@
|
||||||
position: relative;
|
position: relative;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
|
margin-left:10px
|
||||||
"
|
"
|
||||||
>
|
>
|
||||||
<!-- 新增 -->
|
<!-- 新增 -->
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
|
@ -654,6 +654,7 @@ export default {
|
||||||
this.loading = true;
|
this.loading = true;
|
||||||
this.data.TrialId = this.$route.query.trialId;
|
this.data.TrialId = this.$route.query.trialId;
|
||||||
var param = {
|
var param = {
|
||||||
|
SubjectVisitId: this.studyData.SubjectVisitId,
|
||||||
StudyId: this.studyData.StudyId,
|
StudyId: this.studyData.StudyId,
|
||||||
TrialId: this.$route.query.trialId,
|
TrialId: this.$route.query.trialId,
|
||||||
SubjectId: this.studyData.SubjectId,
|
SubjectId: this.studyData.SubjectId,
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@
|
||||||
<span style="font-weight:700;">{{ record.CreateUserName }} </span>
|
<span style="font-weight:700;">{{ record.CreateUserName }} </span>
|
||||||
<span>({{ record.CreateTime }}) </span>
|
<span>({{ record.CreateTime }}) </span>
|
||||||
</p>
|
</p>
|
||||||
<div class="info-content" v-html="record.TalkContent" />
|
<div class="info-content" v-html="formattedText(record.TalkContent)" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
@ -23,7 +23,7 @@
|
||||||
<span style="font-weight:700;">{{ record.CreateUserName }} </span>
|
<span style="font-weight:700;">{{ record.CreateUserName }} </span>
|
||||||
<span>({{ record.CreateTime }}) </span>
|
<span>({{ record.CreateTime }}) </span>
|
||||||
</p>
|
</p>
|
||||||
<div class="info-content" v-html="record.TalkContent" />
|
<div class="info-content" v-html="formattedText(record.TalkContent)" />
|
||||||
</div>
|
</div>
|
||||||
<!-- <img :src="record.headUrl"> -->
|
<!-- <img :src="record.headUrl"> -->
|
||||||
<img v-if="record.UserTypeEnum*1 === 8" :src="adminAvatar" alt="Admin">
|
<img v-if="record.UserTypeEnum*1 === 8" :src="adminAvatar" alt="Admin">
|
||||||
|
|
@ -153,6 +153,9 @@ export default {
|
||||||
close() {
|
close() {
|
||||||
this.$emit('close')
|
this.$emit('close')
|
||||||
},
|
},
|
||||||
|
formattedText(text) {
|
||||||
|
return text.replace(/\n/g, '<br>')
|
||||||
|
},
|
||||||
// 初始化聊天信息
|
// 初始化聊天信息
|
||||||
getMessageList() {
|
getMessageList() {
|
||||||
var recordContent = []
|
var recordContent = []
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load Diff
|
|
@ -16,7 +16,7 @@ const name = process.env.NODE_ENV === 'usa' ? 'LILI' : defaultSettings.title ||
|
||||||
// eslint-disable-next-line no-undef
|
// eslint-disable-next-line no-undef
|
||||||
module.exports = {
|
module.exports = {
|
||||||
// lintOnSave: false,
|
// lintOnSave: false,
|
||||||
transpileDependencies: ['@cornerstonejs', 'minio'],
|
transpileDependencies: ['@cornerstonejs', 'minio', '@aws-sdk', '@smithy'],
|
||||||
publicPath: process.env.NODE_ENV === 'development' || process.env.VUE_APP_OSS_CONFIG_BUCKET === 'zyypacs-usa' ? process.env.VUE_APP_BASE_PATH : `${process.env.VUE_FILE_PATH}${process.env.VUE_APP_OSS_PATH}${distDate}/`,
|
publicPath: process.env.NODE_ENV === 'development' || process.env.VUE_APP_OSS_CONFIG_BUCKET === 'zyypacs-usa' ? process.env.VUE_APP_BASE_PATH : `${process.env.VUE_FILE_PATH}${process.env.VUE_APP_OSS_PATH}${distDate}/`,
|
||||||
// publicPath: '/',
|
// publicPath: '/',
|
||||||
outputDir: 'dist',
|
outputDir: 'dist',
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue