v1.7.0发布
commit
a2939e52b2
2
.env.usa
2
.env.usa
|
|
@ -2,7 +2,7 @@
|
||||||
ENV = 'usa'
|
ENV = 'usa'
|
||||||
NODE_ENV = 'usa'
|
NODE_ENV = 'usa'
|
||||||
# base public path
|
# base public path
|
||||||
VUE_APP_BASE_PATH = 'https://ei-med-s3-uat-code.s3.amazonaws.com/2024-09-14/'
|
VUE_APP_BASE_PATH = 'https://ei-med-s3-uat-code.s3.amazonaws.com/2024-10-14/'
|
||||||
|
|
||||||
# 是否开启登陆限制 true:是 false:否
|
# 是否开启登陆限制 true:是 false:否
|
||||||
VUE_APP_LOGIN_FOR_PERMISSION = true
|
VUE_APP_LOGIN_FOR_PERMISSION = true
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
ENV = 'usa'
|
ENV = 'usa'
|
||||||
NODE_ENV = 'usa'
|
NODE_ENV = 'usa'
|
||||||
# base public path
|
# base public path
|
||||||
VUE_APP_BASE_PATH = 'https://ei-med-s3-code.s3.amazonaws.com/2024-09-05/'
|
VUE_APP_BASE_PATH = 'https://ei-med-s3-code.s3.amazonaws.com/2024-10-14/'
|
||||||
|
|
||||||
# 是否开启登陆限制 true:是 false:否
|
# 是否开启登陆限制 true:是 false:否
|
||||||
VUE_APP_LOGIN_FOR_PERMISSION = true
|
VUE_APP_LOGIN_FOR_PERMISSION = true
|
||||||
|
|
|
||||||
|
|
@ -28,11 +28,13 @@
|
||||||
"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",
|
||||||
"cornerstone-tools": "^6.0.10",
|
"cornerstone-tools": "^6.0.10",
|
||||||
"cornerstone-wado-image-loader": "^4.13.2",
|
"cornerstone-wado-image-loader": "^4.13.2",
|
||||||
|
"crypto-js": "^4.2.0",
|
||||||
"dcmjs": "^0.29.8",
|
"dcmjs": "^0.29.8",
|
||||||
"dicom-parser": "^1.8.9",
|
"dicom-parser": "^1.8.9",
|
||||||
"dicomedit": "^0.1.0",
|
"dicomedit": "^0.1.0",
|
||||||
|
|
@ -43,6 +45,7 @@
|
||||||
"hammerjs": "^2.0.8",
|
"hammerjs": "^2.0.8",
|
||||||
"html2canvas": "^1.4.1",
|
"html2canvas": "^1.4.1",
|
||||||
"js-md5": "^0.7.3",
|
"js-md5": "^0.7.3",
|
||||||
|
"jsencrypt": "^3.3.2",
|
||||||
"jszip": "^3.7.1",
|
"jszip": "^3.7.1",
|
||||||
"moment": "^2.27.0",
|
"moment": "^2.27.0",
|
||||||
"node-polyfill-webpack-plugin": "^2.0.1",
|
"node-polyfill-webpack-plugin": "^2.0.1",
|
||||||
|
|
|
||||||
|
|
@ -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,67 @@ 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
|
||||||
|
})
|
||||||
|
}
|
||||||
|
// 影像下载成功确认
|
||||||
|
export function downloadImageSuccess(params) {
|
||||||
|
return request({
|
||||||
|
url: '/DownloadAndUpload/downloadImageSuccess',
|
||||||
|
method: 'post',
|
||||||
|
params
|
||||||
|
})
|
||||||
|
}
|
||||||
|
// 影像下载记录列表
|
||||||
|
export function getTrialDownloadList(data) {
|
||||||
|
return request({
|
||||||
|
url: '/DownloadAndUpload/getTrialDownloadList',
|
||||||
|
method: 'post',
|
||||||
|
data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
// 修改后处理检查类型
|
||||||
|
export function updateTaskStudyModality(params) {
|
||||||
|
return request({
|
||||||
|
url: '/DownloadAndUpload/updateTaskStudyModality',
|
||||||
|
method: 'put',
|
||||||
|
params
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
import request from '@/utils/request'
|
import request from '@/utils/request'
|
||||||
|
import requestDownload from '@/utils/request-download'
|
||||||
export function addBaseLineLesion(param) {
|
export function addBaseLineLesion(param) {
|
||||||
return request({
|
return request({
|
||||||
url: '/report/addBaseLineLesion',
|
url: '/report/addBaseLineLesion',
|
||||||
|
|
@ -133,9 +133,11 @@ export function AddAdjudicationReport(param) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getVisitStudyList(trialId, subjectVisitId, isReading) {
|
export function getVisitStudyList(trialId, subjectVisitId, isReading, visitTaskId) {
|
||||||
|
let url = `/SubjectVisit/getVisitStudyList/${trialId}/${subjectVisitId}/${isReading}`
|
||||||
|
url = visitTaskId ? `${url}?visitTaskId=${visitTaskId}` : url
|
||||||
return request({
|
return request({
|
||||||
url: `/SubjectVisit/getVisitStudyList/${trialId}/${subjectVisitId}/${isReading}`,
|
url: url,
|
||||||
method: 'get'
|
method: 'get'
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
@ -194,3 +196,58 @@ export function resetReadingTask(param) {
|
||||||
data: param
|
data: param
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
export function getTaskUploadedDicomStudyList(param) {
|
||||||
|
return request({
|
||||||
|
url: `/DownloadAndUpload/getTaskUploadedDicomStudyList`,
|
||||||
|
method: 'post',
|
||||||
|
data: param
|
||||||
|
})
|
||||||
|
}
|
||||||
|
export function getIVUSTemplate(param) {
|
||||||
|
return requestDownload({
|
||||||
|
url: '/IVUSCalculate/getIVUSTemplate',
|
||||||
|
method: 'post',
|
||||||
|
responseType: 'blob',
|
||||||
|
data: param
|
||||||
|
})
|
||||||
|
}
|
||||||
|
export function uploadIVUSTemplate(param) {
|
||||||
|
return request({
|
||||||
|
url: `/IVUSCalculate/uploadIVUSTemplate`,
|
||||||
|
method: 'post',
|
||||||
|
data: param
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getOCTFCTTemplate(param) {
|
||||||
|
return requestDownload({
|
||||||
|
url: '/OCTCalculate/getOCTFCTTemplate',
|
||||||
|
method: 'post',
|
||||||
|
responseType: 'blob',
|
||||||
|
data: param
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export function uploadOCTFCTTemplate(param) {
|
||||||
|
return request({
|
||||||
|
url: `/OCTCalculate/uploadOCTFCTTemplate`,
|
||||||
|
method: 'post',
|
||||||
|
data: param
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getOCTLipidAngleTemplate(param) {
|
||||||
|
return requestDownload({
|
||||||
|
url: '/OCTCalculate/getOCTLipidAngleTemplate',
|
||||||
|
method: 'post',
|
||||||
|
responseType: 'blob',
|
||||||
|
data: param
|
||||||
|
})
|
||||||
|
}
|
||||||
|
export function uploadOCTLipidAngleTemplate(param) {
|
||||||
|
return request({
|
||||||
|
url: `/OCTCalculate/uploadOCTLipidAngleTemplate`,
|
||||||
|
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'
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,8 @@ export function login(data) {
|
||||||
return request({
|
return request({
|
||||||
url: '/user/login',
|
url: '/user/login',
|
||||||
method: 'post',
|
method: 'post',
|
||||||
data
|
data,
|
||||||
|
ENCRYPT: true
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
export function loginOut(params) {
|
export function loginOut(params) {
|
||||||
|
|
@ -185,3 +186,10 @@ export function sendMFAEmail(params) {
|
||||||
params
|
params
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
// 获取公钥
|
||||||
|
export function getPublicKey() {
|
||||||
|
return request({
|
||||||
|
url: `/user/getPublicKey`,
|
||||||
|
method: 'get',
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
|
||||||
Binary file not shown.
|
Before Width: | Height: | Size: 145 KiB After Width: | Height: | Size: 61 KiB |
|
|
@ -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,7 +376,7 @@ 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
|
||||||
|
|
@ -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
|
|
@ -9,7 +9,7 @@
|
||||||
/>
|
/>
|
||||||
<!-- <embed v-else-if="fileType.indexOf('pdf') !== -1" :src="filePath+'#toolbar=0'" style="width: 100%; height: 100%"> -->
|
<!-- <embed v-else-if="fileType.indexOf('pdf') !== -1" :src="filePath+'#toolbar=0'" style="width: 100%; height: 100%"> -->
|
||||||
<!-- <iframe v-else-if="fileType.indexOf('pdf') !== -1" :src="filePath+'#toolbar=0'" width="100%" height="100%" frameborder="0" /> -->
|
<!-- <iframe v-else-if="fileType.indexOf('pdf') !== -1" :src="filePath+'#toolbar=0'" width="100%" height="100%" frameborder="0" /> -->
|
||||||
<iframe v-else-if="fileType.indexOf('pdf') !== -1" :src="`/static/pdfjs/web/viewer.html?file=${OSSclientConfig.basePath}${filePath}?userName=${currentUser}`" width="100%" height="100%" frameborder="0" crossorigin="anonymous" />
|
<iframe v-else-if="fileType.indexOf('pdf') !== -1" :src="`/static/pdfjs/web/viewer.html?file=${OSSclientConfig.basePath}${filePath}?userName=${currentUser}&COMPANY=${COMPANY}`" width="100%" height="100%" frameborder="0" crossorigin="anonymous" />
|
||||||
<!-- <pdf-->
|
<!-- <pdf-->
|
||||||
<!-- v-else-if="fileType.indexOf('pdf') !== -1"-->
|
<!-- v-else-if="fileType.indexOf('pdf') !== -1"-->
|
||||||
<!-- :src="`/static/pdfjs/web/viewer.html?file=${filePath}`">-->
|
<!-- :src="`/static/pdfjs/web/viewer.html?file=${filePath}`">-->
|
||||||
|
|
@ -40,7 +40,8 @@ export default {
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
currentUser: zzSessionStorage.getItem('userName')
|
currentUser: zzSessionStorage.getItem('userName'),
|
||||||
|
COMPANY:process.env.VUE_APP_COMPANY_NAME
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,511 @@
|
||||||
|
<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"
|
||||||
|
v-if="hasDicom || hasNonedicom"
|
||||||
|
@click.stop="getIRReadingDownloadStudyInfo('all')"
|
||||||
|
>
|
||||||
|
{{ $t('download:button:downloadAll') }}
|
||||||
|
</el-button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="tip">
|
||||||
|
<i class="el-icon-warning-outline"></i>
|
||||||
|
<div v-html="$t('download:tip:message')"></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"
|
||||||
|
:bodyPart="bodyPart"
|
||||||
|
:IsDicom="IsDicom"
|
||||||
|
:visitTaskId="modelTaskId"
|
||||||
|
/>
|
||||||
|
</el-dialog>
|
||||||
|
</template>
|
||||||
|
<script>
|
||||||
|
import {
|
||||||
|
getSubjectImageDownloadSelectList,
|
||||||
|
getIRReadingDownloadStudyInfo,
|
||||||
|
downloadImageSuccess,
|
||||||
|
} 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,
|
||||||
|
downloadId: null,
|
||||||
|
IsReadingTaskViewInOrder: 0, // 阅片规则
|
||||||
|
bodyPart: [],
|
||||||
|
modelTaskId: null,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
async mounted() {
|
||||||
|
this.getList()
|
||||||
|
this.bodyPart = await this.$getBodyPart(this.$route.query.trialId)
|
||||||
|
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 || this.list[0].SubjectId,
|
||||||
|
TrialReadingCriterionId: this.Criterion.TrialReadingCriterionId,
|
||||||
|
SubjectCode: this.SubjectCode || this.list[0].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.downloadId = res.OtherInfo.PreDownloadId
|
||||||
|
this.IsReadingTaskViewInOrder = res.OtherInfo.IsReadingTaskViewInOrder
|
||||||
|
this.downloadImage(res.Result)
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
this.btnLoading = false
|
||||||
|
console.log(err)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// 打包下载
|
||||||
|
async downloadImage(data) {
|
||||||
|
try {
|
||||||
|
let { files, name, fileType } = this.formatDownloadFile(data)
|
||||||
|
let res = await downLoadFile(files, name, 'zip')
|
||||||
|
if (res && this.downloadId) {
|
||||||
|
this.downloadImageSuccess()
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
console.log(err)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// 格式化下载文件路径
|
||||||
|
formatDownloadFile(list) {
|
||||||
|
let files = [],
|
||||||
|
name = `${list[0].SubjectCode}_${new Date().getTime()}.zip`
|
||||||
|
if (this.IsReadingTaskViewInOrder === 1) {
|
||||||
|
name = `${list[0].SubjectCode}_${list[0].TaskBlindName}.zip`
|
||||||
|
}
|
||||||
|
if (this.IsReadingTaskViewInOrder === 0) {
|
||||||
|
name = `${list[0].TaskBlindName}.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,
|
||||||
|
}
|
||||||
|
if (this.IsReadingTaskViewInOrder === 0) {
|
||||||
|
obj = {
|
||||||
|
name: `${data.TaskBlindName}/${this.$fd(
|
||||||
|
'IsDicom',
|
||||||
|
true
|
||||||
|
)}/${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,
|
||||||
|
}
|
||||||
|
if (this.IsReadingTaskViewInOrder === 0) {
|
||||||
|
obj = {
|
||||||
|
name: `${data.TaskBlindName}/${this.$fd(
|
||||||
|
'IsDicom',
|
||||||
|
false
|
||||||
|
)}/${item.FileName}`,
|
||||||
|
url: this.OSSclientConfig.basePath + item.Path,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
files.push(obj)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
return { files, name }
|
||||||
|
},
|
||||||
|
// 影像下载成功确认
|
||||||
|
async downloadImageSuccess() {
|
||||||
|
try {
|
||||||
|
let params = {
|
||||||
|
TrialImageDownloadId: this.downloadId,
|
||||||
|
}
|
||||||
|
await downloadImageSuccess(params)
|
||||||
|
} catch (err) {
|
||||||
|
console.log(err)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
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.modelTaskId = item.VisitTaskId
|
||||||
|
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}&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?page=download&trialId=${trialId}&visitTaskId=${row.VisitTaskId}&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;
|
||||||
|
}
|
||||||
|
.tip {
|
||||||
|
display: flex;
|
||||||
|
align-items: flex-start;
|
||||||
|
margin-top: 5px;
|
||||||
|
i {
|
||||||
|
margin: 3px 5px 0 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
@ -52,7 +52,7 @@
|
||||||
class="el-icon-warning-outline"
|
class="el-icon-warning-outline"
|
||||||
style="color: #f56c6c; font-size: 24px"
|
style="color: #f56c6c; font-size: 24px"
|
||||||
></i>
|
></i>
|
||||||
<span>{{ $t("feedBack:imgfail:tip") }}</span>
|
<span>{{ $t('feedBack:imgfail:tip') }}</span>
|
||||||
</p>
|
</p>
|
||||||
<!-- 问题反馈 -->
|
<!-- 问题反馈 -->
|
||||||
<el-form-item
|
<el-form-item
|
||||||
|
|
@ -140,7 +140,7 @@
|
||||||
<div slot="footer" v-if="type !== 'detail' || isImgfail">
|
<div slot="footer" v-if="type !== 'detail' || isImgfail">
|
||||||
<!-- 取消 -->
|
<!-- 取消 -->
|
||||||
<el-button size="small" @click.stop="cancel">
|
<el-button size="small" @click.stop="cancel">
|
||||||
{{ $t("feedBack:button:cancel") }}
|
{{ $t('feedBack:button:cancel') }}
|
||||||
</el-button>
|
</el-button>
|
||||||
<!-- 保存 -->
|
<!-- 保存 -->
|
||||||
<el-button
|
<el-button
|
||||||
|
|
@ -149,21 +149,21 @@
|
||||||
@click.stop="save"
|
@click.stop="save"
|
||||||
:loading="loading"
|
:loading="loading"
|
||||||
>
|
>
|
||||||
{{ $t("feedBack:button:save") }}
|
{{ $t('feedBack:button:save') }}
|
||||||
</el-button>
|
</el-button>
|
||||||
</div>
|
</div>
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script>
|
<script>
|
||||||
import uploadImage from "./uploadImage.vue";
|
import uploadImage from './uploadImage.vue'
|
||||||
import {
|
import {
|
||||||
addOrUpdateUserFeedBack,
|
addOrUpdateUserFeedBack,
|
||||||
getUserFeedBackInfo,
|
getUserFeedBackInfo,
|
||||||
batchUpdateFeedBackState,
|
batchUpdateFeedBackState,
|
||||||
} from "@/api/trials.js";
|
} from '@/api/trials.js'
|
||||||
export default {
|
export default {
|
||||||
name: "FB",
|
name: 'FB',
|
||||||
components: { uploadImage },
|
components: { uploadImage },
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
|
|
@ -195,131 +195,131 @@ export default {
|
||||||
QuestionType: [
|
QuestionType: [
|
||||||
{
|
{
|
||||||
required: true,
|
required: true,
|
||||||
message: this.$t("common:ruleMessage:specify"),
|
message: this.$t('common:ruleMessage:specify'),
|
||||||
trigger: "blur",
|
trigger: 'blur',
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
QuestionDescription: [
|
QuestionDescription: [
|
||||||
{
|
{
|
||||||
required: true,
|
required: true,
|
||||||
message: this.$t("common:ruleMessage:specify"),
|
message: this.$t('common:ruleMessage:specify'),
|
||||||
trigger: "blur",
|
trigger: 'blur',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
validator: (rule, value, callback) => {
|
validator: (rule, value, callback) => {
|
||||||
if (value.length < 5) {
|
if (value.length < 5) {
|
||||||
callback(
|
callback(
|
||||||
new Error(this.$t("feedBack:ruleMessage:lengthLimitMin5"))
|
new Error(this.$t('feedBack:ruleMessage:lengthLimitMin5'))
|
||||||
);
|
)
|
||||||
}
|
}
|
||||||
callback();
|
callback()
|
||||||
},
|
},
|
||||||
trigger: "blur",
|
trigger: 'blur',
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
isUpload: false,
|
isUpload: false,
|
||||||
};
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
level() {
|
level() {
|
||||||
if (this.hasPermi(["role:dev", "role:admin"])) {
|
if (this.hasPermi(['role:dev', 'role:admin'])) {
|
||||||
return 9;
|
return 9
|
||||||
}
|
}
|
||||||
if (this.hasPermi(["role:pm"])) {
|
if (this.hasPermi(['role:pm', 'role:apm'])) {
|
||||||
return 8;
|
return 8
|
||||||
}
|
}
|
||||||
if (this.hasPermi(["role:ir", "role:crc"])) {
|
if (this.hasPermi(['role:ir', 'role:crc'])) {
|
||||||
return 7;
|
return 7
|
||||||
}
|
}
|
||||||
return 0;
|
return 0
|
||||||
},
|
},
|
||||||
QuestionTypeOptions() {
|
QuestionTypeOptions() {
|
||||||
if (this.level > 7) {
|
if (this.level > 7) {
|
||||||
return [
|
return [
|
||||||
...this.$d.FeedBackTypeToCRC.filter((item) => item.value > 0),
|
...this.$d.FeedBackTypeToCRC.filter((item) => item.value > 0),
|
||||||
...this.$d.FeedBackTypeToIR,
|
...this.$d.FeedBackTypeToIR,
|
||||||
];
|
]
|
||||||
}
|
}
|
||||||
if (this.hasPermi(["role:ir"])) {
|
if (this.hasPermi(['role:ir'])) {
|
||||||
return this.$d.FeedBackTypeToIR;
|
return this.$d.FeedBackTypeToIR
|
||||||
}
|
}
|
||||||
if (this.hasPermi(["role:crc"])) {
|
if (this.hasPermi(['role:crc'])) {
|
||||||
return this.$d.FeedBackTypeToCRC;
|
return this.$d.FeedBackTypeToCRC
|
||||||
}
|
}
|
||||||
return [];
|
return []
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
open(data) {
|
open(data) {
|
||||||
let { type, trialId, Id, visitTaskId, SubjectVisitId } = data;
|
let { type, trialId, Id, visitTaskId, SubjectVisitId } = data
|
||||||
this.type = type;
|
this.type = type
|
||||||
this.trialId = trialId;
|
this.trialId = trialId
|
||||||
this.Id = Id;
|
this.Id = Id
|
||||||
this.visitTaskId = visitTaskId;
|
this.visitTaskId = visitTaskId
|
||||||
this.SubjectVisitId = SubjectVisitId;
|
this.SubjectVisitId = SubjectVisitId
|
||||||
if (visitTaskId) {
|
if (visitTaskId) {
|
||||||
this.isImgfail = true;
|
this.isImgfail = true
|
||||||
}
|
}
|
||||||
this.setTypeOption();
|
this.setTypeOption()
|
||||||
if (!Id) {
|
if (!Id) {
|
||||||
this.title = this.setTitle();
|
this.title = this.setTitle()
|
||||||
}
|
}
|
||||||
if (Id || visitTaskId) {
|
if (Id || visitTaskId) {
|
||||||
this.getInfo(Id, visitTaskId);
|
this.getInfo(Id, visitTaskId)
|
||||||
}
|
}
|
||||||
this.visible = true;
|
this.visible = true
|
||||||
},
|
},
|
||||||
cancel() {
|
cancel() {
|
||||||
this.visible = false;
|
this.visible = false
|
||||||
this.$emit("closed");
|
this.$emit('closed')
|
||||||
},
|
},
|
||||||
async save() {
|
async save() {
|
||||||
try {
|
try {
|
||||||
let validate = await this.$refs.feedBackForm.validate();
|
let validate = await this.$refs.feedBackForm.validate()
|
||||||
if (!validate) return;
|
if (!validate) return
|
||||||
if (this.trialId) {
|
if (this.trialId) {
|
||||||
this.form.TrialId = this.trialId;
|
this.form.TrialId = this.trialId
|
||||||
}
|
}
|
||||||
if (this.visitTaskId) {
|
if (this.visitTaskId) {
|
||||||
this.form.VisitTaskId = this.visitTaskId;
|
this.form.VisitTaskId = this.visitTaskId
|
||||||
}
|
}
|
||||||
if (this.SubjectVisitId) {
|
if (this.SubjectVisitId) {
|
||||||
this.form.SubjectVisitId = this.SubjectVisitId;
|
this.form.SubjectVisitId = this.SubjectVisitId
|
||||||
}
|
}
|
||||||
if (this.Id) {
|
if (this.Id) {
|
||||||
this.form.Id = this.Id;
|
this.form.Id = this.Id
|
||||||
}
|
}
|
||||||
this.loading = true;
|
this.loading = true
|
||||||
let res = await addOrUpdateUserFeedBack(this.form);
|
let res = await addOrUpdateUserFeedBack(this.form)
|
||||||
this.loading = false;
|
this.loading = false
|
||||||
if (res.IsSuccess) {
|
if (res.IsSuccess) {
|
||||||
this.$emit("success");
|
this.$emit('success')
|
||||||
this.$message.success(this.$t("feedBack:save:success"));
|
this.$message.success(this.$t('feedBack:save:success'))
|
||||||
this.cancel();
|
this.cancel()
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
this.loading = false;
|
this.loading = false
|
||||||
console.log(err);
|
console.log(err)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
// 修改状态
|
// 修改状态
|
||||||
async changeState() {
|
async changeState() {
|
||||||
if (this.isImgfail) return;
|
if (this.isImgfail) return
|
||||||
try {
|
try {
|
||||||
let data = {
|
let data = {
|
||||||
IdList: [this.Id],
|
IdList: [this.Id],
|
||||||
State: this.form.State,
|
State: this.form.State,
|
||||||
};
|
}
|
||||||
let res = await batchUpdateFeedBackState(data);
|
let res = await batchUpdateFeedBackState(data)
|
||||||
if (res.IsSuccess) {
|
if (res.IsSuccess) {
|
||||||
this.$message.success(this.$t("feedBack:changeState:success"));
|
this.$message.success(this.$t('feedBack:changeState:success'))
|
||||||
this.$emit("success");
|
this.$emit('success')
|
||||||
// this.cancel();
|
// this.cancel();
|
||||||
this.getInfo(this.Id, this.visitTaskId);
|
this.getInfo(this.Id, this.visitTaskId)
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.log(err);
|
console.log(err)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
// 获取反馈详情
|
// 获取反馈详情
|
||||||
|
|
@ -328,56 +328,56 @@ export default {
|
||||||
let data = {
|
let data = {
|
||||||
Id,
|
Id,
|
||||||
visitTaskId,
|
visitTaskId,
|
||||||
};
|
}
|
||||||
let res = await getUserFeedBackInfo(data);
|
let res = await getUserFeedBackInfo(data)
|
||||||
if (res.IsSuccess && res.Result) {
|
if (res.IsSuccess && res.Result) {
|
||||||
this.form = res.Result;
|
this.form = res.Result
|
||||||
this.Id = res.Result.Id;
|
this.form.ScreenshotList = this.form.ScreenshotList || []
|
||||||
|
this.Id = res.Result.Id
|
||||||
if (res.Result.State > 0) {
|
if (res.Result.State > 0) {
|
||||||
this.isStateChange = false;
|
this.isStateChange = false
|
||||||
}
|
}
|
||||||
if (res.Result.VisitTaskId) {
|
if (res.Result.VisitTaskId) {
|
||||||
this.visitTaskId = res.Result.VisitTaskId;
|
this.visitTaskId = res.Result.VisitTaskId
|
||||||
}
|
}
|
||||||
if (res.Result.SubjectVisitId) {
|
if (res.Result.SubjectVisitId) {
|
||||||
this.SubjectVisitId = res.Result.SubjectVisitId;
|
this.SubjectVisitId = res.Result.SubjectVisitId
|
||||||
}
|
}
|
||||||
let code = this.$fd("UserType", res.Result.UserTypeEnum);
|
let code = this.$fd('UserType', res.Result.UserTypeEnum)
|
||||||
this.title = this.setTitle(code, res.Result.FeedBackFullName);
|
this.title = this.setTitle(code, res.Result.FeedBackFullName)
|
||||||
if (visitTaskId) {
|
if (visitTaskId) {
|
||||||
code = `${res.Result.SubjectCode}-${res.Result.SubjectVisitName}`;
|
code = `${res.Result.SubjectCode}-${res.Result.SubjectVisitName}`
|
||||||
this.title = this.setTitle(code, res.Result.FeedBackFullName);
|
this.title = this.setTitle(code, res.Result.FeedBackFullName)
|
||||||
}
|
}
|
||||||
this.$refs.uploadImage.initFileList(res.Result.ScreenshotList);
|
this.$refs.uploadImage.initFileList(res.Result.ScreenshotList)
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.log(err);
|
console.log(err)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
setTypeOption() {
|
setTypeOption() {
|
||||||
if (!this.trialId) return (this.options = []);
|
if (!this.trialId) return (this.options = [])
|
||||||
if (this.hasPermi(["role:ir"]))
|
if (this.hasPermi(['role:ir']))
|
||||||
return (this.option = this.$d.FeedBackTypeToIR);
|
return (this.option = this.$d.FeedBackTypeToIR)
|
||||||
if (this.hasPermi(["role:crc"]))
|
if (this.hasPermi(['role:crc']))
|
||||||
return (this.option = this.$d.FeedBackTypeToCRC);
|
return (this.option = this.$d.FeedBackTypeToCRC)
|
||||||
},
|
},
|
||||||
setTitle(code, name) {
|
setTitle(code, name) {
|
||||||
console.log(code, name);
|
if (this.hasPermi(['role:pm']) && this.visitTaskId) {
|
||||||
if (this.hasPermi(["role:pm"]) && this.visitTaskId) {
|
return `${this.$t('feedBack:form:title:pm2')}(${code}/${name})`
|
||||||
return `${this.$t("feedBack:form:title:pm2")}(${code}/${name})`;
|
|
||||||
}
|
}
|
||||||
if (this.hasPermi(["role:pm", "role:dev", "role:admin"])) {
|
if (this.hasPermi(['role:pm', 'role:dev', 'role:admin'])) {
|
||||||
return `${this.$t("feedBack:form:title:pm")}(${code},${name})`;
|
return `${this.$t('feedBack:form:title:pm')}(${code},${name})`
|
||||||
}
|
}
|
||||||
if (this.hasPermi(["role:ir", "role:crc"]) && this.type === "detail") {
|
if (this.hasPermi(['role:ir', 'role:crc']) && this.type === 'detail') {
|
||||||
return `${this.$t("feedBack:form:detail:title")}`;
|
return `${this.$t('feedBack:form:detail:title')}`
|
||||||
}
|
}
|
||||||
if (this.hasPermi(["role:ir", "role:crc"])) {
|
if (this.hasPermi(['role:ir', 'role:crc'])) {
|
||||||
return `${this.$t("feedBack:form:title")}`;
|
return `${this.$t('feedBack:form:title')}`
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
}
|
||||||
</script>
|
</script>
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
.tip {
|
.tip {
|
||||||
|
|
|
||||||
|
|
@ -58,14 +58,14 @@
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script>
|
<script>
|
||||||
const type = "Statement of Work";
|
const type = 'Statement of Work'
|
||||||
export default {
|
export default {
|
||||||
name: "UploadImage",
|
name: 'UploadImage',
|
||||||
props: {
|
props: {
|
||||||
path: {
|
path: {
|
||||||
required: true,
|
required: true,
|
||||||
default: () => {
|
default: () => {
|
||||||
return [];
|
return []
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
disabled: {
|
disabled: {
|
||||||
|
|
@ -78,14 +78,14 @@ export default {
|
||||||
},
|
},
|
||||||
trialId: {
|
trialId: {
|
||||||
type: String,
|
type: String,
|
||||||
default: "",
|
default: '',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
fileList: [],
|
fileList: [],
|
||||||
btnDisabled: false,
|
btnDisabled: false,
|
||||||
};
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
remove(file, fileList) {
|
remove(file, fileList) {
|
||||||
|
|
@ -93,115 +93,113 @@ export default {
|
||||||
},
|
},
|
||||||
fileToBlob(file) {
|
fileToBlob(file) {
|
||||||
// 创建 FileReader 对象
|
// 创建 FileReader 对象
|
||||||
const reader = new FileReader();
|
const reader = new FileReader()
|
||||||
return new Promise((resolve) => {
|
return new Promise((resolve) => {
|
||||||
// FileReader 添加 load 事件
|
// FileReader 添加 load 事件
|
||||||
reader.addEventListener("load", (e) => {
|
reader.addEventListener('load', (e) => {
|
||||||
let blob;
|
let blob
|
||||||
if (typeof e.target.result === "object") {
|
if (typeof e.target.result === 'object') {
|
||||||
blob = new Blob([e.target.result]);
|
blob = new Blob([e.target.result])
|
||||||
} else {
|
} else {
|
||||||
blob = e.target.result;
|
blob = e.target.result
|
||||||
}
|
}
|
||||||
resolve(blob);
|
resolve(blob)
|
||||||
});
|
})
|
||||||
// FileReader 以 ArrayBuffer 格式 读取 File 对象中数据
|
// FileReader 以 ArrayBuffer 格式 读取 File 对象中数据
|
||||||
reader.readAsArrayBuffer(file);
|
reader.readAsArrayBuffer(file)
|
||||||
});
|
})
|
||||||
},
|
},
|
||||||
// 上传oss
|
// 上传oss
|
||||||
async uploadToOSS(name, file) {
|
async uploadToOSS(name, file) {
|
||||||
try {
|
try {
|
||||||
let defaultPath = "/System/FeedBack/";
|
let defaultPath = '/System/FeedBack/'
|
||||||
if (this.trialId) {
|
if (this.trialId) {
|
||||||
defaultPath = `/${this.trialId}/FeedBack/`;
|
defaultPath = `/${this.trialId}/FeedBack/`
|
||||||
}
|
}
|
||||||
let res = await this.OSSclient.put(`${defaultPath}${name}`, file);
|
let res = await this.OSSclient.put(`${defaultPath}${name}`, file)
|
||||||
return res;
|
return res
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.log(err);
|
console.log(err)
|
||||||
return false;
|
return false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
initFileList(list) {
|
initFileList(list) {
|
||||||
if (list && list.length > 0) {
|
if (list && list.length > 0) {
|
||||||
this.fileList = [];
|
this.fileList = []
|
||||||
list.forEach((item, index) => {
|
list.forEach((item, index) => {
|
||||||
let name = item.split("/");
|
let name = item.split('/')
|
||||||
this.fileList.push({
|
this.fileList.push({
|
||||||
name: name[name.length - 1],
|
name: name[name.length - 1],
|
||||||
path: item,
|
path: item,
|
||||||
fullPath: this.OSSclientConfig.basePath + item,
|
fullPath: this.OSSclientConfig.basePath + item,
|
||||||
url: this.OSSclientConfig.basePath + item,
|
url: this.OSSclientConfig.basePath + item,
|
||||||
uid: `${name[name.length - 1]}${index}`,
|
uid: `${name[name.length - 1]}${index}`,
|
||||||
});
|
})
|
||||||
});
|
})
|
||||||
console.log(this.fileList);
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
async uploadFile(param) {
|
async uploadFile(param) {
|
||||||
var fileName = param.file.name;
|
var fileName = param.file.name
|
||||||
this.$emit("update:isUpload", true);
|
this.$emit('update:isUpload', true)
|
||||||
this.btnDisabled = true;
|
this.btnDisabled = true
|
||||||
this.fileList.push({
|
this.fileList.push({
|
||||||
url: param.file.url,
|
url: param.file.url,
|
||||||
path: fileName,
|
path: fileName,
|
||||||
uid: param.file.uid,
|
uid: param.file.uid,
|
||||||
});
|
})
|
||||||
let file = await this.fileToBlob(param.file);
|
let file = await this.fileToBlob(param.file)
|
||||||
let res = await this.uploadToOSS(fileName, file);
|
let res = await this.uploadToOSS(fileName, file)
|
||||||
this.btnDisabled = false;
|
this.btnDisabled = false
|
||||||
let index = this.fileList.findIndex(
|
let index = this.fileList.findIndex((item) => item.uid === param.file.uid)
|
||||||
(item) => item.uid === param.file.uid
|
|
||||||
);
|
|
||||||
if (!res) {
|
if (!res) {
|
||||||
if (index >= 0) {
|
if (index >= 0) {
|
||||||
this.fileList.splice(index, 1);
|
this.fileList.splice(index, 1)
|
||||||
}
|
}
|
||||||
return this.$emit("update:isUpload", false);
|
return this.$emit('update:isUpload', false)
|
||||||
}
|
}
|
||||||
this.fileList[index].url = this.OSSclientConfig.basePath + res.name;
|
let name = this.$getObjectName(res.url)
|
||||||
this.fileList[index].path = res.name;
|
this.fileList[index].url = this.OSSclientConfig.basePath + name
|
||||||
this.$emit("update:path", [...this.path, res.name]);
|
this.fileList[index].path = name
|
||||||
this.$emit("update:isUpload", false);
|
this.$emit('update:path', [...this.path, res.name])
|
||||||
return false;
|
this.$emit('update:isUpload', false)
|
||||||
|
return false
|
||||||
},
|
},
|
||||||
beforeUpload(file, fileList) {
|
beforeUpload(file, fileList) {
|
||||||
const isValidFile = this.fileValid(file.name, ["png", "jpg", "jpeg"]);
|
const isValidFile = this.fileValid(file.name, ['png', 'jpg', 'jpeg'])
|
||||||
if (isValidFile) {
|
if (isValidFile) {
|
||||||
// this.fileList = [];
|
// this.fileList = [];
|
||||||
} else {
|
} else {
|
||||||
this.$alert(this.$t("feedBack:uploadImg:format"));
|
this.$alert(this.$t('feedBack:uploadImg:format'))
|
||||||
return false;
|
return false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
handlePreview(file) {
|
handlePreview(file) {
|
||||||
file.fullPath ? window.open(file.fullPath, "_blank") : "";
|
file.fullPath ? window.open(file.fullPath, '_blank') : ''
|
||||||
},
|
},
|
||||||
handleExceed(files, fileList) {
|
handleExceed(files, fileList) {
|
||||||
this.$message.warning(`Upload is currently limited to 1 file`);
|
this.$message.warning(`Upload is currently limited to 1 file`)
|
||||||
},
|
},
|
||||||
fileValid(fileName, typeArr) {
|
fileValid(fileName, typeArr) {
|
||||||
var extendName = fileName
|
var extendName = fileName
|
||||||
.substring(fileName.lastIndexOf(".") + 1)
|
.substring(fileName.lastIndexOf('.') + 1)
|
||||||
.toLocaleLowerCase();
|
.toLocaleLowerCase()
|
||||||
if (typeArr.indexOf(extendName) > -1) {
|
if (typeArr.indexOf(extendName) > -1) {
|
||||||
return true;
|
return true
|
||||||
} else {
|
} else {
|
||||||
return false;
|
return false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
handlePictureCardPreview(file) {
|
handlePictureCardPreview(file) {
|
||||||
this.$refs[file.url].$viewer.show();
|
this.$refs[file.url].$viewer.show()
|
||||||
},
|
},
|
||||||
handleRemove(file) {
|
handleRemove(file) {
|
||||||
let index = this.fileList.findIndex((item) => item.uid === file.uid);
|
let index = this.fileList.findIndex((item) => item.uid === file.uid)
|
||||||
this.fileList.splice(index, 1);
|
this.fileList.splice(index, 1)
|
||||||
let arr = this.fileList.map((item) => item.path);
|
let arr = this.fileList.map((item) => item.path)
|
||||||
this.$emit("update:path", arr);
|
this.$emit('update:path', arr)
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
}
|
||||||
</script>
|
</script>
|
||||||
<style>
|
<style>
|
||||||
.upload-container .el-upload--text {
|
.upload-container .el-upload--text {
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,117 @@
|
||||||
|
<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"
|
||||||
|
:TaskId="VisitTaskId"
|
||||||
|
:isUpload.sync="isUpload"
|
||||||
|
:isReadingTaskViewInOrder="isReadingTaskViewInOrder"
|
||||||
|
/>
|
||||||
|
</el-tab-pane>
|
||||||
|
<el-tab-pane
|
||||||
|
:label="$t('uploadDicomAndNonedicom:label:nonedicom')"
|
||||||
|
name="nonedicom"
|
||||||
|
>
|
||||||
|
<nonedicomFile
|
||||||
|
v-if="activeName === 'nonedicom'"
|
||||||
|
:SubjectId="SubjectId"
|
||||||
|
:SubjectCode="SubjectCode"
|
||||||
|
:Criterion="Criterion"
|
||||||
|
:VisitTaskId="VisitTaskId"
|
||||||
|
:isUpload.sync="isUpload"
|
||||||
|
/>
|
||||||
|
</el-tab-pane>
|
||||||
|
</el-tabs>
|
||||||
|
</el-dialog>
|
||||||
|
</template>
|
||||||
|
<script>
|
||||||
|
import dicomFile from './dicomFile.vue'
|
||||||
|
import nonedicomFile from './nonedicomFile.vue'
|
||||||
|
import store from '@/store'
|
||||||
|
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 {}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
VisitTaskId: {
|
||||||
|
type: String,
|
||||||
|
default: '',
|
||||||
|
},
|
||||||
|
isReadingTaskViewInOrder: {
|
||||||
|
type: Number,
|
||||||
|
default: 0,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
title: '',
|
||||||
|
activeName: 'dicom',
|
||||||
|
isUpload: false,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this.title = `Upload Images:${this.SubjectCode}(${this.Criterion.TrialReadingCriterionName})`
|
||||||
|
store.dispatch('trials/setUnLock', true)
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
beforeClose() {
|
||||||
|
if (
|
||||||
|
this.$route.path !== '/trials/trials-panel/reading/readingTask' &&
|
||||||
|
this.isUpload
|
||||||
|
) {
|
||||||
|
return window.location.reload()
|
||||||
|
}
|
||||||
|
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,919 @@
|
||||||
|
<template>
|
||||||
|
<div class="nonedicomFile">
|
||||||
|
<div class="top">
|
||||||
|
<span>{{ $t('upload:nonedicom:title') }}</span>
|
||||||
|
<div class="tip">
|
||||||
|
<i class="el-icon-warning-outline"></i>
|
||||||
|
<div v-html="$t('upload:nonedicom:tip:message')"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!--检查列表-->
|
||||||
|
<el-table
|
||||||
|
:data="list"
|
||||||
|
style="width: 100%"
|
||||||
|
v-adaptive="{ bottomOffset: 60 }"
|
||||||
|
: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
|
||||||
|
prop="FileSize"
|
||||||
|
:label="$t('trials:audit:table:nonDicomsFileSize')"
|
||||||
|
width="100"
|
||||||
|
>
|
||||||
|
<template slot-scope="scope">
|
||||||
|
<span>{{
|
||||||
|
scope.row.FileSize && scope.row.FileSize > 0
|
||||||
|
? `${(scope.row.FileSize / 1024 / 1024).toFixed(2)}MB`
|
||||||
|
: ''
|
||||||
|
}}</span>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column :label="$t('common:action:action')" width="120">
|
||||||
|
<template slot-scope="files">
|
||||||
|
<!-- 预览 -->
|
||||||
|
<viewer
|
||||||
|
:ref="files.row.Path"
|
||||||
|
style="margin: 0 10px"
|
||||||
|
:images="[`${OSSclientConfig.basePath}${files.row.Path}`]"
|
||||||
|
>
|
||||||
|
<el-button
|
||||||
|
circle
|
||||||
|
icon="el-icon-view"
|
||||||
|
:title="$t('upload:nonedicom:button:preview')"
|
||||||
|
:disabled="
|
||||||
|
files.row.FileType &&
|
||||||
|
files.row.FileType.indexOf('zip') >= 0
|
||||||
|
"
|
||||||
|
@click.native.prevent="previewFile(files.row)"
|
||||||
|
/>
|
||||||
|
<img
|
||||||
|
v-show="false"
|
||||||
|
crossorigin="anonymous"
|
||||||
|
:src="`${OSSclientConfig.basePath}${files.row.Path}`"
|
||||||
|
alt="Image"
|
||||||
|
/>
|
||||||
|
</viewer>
|
||||||
|
</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
|
||||||
|
prop="FileSize"
|
||||||
|
:label="$t('trials:audit:table:nonDicomsFileSize')"
|
||||||
|
width="100"
|
||||||
|
>
|
||||||
|
<template slot-scope="scope">
|
||||||
|
<span>{{
|
||||||
|
scope.row.FileSize && scope.row.FileSize > 0
|
||||||
|
? `${(scope.row.FileSize / 1024 / 1024).toFixed(2)}MB`
|
||||||
|
: ''
|
||||||
|
}}</span>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column :label="$t('common:action:action')" width="120">
|
||||||
|
<template slot-scope="files">
|
||||||
|
<!-- 预览 -->
|
||||||
|
<viewer
|
||||||
|
:ref="files.row.Path"
|
||||||
|
style="margin: 0 10px"
|
||||||
|
:images="[`${OSSclientConfig.basePath}${files.row.Path}`]"
|
||||||
|
>
|
||||||
|
<el-button
|
||||||
|
circle
|
||||||
|
icon="el-icon-view"
|
||||||
|
:title="$t('upload:nonedicom:button:preview')"
|
||||||
|
:disabled="
|
||||||
|
files.row.FileType &&
|
||||||
|
files.row.FileType.indexOf('zip') >= 0
|
||||||
|
"
|
||||||
|
@click.native.prevent="previewFile(files.row)"
|
||||||
|
/>
|
||||||
|
<img
|
||||||
|
v-show="false"
|
||||||
|
crossorigin="anonymous"
|
||||||
|
:src="`${OSSclientConfig.basePath}${files.row.Path}`"
|
||||||
|
alt="Image"
|
||||||
|
/>
|
||||||
|
</viewer>
|
||||||
|
</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 ||
|
||||||
|
scope.row.ReadingTaskState === 2
|
||||||
|
"
|
||||||
|
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`
|
||||||
|
: ''
|
||||||
|
}}</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 {}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
VisitTaskId: {
|
||||||
|
type: String,
|
||||||
|
default: '',
|
||||||
|
},
|
||||||
|
isUpload: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
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
|
||||||
|
if (this.VisitTaskId) {
|
||||||
|
this.searchData.VisitTaskId = this.VisitTaskId
|
||||||
|
}
|
||||||
|
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
|
||||||
|
this.$refs[row.Path].$viewer.show()
|
||||||
|
},
|
||||||
|
// 预览单个检查下非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.$emit('update:isUpload', true)
|
||||||
|
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 * 2 // 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,
|
||||||
|
FileCount: this.selectArr.length,
|
||||||
|
})
|
||||||
|
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
|
||||||
|
let path = `/${this.$route.query.trialId}/TaskImage/${
|
||||||
|
this.currentRow.SubjectId
|
||||||
|
}/${this.currentRow.VisitTaskId}/${this.$guid()}${file.name
|
||||||
|
.substring(file.name.lastIndexOf('.'))
|
||||||
|
.toLocaleLowerCase()}`
|
||||||
|
file.curPath = 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) {
|
||||||
|
let RecordPath = await this.uploadRecord(arr)
|
||||||
|
return this.submitFile(this.successFileList, RecordPath)
|
||||||
|
}
|
||||||
|
} 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) {
|
||||||
|
let RecordPath = await this.uploadRecord(arr)
|
||||||
|
this.$refs.filesTable.clearSelection()
|
||||||
|
failFileList.forEach((row) => {
|
||||||
|
row.uploadFileSize = 0
|
||||||
|
this.$refs.filesTable.toggleRowSelection(row)
|
||||||
|
})
|
||||||
|
this.isFail = true
|
||||||
|
this.submitFile(this.successFileList, RecordPath, 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, RecordPath, isReLoad = false) {
|
||||||
|
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,
|
||||||
|
}
|
||||||
|
if (RecordPath) {
|
||||||
|
params.RecordPath = RecordPath.path
|
||||||
|
params.FailedFileCount = RecordPath.Record.Failed.length
|
||||||
|
}
|
||||||
|
uploadNoneDicomFile(params)
|
||||||
|
.then((res) => {
|
||||||
|
if (!isReLoad) {
|
||||||
|
this.resetFileDiaolg()
|
||||||
|
}
|
||||||
|
this.getList()
|
||||||
|
this.$emit('update:isUpload', true)
|
||||||
|
// 刷新父组件列表
|
||||||
|
this.$emit('getList')
|
||||||
|
this.$message.success(
|
||||||
|
this.$t('trials:uploadNonDicoms:message:uploadedSuccessfully')
|
||||||
|
)
|
||||||
|
})
|
||||||
|
.catch(() => {
|
||||||
|
this.btnLoading = false
|
||||||
|
})
|
||||||
|
},
|
||||||
|
// 上传提交记录
|
||||||
|
uploadRecord(arr) {
|
||||||
|
return new Promise(async (resolve) => {
|
||||||
|
try {
|
||||||
|
let Record = {
|
||||||
|
Failed: [],
|
||||||
|
Existed: [],
|
||||||
|
Uploaded: [],
|
||||||
|
FileCount: arr.length,
|
||||||
|
}
|
||||||
|
arr.forEach((item) => {
|
||||||
|
let file = this.fileList.find((data) => data.id === item.id)
|
||||||
|
if (file.status === 2) {
|
||||||
|
Record.Uploaded.push(file.curPath)
|
||||||
|
}
|
||||||
|
if (file.status === 3) {
|
||||||
|
Record.Failed.push(file.curPath)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
let text = JSON.stringify(Record)
|
||||||
|
let logJsonBlob = this.generateTxtFile(text)
|
||||||
|
let logJsonObjectName = `/${this.$route.query.trialId}/TaskImage/${this.currentRow.SubjectId}/${this.currentRow.VisitTaskId}/${this.studyMonitorId}.txt`
|
||||||
|
let logRes
|
||||||
|
try {
|
||||||
|
logRes = await this.OSSclient.put(logJsonObjectName, logJsonBlob)
|
||||||
|
if (logRes && logRes.url) {
|
||||||
|
resolve({ path: this.$getObjectName(logRes.url), Record })
|
||||||
|
} else {
|
||||||
|
resolve(false)
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
resolve(false)
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
console.log(err)
|
||||||
|
resolve(false)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
generateTxtFile(text) {
|
||||||
|
let blob = new Blob(['\ufeff', text], { type: 'text/plain' })
|
||||||
|
return blob
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
</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用来控制该标签的点击穿透事件
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.tip {
|
||||||
|
display: flex;
|
||||||
|
align-items: flex-start;
|
||||||
|
margin-top: 5px;
|
||||||
|
i {
|
||||||
|
margin: 3px 5px 0 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
@ -0,0 +1,291 @@
|
||||||
|
<template>
|
||||||
|
<div v-if="model_cfg.visible">
|
||||||
|
<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"
|
||||||
|
>
|
||||||
|
<template slot-scope="scope">
|
||||||
|
<span>{{
|
||||||
|
$fd(
|
||||||
|
'Bodypart',
|
||||||
|
scope.row.BodyPartForEdit,
|
||||||
|
'Code',
|
||||||
|
{ Bodypart: bodyPart },
|
||||||
|
'Name'
|
||||||
|
)
|
||||||
|
}}</span>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<!--序列数量-->
|
||||||
|
<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"
|
||||||
|
>
|
||||||
|
<template slot-scope="scope">
|
||||||
|
<span>{{
|
||||||
|
$fd(
|
||||||
|
'Bodypart',
|
||||||
|
scope.row.BodyPart,
|
||||||
|
'Code',
|
||||||
|
{ Bodypart: bodyPart },
|
||||||
|
'Name'
|
||||||
|
)
|
||||||
|
}}</span>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<!--文件数量-->
|
||||||
|
<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:preview')"
|
||||||
|
v-if="!isUpload"
|
||||||
|
@click.stop="preview(scope.row)"
|
||||||
|
/>
|
||||||
|
<!--编辑--->
|
||||||
|
<el-button
|
||||||
|
circle
|
||||||
|
icon="el-icon-edit-outline"
|
||||||
|
:title="$t('trials:uploadImage:button:edit')"
|
||||||
|
v-else
|
||||||
|
@click.stop="openEdit(scope.row)"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
</div>
|
||||||
|
</base-model>
|
||||||
|
<!--新增检查部位-->
|
||||||
|
<base-model v-if="editModality_model.visible" :config="editModality_model">
|
||||||
|
<template slot="dialog-body">
|
||||||
|
<el-form
|
||||||
|
ref="editModalityform"
|
||||||
|
:inline="true"
|
||||||
|
:model="form"
|
||||||
|
class="demo-form-inline"
|
||||||
|
:rules="rules"
|
||||||
|
>
|
||||||
|
<el-form-item
|
||||||
|
:label="$t('trials:uploadImage:form:ModalityForEdit')"
|
||||||
|
prop="Modality"
|
||||||
|
label-width="150px"
|
||||||
|
>
|
||||||
|
<el-select v-model="form.Modality" placeholder="">
|
||||||
|
<el-option
|
||||||
|
v-for="item in TrialModality"
|
||||||
|
:key="item"
|
||||||
|
:label="item"
|
||||||
|
:value="item"
|
||||||
|
>
|
||||||
|
</el-option>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
</template>
|
||||||
|
<template slot="dialog-footer">
|
||||||
|
<el-button
|
||||||
|
type="primary"
|
||||||
|
@click="updateTaskStudyModality"
|
||||||
|
:loading="loading"
|
||||||
|
>
|
||||||
|
{{ $t('common:button:confirm') }}
|
||||||
|
</el-button>
|
||||||
|
<el-button
|
||||||
|
@click="editModality_model.visible = false"
|
||||||
|
:loading="loading"
|
||||||
|
>
|
||||||
|
{{ $t('common:button:cancel') }}
|
||||||
|
</el-button>
|
||||||
|
</template>
|
||||||
|
</base-model>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<script>
|
||||||
|
import baseModel from '@/components/BaseModel'
|
||||||
|
import { getToken } from '@/utils/auth'
|
||||||
|
import { updateTaskStudyModality } from '@/api/load.js'
|
||||||
|
export default {
|
||||||
|
name: 'studyView',
|
||||||
|
props: {
|
||||||
|
model_cfg: {
|
||||||
|
type: Object,
|
||||||
|
default: () => {
|
||||||
|
return {}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
bodyPart: {
|
||||||
|
type: Array,
|
||||||
|
default: () => {
|
||||||
|
return []
|
||||||
|
},
|
||||||
|
},
|
||||||
|
modelList: {
|
||||||
|
type: Array,
|
||||||
|
default: () => {
|
||||||
|
return []
|
||||||
|
},
|
||||||
|
},
|
||||||
|
TrialModality: {
|
||||||
|
type: Array,
|
||||||
|
default: () => {
|
||||||
|
return []
|
||||||
|
},
|
||||||
|
},
|
||||||
|
visitTaskId: {
|
||||||
|
type: String,
|
||||||
|
},
|
||||||
|
IsDicom: {
|
||||||
|
required: true,
|
||||||
|
type: Boolean,
|
||||||
|
default: true,
|
||||||
|
},
|
||||||
|
isUpload: {
|
||||||
|
required: true,
|
||||||
|
type: Boolean,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
components: {
|
||||||
|
'base-model': baseModel,
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
form: {
|
||||||
|
Modality: null,
|
||||||
|
TaskStudyId: null,
|
||||||
|
},
|
||||||
|
editModality_model: {
|
||||||
|
visible: false,
|
||||||
|
title: this.$t('trials:uploadImage:button:edit'),
|
||||||
|
width: '500px',
|
||||||
|
appendToBody: true,
|
||||||
|
},
|
||||||
|
rules: {
|
||||||
|
Modality: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: this.$t('trials:uploadImage:format:notModality'),
|
||||||
|
trigger: ['blur', 'change'],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
loading: false,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
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&visitTaskId=${this.visitTaskId}`,
|
||||||
|
})
|
||||||
|
} 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')
|
||||||
|
},
|
||||||
|
// 打开编辑
|
||||||
|
openEdit(row) {
|
||||||
|
this.form.TaskStudyId = row.Id
|
||||||
|
this.form.Modality = row.ModalityForEdit
|
||||||
|
this.editModality_model.visible = true
|
||||||
|
},
|
||||||
|
// 修改检查类型
|
||||||
|
async updateTaskStudyModality() {
|
||||||
|
try {
|
||||||
|
let validate = await this.$refs.editModalityform.validate()
|
||||||
|
if (!validate) return false
|
||||||
|
this.loading = true
|
||||||
|
let res = await updateTaskStudyModality(this.form)
|
||||||
|
this.loading = false
|
||||||
|
if (res.IsSuccess) {
|
||||||
|
this.modelList.some((item) => {
|
||||||
|
if (this.form.TaskStudyId === item.Id) {
|
||||||
|
item.ModalityForEdit = this.form.Modality
|
||||||
|
}
|
||||||
|
return this.form.TaskStudyId === item.Id
|
||||||
|
})
|
||||||
|
this.editModality_model.visible = false
|
||||||
|
this.$emit('getList')
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
console.log(err)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
</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);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
|
||||||
84
src/main.js
84
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()
|
||||||
|
|
@ -252,6 +255,19 @@ async function VueInit() {
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Vue.prototype.$company = (isShort = true) => {
|
||||||
|
let companyName = null
|
||||||
|
if (localStorage.getItem('CompanyInfo')) {
|
||||||
|
let CompanyInfo = JSON.parse(localStorage.getItem('CompanyInfo'))
|
||||||
|
let isZh = zzSessionStorage.getItem('lang') === 'zh' || _vm.$i18n.locale == 'zh'
|
||||||
|
if (isZh) {
|
||||||
|
companyName = isShort ? CompanyInfo.CompanyShortNameCN : CompanyInfo.CompanyNameCN
|
||||||
|
} else {
|
||||||
|
companyName = isShort ? CompanyInfo.CompanyShortName : CompanyInfo.CompanyName
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return companyName;
|
||||||
|
}
|
||||||
Vue.prototype.$updateDictionary = function () {
|
Vue.prototype.$updateDictionary = function () {
|
||||||
Vue.prototype.$d = function (code) {
|
Vue.prototype.$d = function (code) {
|
||||||
var dictInfo = res.Result
|
var dictInfo = res.Result
|
||||||
|
|
@ -296,7 +312,8 @@ async function VueInit() {
|
||||||
data: {
|
data: {
|
||||||
unlock: {
|
unlock: {
|
||||||
my_username: null,
|
my_username: null,
|
||||||
my_password: null
|
my_password: null,
|
||||||
|
view: false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
render: h => h(App)
|
render: h => h(App)
|
||||||
|
|
@ -368,7 +385,7 @@ async function VueInit() {
|
||||||
// process.env.VUE_APP_LOGOUT_FOR_TIME
|
// process.env.VUE_APP_LOGOUT_FOR_TIME
|
||||||
// eval(process.env.VUE_APP_LOCK_FOR_PERMISSION)
|
// eval(process.env.VUE_APP_LOCK_FOR_PERMISSION)
|
||||||
// process.env.VUE_APP_LOCK_FOR_TIME
|
// process.env.VUE_APP_LOCK_FOR_TIME
|
||||||
window.VUE_APP_COMPANY_NAME = process.env.VUE_APP_COMPANY_NAME;
|
// window.VUE_APP_COMPANY_NAME = process.env.VUE_APP_COMPANY_NAME;
|
||||||
waitOperate(eval(process.env.VUE_APP_LOGOUT_FOR_PERMISSION) ? () => {
|
waitOperate(eval(process.env.VUE_APP_LOGOUT_FOR_PERMISSION) ? () => {
|
||||||
var lang = zzSessionStorage.getItem('lang') ? zzSessionStorage.getItem('lang') : 'zh'
|
var lang = zzSessionStorage.getItem('lang') ? zzSessionStorage.getItem('lang') : 'zh'
|
||||||
if (_vm.$store.state.trials.unlock || _vm.$route.path === '/ReviewersResearchForm' || _vm.$route.path === '/ReviewersResearch' || _vm.$route.path === '/login' || _vm.$route.path === '/researchForm' || _vm.$route.path === '/researchDetail_m' || _vm.$route.path === '/researchLogin_m' || _vm.$route.path === '/researchLogin' || _vm.$route.path === '/email-recompose' || _vm.$route.path === '/recompose' || _vm.$route.path === '/resetpassword' || _vm.$route.path === '/error') {
|
if (_vm.$store.state.trials.unlock || _vm.$route.path === '/ReviewersResearchForm' || _vm.$route.path === '/ReviewersResearch' || _vm.$route.path === '/login' || _vm.$route.path === '/researchForm' || _vm.$route.path === '/researchDetail_m' || _vm.$route.path === '/researchLogin_m' || _vm.$route.path === '/researchLogin' || _vm.$route.path === '/email-recompose' || _vm.$route.path === '/recompose' || _vm.$route.path === '/resetpassword' || _vm.$route.path === '/error') {
|
||||||
|
|
@ -440,7 +457,8 @@ async function VueInit() {
|
||||||
_vm.$message.success(_vm.$t("env:lock:msgBox:lockSuccess"))
|
_vm.$message.success(_vm.$t("env:lock:msgBox:lockSuccess"))
|
||||||
_vm.unlock = {
|
_vm.unlock = {
|
||||||
my_username: null,
|
my_username: null,
|
||||||
my_password: null
|
my_password: null,
|
||||||
|
view: false
|
||||||
}
|
}
|
||||||
isOpen = false
|
isOpen = false
|
||||||
count = 0;
|
count = 0;
|
||||||
|
|
@ -504,16 +522,21 @@ async function VueInit() {
|
||||||
]),
|
]),
|
||||||
h('el-form-item', {
|
h('el-form-item', {
|
||||||
props: { label: _vm.$t("env:lock:msgBox:form:Password") },
|
props: { label: _vm.$t("env:lock:msgBox:form:Password") },
|
||||||
|
attrs: {
|
||||||
|
style: "position: relative;"
|
||||||
|
}
|
||||||
}, [
|
}, [
|
||||||
h('input', {
|
h('input', {
|
||||||
props: {
|
props: {
|
||||||
value: _vm.unlock.my_password
|
value: _vm.unlock.my_password
|
||||||
},
|
},
|
||||||
|
ref: "unlock_my_password_input",
|
||||||
attrs: {
|
attrs: {
|
||||||
id: 'my_password',
|
id: 'my_password',
|
||||||
class: 'el-input__inner',
|
class: 'el-input__inner',
|
||||||
type: 'password',
|
type: _vm.unlock.view ? 'text' : 'password',
|
||||||
autocomplete: 'new-password'
|
autocomplete: 'new-password',
|
||||||
|
style: "padding-right:25px"
|
||||||
},
|
},
|
||||||
on: {
|
on: {
|
||||||
change: (event) => {
|
change: (event) => {
|
||||||
|
|
@ -523,7 +546,24 @@ async function VueInit() {
|
||||||
_vm.unlock.my_password = event.target.value
|
_vm.unlock.my_password = event.target.value
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
}),
|
||||||
|
h('i', {
|
||||||
|
attrs: {
|
||||||
|
id: 'my_password_view',
|
||||||
|
class: "el-icon-view",
|
||||||
|
style: "cursor: pointer;position: absolute;top:35%;right:10px"
|
||||||
|
},
|
||||||
|
on: {
|
||||||
|
click: (event) => {
|
||||||
|
_vm.unlock.view = !_vm.unlock.view
|
||||||
|
if (_vm.unlock.view) {
|
||||||
|
_vm.$refs['unlock_my_password_input'].type = "text"
|
||||||
|
} else {
|
||||||
|
_vm.$refs['unlock_my_password_input'].type = "password"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}),
|
||||||
])
|
])
|
||||||
])
|
])
|
||||||
])
|
])
|
||||||
|
|
|
||||||
|
|
@ -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.Type === 'basicTable') && 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 {
|
||||||
|
|
@ -70,7 +94,7 @@ function getQuestions(questions) {
|
||||||
}
|
}
|
||||||
function findQuestionAndRemoveLesion(questions, obj) {
|
function findQuestionAndRemoveLesion(questions, obj) {
|
||||||
for (var i = 0; i < questions.length; i++) {
|
for (var i = 0; i < questions.length; i++) {
|
||||||
if (questions[i].Type === 'table' && questions[i].TableQuestions && (questions[i].LesionType === obj.lesionType) && questions[i].TableQuestions.Answers.length > 0) {
|
if ((questions[i].Type === 'table' || questions[i].Type === 'basicTable') && questions[i].TableQuestions && (questions[i].LesionType === obj.lesionType) && questions[i].TableQuestions.Answers.length > 0) {
|
||||||
var idx = questions[i].TableQuestions.Answers.findIndex(i => String(i.RowIndex) === String(obj.rowIndex))
|
var idx = questions[i].TableQuestions.Answers.findIndex(i => String(i.RowIndex) === String(obj.rowIndex))
|
||||||
if (idx > -1) {
|
if (idx > -1) {
|
||||||
questions[i].TableQuestions.Answers.splice(idx, 1)
|
questions[i].TableQuestions.Answers.splice(idx, 1)
|
||||||
|
|
@ -86,7 +110,7 @@ function findQuestionAndRemoveLesion(questions, obj) {
|
||||||
function findQuestionAndUpdateLesion(questions, obj) {
|
function findQuestionAndUpdateLesion(questions, obj) {
|
||||||
for (var i = 0; i < questions.length; i++) {
|
for (var i = 0; i < questions.length; i++) {
|
||||||
var item = questions[i]
|
var item = questions[i]
|
||||||
if (item.Type === 'table' && item.Id === obj.questionId) {
|
if ((item.Type === 'table' || item.Type === 'basicTable') && item.Id === obj.questionId) {
|
||||||
var idx = item.TableQuestions.Answers.findIndex(i => i.RowIndex === obj.rowIndex)
|
var idx = item.TableQuestions.Answers.findIndex(i => i.RowIndex === obj.rowIndex)
|
||||||
item.TableQuestions.Answers[idx].isLymphLesion = obj.isLymphLesion
|
item.TableQuestions.Answers[idx].isLymphLesion = obj.isLymphLesion
|
||||||
item.TableQuestions.Answers[idx].loctation = obj.lesionOrgan
|
item.TableQuestions.Answers[idx].loctation = obj.lesionOrgan
|
||||||
|
|
@ -115,10 +139,10 @@ function findQuestionAndUpdateLesion(questions, obj) {
|
||||||
}
|
}
|
||||||
function findQuestionAndAddLesion(questions, obj) {
|
function findQuestionAndAddLesion(questions, obj) {
|
||||||
for (var i = 0; i < questions.length; i++) {
|
for (var i = 0; i < questions.length; i++) {
|
||||||
if (questions[i].Type === 'table' && questions[i].TableQuestions && (questions[i].LesionType === obj.lesionType)) {
|
if ((questions[i].Type === 'table' || questions[i].Type === 'basicTable') && questions[i].TableQuestions && (questions[i].LesionType === obj.lesionType)) {
|
||||||
var sourceObj = {}
|
var sourceObj = {}
|
||||||
questions[i].TableQuestions.Questions.forEach(item => {
|
questions[i].TableQuestions.Questions.forEach(item => {
|
||||||
sourceObj[item.Id] = ''
|
sourceObj[item.Id] = null
|
||||||
})
|
})
|
||||||
var targetObj = Object.assign(sourceObj, obj.lesionObj)
|
var targetObj = Object.assign(sourceObj, obj.lesionObj)
|
||||||
targetObj.IsCurrentTaskAdd = 'True'
|
targetObj.IsCurrentTaskAdd = 'True'
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -97,6 +97,7 @@ const actions = {
|
||||||
zzSessionStorage.setItem('my_username', username.trim())
|
zzSessionStorage.setItem('my_username', username.trim())
|
||||||
zzSessionStorage.setItem('my_password', md5(password))
|
zzSessionStorage.setItem('my_password', md5(password))
|
||||||
zzSessionStorage.setItem('my_EMail', response.Result.BasicInfo.EMail)
|
zzSessionStorage.setItem('my_EMail', response.Result.BasicInfo.EMail)
|
||||||
|
localStorage.setItem('CompanyInfo', JSON.stringify(response.Result.CompanyInfo))
|
||||||
const data = response.Result
|
const data = response.Result
|
||||||
if (data.BasicInfo.IsFirstAdd || data.BasicInfo.LoginState === 1) {
|
if (data.BasicInfo.IsFirstAdd || data.BasicInfo.LoginState === 1) {
|
||||||
try {
|
try {
|
||||||
|
|
|
||||||
|
|
@ -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,44 @@
|
||||||
|
// crypto.js
|
||||||
|
import CryptoJS from 'crypto-js';
|
||||||
|
import { JSEncrypt } from "jsencrypt";
|
||||||
|
import { getPublicKey } from "@/api/user.js"
|
||||||
|
export const Crypto = {
|
||||||
|
AES: {
|
||||||
|
encrypt: function (plaintext, secretKey) {
|
||||||
|
return CryptoJS.AES.encrypt(plaintext, CryptoJS.enc.Utf8.parse(secretKey), {
|
||||||
|
mode: CryptoJS.mode.ECB,
|
||||||
|
padding: CryptoJS.pad.Pkcs7,
|
||||||
|
iv: ''
|
||||||
|
}).ciphertext.toString(CryptoJS.enc.Base64);
|
||||||
|
},
|
||||||
|
decrypt: function (ciphertext, secretKey) {
|
||||||
|
const bytes = CryptoJS.AES.decrypt(ciphertext, secretKey);
|
||||||
|
return bytes.toString(CryptoJS.enc.Utf8);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
export const Encrypt = {
|
||||||
|
encrypt: async function (plaintext) {
|
||||||
|
let PublicKey = null;
|
||||||
|
if (sessionStorage.getItem('PublicKey')) {
|
||||||
|
PublicKey = atob(sessionStorage.getItem('PublicKey'));
|
||||||
|
} else {
|
||||||
|
try {
|
||||||
|
let res = await getPublicKey();
|
||||||
|
if (res.IsSuccess) {
|
||||||
|
PublicKey = atob(res.Result)
|
||||||
|
sessionStorage.setItem('PublicKey', res.Result)
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
console.log(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let encryptor = new JSEncrypt()
|
||||||
|
encryptor.setPublicKey(PublicKey)
|
||||||
|
return encryptor.encrypt(plaintext)
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,30 @@
|
||||||
|
import { Encrypt, Crypto } from "./crypto";
|
||||||
|
export const encryptConfig = async (config) => {
|
||||||
|
let secretKey = randomRange(32, 32);
|
||||||
|
let encryptSecretKey = await Encrypt.encrypt(secretKey); // 密钥进行非对称加密
|
||||||
|
if (encryptSecretKey) {
|
||||||
|
config.headers['X-Encrypted-Key'] = encryptSecretKey;
|
||||||
|
}
|
||||||
|
if (config.data && Object.prototype.toString.call(config.data) === '[object Object]') {
|
||||||
|
Object.keys(config.data).forEach(async key => {
|
||||||
|
config.data[key] = Crypto.AES.encrypt(config.data[key], secretKey)
|
||||||
|
console.log(config.data[key], 'KEY')
|
||||||
|
// config.data[key] = await Encrypt.encrypt(config.data[key])
|
||||||
|
})
|
||||||
|
}
|
||||||
|
return config;
|
||||||
|
}
|
||||||
|
const randomRange = (min, max, charStr) => {
|
||||||
|
var returnStr = "",
|
||||||
|
range;
|
||||||
|
if (typeof max == 'string') {
|
||||||
|
charStr = max;
|
||||||
|
}
|
||||||
|
range = ((max && typeof max == 'number') ? Math.round(Math.random() * (max - min)) + min : min);
|
||||||
|
charStr = charStr || 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
|
||||||
|
for (var i = 0; i < range; i++) {
|
||||||
|
var index = Math.round(Math.random() * (charStr.length - 1));
|
||||||
|
returnStr += charStr.substring(index, index + 1);
|
||||||
|
}
|
||||||
|
return returnStr;
|
||||||
|
}
|
||||||
|
|
@ -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(1, fileInformation.file, 0);
|
||||||
|
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,161 @@
|
||||||
|
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);
|
||||||
|
} else if (res.res.status === 404) {
|
||||||
|
delete savaData[saveFileId];
|
||||||
|
saveFinishedData(savaData);
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
} catch (e) {
|
||||||
|
console.log(e);
|
||||||
|
delete savaData[saveFileId];
|
||||||
|
saveFinishedData(savaData);
|
||||||
|
// 捕获超时异常。
|
||||||
|
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
243
src/utils/oss.js
243
src/utils/oss.js
|
|
@ -3,30 +3,39 @@ 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 = null;
|
||||||
|
if (localStorage.getItem('stsToken')) {
|
||||||
|
res = JSON.parse(localStorage.getItem('stsToken'))
|
||||||
|
} else {
|
||||||
|
res = await GetObjectStoreToken()
|
||||||
|
localStorage.setItem('stsToken', JSON.stringify(res))
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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 +58,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 +135,121 @@ 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('/')
|
||||||
|
}
|
||||||
|
let bucketName = data.path.split("/")[1] || Vue.prototype.OSSclientConfig.bucket
|
||||||
|
let curPath = data.path;
|
||||||
|
data.path = data.path.replace(`/${bucketName}/`, '');
|
||||||
|
await exist(aws, bucketName, data, progress, (path, status) => {
|
||||||
|
if (status === 'success') {
|
||||||
|
resolve({
|
||||||
|
name: decodeUtf8(curPath),
|
||||||
|
url: Vue.prototype.OSSclientConfig.viewEndpoint + decodeUtf8(curPath)
|
||||||
|
})
|
||||||
|
} 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 +259,48 @@ 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;
|
||||||
|
localStorage.setItem('stsToken', JSON.stringify(res))
|
||||||
|
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
|
||||||
|
|
|
||||||
|
|
@ -113,10 +113,14 @@ export const parseDicom = (file, name = false) => {
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
uintKey.forEach(key => {
|
uintKey.forEach(key => {
|
||||||
|
if (res.hasOwnProperty(key)) {
|
||||||
res[key] = data.uint16(dicom[key])
|
res[key] = data.uint16(dicom[key])
|
||||||
|
}
|
||||||
})
|
})
|
||||||
intStringKey.forEach(key => {
|
intStringKey.forEach(key => {
|
||||||
|
if (res.hasOwnProperty(key)) {
|
||||||
res[key] = data.intString(dicom[key])
|
res[key] = data.intString(dicom[key])
|
||||||
|
}
|
||||||
})
|
})
|
||||||
defaultKey.forEach(key => {
|
defaultKey.forEach(key => {
|
||||||
if (!res[key] && res.hasOwnProperty(key)) {
|
if (!res[key] && res.hasOwnProperty(key)) {
|
||||||
|
|
|
||||||
|
|
@ -2,9 +2,9 @@ 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())
|
import { encryptConfig } from "@/utils/encrypt"
|
||||||
axios.defaults.withCredentials = false
|
axios.defaults.withCredentials = false
|
||||||
const service = axios.create({
|
const service = axios.create({
|
||||||
baseURL: '/api',
|
baseURL: '/api',
|
||||||
|
|
@ -16,18 +16,28 @@ var path
|
||||||
// var lang = store.state.lang.language
|
// var lang = store.state.lang.language
|
||||||
|
|
||||||
service.interceptors.request.use(
|
service.interceptors.request.use(
|
||||||
config => {
|
async config => {
|
||||||
path = router && router.app && router.app._route && router.app._route.path
|
path = router && router.app && router.app._route && router.app._route.path
|
||||||
config.headers['Content-Type'] = 'application/json;charset=UTF-8'
|
config.headers['Content-Type'] = 'application/json;charset=UTF-8'
|
||||||
var language = zzSessionStorage.getItem('lang')
|
var language = zzSessionStorage.getItem('lang')
|
||||||
config.headers['Accept-Language'] = language === 'en' ? 'en-US,en;q=0.5' : 'zh-CN,zh;q=0.9'
|
config.headers['Accept-Language'] = language === 'en' ? 'en-US,en;q=0.5' : 'zh-CN,zh;q=0.9'
|
||||||
config.headers['TimeZoneId'] = moment.tz.guess()
|
config.headers['TimeZoneId'] = moment.tz.guess()
|
||||||
if (store.getters.token) {
|
if (config.ENCRYPT) {
|
||||||
|
try {
|
||||||
|
config = await encryptConfig(config)
|
||||||
|
} catch (err) {
|
||||||
|
console.log(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (store.getters.token && !config.clearToken) {
|
||||||
config.headers.Authorization = `Bearer ${store.getters.token}`
|
config.headers.Authorization = `Bearer ${store.getters.token}`
|
||||||
}
|
}
|
||||||
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,106 @@
|
||||||
|
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) {
|
||||||
|
return new Promise((resolve) => {
|
||||||
|
try {
|
||||||
|
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)
|
||||||
|
resolve(true)
|
||||||
|
}).catch(err => {
|
||||||
|
console.log(err);
|
||||||
|
resolve(false)
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
resolve(false)
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
console.log(err);
|
||||||
|
resolve(false)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
}
|
||||||
|
// 下载文件并修改名称
|
||||||
|
async function updateFile(file, name) {
|
||||||
|
return new Promise(async resolve => {
|
||||||
|
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)
|
||||||
|
resolve(true)
|
||||||
|
}).catch(err => {
|
||||||
|
console.log(err)
|
||||||
|
resolve(false)
|
||||||
|
});
|
||||||
|
} catch (err) {
|
||||||
|
console.log(err)
|
||||||
|
resolve(false)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
// 同名文件修改名称
|
||||||
|
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 async function downLoadFile(file, name, type = 'file') {
|
||||||
|
if (type === 'zip') return await zipFiles(name, file);
|
||||||
|
return await 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 = ['/', 'researchDetail_m', '/researchForm', '/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
|
||||||
|
|
@ -251,7 +251,7 @@ export default {
|
||||||
},
|
},
|
||||||
async loadPatientStudy() {
|
async loadPatientStudy() {
|
||||||
try {
|
try {
|
||||||
let data = await getPatientSeriesList(this.studyId);
|
const data = await getPatientSeriesList(this.studyId)
|
||||||
if (data.IsSuccess) {
|
if (data.IsSuccess) {
|
||||||
const { Result } = data
|
const { Result } = data
|
||||||
var seriesList = []
|
var seriesList = []
|
||||||
|
|
|
||||||
|
|
@ -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;">
|
||||||
|
|
@ -143,7 +143,7 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</el-tab-pane>
|
</el-tab-pane>
|
||||||
<el-tab-pane :label="$t('trials:dicom-show:relatedVisit')" name="relation-study" class="pane-relation-wrapper">
|
<el-tab-pane :label="$t('trials:dicom-show:relatedVisit')" name="relation-study" class="pane-relation-wrapper" v-if="!visitTaskId">
|
||||||
<div class="viewerSidethumbinner">
|
<div class="viewerSidethumbinner">
|
||||||
<el-collapse v-model="relationActiveName" @change="handelRelationActiveChange">
|
<el-collapse v-model="relationActiveName" @change="handelRelationActiveChange">
|
||||||
<el-collapse-item v-for="(study,studyIndex) in relationStudyList" :key="`${study.StudyId}`" :name="`${study.StudyId}`">
|
<el-collapse-item v-for="(study,studyIndex) in relationStudyList" :key="`${study.StudyId}`" :name="`${study.StudyId}`">
|
||||||
|
|
@ -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,9 @@ export default {
|
||||||
relationActiveName: [],
|
relationActiveName: [],
|
||||||
showSeriesList: [],
|
showSeriesList: [],
|
||||||
currentLoadIns: [],
|
currentLoadIns: [],
|
||||||
isFromCRCUpload: false
|
isFromCRCUpload: false,
|
||||||
|
visitTaskId: null,
|
||||||
|
page: ''
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
|
|
@ -318,6 +321,8 @@ 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
|
||||||
|
this.page = this.$route.query.page
|
||||||
// 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 +343,14 @@ 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.page === 'upload') {
|
||||||
|
res = await getTaskUploadedDicomStudyList({ visitTaskId: this.visitTaskId })
|
||||||
|
} else if (this.page === 'download'){
|
||||||
|
res = await getVisitStudyList(this.trialId, this.subjectVisitId, this.isReading, 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,9 +60,20 @@
|
||||||
<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="描述">
|
||||||
|
|
@ -72,23 +85,36 @@
|
||||||
/>
|
/>
|
||||||
</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,14 +252,16 @@ 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>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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,20 +25,24 @@
|
||||||
{{ $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
|
||||||
|
|
@ -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>
|
||||||
|
|
|
||||||
|
|
@ -49,7 +49,7 @@
|
||||||
<el-table-column prop="Identification" label="标识" :show-overflow-tooltip="true" min-width="200px" />
|
<el-table-column prop="Identification" label="标识" :show-overflow-tooltip="true" min-width="200px" />
|
||||||
<el-table-column prop="OptTypeValueCN" label="操作类型" show-overflow-tooltip width="100px" />
|
<el-table-column prop="OptTypeValueCN" label="操作类型" show-overflow-tooltip width="100px" />
|
||||||
<el-table-column prop="ObjectTypeValueCN" label="对象类型" show-overflow-tooltip min-width="100px" />
|
<el-table-column prop="ObjectTypeValueCN" label="对象类型" show-overflow-tooltip min-width="100px" />
|
||||||
<el-table-column prop="ChildrenTypeValueCN" label="数据类型" show-overflow-tooltip min-width="100px" show-overflow-tooltip />
|
<el-table-column prop="ChildrenTypeValueCN" label="数据类型" show-overflow-tooltip min-width="100px"/>
|
||||||
<el-table-column
|
<el-table-column
|
||||||
prop="Sort"
|
prop="Sort"
|
||||||
label="显示顺序"
|
label="显示顺序"
|
||||||
|
|
@ -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="请输入字段英文" />
|
||||||
|
|
@ -372,6 +377,16 @@
|
||||||
<el-input :disabled="!scope.row.IsFixedColumn" v-model="scope.row.FixedColumnName" placeholder="固定列名"/>
|
<el-input :disabled="!scope.row.IsFixedColumn" v-model="scope.row.FixedColumnName" placeholder="固定列名"/>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
|
<el-table-column
|
||||||
|
prop="FixedColumnEnName"
|
||||||
|
min-width="120"
|
||||||
|
label="固定列名EN"
|
||||||
|
show-overflow-tooltip
|
||||||
|
>
|
||||||
|
<template slot-scope="scope">
|
||||||
|
<el-input :disabled="!scope.row.IsFixedColumn" v-model="scope.row.FixedColumnEnName" placeholder="固定列名EN"/>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
<el-table-column
|
<el-table-column
|
||||||
prop="ColumnName"
|
prop="ColumnName"
|
||||||
min-width="120"
|
min-width="120"
|
||||||
|
|
@ -382,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"
|
||||||
|
|
@ -415,6 +440,16 @@
|
||||||
<el-input :disabled="!scope.row.IsMerge" v-model="scope.row.MergeColumnName" placeholder="合并组"/>
|
<el-input :disabled="!scope.row.IsMerge" v-model="scope.row.MergeColumnName" placeholder="合并组"/>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
|
<el-table-column
|
||||||
|
prop="MergeColumnEnName"
|
||||||
|
min-width="120"
|
||||||
|
label="合并组EN"
|
||||||
|
show-overflow-tooltip
|
||||||
|
>
|
||||||
|
<template slot-scope="scope">
|
||||||
|
<el-input :disabled="!scope.row.IsMerge" v-model="scope.row.MergeColumnEnName" placeholder="合并组EN"/>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
<el-table-column
|
<el-table-column
|
||||||
prop="IsPicture"
|
prop="IsPicture"
|
||||||
min-width="120"
|
min-width="120"
|
||||||
|
|
@ -489,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">
|
||||||
|
|
@ -559,6 +602,11 @@
|
||||||
<el-input v-model="form.ForeignKeyText" placeholder="请输入数据库字段to" />
|
<el-input v-model="form.ForeignKeyText" placeholder="请输入数据库字段to" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
|
<el-col v-show="form.ConfigType === 'C' && title !== '复制' && form.EnumType === 'Foreign'" :span="12">
|
||||||
|
<el-form-item label="字段toEN">
|
||||||
|
<el-input v-model="form.ForeignKeyEnText" placeholder="请输入数据库字段toEN" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col v-show="title !== '复制'" :span="24">
|
<el-col v-show="title !== '复制'" :span="24">
|
||||||
|
|
@ -643,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
|
||||||
|
|
@ -821,10 +870,13 @@ export default {
|
||||||
ListName: null,
|
ListName: null,
|
||||||
IsFixedColumn: false,
|
IsFixedColumn: false,
|
||||||
FixedColumnName: null,
|
FixedColumnName: null,
|
||||||
|
FixedColumnEnName: null,
|
||||||
ColumnName: null,
|
ColumnName: null,
|
||||||
|
ColumnEnName: null,
|
||||||
ColumnValue: null,
|
ColumnValue: null,
|
||||||
IsMerge: false,
|
IsMerge: false,
|
||||||
MergeColumnName: null,
|
MergeColumnName: null,
|
||||||
|
MergeColumnEnName: null,
|
||||||
IsPicture: false,
|
IsPicture: false,
|
||||||
IsDynamicTranslate: false,
|
IsDynamicTranslate: false,
|
||||||
IsNeedTransalate: false,
|
IsNeedTransalate: false,
|
||||||
|
|
@ -1097,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: '',
|
||||||
|
|
@ -1111,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,
|
||||||
|
|
@ -1118,6 +1172,7 @@ export default {
|
||||||
ForeignKeyTableName: null,
|
ForeignKeyTableName: null,
|
||||||
ForeignKeyValue: null,
|
ForeignKeyValue: null,
|
||||||
ForeignKeyText: null,
|
ForeignKeyText: null,
|
||||||
|
ForeignKeyEnText: null,
|
||||||
TableConfigList: [],
|
TableConfigList: [],
|
||||||
UrlConfig: {
|
UrlConfig: {
|
||||||
RoutePath: null,
|
RoutePath: null,
|
||||||
|
|
|
||||||
|
|
@ -213,7 +213,6 @@ export default {
|
||||||
}).then(res => {
|
}).then(res => {
|
||||||
this.loading = false
|
this.loading = false
|
||||||
this.list = res.Result
|
this.list = res.Result
|
||||||
console.log(this.$d.GlobalAssessType)
|
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
handleAdd() {
|
handleAdd() {
|
||||||
|
|
@ -265,7 +264,7 @@ export default {
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style lang="scss" scoped>
|
||||||
/deep/ .el-form-item__content{
|
/deep/ .el-form-item__content{
|
||||||
width: calc(100% - 110px);
|
width: calc(100% - 110px);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -62,7 +62,7 @@
|
||||||
<template slot-scope="scope">
|
<template slot-scope="scope">
|
||||||
<div>
|
<div>
|
||||||
<el-radio-group v-model="scope.row.CrterionDictionaryGroup" @change="(v) => {crterionDictionaryGroupChange(v, scope.row)}" size="mini">
|
<el-radio-group v-model="scope.row.CrterionDictionaryGroup" @change="(v) => {crterionDictionaryGroupChange(v, scope.row)}" size="mini">
|
||||||
<el-radio-button v-for="item of $d.CrterionDictionaryGroup" :label="item.value">{{item.label}}</el-radio-button>
|
<el-radio-button v-for="item of $d.CrterionDictionaryGroup" :label="item.value" :key="item.id">{{item.label}}</el-radio-button>
|
||||||
</el-radio-group>
|
</el-radio-group>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
@ -158,7 +158,6 @@ export default {
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
this.getList()
|
this.getList()
|
||||||
console.log(this.$d[this.parentCode])
|
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
crterionDictionaryGroupChange(v, row) {
|
crterionDictionaryGroupChange(v, row) {
|
||||||
|
|
@ -231,7 +230,7 @@ export default {
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style lang="scss" scoped>
|
||||||
/deep/ .el-form-item__content{
|
/deep/ .el-form-item__content{
|
||||||
width: calc(100% - 110px);
|
width: calc(100% - 110px);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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,10 +108,7 @@
|
||||||
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"
|
||||||
|
|
@ -121,6 +117,20 @@
|
||||||
/>
|
/>
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
<el-form-item
|
||||||
|
v-if="form.Type === 'basicTable'"
|
||||||
|
label="表格类型标识"
|
||||||
|
prop="LesionType"
|
||||||
|
>
|
||||||
|
<el-select v-model="form.LesionType" clearable>
|
||||||
|
<el-option
|
||||||
|
v-for="item of lesionTypeList"
|
||||||
|
:key="item.Id"
|
||||||
|
:value="parseInt(item.Code)"
|
||||||
|
:label="item.ValueCN"
|
||||||
|
/>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
<!-- <el-form-item
|
<!-- <el-form-item
|
||||||
v-if="form.Type === 'select' || form.Type === 'radio'"
|
v-if="form.Type === 'select' || form.Type === 'radio'"
|
||||||
label="选项"
|
label="选项"
|
||||||
|
|
@ -133,22 +143,24 @@
|
||||||
</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"
|
||||||
|
|
@ -183,13 +195,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"
|
||||||
|
|
@ -204,7 +211,15 @@
|
||||||
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 +228,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 +238,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 +249,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"
|
||||||
|
|
@ -264,7 +281,11 @@
|
||||||
<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,7 +296,11 @@
|
||||||
</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
|
||||||
|
v-if="form.ParentId && form.ShowQuestion === 1"
|
||||||
|
label="显示触发值"
|
||||||
|
prop="ParentTriggerValueList"
|
||||||
|
>
|
||||||
<!-- <el-select v-model="form.ParentTriggerValue" clearable>-->
|
<!-- <el-select v-model="form.ParentTriggerValue" clearable>-->
|
||||||
<!-- <el-option-->
|
<!-- <el-option-->
|
||||||
<!-- v-for="item of parentTriggerValOptions"-->
|
<!-- v-for="item of parentTriggerValOptions"-->
|
||||||
|
|
@ -293,16 +318,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 +376,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"
|
||||||
|
|
@ -385,7 +442,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 +457,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 +480,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 +496,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 +548,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 +576,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 +589,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) => {
|
||||||
|
|
@ -570,32 +666,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,
|
||||||
|
|
@ -607,7 +709,8 @@ export default {
|
||||||
dicList: [],
|
dicList: [],
|
||||||
CriterionDictionaryList: [],
|
CriterionDictionaryList: [],
|
||||||
groupClassifyList: [],
|
groupClassifyList: [],
|
||||||
highlightAnswers: []
|
highlightAnswers: [],
|
||||||
|
lesionTypeList: []
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
|
|
@ -622,14 +725,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,22 +741,31 @@ 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
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
getLesionTypeDictionary() {
|
||||||
|
getCriterionDictionary({
|
||||||
|
ReadingCriterionId: this.data.ReadingQuestionCriterionSystemId,
|
||||||
|
DictionaryCode: 'LesionType',
|
||||||
|
}).then((res) => {
|
||||||
|
this.lesionTypeList = res.Result.LesionType
|
||||||
|
})
|
||||||
|
},
|
||||||
async initForm() {
|
async initForm() {
|
||||||
await this.getGroupOptions()
|
await this.getGroupOptions()
|
||||||
await this.getParentQuestions()
|
await this.getParentQuestions()
|
||||||
|
await this.getLesionTypeDictionary()
|
||||||
await this.getLesionType()
|
await this.getLesionType()
|
||||||
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) {
|
||||||
|
|
@ -661,37 +773,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 +823,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 +845,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 +863,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 +947,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 +976,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 +1005,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 +1021,8 @@ export default {
|
||||||
},
|
},
|
||||||
close() {
|
close() {
|
||||||
this.$emit('close')
|
this.$emit('close')
|
||||||
}
|
},
|
||||||
|
},
|
||||||
}
|
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
|
|
|
||||||
|
|
@ -170,7 +170,7 @@
|
||||||
<el-button
|
<el-button
|
||||||
type="primary"
|
type="primary"
|
||||||
size="mini"
|
size="mini"
|
||||||
:disabled="scope.row.Type !== 'table'"
|
:disabled="!(scope.row.Type === 'table' || scope.row.Type === 'basicTable')"
|
||||||
@click="handleConfig(scope.row)"
|
@click="handleConfig(scope.row)"
|
||||||
>
|
>
|
||||||
表格问题
|
表格问题
|
||||||
|
|
|
||||||
|
|
@ -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,
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@
|
||||||
<el-form :inline="true" size="mini">
|
<el-form :inline="true" size="mini">
|
||||||
<el-form-item label="器官类型">
|
<el-form-item label="器官类型">
|
||||||
<el-select v-model="searchData.OrganType" clearable style="width:130px;">
|
<el-select v-model="searchData.OrganType" clearable style="width:130px;">
|
||||||
<el-option v-for="item of CriterionDictionaryOrganTypeList.OrganType" :key="item.Id" :value="parseInt(item.Code)" :label="item.ValueCN" />
|
<el-option v-for="item of CriterionDictionaryOrganTypeList && CriterionDictionaryOrganTypeList.OrganType" :key="item.Id" :value="parseInt(item.Code)" :label="item.ValueCN" />
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="部位">
|
<el-form-item label="部位">
|
||||||
|
|
|
||||||
|
|
@ -355,11 +355,11 @@
|
||||||
<el-radio v-for="item of $d.LimitEdit" :key="item.value" :label="item.value">{{ item.label }}</el-radio>
|
<el-radio v-for="item of $d.LimitEdit" :key="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> -->
|
||||||
</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>
|
||||||
|
|
@ -445,7 +445,7 @@ export default {
|
||||||
DependParentId: '',
|
DependParentId: '',
|
||||||
QuestionMark: null,
|
QuestionMark: null,
|
||||||
LimitEdit: 0,
|
LimitEdit: 0,
|
||||||
GlobalReadingShowType: null,
|
// GlobalReadingShowType: null,
|
||||||
QuestionClassify: null,
|
QuestionClassify: null,
|
||||||
HighlightAnswerList: []
|
HighlightAnswerList: []
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,29 @@
|
||||||
<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="200px">
|
<el-form
|
||||||
|
ref="passwordForm"
|
||||||
|
v-loading="loading"
|
||||||
|
label-position="right"
|
||||||
|
:model="password"
|
||||||
|
:rules="passwordFormRules"
|
||||||
|
:label-width="$i18n.locale == 'zh' ? '100px' : '200px'"
|
||||||
|
>
|
||||||
<!-- 邮箱 -->
|
<!-- 邮箱 -->
|
||||||
<el-form-item :label="$t('recompose:form:email')" prop="Email">
|
<el-form-item :label="$t('recompose:form:email')" prop="Email">
|
||||||
<el-input v-model="password.Email" disabled />
|
<el-input v-model="password.Email" disabled />
|
||||||
|
|
@ -19,70 +37,135 @@
|
||||||
<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: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')"
|
||||||
|
prop="ConfirmPassWord"
|
||||||
|
>
|
||||||
|
<el-input
|
||||||
|
v-model="password.ConfirmPassWord"
|
||||||
|
type="password"
|
||||||
|
show-password
|
||||||
|
auto-complete="new-password"
|
||||||
|
/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item style="text-align: right">
|
<el-form-item style="text-align: right">
|
||||||
<!-- 取消 -->
|
<!-- 取消 -->
|
||||||
<el-button
|
<el-button size="small" @click="cancel">
|
||||||
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 { initSetUserNameAndPwd } from '@/api/admin.js'
|
import { initSetUserNameAndPwd } from '@/api/admin.js'
|
||||||
import md5 from 'js-md5'
|
import md5 from 'js-md5'
|
||||||
import {mapGetters, mapMutations} from "vuex";
|
import { mapGetters, mapMutations } from 'vuex'
|
||||||
export default {
|
export default {
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
password: {
|
password: {
|
||||||
NewUserName: null,
|
NewUserName: null,
|
||||||
UserId: null
|
UserId: null,
|
||||||
},
|
},
|
||||||
passwordFormRules: {
|
passwordFormRules: {
|
||||||
NewUserName: [{ required: true, validator: (rule, value, callback) => {!value ? callback(new Error(this.$t('trials:researchForm:formRule:specify'))) : callback()}, trigger: 'blur' }],
|
NewUserName: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
validator: (rule, value, callback) => {
|
||||||
|
var lang = zzSessionStorage.getItem('lang')
|
||||||
|
? zzSessionStorage.getItem('lang')
|
||||||
|
: 'zh'
|
||||||
|
/* eslint-disable */
|
||||||
|
var reg1 = /^[a-zA-Z0-9_]{4,16}$/ //密码必须是8位以上、必须含有字母、数字、特殊符号
|
||||||
|
console.log(!reg1.test(value))
|
||||||
|
if (!reg1.test(value)) {
|
||||||
|
callback(
|
||||||
|
lang === 'zh'
|
||||||
|
? new Error(
|
||||||
|
'1)新建账号,用户名字符长度最小为4个字符,最大为16个字符,只可使用字母、数字、下划线;'
|
||||||
|
)
|
||||||
|
: new Error(
|
||||||
|
'For a new account, the username must have:1) At least 4 characters;2) At most 16 characters;3)Only letters, numbers, and underscores are allowed.'
|
||||||
|
)
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
callback()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
trigger: 'blur',
|
||||||
|
},
|
||||||
|
],
|
||||||
NewPassWord: [
|
NewPassWord: [
|
||||||
{ required: true, validator: (rule, value, callback) => {!value ? callback(new Error(this.$t('trials:researchForm:formRule:specify'))) : callback()}, trigger: 'blur' },
|
{
|
||||||
|
required: true,
|
||||||
|
validator: (rule, value, callback) => {
|
||||||
|
!value
|
||||||
|
? callback(
|
||||||
|
new Error(this.$t('trials:researchForm:formRule:specify'))
|
||||||
|
)
|
||||||
|
: callback()
|
||||||
|
},
|
||||||
|
trigger: 'blur',
|
||||||
|
},
|
||||||
{
|
{
|
||||||
required: true,
|
required: true,
|
||||||
trigger: 'blur',
|
trigger: 'blur',
|
||||||
validator: this.$validatePassword
|
validator: this.$validatePassword,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
ConfirmPassWord: [
|
ConfirmPassWord: [
|
||||||
{ required: true, validator: (rule, value, callback) => {!value ? callback(new Error(this.$t('trials:researchForm:formRule:specify'))) : callback()}, trigger: 'blur' }
|
{
|
||||||
]
|
required: true,
|
||||||
|
validator: (rule, value, callback) => {
|
||||||
|
!value
|
||||||
|
? callback(
|
||||||
|
new Error(this.$t('trials:researchForm:formRule:specify'))
|
||||||
|
)
|
||||||
|
: callback()
|
||||||
|
},
|
||||||
|
trigger: 'blur',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
trigger: 'blur',
|
||||||
|
validator: (rule, value, callback) => {
|
||||||
|
value !== this.password.NewPassWord
|
||||||
|
? callback(
|
||||||
|
new Error(
|
||||||
|
this.$t(
|
||||||
|
'trials:researchForm:formRule:NewPassWordAndConfirmPassWord'
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
: callback()
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
},
|
},
|
||||||
userId: null,
|
userId: null,
|
||||||
loading: false
|
loading: false,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
...mapGetters([
|
...mapGetters(['asyncRoutes', 'routes', 'language']),
|
||||||
'asyncRoutes',
|
|
||||||
'routes',
|
|
||||||
'language'
|
|
||||||
])
|
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
this.password.UserId = this.$route.query.UserId
|
this.password.UserId = this.$route.query.UserId
|
||||||
|
|
@ -112,7 +195,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) {
|
||||||
// 两次密码输入不一致
|
// 两次密码输入不一致
|
||||||
|
|
@ -123,26 +206,32 @@ export default {
|
||||||
NewUserName: this.password.NewUserName,
|
NewUserName: this.password.NewUserName,
|
||||||
UserId: this.password.UserId,
|
UserId: this.password.UserId,
|
||||||
NewPwd: md5(this.password.NewPassWord),
|
NewPwd: md5(this.password.NewPassWord),
|
||||||
access_token: this.password.access_token
|
access_token: this.password.access_token,
|
||||||
}
|
}
|
||||||
this.loading = true
|
this.loading = true
|
||||||
initSetUserNameAndPwd(param).then(res => {
|
initSetUserNameAndPwd(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>
|
||||||
|
|
@ -174,4 +263,7 @@ input {
|
||||||
background-color: transparent;
|
background-color: transparent;
|
||||||
caret-color: #fff;
|
caret-color: #fff;
|
||||||
}
|
}
|
||||||
|
.el-form-item {
|
||||||
|
margin-bottom: 30px;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
||||||
|
|
@ -114,7 +114,7 @@
|
||||||
size="mini"
|
size="mini"
|
||||||
@click="getList"
|
@click="getList"
|
||||||
>
|
>
|
||||||
{{ $t("common:button:search") }}
|
{{ $t('common:button:search') }}
|
||||||
</el-button>
|
</el-button>
|
||||||
<!-- 重置 -->
|
<!-- 重置 -->
|
||||||
<el-button
|
<el-button
|
||||||
|
|
@ -122,7 +122,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-button
|
<!-- <el-button
|
||||||
type="primary"
|
type="primary"
|
||||||
|
|
@ -141,7 +141,7 @@
|
||||||
v-if="level > 7"
|
v-if="level > 7"
|
||||||
:disabled="tableSelectData.length <= 0"
|
:disabled="tableSelectData.length <= 0"
|
||||||
>
|
>
|
||||||
{{ $t("feedBack:button:resolve") }}
|
{{ $t('feedBack:button:resolve') }}
|
||||||
</el-button>
|
</el-button>
|
||||||
</el-form>
|
</el-form>
|
||||||
<el-table
|
<el-table
|
||||||
|
|
@ -257,7 +257,7 @@
|
||||||
>
|
>
|
||||||
<template slot-scope="scope">
|
<template slot-scope="scope">
|
||||||
<el-tag :type="['danger', 'success'][scope.row.State]">{{
|
<el-tag :type="['danger', 'success'][scope.row.State]">{{
|
||||||
$fd("FeedBackStatus", scope.row.State)
|
$fd('FeedBackStatus', scope.row.State)
|
||||||
}}</el-tag>
|
}}</el-tag>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
|
|
@ -278,7 +278,7 @@
|
||||||
>
|
>
|
||||||
<template slot-scope="scope">
|
<template slot-scope="scope">
|
||||||
<el-button size="mini" type="text" @click="getDetail(scope.row)">
|
<el-button size="mini" type="text" @click="getDetail(scope.row)">
|
||||||
{{ $t("common:button:view") }}
|
{{ $t('common:button:view') }}
|
||||||
</el-button>
|
</el-button>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
|
|
@ -295,8 +295,8 @@
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script>
|
<script>
|
||||||
import Pagination from "@/components/Pagination";
|
import Pagination from '@/components/Pagination'
|
||||||
import { batchUpdateFeedBackState, getUserFeedBackList } from "@/api/trials.js";
|
import { batchUpdateFeedBackState, getUserFeedBackList } from '@/api/trials.js'
|
||||||
const searchDataDefault = () => {
|
const searchDataDefault = () => {
|
||||||
return {
|
return {
|
||||||
TrialKeyInfo: null,
|
TrialKeyInfo: null,
|
||||||
|
|
@ -312,23 +312,23 @@ const searchDataDefault = () => {
|
||||||
PageIndex: 1,
|
PageIndex: 1,
|
||||||
PageSize: 20,
|
PageSize: 20,
|
||||||
Asc: false,
|
Asc: false,
|
||||||
SortField: "CreateTime",
|
SortField: 'CreateTime',
|
||||||
};
|
}
|
||||||
};
|
}
|
||||||
export default {
|
export default {
|
||||||
components: { Pagination },
|
components: { Pagination },
|
||||||
props: {
|
props: {
|
||||||
trialId: {
|
trialId: {
|
||||||
type: String,
|
type: String,
|
||||||
default: "",
|
default: '',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
dicts: [
|
dicts: [
|
||||||
"NoticeApplicableTrial",
|
'NoticeApplicableTrial',
|
||||||
"NoteLevel",
|
'NoteLevel',
|
||||||
"NoteType",
|
'NoteType',
|
||||||
"NoticeState",
|
'NoticeState',
|
||||||
"NoticeMode",
|
'NoticeMode',
|
||||||
],
|
],
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
|
|
@ -340,100 +340,100 @@ export default {
|
||||||
searchData: searchDataDefault(),
|
searchData: searchDataDefault(),
|
||||||
tableSelectData: [],
|
tableSelectData: [],
|
||||||
UserTypeOptins: [
|
UserTypeOptins: [
|
||||||
{ label: "CRC", value: 2 },
|
{ label: 'CRC', value: 2 },
|
||||||
{ label: "IR", value: 13 },
|
{ label: 'IR', value: 13 },
|
||||||
],
|
],
|
||||||
};
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
level() {
|
level() {
|
||||||
if (this.hasPermi(["role:dev", "role:admin"])) {
|
if (this.hasPermi(['role:dev', 'role:admin'])) {
|
||||||
return 9;
|
return 9
|
||||||
}
|
}
|
||||||
if (this.hasPermi(["role:pm"])) {
|
if (this.hasPermi(['role:pm', 'role:apm'])) {
|
||||||
return 8;
|
return 8
|
||||||
}
|
}
|
||||||
if (this.hasPermi(["role:ir", "role:crc"])) {
|
if (this.hasPermi(['role:ir', 'role:crc'])) {
|
||||||
return 7;
|
return 7
|
||||||
}
|
}
|
||||||
return 0;
|
return 0
|
||||||
},
|
},
|
||||||
QuestionTypeOptions() {
|
QuestionTypeOptions() {
|
||||||
if (this.level > 7) {
|
if (this.level > 7) {
|
||||||
return [
|
return [
|
||||||
...this.$d.FeedBackTypeToCRC.filter((item) => item.value > 0),
|
...this.$d.FeedBackTypeToCRC.filter((item) => item.value > 0),
|
||||||
...this.$d.FeedBackTypeToIR,
|
...this.$d.FeedBackTypeToIR,
|
||||||
];
|
]
|
||||||
}
|
}
|
||||||
if (this.hasPermi(["role:ir"])) {
|
if (this.hasPermi(['role:ir'])) {
|
||||||
return this.$d.FeedBackTypeToIR;
|
return this.$d.FeedBackTypeToIR
|
||||||
}
|
}
|
||||||
if (this.hasPermi(["role:crc"])) {
|
if (this.hasPermi(['role:crc'])) {
|
||||||
return this.$d.FeedBackTypeToCRC;
|
return this.$d.FeedBackTypeToCRC
|
||||||
}
|
}
|
||||||
return [];
|
return []
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
created() {
|
created() {
|
||||||
this.getList();
|
this.getList()
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
// 通过提交状态决定该行的 CheckBox 是否可以勾选
|
// 通过提交状态决定该行的 CheckBox 是否可以勾选
|
||||||
handleSelectTable(row) {
|
handleSelectTable(row) {
|
||||||
return row.State < 1;
|
return row.State < 1
|
||||||
},
|
},
|
||||||
async getList() {
|
async getList() {
|
||||||
try {
|
try {
|
||||||
if (this.trialId) {
|
if (this.trialId) {
|
||||||
this.searchData.TrialId = this.trialId;
|
this.searchData.TrialId = this.trialId
|
||||||
}
|
}
|
||||||
this.loading = true;
|
this.loading = true
|
||||||
let res = await getUserFeedBackList(this.searchData);
|
let res = await getUserFeedBackList(this.searchData)
|
||||||
this.loading = false;
|
this.loading = false
|
||||||
if (res.IsSuccess) {
|
if (res.IsSuccess) {
|
||||||
this.list = res.Result.CurrentPageData;
|
this.list = res.Result.CurrentPageData
|
||||||
this.total = res.Result.TotalCount;
|
this.total = res.Result.TotalCount
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
this.loading = false;
|
this.loading = false
|
||||||
console.log(err);
|
console.log(err)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
handleDatetimeChange(val) {
|
handleDatetimeChange(val) {
|
||||||
if (val) {
|
if (val) {
|
||||||
this.searchData.BeginCreatime = val[0];
|
this.searchData.BeginCreatime = val[0]
|
||||||
this.searchData.EndCreatime = val[1];
|
this.searchData.EndCreatime = val[1]
|
||||||
} else {
|
} else {
|
||||||
this.searchData.BeginCreatime = "";
|
this.searchData.BeginCreatime = ''
|
||||||
this.searchData.EndCreatime = "";
|
this.searchData.EndCreatime = ''
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
// 重置列表查询
|
// 重置列表查询
|
||||||
handleReset() {
|
handleReset() {
|
||||||
this.datetimerange = null;
|
this.datetimerange = null
|
||||||
this.handleDatetimeChange();
|
this.handleDatetimeChange()
|
||||||
this.searchData = searchDataDefault();
|
this.searchData = searchDataDefault()
|
||||||
this.getList();
|
this.getList()
|
||||||
},
|
},
|
||||||
// 设为解决
|
// 设为解决
|
||||||
async resolve() {
|
async resolve() {
|
||||||
try {
|
try {
|
||||||
let confirm = await this.$confirm(this.$t("feedBack:resolve:tip"), {
|
let confirm = await this.$confirm(this.$t('feedBack:resolve:tip'), {
|
||||||
type: "warning",
|
type: 'warning',
|
||||||
distinguishCancelAndClose: true,
|
distinguishCancelAndClose: true,
|
||||||
});
|
})
|
||||||
if (!confirm) return;
|
if (!confirm) return
|
||||||
let data = {
|
let data = {
|
||||||
IdList: this.tableSelectData.map((item) => item.Id),
|
IdList: this.tableSelectData.map((item) => item.Id),
|
||||||
state: 1,
|
state: 1,
|
||||||
};
|
}
|
||||||
let res = await batchUpdateFeedBackState(data);
|
let res = await batchUpdateFeedBackState(data)
|
||||||
if (res.IsSuccess) {
|
if (res.IsSuccess) {
|
||||||
this.$message.success(this.$t("feedBack:resolve:success"));
|
this.$message.success(this.$t('feedBack:resolve:success'))
|
||||||
this.getList();
|
this.getList()
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.log(err);
|
console.log(err)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
// 导出
|
// 导出
|
||||||
|
|
@ -441,32 +441,32 @@ export default {
|
||||||
// 表格选择
|
// 表格选择
|
||||||
handleSelectChange(selection) {
|
handleSelectChange(selection) {
|
||||||
// console.log(selection, "handleSelectChange");
|
// console.log(selection, "handleSelectChange");
|
||||||
this.tableSelectData = selection;
|
this.tableSelectData = selection
|
||||||
},
|
},
|
||||||
// 排序
|
// 排序
|
||||||
handleSortByColumn(column) {
|
handleSortByColumn(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
|
||||||
}
|
}
|
||||||
this.searchData.SortField = column.prop;
|
this.searchData.SortField = column.prop
|
||||||
this.searchData.PageIndex = 1;
|
this.searchData.PageIndex = 1
|
||||||
this.getList();
|
this.getList()
|
||||||
},
|
},
|
||||||
// 获取详情
|
// 获取详情
|
||||||
getDetail(row) {
|
getDetail(row) {
|
||||||
this.$FB({
|
this.$FB({
|
||||||
type: "detail",
|
type: 'detail',
|
||||||
Id: row.Id,
|
Id: row.Id,
|
||||||
callBack: () => {
|
callBack: () => {
|
||||||
this.getList();
|
this.getList()
|
||||||
this.$emit("success");
|
this.$emit('success')
|
||||||
},
|
},
|
||||||
});
|
})
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
}
|
||||||
</script>
|
</script>
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
.role {
|
.role {
|
||||||
|
|
|
||||||
|
|
@ -61,16 +61,16 @@
|
||||||
:disabled="form.VerificationCode === '' || form.EmailOrPhone === ''"
|
:disabled="form.VerificationCode === '' || form.EmailOrPhone === ''"
|
||||||
@click="verifyCode"
|
@click="verifyCode"
|
||||||
>
|
>
|
||||||
{{ $t("passwordReset:button:verify") }}
|
{{ $t('passwordReset:button:verify') }}
|
||||||
</el-button>
|
</el-button>
|
||||||
</div>
|
</div>
|
||||||
<div class="box-wrapper" v-if="active === 1">
|
<div class="box-wrapper" v-show="active === 1">
|
||||||
<el-form
|
<el-form
|
||||||
ref="resetForm"
|
ref="resetForm2"
|
||||||
v-loading="formLoading"
|
v-loading="formLoading"
|
||||||
:model="form"
|
:model="form"
|
||||||
label-width="100px"
|
:label-width="$i18n.locale === 'en' ? '180px' : '100px'"
|
||||||
:rules="rules"
|
:rules="rules2"
|
||||||
class="demo-ruleForm"
|
class="demo-ruleForm"
|
||||||
size="small"
|
size="small"
|
||||||
>
|
>
|
||||||
|
|
@ -131,7 +131,7 @@
|
||||||
<div style="width: 50%; margin: auto; display: flex">
|
<div style="width: 50%; margin: auto; display: flex">
|
||||||
<!-- 取消 -->
|
<!-- 取消 -->
|
||||||
<el-button size="small" @click="onCancel" style="width: 46%">
|
<el-button size="small" @click="onCancel" style="width: 46%">
|
||||||
{{ $t("passwordReset:button:cancel") }}
|
{{ $t('passwordReset:button:cancel') }}
|
||||||
</el-button>
|
</el-button>
|
||||||
<!-- 提交 -->
|
<!-- 提交 -->
|
||||||
<el-button
|
<el-button
|
||||||
|
|
@ -140,17 +140,17 @@
|
||||||
@click="onSubmit"
|
@click="onSubmit"
|
||||||
style="width: 46%"
|
style="width: 46%"
|
||||||
>
|
>
|
||||||
{{ $t("passwordReset:button:submit") }}
|
{{ $t('passwordReset:button:submit') }}
|
||||||
</el-button>
|
</el-button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="box-wrapper flexBox" v-if="active === 3">
|
<div class="box-wrapper flexBox" v-if="active === 3">
|
||||||
<svg-icon icon-class="resetSuccess" style="width: 300px; height: 300px" />
|
<svg-icon icon-class="resetSuccess" style="width: 300px; height: 300px" />
|
||||||
<p style="width: 100%; text-align: center">
|
<p style="width: 100%; text-align: center">
|
||||||
{{ $t("resetPassword:successTip") }}
|
{{ $t('resetPassword:successTip') }}
|
||||||
</p>
|
</p>
|
||||||
<el-button size="small" type="primary" @click="goBack">
|
<el-button size="small" type="primary" @click="goBack">
|
||||||
{{ $t("passwordReset:button:back") }}
|
{{ $t('passwordReset:button:back') }}
|
||||||
</el-button>
|
</el-button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -160,32 +160,30 @@ import {
|
||||||
anonymousSendVerificationCode,
|
anonymousSendVerificationCode,
|
||||||
verifyAnonymousVerifyCode,
|
verifyAnonymousVerifyCode,
|
||||||
anonymousSetPassword,
|
anonymousSetPassword,
|
||||||
} from "@/api/user";
|
} from '@/api/user'
|
||||||
import md5 from "js-md5";
|
import md5 from 'js-md5'
|
||||||
import Img from "@/assets/icons/svg/resetSuccess.svg";
|
import Img from '@/assets/icons/svg/resetSuccess.svg'
|
||||||
var timer = "";
|
var timer = ''
|
||||||
var countdown = 60;
|
var countdown = 60
|
||||||
export default {
|
export default {
|
||||||
data() {
|
data() {
|
||||||
var validateEmail = (rule, value, callback) => {
|
var validateEmail = (rule, value, callback) => {
|
||||||
if (value === "") {
|
if (value === '') {
|
||||||
// 请输入邮箱
|
// 请输入邮箱
|
||||||
callback(new Error(this.$t("passwordReset:formRule:email")));
|
callback(new Error(this.$t('passwordReset:formRule:email')))
|
||||||
} else {
|
} else {
|
||||||
var reg =
|
var reg =
|
||||||
/^[A-Za-z0-9]+([_\.][A-Za-z0-9]+)*@([A-Za-z0-9\-]+\.)+[A-Za-z]{2,6}$/;
|
/^[A-Za-z0-9]+([_\.][A-Za-z0-9]+)*@([A-Za-z0-9\-]+\.)+[A-Za-z]{2,6}$/
|
||||||
if (this.form.EmailOrPhone && reg.test(this.form.EmailOrPhone)) {
|
if (this.form.EmailOrPhone && reg.test(this.form.EmailOrPhone)) {
|
||||||
this.sendDisabled = false;
|
this.sendDisabled = false
|
||||||
callback();
|
callback()
|
||||||
} else {
|
} else {
|
||||||
// 邮箱无效
|
// 邮箱无效
|
||||||
callback(
|
callback(new Error(this.$t('passwordReset:formRule:passwordinvalid')))
|
||||||
new Error(this.$t("passwordReset:formRule:passwordinvalid"))
|
this.sendDisabled = true
|
||||||
);
|
}
|
||||||
this.sendDisabled = true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
|
||||||
// var validatePass = (rule, value, callback) => {
|
// var validatePass = (rule, value, callback) => {
|
||||||
// if (value === '') {
|
// if (value === '') {
|
||||||
// // 请输入密码
|
// // 请输入密码
|
||||||
|
|
@ -198,181 +196,206 @@ export default {
|
||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
var validatePass2 = (rule, value, callback) => {
|
var validatePass2 = (rule, value, callback) => {
|
||||||
if (value === "" || value === undefined) {
|
if (value === '' || value === undefined) {
|
||||||
// 请再次输入密码
|
// 请再次输入密码
|
||||||
callback(new Error(this.$t("passwordReset:formRule:confirmPassword")));
|
callback(new Error(this.$t('passwordReset:formRule:confirmPassword')))
|
||||||
} else if (value !== undefined && value !== this.form.NewPwd) {
|
} else if (value !== undefined && value !== this.form.NewPwd) {
|
||||||
// 两次密码不一致
|
// 两次密码不一致
|
||||||
callback(new Error(this.$t("passwordReset:formRule:passwordsDiffer")));
|
callback(new Error(this.$t('passwordReset:formRule:passwordsDiffer')))
|
||||||
} else {
|
} else {
|
||||||
callback();
|
callback()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
|
||||||
return {
|
return {
|
||||||
active: 0,
|
active: 0,
|
||||||
Img,
|
Img,
|
||||||
form: {
|
form: {
|
||||||
EmailOrPhone: "",
|
EmailOrPhone: '',
|
||||||
VerificationCode: "",
|
VerificationCode: '',
|
||||||
NewPwd: "",
|
NewPwd: '',
|
||||||
UserId: "",
|
CheckPass: '',
|
||||||
UserType: "",
|
UserId: '',
|
||||||
|
UserType: '',
|
||||||
},
|
},
|
||||||
users: [],
|
users: [],
|
||||||
CheckPass: "",
|
CheckPass: '',
|
||||||
rules: {
|
rules: {
|
||||||
EmailOrPhone: [
|
EmailOrPhone: [
|
||||||
{
|
{
|
||||||
required: true,
|
required: true,
|
||||||
validator: validateEmail,
|
validator: validateEmail,
|
||||||
trigger: ["blur", "change"],
|
trigger: ['blur', 'change'],
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
VerificationCode: [
|
VerificationCode: [
|
||||||
{
|
{
|
||||||
required: true,
|
required: true,
|
||||||
message: this.$t("common:ruleMessage:specify"),
|
message: this.$t('common:ruleMessage:specify'),
|
||||||
trigger: ["blur", "change"],
|
trigger: ['blur', 'change'],
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
NewPwd: [
|
NewPwd: [
|
||||||
{
|
{
|
||||||
required: true,
|
required: true,
|
||||||
validator: this.$validatePassword,
|
validator: this.$validatePassword,
|
||||||
trigger: ["blur", "change"],
|
trigger: ['blur', 'change'],
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
CheckPass: [
|
CheckPass: [
|
||||||
{
|
{
|
||||||
required: true,
|
required: true,
|
||||||
validator: validatePass2,
|
validator: validatePass2,
|
||||||
trigger: ["blur", "change"],
|
trigger: ['blur', 'change'],
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
UserId: [
|
UserId: [
|
||||||
{
|
{
|
||||||
required: true,
|
required: true,
|
||||||
message: this.$t("common:ruleMessage:select"),
|
message: this.$t('common:ruleMessage:select'),
|
||||||
trigger: ["blur", "change"],
|
trigger: ['blur', 'change'],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
rules2: {
|
||||||
|
NewPwd: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
validator: this.$validatePassword,
|
||||||
|
trigger: ['blur', 'change'],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
CheckPass: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
validator: validatePass2,
|
||||||
|
trigger: ['blur', 'change'],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
UserId: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: this.$t('common:ruleMessage:select'),
|
||||||
|
trigger: ['blur', 'change'],
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
sendDisabled: true,
|
sendDisabled: true,
|
||||||
sendTitle: this.$t("passwordReset:button:send"),
|
sendTitle: this.$t('passwordReset:button:send'),
|
||||||
formLoading: false,
|
formLoading: false,
|
||||||
};
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
onSubmit() {
|
onSubmit() {
|
||||||
this.$refs["resetForm"].validate((valid) => {
|
this.$refs['resetForm2'].validate((valid) => {
|
||||||
if (valid) {
|
if (valid) {
|
||||||
this.formLoading = true;
|
this.formLoading = true
|
||||||
anonymousSetPassword(this.form.UserId, md5(this.form.NewPwd))
|
anonymousSetPassword(this.form.UserId, md5(this.form.NewPwd))
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
if (res.IsSuccess) {
|
if (res.IsSuccess) {
|
||||||
// 修改成功
|
// 修改成功
|
||||||
this.$message.success(
|
this.$message.success(
|
||||||
this.$t("passwordReset:message:updatedSuccessfully")
|
this.$t('passwordReset:message:updatedSuccessfully')
|
||||||
);
|
)
|
||||||
this.formLoading = false;
|
this.formLoading = false
|
||||||
this.active = 3;
|
this.active = 3
|
||||||
// this.goBack();
|
// this.goBack();
|
||||||
} else {
|
} else {
|
||||||
this.$alert(res.ErrorMessage);
|
this.$alert(res.ErrorMessage)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.catch(() => {
|
.catch(() => {
|
||||||
this.formLoading = false;
|
this.formLoading = false
|
||||||
});
|
})
|
||||||
}
|
}
|
||||||
});
|
})
|
||||||
},
|
},
|
||||||
handleSendCode() {
|
handleSendCode() {
|
||||||
const that = this;
|
const that = this
|
||||||
this.sendDisabled = true;
|
this.sendDisabled = true
|
||||||
// var isReviewer = JSON.parse(zzSessionStorage.getItem('IsReviewer'))
|
// var isReviewer = JSON.parse(zzSessionStorage.getItem('IsReviewer'))
|
||||||
anonymousSendVerificationCode(this.form.EmailOrPhone)
|
anonymousSendVerificationCode(this.form.EmailOrPhone)
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
if (res.IsSuccess) {
|
if (res.IsSuccess) {
|
||||||
let msg = this.$t('passwordReset:message:tip:sendCode').replace("xxx", this.form.EmailOrPhone)
|
let msg = this.$t('passwordReset:message:tip:sendCode').replace(
|
||||||
|
'xxx',
|
||||||
|
this.form.EmailOrPhone
|
||||||
|
)
|
||||||
this.$message.success(msg)
|
this.$message.success(msg)
|
||||||
that.settime(that);
|
that.settime(that)
|
||||||
} else {
|
} else {
|
||||||
that.$alert(res.ErrorMessage);
|
that.$alert(res.ErrorMessage)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.catch(() => {
|
.catch(() => {
|
||||||
this.sendDisabled = false;
|
this.sendDisabled = false
|
||||||
});
|
})
|
||||||
},
|
},
|
||||||
verifyCode() {
|
verifyCode() {
|
||||||
this.formLoading = true;
|
this.formLoading = true
|
||||||
verifyAnonymousVerifyCode(
|
verifyAnonymousVerifyCode(
|
||||||
this.form.EmailOrPhone,
|
this.form.EmailOrPhone,
|
||||||
this.form.VerificationCode
|
this.form.VerificationCode
|
||||||
)
|
)
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
this.formLoading = false;
|
this.formLoading = false
|
||||||
this.users = res.Result;
|
this.users = res.Result
|
||||||
if (this.users.length === 1) {
|
if (this.users.length === 1) {
|
||||||
this.form.UserId = this.users[0].UserId;
|
this.form.UserId = this.users[0].UserId
|
||||||
this.form.UserType = this.users[0].UserType;
|
this.form.UserType = this.users[0].UserType
|
||||||
}
|
}
|
||||||
// 验证成功
|
// 验证成功
|
||||||
this.$message.success(
|
this.$message.success(
|
||||||
this.$t("passwordReset:message:verifiedSuccessfully")
|
this.$t('passwordReset:message:verifiedSuccessfully')
|
||||||
);
|
)
|
||||||
this.active = 1;
|
this.active = 1
|
||||||
})
|
})
|
||||||
.catch(() => {
|
.catch(() => {
|
||||||
this.formLoading = false;
|
this.formLoading = false
|
||||||
});
|
})
|
||||||
},
|
},
|
||||||
handleEmailChange() {
|
handleEmailChange() {
|
||||||
var reg =
|
var reg =
|
||||||
/^[A-Za-z0-9]+([_\.][A-Za-z0-9]+)*@([A-Za-z0-9\-]+\.)+[A-Za-z]{2,6}$/;
|
/^[A-Za-z0-9]+([_\.][A-Za-z0-9]+)*@([A-Za-z0-9\-]+\.)+[A-Za-z]{2,6}$/
|
||||||
if (this.form.EmailOrPhone && reg.test(this.form.EmailOrPhone)) {
|
if (this.form.EmailOrPhone && reg.test(this.form.EmailOrPhone)) {
|
||||||
this.sendDisabled = false;
|
this.sendDisabled = false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
handleUserChange(val) {
|
handleUserChange(val) {
|
||||||
const seleted = this.users.findIndex((user) => user.UserId === val);
|
const seleted = this.users.findIndex((user) => user.UserId === val)
|
||||||
if (seleted > -1) {
|
if (seleted > -1) {
|
||||||
this.form.UserType = this.users[seleted].UserType;
|
this.form.UserType = this.users[seleted].UserType
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
settime(obj) {
|
settime(obj) {
|
||||||
if (countdown === 0) {
|
if (countdown === 0) {
|
||||||
obj.sendDisabled = false;
|
obj.sendDisabled = false
|
||||||
obj.sendTitle = this.$t("passwordReset:button:send");
|
obj.sendTitle = this.$t('passwordReset:button:send')
|
||||||
countdown = 60;
|
countdown = 60
|
||||||
clearTimeout(timer);
|
clearTimeout(timer)
|
||||||
return;
|
return
|
||||||
} else {
|
} else {
|
||||||
obj.sendDisabled = true;
|
obj.sendDisabled = true
|
||||||
obj.sendTitle = `${this.$t(
|
obj.sendTitle = `${this.$t('passwordReset:button:wait')}(${countdown}s)`
|
||||||
"passwordReset:button:wait"
|
countdown--
|
||||||
)}(${countdown}s)`;
|
|
||||||
countdown--;
|
|
||||||
// eslint-disable-next-line no-self-assign
|
// eslint-disable-next-line no-self-assign
|
||||||
countdown = countdown;
|
countdown = countdown
|
||||||
timer = setTimeout(function () {
|
timer = setTimeout(function () {
|
||||||
obj.settime(obj);
|
obj.settime(obj)
|
||||||
}, 1000);
|
}, 1000)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
onCancel() {
|
onCancel() {
|
||||||
this.$refs["resetForm"].resetFields();
|
this.$refs['resetForm'].resetFields()
|
||||||
Object.keys(this.form).forEach((key) => {
|
Object.keys(this.form).forEach((key) => {
|
||||||
this.form[key] = "";
|
this.form[key] = ''
|
||||||
});
|
})
|
||||||
this.active = 0;
|
this.active = 0
|
||||||
},
|
},
|
||||||
goBack() {
|
goBack() {
|
||||||
this.$router.push("/login");
|
this.$router.push('/login')
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
}
|
||||||
</script>
|
</script>
|
||||||
<style>
|
<style>
|
||||||
.reset-wrapper {
|
.reset-wrapper {
|
||||||
|
|
|
||||||
|
|
@ -27,7 +27,7 @@
|
||||||
style="width: 300px; height: 94px"
|
style="width: 300px; height: 94px"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div class="title" v-else>{{ $t("login:title:system") }}</div>
|
<div class="title" v-else>{{ $t('login:title:system') }}</div>
|
||||||
</div>
|
</div>
|
||||||
<el-form
|
<el-form
|
||||||
ref="loginForm"
|
ref="loginForm"
|
||||||
|
|
@ -105,7 +105,7 @@
|
||||||
size="medium"
|
size="medium"
|
||||||
@click.native.prevent="handleLogin"
|
@click.native.prevent="handleLogin"
|
||||||
>
|
>
|
||||||
{{ $t("login:button:login") }}
|
{{ $t('login:button:login') }}
|
||||||
</el-button>
|
</el-button>
|
||||||
<div style="text-align: right">
|
<div style="text-align: right">
|
||||||
<TopLang
|
<TopLang
|
||||||
|
|
@ -121,7 +121,7 @@
|
||||||
@click.native.prevent="handleResetPwd"
|
@click.native.prevent="handleResetPwd"
|
||||||
style="color: rgb(0, 147, 221)"
|
style="color: rgb(0, 147, 221)"
|
||||||
>
|
>
|
||||||
{{ $t("login:button:forgetPassword") }}
|
{{ $t('login:button:forgetPassword') }}
|
||||||
</el-button>
|
</el-button>
|
||||||
</div>
|
</div>
|
||||||
</el-form>
|
</el-form>
|
||||||
|
|
@ -174,10 +174,12 @@
|
||||||
>
|
>
|
||||||
<h1 style="text-align: center; margin-bottom: 20px">关于</h1>
|
<h1 style="text-align: center; margin-bottom: 20px">关于</h1>
|
||||||
<p style="margin-bottom: 20px" v-if="NODE_ENV === 'usa'">
|
<p style="margin-bottom: 20px" v-if="NODE_ENV === 'usa'">
|
||||||
{{ $t("login:title:system_title") }}
|
{{ $t('login:title:system_title') }}
|
||||||
|
</p>
|
||||||
|
<p style="margin-bottom: 20px" v-else>{{ $t('login:title:system') }}</p>
|
||||||
|
<p style="margin-bottom: 20px">
|
||||||
|
V{{ $version.IsEnv_US ? $version.Version_US : $version.Version }}
|
||||||
</p>
|
</p>
|
||||||
<p style="margin-bottom: 20px" v-else>{{ $t("login:title:system") }}</p>
|
|
||||||
<p style="margin-bottom: 20px">V{{ $version.Version }}</p>
|
|
||||||
<p style="margin-bottom: 20px" v-if="language === 'zh'">
|
<p style="margin-bottom: 20px" v-if="language === 'zh'">
|
||||||
Copyright © {{ new Date().getFullYear() }} 上海展影医疗科技有限公司
|
Copyright © {{ new Date().getFullYear() }} 上海展影医疗科技有限公司
|
||||||
版权所有
|
版权所有
|
||||||
|
|
@ -201,14 +203,14 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { mapGetters, mapMutations } from "vuex";
|
import { mapGetters, mapMutations } from 'vuex'
|
||||||
import TopLang from "./topLang";
|
import TopLang from './topLang'
|
||||||
// import NoticeMarquee from '../trials/trials-layout/components/noticeMarquee'
|
// import NoticeMarquee from '../trials/trials-layout/components/noticeMarquee'
|
||||||
import Vcode from "vue-puzzle-vcode";
|
import Vcode from 'vue-puzzle-vcode'
|
||||||
import browserTip from "@/views/dictionary/template/browser/tip.vue";
|
import browserTip from '@/views/dictionary/template/browser/tip.vue'
|
||||||
import Img1 from "@/assets/pic-2.png";
|
import Img1 from '@/assets/pic-2.png'
|
||||||
export default {
|
export default {
|
||||||
name: "Login",
|
name: 'Login',
|
||||||
components: { TopLang, Vcode, browserTip },
|
components: { TopLang, Vcode, browserTip },
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
|
|
@ -216,18 +218,18 @@ export default {
|
||||||
VUE_APP_OSS_CONFIG_REGION: process.env.VUE_APP_OSS_CONFIG_REGION,
|
VUE_APP_OSS_CONFIG_REGION: process.env.VUE_APP_OSS_CONFIG_REGION,
|
||||||
aboutVisible: false,
|
aboutVisible: false,
|
||||||
loginForm: {
|
loginForm: {
|
||||||
username: "",
|
username: '',
|
||||||
password: "",
|
password: '',
|
||||||
UserId: null,
|
UserId: null,
|
||||||
},
|
},
|
||||||
loginRules: {
|
loginRules: {
|
||||||
username: [
|
username: [
|
||||||
{
|
{
|
||||||
required: true,
|
required: true,
|
||||||
message: this.$t("login:formRule:userName"),
|
message: this.$t('login:formRule:userName'),
|
||||||
trigger: "blur",
|
trigger: 'blur',
|
||||||
},
|
},
|
||||||
{ max: 20, message: `${this.$t("common:ruleMessage:maxLength")} 20` },
|
{ max: 20, message: `${this.$t('common:ruleMessage:maxLength')} 20` },
|
||||||
],
|
],
|
||||||
password: [
|
password: [
|
||||||
// {
|
// {
|
||||||
|
|
@ -237,29 +239,29 @@ export default {
|
||||||
// },
|
// },
|
||||||
{
|
{
|
||||||
required: true,
|
required: true,
|
||||||
message: this.$t("login:formRule:password"),
|
message: this.$t('login:formRule:password'),
|
||||||
trigger: "blur",
|
trigger: 'blur',
|
||||||
},
|
},
|
||||||
{ max: 20, message: `${this.$t("common:ruleMessage:maxLength")} 20` },
|
{ max: 20, message: `${this.$t('common:ruleMessage:maxLength')} 20` },
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
loading: false,
|
loading: false,
|
||||||
passwordType: "password",
|
passwordType: 'password',
|
||||||
loginType: null,
|
loginType: null,
|
||||||
location: null,
|
location: null,
|
||||||
isShow: false,
|
isShow: false,
|
||||||
showCode: false,
|
showCode: false,
|
||||||
Img1,
|
Img1,
|
||||||
};
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
...mapGetters(["asyncRoutes", "routes", "language"]),
|
...mapGetters(['asyncRoutes', 'routes', 'language']),
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
"$i18n.locale": {
|
'$i18n.locale': {
|
||||||
handler() {
|
handler() {
|
||||||
if (this.$refs.browserTip) {
|
if (this.$refs.browserTip) {
|
||||||
this.$refs.browserTip.open();
|
this.$refs.browserTip.open()
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
deep: true,
|
deep: true,
|
||||||
|
|
@ -267,88 +269,88 @@ export default {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
this.loginType = this.$route.query.loginType;
|
this.loginType = this.$route.query.loginType
|
||||||
this.location = this.$route.query.location;
|
this.location = this.$route.query.location
|
||||||
zzSessionStorage.setItem("loginType", this.loginType);
|
zzSessionStorage.setItem('loginType', this.loginType)
|
||||||
localStorage.setItem("location", this.location);
|
localStorage.setItem('location', this.location)
|
||||||
if (process.env.VUE_APP_OSS_CONFIG_REGION === "oss-us-west-1") {
|
if (process.env.VUE_APP_OSS_CONFIG_REGION === 'oss-us-west-1') {
|
||||||
this.$i18n.locale = "en";
|
this.$i18n.locale = 'en'
|
||||||
this.setLanguage("en");
|
this.setLanguage('en')
|
||||||
this.$updateDictionary();
|
this.$updateDictionary()
|
||||||
} else {
|
} else {
|
||||||
if (this.location === "USA" || this.NODE_ENV === "usa") {
|
if (this.location === 'USA' || this.NODE_ENV === 'usa') {
|
||||||
this.$i18n.locale = "en";
|
this.$i18n.locale = 'en'
|
||||||
this.setLanguage("en");
|
this.setLanguage('en')
|
||||||
this.$updateDictionary();
|
this.$updateDictionary()
|
||||||
} else {
|
} else {
|
||||||
// this.$i18n.locale = 'zh'
|
// this.$i18n.locale = 'zh'
|
||||||
// this.setLanguage('zh')
|
// this.setLanguage('zh')
|
||||||
// this.$updateDictionary()
|
// this.$updateDictionary()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
this.$refs.browserTip.open();
|
this.$refs.browserTip.open()
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
...mapMutations({ setLanguage: "lang/setLanguage" }),
|
...mapMutations({ setLanguage: 'lang/setLanguage' }),
|
||||||
openAbout() {
|
openAbout() {
|
||||||
this.aboutVisible = true;
|
this.aboutVisible = true
|
||||||
},
|
},
|
||||||
showPwd() {
|
showPwd() {
|
||||||
if (this.passwordType === "password") {
|
if (this.passwordType === 'password') {
|
||||||
this.passwordType = "";
|
this.passwordType = ''
|
||||||
} else {
|
} else {
|
||||||
this.passwordType = "password";
|
this.passwordType = 'password'
|
||||||
}
|
}
|
||||||
this.$nextTick(() => {
|
this.$nextTick(() => {
|
||||||
this.$refs.password.focus();
|
this.$refs.password.focus()
|
||||||
});
|
})
|
||||||
},
|
},
|
||||||
handleLogin() {
|
handleLogin() {
|
||||||
this.loginType = this.$route.query.loginType;
|
this.loginType = this.$route.query.loginType
|
||||||
this.$refs.loginForm.validate((valid) => {
|
this.$refs.loginForm.validate((valid) => {
|
||||||
if (valid) {
|
if (valid) {
|
||||||
if (this.showCode) {
|
if (this.showCode) {
|
||||||
this.isShow = true;
|
this.isShow = true
|
||||||
} else {
|
} else {
|
||||||
this.onSuccess();
|
this.onSuccess()
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// console.log('error submit!!')
|
// console.log('error submit!!')
|
||||||
return false;
|
return false
|
||||||
}
|
}
|
||||||
});
|
})
|
||||||
},
|
},
|
||||||
loginIn(Id) {
|
loginIn(Id) {
|
||||||
this.loading = true;
|
this.loading = true
|
||||||
this.showCode = false;
|
this.showCode = false
|
||||||
if (Id) this.loginForm.UserId = Id;
|
if (Id) this.loginForm.UserId = Id
|
||||||
this.$store
|
this.$store
|
||||||
.dispatch("user/login", this.loginForm)
|
.dispatch('user/login', this.loginForm)
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
if (res.BasicInfo.IsFirstAdd) {
|
if (res.BasicInfo.IsFirstAdd) {
|
||||||
// 当前用户为首次登录,请先修改密码之后再次登录
|
// 当前用户为首次登录,请先修改密码之后再次登录
|
||||||
this.$message.success(this.$t("login:message:login1"));
|
this.$message.success(this.$t('login:message:login1'))
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
this.$router.push({
|
this.$router.push({
|
||||||
path: `/recompose?userName=${this.loginForm.username}`,
|
path: `/recompose?userName=${this.loginForm.username}`,
|
||||||
});
|
})
|
||||||
}, 500);
|
}, 500)
|
||||||
return;
|
return
|
||||||
} else if (res.BasicInfo.LoginState === 1) {
|
} else if (res.BasicInfo.LoginState === 1) {
|
||||||
// 请先修改密码后再登录!
|
// 请先修改密码后再登录!
|
||||||
this.$alert(
|
this.$alert(
|
||||||
this.$t("login:message:login3"),
|
this.$t('login:message:login3'),
|
||||||
this.$t("common:title:warning"),
|
this.$t('common:title:warning'),
|
||||||
{
|
{
|
||||||
callback: (action) => {
|
callback: (action) => {
|
||||||
this.$router.push({
|
this.$router.push({
|
||||||
path: `/recompose?userName=${this.loginForm.username}`,
|
path: `/recompose?userName=${this.loginForm.username}`,
|
||||||
});
|
})
|
||||||
return;
|
return
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
);
|
)
|
||||||
return;
|
return
|
||||||
} else if (res.IsMFA) {
|
} else if (res.IsMFA) {
|
||||||
this.$MFA({
|
this.$MFA({
|
||||||
UserId: res.BasicInfo.Id,
|
UserId: res.BasicInfo.Id,
|
||||||
|
|
@ -356,55 +358,55 @@ export default {
|
||||||
username: this.loginForm.username,
|
username: this.loginForm.username,
|
||||||
callBack: this.loginIn,
|
callBack: this.loginIn,
|
||||||
cancelBack: () => {
|
cancelBack: () => {
|
||||||
this.loading = false;
|
this.loading = false
|
||||||
},
|
},
|
||||||
});
|
})
|
||||||
return;
|
return
|
||||||
} else if (res.BasicInfo.LoginState === 2) {
|
} else if (res.BasicInfo.LoginState === 2) {
|
||||||
// 本次登录的IP或设备与上次不一致,请确认'
|
// 本次登录的IP或设备与上次不一致,请确认'
|
||||||
// this.$alert(this.$t('login:message:login4'), this.$t('common:title:warning'))
|
// this.$alert(this.$t('login:message:login4'), this.$t('common:title:warning'))
|
||||||
this.$message.warning(this.$t("login:message:login4"));
|
this.$message.warning(this.$t('login:message:login4'))
|
||||||
}
|
}
|
||||||
this.$store.dispatch("permission/generateRoutes").then((res) => {
|
this.$store.dispatch('permission/generateRoutes').then((res) => {
|
||||||
this.loading = false;
|
this.loading = false
|
||||||
if (res && res.length > 0) {
|
if (res && res.length > 0) {
|
||||||
this.$store.dispatch("global/getNoticeList");
|
this.$store.dispatch('global/getNoticeList')
|
||||||
this.$router.addRoutes(res);
|
this.$router.addRoutes(res)
|
||||||
if (this.loginType === "DevOps") {
|
if (this.loginType === 'DevOps') {
|
||||||
this.$router.replace({ path: res[0].path });
|
this.$router.replace({ path: res[0].path })
|
||||||
return;
|
return
|
||||||
}
|
}
|
||||||
if (this.hasPermi(["role:radmin"])) {
|
if (this.hasPermi(['role:radmin'])) {
|
||||||
this.$router.replace({ path: res[0].path });
|
this.$router.replace({ path: res[0].path })
|
||||||
return;
|
return
|
||||||
}
|
}
|
||||||
if (
|
if (
|
||||||
this.hasPermi(["role:air", "role:rpm", "role:rcrc", "role:rir"])
|
this.hasPermi(['role:air', 'role:rpm', 'role:rcrc', 'role:rir'])
|
||||||
) {
|
) {
|
||||||
this.$router.replace({ path: "/trials/trials-list" });
|
this.$router.replace({ path: '/trials/trials-list' })
|
||||||
} else {
|
} else {
|
||||||
this.$router.replace({ path: "/trials" });
|
this.$router.replace({ path: '/trials' })
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// 此账户暂未配置菜单权限,请联系管理员处理后再登录。
|
// 此账户暂未配置菜单权限,请联系管理员处理后再登录。
|
||||||
this.$message.warning(this.$t("login:message:login2"));
|
this.$message.warning(this.$t('login:message:login2'))
|
||||||
}
|
}
|
||||||
});
|
})
|
||||||
})
|
})
|
||||||
.catch(() => {
|
.catch(() => {
|
||||||
this.showCode = true;
|
this.showCode = true
|
||||||
this.loading = false;
|
this.loading = false
|
||||||
});
|
})
|
||||||
},
|
},
|
||||||
onSuccess() {
|
onSuccess() {
|
||||||
this.isShow = false;
|
this.isShow = false
|
||||||
this.loginIn();
|
this.loginIn()
|
||||||
},
|
},
|
||||||
handleResetPwd() {
|
handleResetPwd() {
|
||||||
this.$router.push({ name: "Resetpassword" });
|
this.$router.push({ name: 'Resetpassword' })
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
|
|
|
||||||
|
|
@ -13,8 +13,11 @@
|
||||||
<span>{{ getBodyPart(study.BodyPart) }}</span>
|
<span>{{ getBodyPart(study.BodyPart) }}</span>
|
||||||
</div>
|
</div>
|
||||||
<!-- 文件层级 -->
|
<!-- 文件层级 -->
|
||||||
<div v-if="study.NoneDicomStudyFileList.length === 0" class="empty-text">
|
<div
|
||||||
<slot name="empty">暂无数据</slot>
|
v-if="study.NoneDicomStudyFileList.length === 0"
|
||||||
|
class="empty-text"
|
||||||
|
>
|
||||||
|
<slot name="empty">{{ $t('trials:audit:message:noData') }}</slot>
|
||||||
</div>
|
</div>
|
||||||
<div v-else id="imgList" style="height: 100%; overflow: hidden">
|
<div v-else id="imgList" style="height: 100%; overflow: hidden">
|
||||||
<div
|
<div
|
||||||
|
|
@ -22,32 +25,42 @@
|
||||||
: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)"
|
||||||
>
|
>
|
||||||
|
<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>
|
||||||
</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,8 +125,14 @@ 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(' | ')
|
||||||
|
|
@ -121,22 +140,32 @@ export default {
|
||||||
// 获取非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,9 +200,8 @@ export default {
|
||||||
},
|
},
|
||||||
preview() {
|
preview() {
|
||||||
this.previewVisible = true
|
this.previewVisible = true
|
||||||
}
|
},
|
||||||
|
},
|
||||||
}
|
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
@ -236,13 +270,18 @@ 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;
|
||||||
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) {
|
||||||
|
|
@ -265,5 +304,4 @@ export default {
|
||||||
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')"
|
||||||
|
prop="ConfirmPassWord"
|
||||||
|
>
|
||||||
|
<el-input
|
||||||
|
v-model="password.ConfirmPassWord"
|
||||||
|
type="password"
|
||||||
|
show-password
|
||||||
|
auto-complete="new-password"
|
||||||
|
/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item style="text-align: right">
|
<el-form-item style="text-align: right">
|
||||||
<!-- 取消 -->
|
<!-- 取消 -->
|
||||||
<el-button
|
<el-button size="small" @click="cancel">
|
||||||
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,26 +159,32 @@ 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>
|
||||||
|
|
|
||||||
|
|
@ -38,7 +38,7 @@
|
||||||
<div class="login_content">
|
<div class="login_content">
|
||||||
<el-form-item
|
<el-form-item
|
||||||
:label="$t('trials:researchForm:form:siteName')"
|
:label="$t('trials:researchForm:form:siteName')"
|
||||||
prop="SiteId"
|
prop="TrialSiteId"
|
||||||
>
|
>
|
||||||
<el-select
|
<el-select
|
||||||
v-model="form.TrialSiteId"
|
v-model="form.TrialSiteId"
|
||||||
|
|
|
||||||
|
|
@ -34,7 +34,7 @@
|
||||||
<el-input v-model="form.IndicationType" disabled />
|
<el-input v-model="form.IndicationType" disabled />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<!-- 中心名称 -->
|
<!-- 中心名称 -->
|
||||||
<el-form-item :label="$t('trials:researchForm:form:siteName')" prop="SiteId">
|
<el-form-item :label="$t('trials:researchForm:form:siteName')" prop="TrialSiteId">
|
||||||
<el-select v-model="form.TrialSiteId" filterable style="width:100%;" @change="handleSiteChange">
|
<el-select v-model="form.TrialSiteId" filterable style="width:100%;" @change="handleSiteChange">
|
||||||
<el-option
|
<el-option
|
||||||
v-for="(item,index) of siteOptions"
|
v-for="(item,index) of siteOptions"
|
||||||
|
|
|
||||||
|
|
@ -147,7 +147,7 @@
|
||||||
>
|
>
|
||||||
{{
|
{{
|
||||||
$fd(
|
$fd(
|
||||||
"InternationalizationType",
|
'InternationalizationType',
|
||||||
scope.row.InternationalizationType
|
scope.row.InternationalizationType
|
||||||
)
|
)
|
||||||
}}
|
}}
|
||||||
|
|
@ -158,7 +158,7 @@
|
||||||
>
|
>
|
||||||
{{
|
{{
|
||||||
$fd(
|
$fd(
|
||||||
"InternationalizationType",
|
'InternationalizationType',
|
||||||
scope.row.InternationalizationType
|
scope.row.InternationalizationType
|
||||||
)
|
)
|
||||||
}}
|
}}
|
||||||
|
|
@ -166,7 +166,7 @@
|
||||||
<el-tag v-else>
|
<el-tag v-else>
|
||||||
{{
|
{{
|
||||||
$fd(
|
$fd(
|
||||||
"InternationalizationType",
|
'InternationalizationType',
|
||||||
scope.row.InternationalizationType
|
scope.row.InternationalizationType
|
||||||
)
|
)
|
||||||
}}
|
}}
|
||||||
|
|
@ -176,7 +176,7 @@
|
||||||
<el-table-column
|
<el-table-column
|
||||||
label="功能模块/服务名"
|
label="功能模块/服务名"
|
||||||
prop="Module"
|
prop="Module"
|
||||||
min-width="120"
|
min-width="140"
|
||||||
show-overflow-tooltip
|
show-overflow-tooltip
|
||||||
sortable="custom"
|
sortable="custom"
|
||||||
/>
|
/>
|
||||||
|
|
@ -210,13 +210,13 @@
|
||||||
>
|
>
|
||||||
<template slot-scope="scope">
|
<template slot-scope="scope">
|
||||||
<el-tag v-if="scope.row.State === 0" type="danger">
|
<el-tag v-if="scope.row.State === 0" type="danger">
|
||||||
{{ $fd("InternationalizationKeyState", scope.row.State) }}
|
{{ $fd('InternationalizationKeyState', scope.row.State) }}
|
||||||
</el-tag>
|
</el-tag>
|
||||||
<el-tag v-else-if="scope.row.State === 1" type="primary">
|
<el-tag v-else-if="scope.row.State === 1" type="primary">
|
||||||
{{ $fd("InternationalizationKeyState", scope.row.State) }}
|
{{ $fd('InternationalizationKeyState', scope.row.State) }}
|
||||||
</el-tag>
|
</el-tag>
|
||||||
<el-tag v-else>
|
<el-tag v-else>
|
||||||
{{ $fd("InternationalizationKeyState", scope.row.State) }}
|
{{ $fd('InternationalizationKeyState', scope.row.State) }}
|
||||||
</el-tag>
|
</el-tag>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
|
|
@ -241,7 +241,13 @@
|
||||||
show-overflow-tooltip
|
show-overflow-tooltip
|
||||||
sortable="custom"
|
sortable="custom"
|
||||||
/>
|
/>
|
||||||
|
<el-table-column
|
||||||
|
label="创建时间"
|
||||||
|
prop="CreateTime"
|
||||||
|
width="150"
|
||||||
|
show-overflow-tooltip
|
||||||
|
sortable="custom"
|
||||||
|
/>
|
||||||
<el-table-column
|
<el-table-column
|
||||||
label="操作"
|
label="操作"
|
||||||
fixed="right"
|
fixed="right"
|
||||||
|
|
@ -289,11 +295,11 @@ import {
|
||||||
deleteInternationalization,
|
deleteInternationalization,
|
||||||
getPublishVersionSelect,
|
getPublishVersionSelect,
|
||||||
batchUpdateInternationalInfo,
|
batchUpdateInternationalInfo,
|
||||||
} from "@/api/admin";
|
} from '@/api/admin'
|
||||||
import Pagination from "@/components/Pagination";
|
import Pagination from '@/components/Pagination'
|
||||||
import I18nForm from "./components/I18nForm.vue";
|
import I18nForm from './components/I18nForm.vue'
|
||||||
import BatchAddForm from "./components/BatchAddForm.vue";
|
import BatchAddForm from './components/BatchAddForm.vue'
|
||||||
import moment from "moment";
|
import moment from 'moment'
|
||||||
const searchDataDefault = () => {
|
const searchDataDefault = () => {
|
||||||
return {
|
return {
|
||||||
Description: null,
|
Description: null,
|
||||||
|
|
@ -304,13 +310,13 @@ const searchDataDefault = () => {
|
||||||
Module: null,
|
Module: null,
|
||||||
PublishLogId: null,
|
PublishLogId: null,
|
||||||
Asc: true,
|
Asc: true,
|
||||||
SortField: "",
|
SortField: '',
|
||||||
PageIndex: 1,
|
PageIndex: 1,
|
||||||
PageSize: 20,
|
PageSize: 20,
|
||||||
};
|
}
|
||||||
};
|
}
|
||||||
export default {
|
export default {
|
||||||
name: "I18n",
|
name: 'I18n',
|
||||||
components: { Pagination, I18nForm, BatchAddForm },
|
components: { Pagination, I18nForm, BatchAddForm },
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
|
|
@ -321,140 +327,140 @@ export default {
|
||||||
loading: false,
|
loading: false,
|
||||||
PublishVersionList: [],
|
PublishVersionList: [],
|
||||||
selectTableList: [],
|
selectTableList: [],
|
||||||
};
|
}
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
this.getList();
|
this.getList()
|
||||||
this.getPublishVersionSelect();
|
this.getPublishVersionSelect()
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
// 获取迭代
|
// 获取迭代
|
||||||
async getPublishVersionSelect() {
|
async getPublishVersionSelect() {
|
||||||
try {
|
try {
|
||||||
let res = await getPublishVersionSelect();
|
let res = await getPublishVersionSelect()
|
||||||
if (res.IsSuccess) {
|
if (res.IsSuccess) {
|
||||||
this.PublishVersionList = res.Result;
|
this.PublishVersionList = res.Result
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.log(err);
|
console.log(err)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
getList() {
|
getList() {
|
||||||
this.loading = true;
|
this.loading = true
|
||||||
getInternationalizationList(this.searchData)
|
getInternationalizationList(this.searchData)
|
||||||
.then((res) => {
|
.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
|
||||||
});
|
})
|
||||||
},
|
},
|
||||||
// 批量更新
|
// 批量更新
|
||||||
handleBatchUpdate() {
|
handleBatchUpdate() {
|
||||||
this.$nextTick(() => {
|
this.$nextTick(() => {
|
||||||
this.$refs["i18nForm"].openDialog(
|
this.$refs['i18nForm'].openDialog(
|
||||||
"批量更新",
|
'批量更新',
|
||||||
{},
|
{},
|
||||||
this.PublishVersionList,
|
this.PublishVersionList,
|
||||||
"batch"
|
'batch'
|
||||||
);
|
)
|
||||||
});
|
})
|
||||||
},
|
},
|
||||||
async batch(row) {
|
async batch(row) {
|
||||||
let { PublishLogId, State } = row;
|
let { PublishLogId, State } = row
|
||||||
let data = {
|
let data = {
|
||||||
PublishLogId,
|
PublishLogId,
|
||||||
State,
|
State,
|
||||||
IdList: this.selectTableList.map((item) => item.Id),
|
IdList: this.selectTableList.map((item) => item.Id),
|
||||||
};
|
}
|
||||||
try {
|
try {
|
||||||
let res = await batchUpdateInternationalInfo(data);
|
let res = await batchUpdateInternationalInfo(data)
|
||||||
if (res.IsSuccess) {
|
if (res.IsSuccess) {
|
||||||
this.$message.success(this.$t("common:message:updatedSuccessfully"));
|
this.$message.success(this.$t('common:message:updatedSuccessfully'))
|
||||||
this.getList();
|
this.getList()
|
||||||
this.$nextTick(() => {
|
this.$nextTick(() => {
|
||||||
this.$refs["i18nForm"].handleCancle();
|
this.$refs['i18nForm'].handleCancle()
|
||||||
});
|
})
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.log(err);
|
console.log(err)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
handleAdd() {
|
handleAdd() {
|
||||||
this.$nextTick(() => {
|
this.$nextTick(() => {
|
||||||
this.$refs["i18nForm"].openDialog(
|
this.$refs['i18nForm'].openDialog(
|
||||||
"新增",
|
'新增',
|
||||||
{},
|
{},
|
||||||
this.PublishVersionList,
|
this.PublishVersionList,
|
||||||
"add"
|
'add'
|
||||||
);
|
)
|
||||||
});
|
})
|
||||||
},
|
},
|
||||||
handleBatchAdd() {
|
handleBatchAdd() {
|
||||||
this.$nextTick(() => {
|
this.$nextTick(() => {
|
||||||
this.$refs["batcnAddForm"].openDialog(
|
this.$refs['batcnAddForm'].openDialog(
|
||||||
"批量新增",
|
'批量新增',
|
||||||
{},
|
{},
|
||||||
this.PublishVersionList
|
this.PublishVersionList
|
||||||
);
|
)
|
||||||
});
|
})
|
||||||
},
|
},
|
||||||
handleEdit(row) {
|
handleEdit(row) {
|
||||||
this.$nextTick(() => {
|
this.$nextTick(() => {
|
||||||
this.$refs["i18nForm"].openDialog(
|
this.$refs['i18nForm'].openDialog(
|
||||||
"编辑",
|
'编辑',
|
||||||
row,
|
row,
|
||||||
this.PublishVersionList,
|
this.PublishVersionList,
|
||||||
"update"
|
'update'
|
||||||
);
|
)
|
||||||
});
|
})
|
||||||
},
|
},
|
||||||
// 重置列表查询
|
// 重置列表查询
|
||||||
handleReset() {
|
handleReset() {
|
||||||
this.searchData = searchDataDefault();
|
this.searchData = searchDataDefault()
|
||||||
this.getList();
|
this.getList()
|
||||||
},
|
},
|
||||||
// 删除
|
// 删除
|
||||||
handleDelete(row) {
|
handleDelete(row) {
|
||||||
this.$confirm("是否确认删除?", {
|
this.$confirm('是否确认删除?', {
|
||||||
type: "warning",
|
type: 'warning',
|
||||||
distinguishCancelAndClose: true,
|
distinguishCancelAndClose: true,
|
||||||
}).then(() => {
|
}).then(() => {
|
||||||
this.loading = true;
|
this.loading = true
|
||||||
deleteInternationalization(row.Id)
|
deleteInternationalization(row.Id)
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
this.loading = false;
|
this.loading = false
|
||||||
if (res.IsSuccess) {
|
if (res.IsSuccess) {
|
||||||
this.getList();
|
this.getList()
|
||||||
this.$message.success(
|
this.$message.success(
|
||||||
this.$t("common:message:deletedSuccessfully")
|
this.$t('common:message:deletedSuccessfully')
|
||||||
);
|
)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.catch(() => {
|
.catch(() => {
|
||||||
this.loading = false;
|
this.loading = false
|
||||||
});
|
})
|
||||||
});
|
})
|
||||||
},
|
},
|
||||||
// 排序
|
// 排序
|
||||||
handleSortByColumn(column) {
|
handleSortByColumn(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
|
||||||
}
|
}
|
||||||
this.searchData.SortField = column.prop;
|
this.searchData.SortField = column.prop
|
||||||
this.searchData.PageIndex = 1;
|
this.searchData.PageIndex = 1
|
||||||
this.getList();
|
this.getList()
|
||||||
},
|
},
|
||||||
// 选择
|
// 选择
|
||||||
handleSelectionChange(val) {
|
handleSelectionChange(val) {
|
||||||
this.selectTableList = val;
|
this.selectTableList = val
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
}
|
||||||
</script>
|
</script>
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
.log {
|
.log {
|
||||||
|
|
|
||||||
|
|
@ -9,10 +9,16 @@
|
||||||
label-width="120px"
|
label-width="120px"
|
||||||
size="small"
|
size="small"
|
||||||
>
|
>
|
||||||
<el-form-item label="发布版本" prop="Version">
|
<el-form-item :label="$t('system:log:form:version')" prop="Version">
|
||||||
<el-input v-model="form.Version" />
|
<el-input v-model="form.Version" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="更新功能" prop="UpdateContent">
|
<el-form-item :label="$t('system:log:form:versionUS')" prop="Version">
|
||||||
|
<el-input v-model="form.Version_US" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item
|
||||||
|
:label="$t('system:log:form:updateContent')"
|
||||||
|
prop="UpdateContent"
|
||||||
|
>
|
||||||
<el-input
|
<el-input
|
||||||
v-model="form.UpdateContent"
|
v-model="form.UpdateContent"
|
||||||
type="textarea"
|
type="textarea"
|
||||||
|
|
@ -20,8 +26,8 @@
|
||||||
:autosize="{ minRows: 4, maxRows: 5 }"
|
:autosize="{ minRows: 4, maxRows: 5 }"
|
||||||
/>
|
/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="发布状态" prop="State">
|
<el-form-item :label="$t('system:log:form:State')" prop="State">
|
||||||
<el-select v-model="form.State" placeholder="请选择">
|
<el-select v-model="form.State" placeholder="">
|
||||||
<el-option
|
<el-option
|
||||||
v-for="item in $d.PublishStatus"
|
v-for="item in $d.PublishStatus"
|
||||||
:key="item.id"
|
:key="item.id"
|
||||||
|
|
@ -31,15 +37,18 @@
|
||||||
</el-option>
|
</el-option>
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="发布日期">
|
<el-form-item :label="$t('system:log:form:PublishTime')">
|
||||||
<el-date-picker
|
<el-date-picker
|
||||||
v-model="form.PublishTime"
|
v-model="form.PublishTime"
|
||||||
type="date"
|
type="date"
|
||||||
value-format="yyyy-MM-dd HH:mm:ss"
|
value-format="yyyy-MM-dd HH:mm:ss"
|
||||||
/>
|
/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="是否当前版本" prop="IsCurrentVersion">
|
<el-form-item
|
||||||
<el-select v-model="form.IsCurrentVersion" placeholder="请选择">
|
:label="$t('system:log:form:IsCurrentVersion')"
|
||||||
|
prop="IsCurrentVersion"
|
||||||
|
>
|
||||||
|
<el-select v-model="form.IsCurrentVersion" placeholder="">
|
||||||
<el-option
|
<el-option
|
||||||
v-for="item in $d.YesOrNo"
|
v-for="item in $d.YesOrNo"
|
||||||
:key="item.id"
|
:key="item.id"
|
||||||
|
|
@ -52,30 +61,31 @@
|
||||||
</el-form>
|
</el-form>
|
||||||
</template>
|
</template>
|
||||||
<template slot="dialog-footer">
|
<template slot="dialog-footer">
|
||||||
<el-button size="small" type="primary" @click="handleCancle"
|
<el-button size="small" type="primary" @click="handleCancle">
|
||||||
>取消</el-button
|
{{ $t('common:button:cancel') }}
|
||||||
>
|
</el-button>
|
||||||
<el-button size="small" type="primary" @click="handleSave"
|
<el-button size="small" type="primary" @click="handleSave">
|
||||||
>保存</el-button
|
{{ $t('common:button:save') }}
|
||||||
>
|
</el-button>
|
||||||
</template>
|
</template>
|
||||||
</base-model>
|
</base-model>
|
||||||
</template>
|
</template>
|
||||||
<script>
|
<script>
|
||||||
import { addOrUpdatePublishLog } from "@/api/admin";
|
import { addOrUpdatePublishLog } from '@/api/admin'
|
||||||
import BaseModel from "@/components/BaseModel";
|
import BaseModel from '@/components/BaseModel'
|
||||||
const formDataDefault = () => {
|
const formDataDefault = () => {
|
||||||
return {
|
return {
|
||||||
Id: null,
|
Id: null,
|
||||||
Version: null,
|
Version: null,
|
||||||
|
Version_US: null,
|
||||||
PublishTime: null,
|
PublishTime: null,
|
||||||
UpdateContent: null,
|
UpdateContent: null,
|
||||||
State: null,
|
State: null,
|
||||||
IsCurrentVersion: null,
|
IsCurrentVersion: null,
|
||||||
};
|
}
|
||||||
};
|
}
|
||||||
export default {
|
export default {
|
||||||
name: "LogForm",
|
name: 'LogForm',
|
||||||
components: { BaseModel },
|
components: { BaseModel },
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
|
|
@ -83,69 +93,87 @@ export default {
|
||||||
form: formDataDefault(),
|
form: formDataDefault(),
|
||||||
rules: {
|
rules: {
|
||||||
Version: [
|
Version: [
|
||||||
{ required: true, message: "请注明", trigger: "blur" },
|
{
|
||||||
{ max: 50, message: `${this.$t("common:ruleMessage:maxLength")} 50` },
|
required: true,
|
||||||
|
message: this.$t('common:ruleMessage:specify'),
|
||||||
|
trigger: 'blur',
|
||||||
|
},
|
||||||
|
{ max: 50, message: `${this.$t('common:ruleMessage:maxLength')} 50` },
|
||||||
],
|
],
|
||||||
// PublishTime: [
|
// PublishTime: [
|
||||||
// { required: true, message: '请注明', trigger: 'blur' }
|
// { required: true, message: '请注明', trigger: 'blur' }
|
||||||
// ],
|
// ],
|
||||||
IsCurrentVersion: [
|
IsCurrentVersion: [
|
||||||
{ required: true, message: "请选择", trigger: "blur" },
|
{
|
||||||
|
required: true,
|
||||||
|
message: this.$t('common:ruleMessage:select'),
|
||||||
|
trigger: 'blur',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
State: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: this.$t('common:ruleMessage:select'),
|
||||||
|
trigger: 'blur',
|
||||||
|
},
|
||||||
],
|
],
|
||||||
State: [{ required: true, message: "请选择", trigger: "blur" }],
|
|
||||||
UpdateContent: [
|
UpdateContent: [
|
||||||
{ required: true, message: "请注明", trigger: "blur" },
|
{
|
||||||
|
required: true,
|
||||||
|
message: this.$t('common:ruleMessage:specify'),
|
||||||
|
trigger: 'blur',
|
||||||
|
},
|
||||||
{
|
{
|
||||||
max: 1000,
|
max: 1000,
|
||||||
message: `${this.$t("common:ruleMessage:maxLength")} 500`,
|
message: `${this.$t('common:ruleMessage:maxLength')} 500`,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
model_cfg: {
|
model_cfg: {
|
||||||
visible: false,
|
visible: false,
|
||||||
showClose: true,
|
showClose: true,
|
||||||
width: "500px",
|
width: '500px',
|
||||||
title: "",
|
title: '',
|
||||||
appendToBody: true,
|
appendToBody: true,
|
||||||
},
|
},
|
||||||
};
|
}
|
||||||
},
|
},
|
||||||
mounted() {},
|
mounted() {},
|
||||||
methods: {
|
methods: {
|
||||||
openDialog(title, data) {
|
openDialog(title, data) {
|
||||||
this.model_cfg.visible = true;
|
this.model_cfg.visible = true
|
||||||
this.model_cfg.title = title;
|
this.model_cfg.title = title
|
||||||
if (Object.keys(data).length > 0) {
|
if (Object.keys(data).length > 0) {
|
||||||
for (const k in this.form) {
|
for (const k in this.form) {
|
||||||
if (data.hasOwnProperty(k)) {
|
if (data.hasOwnProperty(k)) {
|
||||||
this.form[k] = data[k];
|
this.form[k] = data[k]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
this.form = formDataDefault();
|
this.form = formDataDefault()
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
handleSave() {
|
handleSave() {
|
||||||
this.$refs.LogForm.validate((valid) => {
|
this.$refs.LogForm.validate((valid) => {
|
||||||
if (!valid) return;
|
if (!valid) return
|
||||||
this.loading = true;
|
this.loading = true
|
||||||
addOrUpdatePublishLog(this.form)
|
addOrUpdatePublishLog(this.form)
|
||||||
.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'))
|
||||||
this.model_cfg.visible = false;
|
this.model_cfg.visible = false
|
||||||
this.$emit("getList");
|
this.$emit('getList')
|
||||||
})
|
})
|
||||||
.catch(() => {
|
.catch(() => {
|
||||||
this.loading = false;
|
this.loading = false
|
||||||
});
|
})
|
||||||
});
|
})
|
||||||
},
|
},
|
||||||
handleCancle() {
|
handleCancle() {
|
||||||
this.model_cfg.visible = false;
|
this.model_cfg.visible = false
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
}
|
||||||
</script>
|
</script>
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
::v-deep .el-select,
|
::v-deep .el-select,
|
||||||
|
|
|
||||||
|
|
@ -2,9 +2,12 @@
|
||||||
<div class="log">
|
<div class="log">
|
||||||
<div ref="leftContainer" class="left">
|
<div ref="leftContainer" class="left">
|
||||||
<el-form :inline="true">
|
<el-form :inline="true">
|
||||||
<el-form-item label="发布版本" prop="Version">
|
<el-form-item :label="$t('system:log:table:version')" prop="Version">
|
||||||
<el-input v-model="searchData.Version" size="small" clearable />
|
<el-input v-model="searchData.Version" size="small" clearable />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
<el-form-item :label="$t('system:log:table:versionUS')" prop="Version">
|
||||||
|
<el-input v-model="searchData.Version_US" size="small" clearable />
|
||||||
|
</el-form-item>
|
||||||
<el-form-item label="更新功能" prop="UpdateContent">
|
<el-form-item label="更新功能" prop="UpdateContent">
|
||||||
<el-input v-model="searchData.UpdateContent" size="small" clearable />
|
<el-input v-model="searchData.UpdateContent" size="small" clearable />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
@ -38,30 +41,37 @@
|
||||||
>
|
>
|
||||||
<el-table-column type="index" width="50" />
|
<el-table-column type="index" width="50" />
|
||||||
<el-table-column
|
<el-table-column
|
||||||
label="发布版本"
|
:label="$t('system:log:table:version')"
|
||||||
prop="Version"
|
prop="Version"
|
||||||
min-width="90"
|
min-width="90"
|
||||||
show-overflow-tooltip
|
show-overflow-tooltip
|
||||||
sortable="custom"
|
sortable="custom"
|
||||||
/>
|
/>
|
||||||
<el-table-column
|
<el-table-column
|
||||||
label="更新功能"
|
:label="$t('system:log:table:versionUS')"
|
||||||
|
prop="Version_US"
|
||||||
|
min-width="90"
|
||||||
|
show-overflow-tooltip
|
||||||
|
sortable="custom"
|
||||||
|
/>
|
||||||
|
<el-table-column
|
||||||
|
:label="$t('system:log:table:UpdateContent')"
|
||||||
prop="UpdateContent"
|
prop="UpdateContent"
|
||||||
min-width="150"
|
min-width="150"
|
||||||
show-overflow-tooltip
|
show-overflow-tooltip
|
||||||
/>
|
/>
|
||||||
<el-table-column
|
<el-table-column
|
||||||
label="发布状态"
|
:label="$t('system:log:table:State')"
|
||||||
prop="State"
|
prop="State"
|
||||||
min-width="150"
|
min-width="150"
|
||||||
show-overflow-tooltip
|
show-overflow-tooltip
|
||||||
>
|
>
|
||||||
<template slot-scope="scope">
|
<template slot-scope="scope">
|
||||||
<span>{{ $fd("PublishStatus", scope.row.State) }}</span>
|
<span>{{ $fd('PublishStatus', scope.row.State) }}</span>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column
|
<el-table-column
|
||||||
label="发布日期"
|
:label="$t('system:log:table:PublishTime')"
|
||||||
prop="PublishTime"
|
prop="PublishTime"
|
||||||
min-width="90"
|
min-width="90"
|
||||||
show-overflow-tooltip
|
show-overflow-tooltip
|
||||||
|
|
@ -70,23 +80,23 @@
|
||||||
<template slot-scope="scope">
|
<template slot-scope="scope">
|
||||||
{{
|
{{
|
||||||
scope.row.PublishTime
|
scope.row.PublishTime
|
||||||
? moment(scope.row.PublishTime).format("YYYY-MM-DD")
|
? moment(scope.row.PublishTime).format('YYYY-MM-DD')
|
||||||
: ""
|
: ''
|
||||||
}}
|
}}
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column
|
<el-table-column
|
||||||
label="是否当前版本"
|
:label="$t('system:log:table:IsCurrentVersion')"
|
||||||
prop="IsCurrentVersion"
|
prop="IsCurrentVersion"
|
||||||
min-width="150"
|
min-width="150"
|
||||||
show-overflow-tooltip
|
show-overflow-tooltip
|
||||||
>
|
>
|
||||||
<template slot-scope="scope">
|
<template slot-scope="scope">
|
||||||
<span>{{ $fd("YesOrNo", scope.row.IsCurrentVersion) }}</span>
|
<span>{{ $fd('YesOrNo', scope.row.IsCurrentVersion) }}</span>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column
|
<el-table-column
|
||||||
label="操作"
|
:label="$t('common:action:action')"
|
||||||
fixed="right"
|
fixed="right"
|
||||||
prop=""
|
prop=""
|
||||||
min-width="200"
|
min-width="200"
|
||||||
|
|
@ -99,7 +109,7 @@
|
||||||
icon="el-icon-edit-outline"
|
icon="el-icon-edit-outline"
|
||||||
@click="handleEdit(scope.row)"
|
@click="handleEdit(scope.row)"
|
||||||
>
|
>
|
||||||
编辑
|
{{ $t('common:button:edit') }}
|
||||||
</el-button>
|
</el-button>
|
||||||
<el-button
|
<el-button
|
||||||
size="mini"
|
size="mini"
|
||||||
|
|
@ -107,7 +117,7 @@
|
||||||
icon="el-icon-delete"
|
icon="el-icon-delete"
|
||||||
@click="handleDelete(scope.row)"
|
@click="handleDelete(scope.row)"
|
||||||
>
|
>
|
||||||
删除
|
{{ $t('common:button:delete') }}
|
||||||
</el-button>
|
</el-button>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
|
|
@ -125,20 +135,21 @@
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script>
|
<script>
|
||||||
import { getPublishLogList, deletePublishLog } from "@/api/admin";
|
import { getPublishLogList, deletePublishLog } from '@/api/admin'
|
||||||
import Pagination from "@/components/Pagination";
|
import Pagination from '@/components/Pagination'
|
||||||
import LogForm from "./components/LogForm.vue";
|
import LogForm from './components/LogForm.vue'
|
||||||
import moment from "moment";
|
import moment from 'moment'
|
||||||
const searchDataDefault = () => {
|
const searchDataDefault = () => {
|
||||||
return {
|
return {
|
||||||
Version: null,
|
Version: null,
|
||||||
|
Version_US: null,
|
||||||
UpdateContent: null,
|
UpdateContent: null,
|
||||||
Asc: false,
|
Asc: false,
|
||||||
SortField: "PublishTime",
|
SortField: 'PublishTime',
|
||||||
PageIndex: 1,
|
PageIndex: 1,
|
||||||
PageSize: 20,
|
PageSize: 20,
|
||||||
};
|
}
|
||||||
};
|
}
|
||||||
export default {
|
export default {
|
||||||
components: { Pagination, LogForm },
|
components: { Pagination, LogForm },
|
||||||
data() {
|
data() {
|
||||||
|
|
@ -148,74 +159,74 @@ export default {
|
||||||
list: [],
|
list: [],
|
||||||
total: 0,
|
total: 0,
|
||||||
loading: false,
|
loading: false,
|
||||||
};
|
}
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
this.getList();
|
this.getList()
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
getList() {
|
getList() {
|
||||||
this.loading = true;
|
this.loading = true
|
||||||
getPublishLogList(this.searchData)
|
getPublishLogList(this.searchData)
|
||||||
.then((res) => {
|
.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
|
||||||
});
|
})
|
||||||
},
|
},
|
||||||
handleAdd() {
|
handleAdd() {
|
||||||
this.$nextTick(() => {
|
this.$nextTick(() => {
|
||||||
this.$refs["LogForm"].openDialog("新增", {});
|
this.$refs['LogForm'].openDialog('新增', {})
|
||||||
});
|
})
|
||||||
},
|
},
|
||||||
handleEdit(row) {
|
handleEdit(row) {
|
||||||
this.$nextTick(() => {
|
this.$nextTick(() => {
|
||||||
this.$refs["LogForm"].openDialog("编辑", row);
|
this.$refs['LogForm'].openDialog('编辑', row)
|
||||||
});
|
})
|
||||||
},
|
},
|
||||||
// 重置列表查询
|
// 重置列表查询
|
||||||
handleReset() {
|
handleReset() {
|
||||||
this.searchData = searchDataDefault();
|
this.searchData = searchDataDefault()
|
||||||
this.getList();
|
this.getList()
|
||||||
},
|
},
|
||||||
// 删除
|
// 删除
|
||||||
handleDelete(row) {
|
handleDelete(row) {
|
||||||
this.$confirm("是否确认删除?", {
|
this.$confirm('是否确认删除?', {
|
||||||
type: "warning",
|
type: 'warning',
|
||||||
distinguishCancelAndClose: true,
|
distinguishCancelAndClose: true,
|
||||||
}).then(() => {
|
}).then(() => {
|
||||||
this.loading = true;
|
this.loading = true
|
||||||
deletePublishLog(row.Id)
|
deletePublishLog(row.Id)
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
this.loading = false;
|
this.loading = false
|
||||||
if (res.IsSuccess) {
|
if (res.IsSuccess) {
|
||||||
this.getList();
|
this.getList()
|
||||||
this.$message.success(
|
this.$message.success(
|
||||||
this.$t("common:message:deletedSuccessfully")
|
this.$t('common:message:deletedSuccessfully')
|
||||||
);
|
)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.catch(() => {
|
.catch(() => {
|
||||||
this.loading = false;
|
this.loading = false
|
||||||
});
|
})
|
||||||
});
|
})
|
||||||
},
|
},
|
||||||
// 排序
|
// 排序
|
||||||
handleSortByColumn(column) {
|
handleSortByColumn(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
|
||||||
}
|
}
|
||||||
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">
|
<style lang="scss">
|
||||||
.log {
|
.log {
|
||||||
|
|
|
||||||
|
|
@ -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>
|
||||||
|
|
|
||||||
|
|
@ -3,14 +3,19 @@
|
||||||
<div class="trial-myinfo-right-box">
|
<div class="trial-myinfo-right-box">
|
||||||
<div class="trial-myinfo-head">
|
<div class="trial-myinfo-head">
|
||||||
<!-- 账号信息 -->
|
<!-- 账号信息 -->
|
||||||
{{ $t("trials:trials-myinfo:title:accountInfo") }}
|
{{ $t('trials:trials-myinfo:title:accountInfo') }}
|
||||||
</div>
|
</div>
|
||||||
<el-form label-position="right" label-width="100px">
|
<el-form
|
||||||
|
label-position="right"
|
||||||
|
label-width="100px"
|
||||||
|
:rules="rule"
|
||||||
|
:model="userForm"
|
||||||
|
ref="userFormRef"
|
||||||
|
>
|
||||||
<!-- 用户名 -->
|
<!-- 用户名 -->
|
||||||
<el-form-item
|
<el-form-item
|
||||||
:label="$t('trials:trials-myinfo:form:userName')"
|
:label="$t('trials:trials-myinfo:form:userName')"
|
||||||
style="margin-bottom: 5px"
|
style="margin-bottom: 5px"
|
||||||
prop="UserName"
|
|
||||||
>
|
>
|
||||||
<span>{{ user.UserName }}</span>
|
<span>{{ user.UserName }}</span>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
@ -27,18 +32,18 @@
|
||||||
size="small"
|
size="small"
|
||||||
@click="setNewUserName"
|
@click="setNewUserName"
|
||||||
>
|
>
|
||||||
{{ $t("trials:trials-myinfo:button:update") }}
|
{{ $t('trials:trials-myinfo:button:update') }}
|
||||||
</el-button>
|
</el-button>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<!-- 电话 -->
|
<!-- 电话 -->
|
||||||
<el-form-item
|
<el-form-item
|
||||||
:label="$t('trials:trials-myinfo:form:phone')"
|
:label="$t('trials:trials-myinfo:form:phone')"
|
||||||
style="margin-bottom: 5px"
|
style="margin-bottom: 5px"
|
||||||
prop="UserName"
|
prop="Phone"
|
||||||
>
|
>
|
||||||
<span>{{ user.Phone }}</span>
|
<span>{{ user.Phone }}</span>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="" style="position: relative" prop="UserName">
|
<el-form-item label="" style="position: relative" prop="Phone">
|
||||||
<el-input
|
<el-input
|
||||||
v-model="userForm.Phone"
|
v-model="userForm.Phone"
|
||||||
:placeholder="$t('trials:trials-myinfo:form:phone')"
|
:placeholder="$t('trials:trials-myinfo:form:phone')"
|
||||||
|
|
@ -51,14 +56,14 @@
|
||||||
size="small"
|
size="small"
|
||||||
@click="setNewPhone"
|
@click="setNewPhone"
|
||||||
>
|
>
|
||||||
{{ $t("trials:trials-myinfo:button:update") }}
|
{{ $t('trials:trials-myinfo:button:update') }}
|
||||||
</el-button>
|
</el-button>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<!-- 邮箱 -->
|
<!-- 邮箱 -->
|
||||||
<el-form-item
|
<el-form-item
|
||||||
:label="$t('trials:trials-myinfo:form:email')"
|
:label="$t('trials:trials-myinfo:form:email')"
|
||||||
style="margin-bottom: 5px"
|
style="margin-bottom: 5px"
|
||||||
prop="UserName"
|
prop="EMail"
|
||||||
>
|
>
|
||||||
<span>{{ user.EMail }}</span>
|
<span>{{ user.EMail }}</span>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
@ -100,7 +105,7 @@
|
||||||
size="small"
|
size="small"
|
||||||
@click="setNewEmail"
|
@click="setNewEmail"
|
||||||
>
|
>
|
||||||
{{ $t("trials:trials-myinfo:button:update") }}
|
{{ $t('trials:trials-myinfo:button:update') }}
|
||||||
</el-button>
|
</el-button>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-form>
|
</el-form>
|
||||||
|
|
@ -114,19 +119,19 @@ import {
|
||||||
setNewEmail,
|
setNewEmail,
|
||||||
setNewPhone,
|
setNewPhone,
|
||||||
setNewUserName,
|
setNewUserName,
|
||||||
} from "@/api/system/user.js";
|
} from '@/api/system/user.js'
|
||||||
import { removeToken } from "@/utils/auth";
|
import { removeToken } from '@/utils/auth'
|
||||||
import password from "./password.vue";
|
import password from './password.vue'
|
||||||
var timer = "";
|
var timer = ''
|
||||||
var countdown = 60;
|
var countdown = 60
|
||||||
export default {
|
export default {
|
||||||
name: "account",
|
name: 'account',
|
||||||
components: { password },
|
components: { password },
|
||||||
props: {
|
props: {
|
||||||
user: {
|
user: {
|
||||||
required: true,
|
required: true,
|
||||||
default: () => {
|
default: () => {
|
||||||
return {};
|
return {}
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
IsCanConnectInternet: {
|
IsCanConnectInternet: {
|
||||||
|
|
@ -138,108 +143,138 @@ export default {
|
||||||
return {
|
return {
|
||||||
userForm: {},
|
userForm: {},
|
||||||
sendDisabled: true,
|
sendDisabled: true,
|
||||||
sendTitle: this.$t("trials:trials-myinfo:button:getVCode"),
|
sendTitle: this.$t('trials:trials-myinfo:button:getVCode'),
|
||||||
};
|
rule: {
|
||||||
|
UserName: [
|
||||||
|
{
|
||||||
|
validator: (rule, value, callback) => {
|
||||||
|
if (!value) return callback()
|
||||||
|
var lang = zzSessionStorage.getItem('lang')
|
||||||
|
? zzSessionStorage.getItem('lang')
|
||||||
|
: 'zh'
|
||||||
|
/* eslint-disable */
|
||||||
|
var reg1 = /^[a-zA-Z0-9_]{4,16}$/ //密码必须是8位以上、必须含有字母、数字、特殊符号
|
||||||
|
if (!reg1.test(value)) {
|
||||||
|
callback(
|
||||||
|
lang === 'zh'
|
||||||
|
? new Error(
|
||||||
|
'1)用户名字符长度最小为4个字符,最大为16个字符,只可使用字母、数字、下划线;'
|
||||||
|
)
|
||||||
|
: new Error(
|
||||||
|
'the username must have:1) At least 4 characters;2) At most 16 characters;3)Only letters, numbers, and underscores are allowed.'
|
||||||
|
)
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
callback()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
trigger: 'blur',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
setNewEmail() {
|
setNewEmail() {
|
||||||
setNewEmail(this.userForm.EMail, this.userForm.VerificationCode).then(
|
setNewEmail(this.userForm.EMail, this.userForm.VerificationCode).then(
|
||||||
() => {
|
() => {
|
||||||
this.userForm.EMail = "";
|
this.userForm.EMail = ''
|
||||||
this.userForm.VerificationCode = "";
|
this.userForm.VerificationCode = ''
|
||||||
this.$message.success(
|
this.$message.success(
|
||||||
this.$t("trials:trials-myinfo:message:updateSuccessfully")
|
this.$t('trials:trials-myinfo:message:updateSuccessfully')
|
||||||
);
|
)
|
||||||
this.$emit("getUserInfo");
|
this.$emit('getUserInfo')
|
||||||
}
|
}
|
||||||
);
|
)
|
||||||
},
|
},
|
||||||
async setNewUserName() {
|
async setNewUserName() {
|
||||||
try {
|
try {
|
||||||
|
let validate = await this.$refs.userFormRef.validate()
|
||||||
|
if (!validate) return false
|
||||||
let confirm = await this.$confirm(
|
let confirm = await this.$confirm(
|
||||||
this.$t("trials:trials-myInfo:confirmMessage:updateUserName"),
|
this.$t('trials:trials-myInfo:confirmMessage:updateUserName'),
|
||||||
{
|
{
|
||||||
type: "warning",
|
type: 'warning',
|
||||||
distinguishCancelAndClose: true,
|
distinguishCancelAndClose: true,
|
||||||
confirmButtonText: this.$t("common:button:confirm"),
|
confirmButtonText: this.$t('common:button:confirm'),
|
||||||
cancelButtonText: this.$t("common:button:cancel"),
|
cancelButtonText: this.$t('common:button:cancel'),
|
||||||
}
|
}
|
||||||
);
|
)
|
||||||
if (confirm !== "confirm") return;
|
if (confirm !== 'confirm') return
|
||||||
let res = await setNewUserName(this.userForm.UserName);
|
let res = await setNewUserName(this.userForm.UserName)
|
||||||
if (res.IsSuccess) {
|
if (res.IsSuccess) {
|
||||||
this.userForm.UserName = "";
|
this.userForm.UserName = ''
|
||||||
this.$message.success(
|
this.$message.success(
|
||||||
this.$t("trials:trials-myinfo:message:updateSuccessfully")
|
this.$t('trials:trials-myinfo:message:updateSuccessfully')
|
||||||
);
|
)
|
||||||
this.$emit("getUserInfo");
|
this.$emit('getUserInfo')
|
||||||
removeToken();
|
removeToken()
|
||||||
this.logout();
|
this.logout()
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.log(err);
|
console.log(err)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
setNewPhone() {
|
setNewPhone() {
|
||||||
setNewPhone(this.userForm.Phone).then(() => {
|
setNewPhone(this.userForm.Phone).then(() => {
|
||||||
this.userForm.Phone = "";
|
this.userForm.Phone = ''
|
||||||
this.$message.success(
|
this.$message.success(
|
||||||
this.$t("trials:trials-myinfo:message:updateSuccessfully")
|
this.$t('trials:trials-myinfo:message:updateSuccessfully')
|
||||||
);
|
)
|
||||||
this.$emit("getUserInfo");
|
this.$emit('getUserInfo')
|
||||||
});
|
})
|
||||||
},
|
},
|
||||||
handleEmailChange() {
|
handleEmailChange() {
|
||||||
var reg =
|
var reg =
|
||||||
/^[A-Za-z0-9]+([_\.][A-Za-z0-9]+)*@([A-Za-z0-9\-]+\.)+[A-Za-z]{2,6}$/;
|
/^[A-Za-z0-9]+([_\.][A-Za-z0-9]+)*@([A-Za-z0-9\-]+\.)+[A-Za-z]{2,6}$/
|
||||||
if (this.userForm.EMail && reg.test(this.userForm.EMail)) {
|
if (this.userForm.EMail && reg.test(this.userForm.EMail)) {
|
||||||
this.sendDisabled = false;
|
this.sendDisabled = false
|
||||||
} else {
|
} else {
|
||||||
this.sendDisabled = true;
|
this.sendDisabled = true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
sendVerificationCode() {
|
sendVerificationCode() {
|
||||||
sendVerificationCode(this.userForm.EMail).then(() => {
|
sendVerificationCode(this.userForm.EMail).then(() => {
|
||||||
this.settime(this);
|
this.settime(this)
|
||||||
// 发送成功
|
// 发送成功
|
||||||
this.$message.success(
|
this.$message.success(
|
||||||
this.$t("trials:trials-myinfo:message:sendSuccessfully")
|
this.$t('trials:trials-myinfo:message:sendSuccessfully')
|
||||||
);
|
)
|
||||||
});
|
})
|
||||||
},
|
},
|
||||||
settime(obj) {
|
settime(obj) {
|
||||||
if (countdown === 0) {
|
if (countdown === 0) {
|
||||||
obj.sendDisabled = false;
|
obj.sendDisabled = false
|
||||||
obj.sendTitle = this.$t("trials:trials-myinfo:button:getVCode"); // '获取验证码'
|
obj.sendTitle = this.$t('trials:trials-myinfo:button:getVCode') // '获取验证码'
|
||||||
countdown = 60;
|
countdown = 60
|
||||||
clearTimeout(timer);
|
clearTimeout(timer)
|
||||||
return;
|
return
|
||||||
} else {
|
} else {
|
||||||
obj.sendDisabled = true;
|
obj.sendDisabled = true
|
||||||
obj.sendTitle = `${this.$t(
|
obj.sendTitle = `${this.$t(
|
||||||
"trials:trials-myinfo:button:wait"
|
'trials:trials-myinfo:button:wait'
|
||||||
)}(${countdown}s)`;
|
)}(${countdown}s)`
|
||||||
countdown--;
|
countdown--
|
||||||
// eslint-disable-next-line no-self-assign
|
// eslint-disable-next-line no-self-assign
|
||||||
countdown = countdown;
|
countdown = countdown
|
||||||
timer = setTimeout(function () {
|
timer = setTimeout(function () {
|
||||||
obj.settime(obj);
|
obj.settime(obj)
|
||||||
}, 1000);
|
}, 1000)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
async logout() {
|
async logout() {
|
||||||
/* eslint-disable */
|
/* eslint-disable */
|
||||||
var loginType = zzSessionStorage.getItem("loginType");
|
var loginType = zzSessionStorage.getItem('loginType')
|
||||||
await this.$store.dispatch("user/logout");
|
await this.$store.dispatch('user/logout')
|
||||||
if (loginType) {
|
if (loginType) {
|
||||||
this.$router.push(`/login?loginType=${loginType}`);
|
this.$router.push(`/login?loginType=${loginType}`)
|
||||||
} else {
|
} else {
|
||||||
this.$router.push(`/login`);
|
this.$router.push(`/login`)
|
||||||
}
|
}
|
||||||
this.$i18n.locale = "zh";
|
this.$i18n.locale = 'zh'
|
||||||
this.setLanguage("zh");
|
this.setLanguage('zh')
|
||||||
this.$updateDictionary();
|
this.$updateDictionary()
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
<div class="trial-myinfo-right-box">
|
<div class="trial-myinfo-right-box">
|
||||||
<div class="trial-myinfo-head">
|
<div class="trial-myinfo-head">
|
||||||
<!-- 修改密码 -->
|
<!-- 修改密码 -->
|
||||||
{{ $t("trials:trials-myinfo:title:updatePaasord") }}
|
{{ $t('trials:trials-myinfo:title:updatePaasord') }}
|
||||||
</div>
|
</div>
|
||||||
<el-form
|
<el-form
|
||||||
ref="passwordForm"
|
ref="passwordForm"
|
||||||
|
|
@ -52,17 +52,17 @@
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-form>
|
</el-form>
|
||||||
<el-button type="primary" size="small" class="trial-info-btn" @click="save">
|
<el-button type="primary" size="small" class="trial-info-btn" @click="save">
|
||||||
{{ $t("trials:trials-myinfo:button:save") }}
|
{{ $t('trials:trials-myinfo:button:save') }}
|
||||||
</el-button>
|
</el-button>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script>
|
<script>
|
||||||
import md5 from "js-md5";
|
import md5 from 'js-md5'
|
||||||
import { mapGetters, mapMutations } from "vuex";
|
import { mapGetters, mapMutations } from 'vuex'
|
||||||
import { modifyPassword } from "@/api/admin.js";
|
import { modifyPassword } from '@/api/admin.js'
|
||||||
import { removeToken } from "@/utils/auth";
|
import { removeToken } from '@/utils/auth'
|
||||||
export default {
|
export default {
|
||||||
name: "password",
|
name: 'password',
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
password: {},
|
password: {},
|
||||||
|
|
@ -70,91 +70,96 @@ export default {
|
||||||
OldPassWord: [
|
OldPassWord: [
|
||||||
{
|
{
|
||||||
required: true,
|
required: true,
|
||||||
message: this.$t("common:ruleMessage:specify"),
|
message: this.$t('common:ruleMessage:specify'),
|
||||||
trigger: "blur",
|
trigger: 'blur',
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
NewPassWord: [
|
NewPassWord: [
|
||||||
{
|
{
|
||||||
required: true,
|
required: true,
|
||||||
message: this.$t("common:ruleMessage:specify"),
|
message: this.$t('common:ruleMessage:specify'),
|
||||||
trigger: "blur",
|
trigger: 'blur',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
required: true,
|
required: true,
|
||||||
trigger: "blur",
|
trigger: 'blur',
|
||||||
validator: this.$validatePassword,
|
validator: this.$validatePassword,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
ConfirmPassWord: [
|
ConfirmPassWord: [
|
||||||
{
|
{
|
||||||
required: true,
|
required: true,
|
||||||
message: this.$t("common:ruleMessage:specify"),
|
message: this.$t('common:ruleMessage:specify'),
|
||||||
trigger: "blur",
|
trigger: 'blur',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
required: true,
|
required: true,
|
||||||
trigger: "blur",
|
trigger: 'blur',
|
||||||
validator: this.$validatePassword,
|
validator: this.$validatePassword,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
};
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
...mapGetters(["userId"]),
|
...mapGetters(['userId']),
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
...mapMutations({ setLanguage: "lang/setLanguage" }),
|
...mapMutations({ setLanguage: 'lang/setLanguage' }),
|
||||||
async save() {
|
async save() {
|
||||||
try {
|
try {
|
||||||
let validate = await this.$refs.passwordForm.validate();
|
let validate = await this.$refs.passwordForm.validate()
|
||||||
if (!validate) return;
|
if (!validate) return
|
||||||
if (this.password.NewPassWord !== this.password.ConfirmPassWord) {
|
if (this.password.NewPassWord !== this.password.ConfirmPassWord) {
|
||||||
this.$alert(this.$t("passwordReset:formRule:passwordsDiffer"));
|
this.$alert(this.$t('passwordReset:formRule:passwordsDiffer'))
|
||||||
return;
|
return
|
||||||
}
|
}
|
||||||
let confirm = await this.$confirm(
|
let confirm = await this.$confirm(
|
||||||
this.$t("trials:trials-myInfo:confirmMessage:updatePassWord"),
|
this.$t('trials:trials-myInfo:confirmMessage:updatePassWord'),
|
||||||
{
|
{
|
||||||
type: "warning",
|
type: 'warning',
|
||||||
distinguishCancelAndClose: true,
|
distinguishCancelAndClose: true,
|
||||||
confirmButtonText: this.$t("common:button:confirm"),
|
confirmButtonText: this.$t('common:button:confirm'),
|
||||||
cancelButtonText: this.$t("common:button:cancel"),
|
cancelButtonText: this.$t('common:button:cancel'),
|
||||||
}
|
}
|
||||||
);
|
)
|
||||||
if (confirm !== "confirm") return;
|
if (confirm !== 'confirm') return
|
||||||
const param = {
|
const param = {
|
||||||
UserId: this.userId,
|
UserId: this.userId,
|
||||||
NewPassWord: md5(this.password.NewPassWord),
|
NewPassWord: md5(this.password.NewPassWord),
|
||||||
OldPassWord: md5(this.password.OldPassWord),
|
OldPassWord: md5(this.password.OldPassWord),
|
||||||
};
|
}
|
||||||
let res = await modifyPassword(param);
|
let res = await modifyPassword(param)
|
||||||
if (res.IsSuccess) {
|
if (res.IsSuccess) {
|
||||||
// 修改成功,请重新登录账号
|
// 修改成功,请重新登录账号
|
||||||
this.$message.success(
|
this.$message.success(
|
||||||
this.$t("trials:trials-myinfo:message:modifyPWSuccessfully")
|
this.$t('trials:trials-myinfo:message:modifyPWSuccessfully')
|
||||||
);
|
)
|
||||||
removeToken();
|
removeToken()
|
||||||
this.logout();
|
this.logout()
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.log(err);
|
console.log(err)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
async logout() {
|
async logout() {
|
||||||
/* eslint-disable */
|
/* eslint-disable */
|
||||||
var loginType = zzSessionStorage.getItem("loginType");
|
var loginType = zzSessionStorage.getItem('loginType')
|
||||||
await this.$store.dispatch("user/logout");
|
await this.$store.dispatch('user/logout')
|
||||||
if (loginType) {
|
if (loginType) {
|
||||||
this.$router.push(`/login?loginType=${loginType}`);
|
this.$router.push(`/login?loginType=${loginType}`)
|
||||||
} else {
|
} else {
|
||||||
this.$router.push(`/login`);
|
this.$router.push(`/login`)
|
||||||
}
|
}
|
||||||
this.$i18n.locale = "zh";
|
this.$i18n.locale = 'zh'
|
||||||
this.setLanguage("zh");
|
this.setLanguage('zh')
|
||||||
this.$updateDictionary();
|
this.$updateDictionary()
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
}
|
||||||
</script>
|
</script>
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.el-form-item {
|
||||||
|
margin-bottom: 30px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
@ -5,7 +5,7 @@
|
||||||
<el-form :inline="true">
|
<el-form :inline="true">
|
||||||
<!-- 文件类型 -->
|
<!-- 文件类型 -->
|
||||||
<el-form-item :label="$t('trials:signRecords:table:fileType')">
|
<el-form-item :label="$t('trials:signRecords:table:fileType')">
|
||||||
<el-select v-model="searchData.FileTypeId" style="width: 150px">
|
<el-select v-model="searchData.FileTypeId" clearable style="width: 150px">
|
||||||
<el-option
|
<el-option
|
||||||
v-for="item of typeOptions"
|
v-for="item of typeOptions"
|
||||||
:key="item.FileTypeId"
|
:key="item.FileTypeId"
|
||||||
|
|
|
||||||
|
|
@ -8,12 +8,15 @@
|
||||||
size="small"
|
size="small"
|
||||||
label-width="100px"
|
label-width="100px"
|
||||||
>
|
>
|
||||||
|
|
||||||
<el-form-item
|
<el-form-item
|
||||||
:label="$t('common:form:sign:userName')"
|
:label="$t('common:form:sign:userName')"
|
||||||
prop="UserName"
|
prop="UserName"
|
||||||
:rules="[
|
:rules="[
|
||||||
{ required: true, message: $t('common:ruleMessage:specify'), trigger: 'blur' }
|
{
|
||||||
|
required: true,
|
||||||
|
message: $t('common:ruleMessage:specify'),
|
||||||
|
trigger: 'blur',
|
||||||
|
},
|
||||||
]"
|
]"
|
||||||
>
|
>
|
||||||
<el-input v-model="signForm.UserName" />
|
<el-input v-model="signForm.UserName" />
|
||||||
|
|
@ -22,18 +25,36 @@
|
||||||
:label="$t('common:form:sign:password')"
|
:label="$t('common:form:sign:password')"
|
||||||
prop="Password"
|
prop="Password"
|
||||||
:rules="[
|
:rules="[
|
||||||
{ required: true, message: $t('common:ruleMessage:specify'), trigger: 'blur' }
|
{
|
||||||
|
required: true,
|
||||||
|
message: $t('common:ruleMessage:specify'),
|
||||||
|
trigger: 'blur',
|
||||||
|
},
|
||||||
]"
|
]"
|
||||||
>
|
>
|
||||||
<el-input v-model="signForm.Password" show-password auto-complete="new-password" />
|
<el-input
|
||||||
|
v-model="signForm.Password"
|
||||||
|
show-password
|
||||||
|
auto-complete="new-password"
|
||||||
|
/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-form>
|
</el-form>
|
||||||
</div>
|
</div>
|
||||||
<div slot="footer" class="dialog-footer sign-form-footer">
|
<div slot="footer" class="dialog-footer sign-form-footer">
|
||||||
<el-button :disabled="btnLoading" size="small" type="primary" @click="handleclose">
|
<el-button
|
||||||
|
:disabled="btnLoading"
|
||||||
|
size="small"
|
||||||
|
type="primary"
|
||||||
|
@click="handleclose"
|
||||||
|
>
|
||||||
{{ $t('common:button:cancel') }}
|
{{ $t('common:button:cancel') }}
|
||||||
</el-button>
|
</el-button>
|
||||||
<el-button :loading="btnLoading" size="small" type="primary" @click="userConfirm">
|
<el-button
|
||||||
|
:loading="btnLoading"
|
||||||
|
size="small"
|
||||||
|
type="primary"
|
||||||
|
@click="userConfirm"
|
||||||
|
>
|
||||||
{{ $t('common:button:sign') }}
|
{{ $t('common:button:sign') }}
|
||||||
</el-button>
|
</el-button>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -49,35 +70,36 @@ export default {
|
||||||
props: {
|
props: {
|
||||||
fileName: {
|
fileName: {
|
||||||
type: String,
|
type: String,
|
||||||
required: true
|
required: true,
|
||||||
},
|
},
|
||||||
isSystemDoc: {
|
isSystemDoc: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
required: true
|
required: true,
|
||||||
},
|
},
|
||||||
documentId: {
|
documentId: {
|
||||||
type: String,
|
type: String,
|
||||||
required: true
|
required: true,
|
||||||
},
|
},
|
||||||
trialId: {
|
trialId: {
|
||||||
type: String,
|
type: String,
|
||||||
default: ''
|
default: '',
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
signForm: {
|
signForm: {
|
||||||
UserName: '',
|
UserName: '',
|
||||||
Password: ''
|
Password: '',
|
||||||
},
|
},
|
||||||
signText: '',
|
signText: '',
|
||||||
btnLoading: false,
|
btnLoading: false,
|
||||||
loading: false
|
loading: false,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
this.loading = true
|
this.loading = true
|
||||||
getSystemBasicData(attachmentSignCode).then(res => {
|
getSystemBasicData(attachmentSignCode)
|
||||||
|
.then((res) => {
|
||||||
var text
|
var text
|
||||||
if (this.$i18n.locale === 'zh') {
|
if (this.$i18n.locale === 'zh') {
|
||||||
text = res.Result.ValueCN
|
text = res.Result.ValueCN
|
||||||
|
|
@ -86,11 +108,16 @@ export default {
|
||||||
}
|
}
|
||||||
this.signText = text.replace('xxx', this.fileName)
|
this.signText = text.replace('xxx', this.fileName)
|
||||||
this.loading = false
|
this.loading = false
|
||||||
}).catch(() => { this.loading = false })
|
})
|
||||||
|
.catch(() => {
|
||||||
|
this.loading = false
|
||||||
|
})
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
userConfirm() {
|
userConfirm() {
|
||||||
const currentUser = zzSessionStorage.getItem('userName').toLocaleLowerCase()
|
const currentUser = zzSessionStorage
|
||||||
|
.getItem('userName')
|
||||||
|
.toLocaleLowerCase()
|
||||||
this.$refs.signForm.validate((valid) => {
|
this.$refs.signForm.validate((valid) => {
|
||||||
console.log(valid)
|
console.log(valid)
|
||||||
if (!valid) return
|
if (!valid) return
|
||||||
|
|
@ -102,33 +129,41 @@ export default {
|
||||||
this.btnLoading = true
|
this.btnLoading = true
|
||||||
var params = {
|
var params = {
|
||||||
data: {
|
data: {
|
||||||
trialId: this.trialId,
|
// trialId: this.trialId,
|
||||||
documentId: this.documentId,
|
documentId: this.documentId,
|
||||||
isSystemDoc: this.isSystemDoc
|
isSystemDoc: this.isSystemDoc,
|
||||||
},
|
},
|
||||||
signInfo: {
|
signInfo: {
|
||||||
UserName: this.signForm.UserName,
|
UserName: this.signForm.UserName,
|
||||||
PassWord: md5(this.signForm.Password),
|
PassWord: md5(this.signForm.Password),
|
||||||
TrialId: this.trialId,
|
// c: this.trialId,
|
||||||
SignCode: '',
|
SignCode: '',
|
||||||
SignText: this.signText,
|
SignText: this.signText,
|
||||||
SignCodeId: '',
|
SignCodeId: '',
|
||||||
SubjectVisitId: ''
|
SubjectVisitId: '',
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
if (!this.isSystemDoc) {
|
||||||
|
params.data.TrialId = this.trialId
|
||||||
|
params.signInfo.TrialId = this.trialId
|
||||||
}
|
}
|
||||||
userConfirm(params).then(res => {
|
userConfirm(params)
|
||||||
|
.then((res) => {
|
||||||
if (res.IsSuccess) {
|
if (res.IsSuccess) {
|
||||||
// 签名成功!
|
// 签名成功!
|
||||||
this.$message.success(this.$t('common:message:signSuccessfully'))
|
this.$message.success(this.$t('common:message:signSuccessfully'))
|
||||||
this.$emit('closeDialog', true)
|
this.$emit('closeDialog', true)
|
||||||
}
|
}
|
||||||
}).catch(() => { this.btnLoading = false })
|
})
|
||||||
|
.catch(() => {
|
||||||
|
this.btnLoading = false
|
||||||
|
})
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
handleclose() {
|
handleclose() {
|
||||||
this.$emit('closeDialog', false)
|
this.$emit('closeDialog', false)
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@
|
||||||
<el-form-item :label="$t('trials:self-attachment:table:fileType')">
|
<el-form-item :label="$t('trials:self-attachment:table:fileType')">
|
||||||
<el-select
|
<el-select
|
||||||
v-model="searchData.FileTypeId"
|
v-model="searchData.FileTypeId"
|
||||||
|
clearable
|
||||||
style="width:150px;"
|
style="width:150px;"
|
||||||
>
|
>
|
||||||
<el-option
|
<el-option
|
||||||
|
|
|
||||||
|
|
@ -32,7 +32,15 @@
|
||||||
v-if="!hasPermi(['role:ea'])"
|
v-if="!hasPermi(['role:ea'])"
|
||||||
>
|
>
|
||||||
<template slot-scope="scope">
|
<template slot-scope="scope">
|
||||||
<el-button type="text" @click="go(`/trialsResume?doctorId=${scope.row.DoctorId}&token=${token}`)">{{ scope.row.LastName }} / {{ scope.row.FirstName }}</el-button>
|
<el-button
|
||||||
|
type="text"
|
||||||
|
@click="
|
||||||
|
go(
|
||||||
|
`/trialsResume?doctorId=${scope.row.DoctorId}&token=${token}`
|
||||||
|
)
|
||||||
|
"
|
||||||
|
>{{ scope.row.LastName }} / {{ scope.row.FirstName }}</el-button
|
||||||
|
>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<!-- Name CN -->
|
<!-- Name CN -->
|
||||||
|
|
@ -61,7 +69,11 @@
|
||||||
show-overflow-tooltip
|
show-overflow-tooltip
|
||||||
>
|
>
|
||||||
<template slot-scope="scope">
|
<template slot-scope="scope">
|
||||||
{{ scope.row.EnrollTime?moment(scope.row.EnrollTime).format('YYYY-MM-DD'):'' }}
|
{{
|
||||||
|
scope.row.EnrollTime
|
||||||
|
? moment(scope.row.EnrollTime).format('YYYY-MM-DD')
|
||||||
|
: ''
|
||||||
|
}}
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column
|
<el-table-column
|
||||||
|
|
@ -78,8 +90,16 @@
|
||||||
:inactive-value="false"
|
:inactive-value="false"
|
||||||
:active-text="$fd('IsEnable', true)"
|
:active-text="$fd('IsEnable', true)"
|
||||||
:inactive-text="$fd('IsEnable', false)"
|
:inactive-text="$fd('IsEnable', false)"
|
||||||
@change="(v) => {return isEnableChange(scope.row, v)}"
|
@change="
|
||||||
:disabled="!hasPermi(['trials:trials-panel:enrolled-reviewers:list:edit'])"
|
(v) => {
|
||||||
|
return isEnableChange(scope.row, v)
|
||||||
|
}
|
||||||
|
"
|
||||||
|
:disabled="
|
||||||
|
!hasPermi([
|
||||||
|
'trials:trials-panel:enrolled-reviewers:list:edit',
|
||||||
|
])
|
||||||
|
"
|
||||||
/>
|
/>
|
||||||
<!-- <span :style="{color:scope.row.IsEnable?'#409eff':'#dcdfe6'}"> {{$fd('IsEnable', scope.row.IsEnable)}}</span> -->
|
<!-- <span :style="{color:scope.row.IsEnable?'#409eff':'#dcdfe6'}"> {{$fd('IsEnable', scope.row.IsEnable)}}</span> -->
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -98,16 +118,46 @@
|
||||||
width="300"
|
width="300"
|
||||||
>
|
>
|
||||||
<template slot-scope="scope">
|
<template slot-scope="scope">
|
||||||
<span v-for="item of scope.row.CriterionCategoryList.find(v => {return v.TrialReadingCriterionId === ite.TrialReadingCriterionId}) ? scope.row.CriterionCategoryList.find(v => {return v.TrialReadingCriterionId === ite.TrialReadingCriterionId}).ReadingCategorys : []" :key="item.TrialReadingCriterionId" style="margin:5px 5px 5px 0;">
|
<span
|
||||||
<el-tag v-if="item === 1" type="primary">{{ $fd('ReadingCategory', item) + ' & ' + $fd('ReadingCategory', 2) }}</el-tag>
|
v-for="item of scope.row.CriterionCategoryList.find((v) => {
|
||||||
|
return (
|
||||||
|
v.TrialReadingCriterionId === ite.TrialReadingCriterionId
|
||||||
|
)
|
||||||
|
})
|
||||||
|
? scope.row.CriterionCategoryList.find((v) => {
|
||||||
|
return (
|
||||||
|
v.TrialReadingCriterionId ===
|
||||||
|
ite.TrialReadingCriterionId
|
||||||
|
)
|
||||||
|
}).ReadingCategorys
|
||||||
|
: []"
|
||||||
|
:key="item.TrialReadingCriterionId"
|
||||||
|
style="margin: 5px 5px 5px 0"
|
||||||
|
>
|
||||||
|
<el-tag v-if="item === 1" type="primary">{{
|
||||||
|
$fd('ReadingCategory', item) +
|
||||||
|
' & ' +
|
||||||
|
$fd('ReadingCategory', 2)
|
||||||
|
}}</el-tag>
|
||||||
<!-- <el-tag v-if="item === 2" type="info">{{ $fd('ReadingCategory', item) }}</el-tag>-->
|
<!-- <el-tag v-if="item === 2" type="info">{{ $fd('ReadingCategory', item) }}</el-tag>-->
|
||||||
<el-tag v-if="item === 4" type="danger">{{ $fd('ReadingCategory', item) }}</el-tag>
|
<el-tag v-if="item === 4" type="danger">{{
|
||||||
<el-tag v-if="item === 5" type="warning">{{ $fd('ReadingCategory', item) }}</el-tag>
|
$fd('ReadingCategory', item)
|
||||||
|
}}</el-tag>
|
||||||
|
<el-tag v-if="item === 5" type="warning">{{
|
||||||
|
$fd('ReadingCategory', item)
|
||||||
|
}}</el-tag>
|
||||||
</span>
|
</span>
|
||||||
<el-button
|
<el-button
|
||||||
v-hasPermi="['trials:trials-panel:enrolled-reviewers:list:edit']"
|
v-hasPermi="[
|
||||||
|
'trials:trials-panel:enrolled-reviewers:list:edit',
|
||||||
|
]"
|
||||||
type="text"
|
type="text"
|
||||||
@click="openSetEnrollReadingCategory(scope.row, ite.TrialReadingCriterionId)"
|
@click="
|
||||||
|
openSetEnrollReadingCategory(
|
||||||
|
scope.row,
|
||||||
|
ite.TrialReadingCriterionId
|
||||||
|
)
|
||||||
|
"
|
||||||
>
|
>
|
||||||
{{ $t('trials:enrolledReviews:button:config') }}
|
{{ $t('trials:enrolledReviews:button:config') }}
|
||||||
</el-button>
|
</el-button>
|
||||||
|
|
@ -120,13 +170,27 @@
|
||||||
>
|
>
|
||||||
<template slot-scope="scope">
|
<template slot-scope="scope">
|
||||||
<el-switch
|
<el-switch
|
||||||
v-model="scope.row.CriterionCategoryList.find(v => {return v.TrialReadingCriterionId === ite.TrialReadingCriterionId}).IsJoinAnalysis"
|
v-model="
|
||||||
|
scope.row.CriterionCategoryList.find((v) => {
|
||||||
|
return (
|
||||||
|
v.TrialReadingCriterionId === ite.TrialReadingCriterionId
|
||||||
|
)
|
||||||
|
}).IsJoinAnalysis
|
||||||
|
"
|
||||||
:active-value="true"
|
:active-value="true"
|
||||||
:inactive-value="false"
|
:inactive-value="false"
|
||||||
:active-text="$fd('YesOrNo', true)"
|
:active-text="$fd('YesOrNo', true)"
|
||||||
:inactive-text="$fd('YesOrNo', false)"
|
:inactive-text="$fd('YesOrNo', false)"
|
||||||
@change="(v) => {return isConsistencyChange(scope.row, ite, v, true)}"
|
@change="
|
||||||
:disabled="!hasPermi(['trials:trials-panel:enrolled-reviewers:list:edit'])"
|
(v) => {
|
||||||
|
return isConsistencyChange(scope.row, ite, v, true)
|
||||||
|
}
|
||||||
|
"
|
||||||
|
:disabled="
|
||||||
|
!hasPermi([
|
||||||
|
'trials:trials-panel:enrolled-reviewers:list:edit',
|
||||||
|
])
|
||||||
|
"
|
||||||
/>
|
/>
|
||||||
<!-- <span v-if="scope.row.CriterionCategoryList.find(v => {return v.TrialReadingCriterionId === ite.TrialReadingCriterionId}).IsJoinAnalysis"> {{$fd('YesOrNo', scope.row.CriterionCategoryList.find(v => {return v.TrialReadingCriterionId === ite.TrialReadingCriterionId}).IsJoinAnalysis)}}</span>
|
<!-- <span v-if="scope.row.CriterionCategoryList.find(v => {return v.TrialReadingCriterionId === ite.TrialReadingCriterionId}).IsJoinAnalysis"> {{$fd('YesOrNo', scope.row.CriterionCategoryList.find(v => {return v.TrialReadingCriterionId === ite.TrialReadingCriterionId}).IsJoinAnalysis)}}</span>
|
||||||
<span v-else> {{$fd('YesOrNo',false)}}</span> -->
|
<span v-else> {{$fd('YesOrNo',false)}}</span> -->
|
||||||
|
|
@ -138,8 +202,20 @@
|
||||||
show-overflow-tooltip
|
show-overflow-tooltip
|
||||||
>
|
>
|
||||||
<template slot-scope="scope">
|
<template slot-scope="scope">
|
||||||
<div v-if="scope.row.CriterionCategoryList.find(v => {return v.TrialReadingCriterionId === ite.TrialReadingCriterionId}).StatementCriterionFileList.length > 0">
|
<div
|
||||||
<el-button type="text" @click="preview(scope.row,ite.TrialReadingCriterionId)">View</el-button>
|
v-if="
|
||||||
|
scope.row.CriterionCategoryList.find((v) => {
|
||||||
|
return (
|
||||||
|
v.TrialReadingCriterionId === ite.TrialReadingCriterionId
|
||||||
|
)
|
||||||
|
}).StatementCriterionFileList.length > 0
|
||||||
|
"
|
||||||
|
>
|
||||||
|
<el-button
|
||||||
|
type="text"
|
||||||
|
@click="preview(scope.row, ite.TrialReadingCriterionId)"
|
||||||
|
>View</el-button
|
||||||
|
>
|
||||||
<!-- <el-button type="text" @click="windowOpen(scope.row.CriterionCategoryList.find(v => {return v.TrialReadingCriterionId === ite.TrialReadingCriterionId}).StatementCriterionFileList[0].FilePath)">View</el-button> -->
|
<!-- <el-button type="text" @click="windowOpen(scope.row.CriterionCategoryList.find(v => {return v.TrialReadingCriterionId === ite.TrialReadingCriterionId}).StatementCriterionFileList[0].FilePath)">View</el-button> -->
|
||||||
</div>
|
</div>
|
||||||
<div v-else>
|
<div v-else>
|
||||||
|
|
@ -147,10 +223,19 @@
|
||||||
<!-- 上传 -->
|
<!-- 上传 -->
|
||||||
<el-button
|
<el-button
|
||||||
v-if="ite.CriterionType === 0"
|
v-if="ite.CriterionType === 0"
|
||||||
v-hasPermi="['trials:trials-panel:enrolled-reviewers:list:edit']"
|
v-hasPermi="[
|
||||||
|
'trials:trials-panel:enrolled-reviewers:list:edit',
|
||||||
|
]"
|
||||||
type="text"
|
type="text"
|
||||||
style="margin-left: 10px"
|
style="margin-left: 10px"
|
||||||
@click="addCol(0, scope.row, ite, $t('trials:enrolledReviews:message:SOW'))"
|
@click="
|
||||||
|
addCol(
|
||||||
|
0,
|
||||||
|
scope.row,
|
||||||
|
ite,
|
||||||
|
$t('trials:enrolledReviews:message:SOW')
|
||||||
|
)
|
||||||
|
"
|
||||||
>
|
>
|
||||||
{{ $t('trials:enrolledReviews:button:upload') }}
|
{{ $t('trials:enrolledReviews:button:upload') }}
|
||||||
</el-button>
|
</el-button>
|
||||||
|
|
@ -163,18 +248,40 @@
|
||||||
show-overflow-tooltip
|
show-overflow-tooltip
|
||||||
>
|
>
|
||||||
<template slot-scope="scope">
|
<template slot-scope="scope">
|
||||||
<div v-if="scope.row.CriterionCategoryList.find(v => {return v.TrialReadingCriterionId === ite.TrialReadingCriterionId}).AcknowledgementCriterionFileList.length > 0">
|
<div
|
||||||
<el-button type="text" @click="windowOpen(scope.row.CriterionCategoryList.find(v => {return v.TrialReadingCriterionId === ite.TrialReadingCriterionId}).AcknowledgementCriterionFileList[0].FilePath)">View</el-button>
|
v-if="
|
||||||
|
scope.row.CriterionCategoryList.find((v) => {
|
||||||
|
return (
|
||||||
|
v.TrialReadingCriterionId === ite.TrialReadingCriterionId
|
||||||
|
)
|
||||||
|
}).AcknowledgementCriterionFileList.length > 0
|
||||||
|
"
|
||||||
|
>
|
||||||
|
<el-button
|
||||||
|
type="text"
|
||||||
|
@click="preview(scope.row, ite.TrialReadingCriterionId)"
|
||||||
|
>
|
||||||
|
View
|
||||||
|
</el-button>
|
||||||
</div>
|
</div>
|
||||||
<div v-else>
|
<div v-else>
|
||||||
<span>{{ $t('trials:enrolledReviews:label:notUpload') }}</span>
|
<span>{{ $t('trials:enrolledReviews:label:notUpload') }}</span>
|
||||||
<!-- 上传 -->
|
<!-- 上传 -->
|
||||||
<el-button
|
<el-button
|
||||||
v-if="ite.CriterionType === 0"
|
v-if="ite.CriterionType === 0"
|
||||||
v-hasPermi="['trials:trials-panel:enrolled-reviewers:list:edit']"
|
v-hasPermi="[
|
||||||
|
'trials:trials-panel:enrolled-reviewers:list:edit',
|
||||||
|
]"
|
||||||
type="text"
|
type="text"
|
||||||
style="margin-left: 10px"
|
style="margin-left: 10px"
|
||||||
@click="addCol(1, scope.row, ite, $t('trials:enrolledReviews:message:SOW'))"
|
@click="
|
||||||
|
addCol(
|
||||||
|
1,
|
||||||
|
scope.row,
|
||||||
|
ite,
|
||||||
|
$t('trials:enrolledReviews:message:SOW')
|
||||||
|
)
|
||||||
|
"
|
||||||
>
|
>
|
||||||
{{ $t('trials:enrolledReviews:button:upload') }}
|
{{ $t('trials:enrolledReviews:button:upload') }}
|
||||||
</el-button>
|
</el-button>
|
||||||
|
|
@ -188,16 +295,33 @@
|
||||||
>
|
>
|
||||||
<template slot-scope="scope">
|
<template slot-scope="scope">
|
||||||
<div>
|
<div>
|
||||||
{{ scope.row.CriterionCategoryList.find(v => {return v.TrialReadingCriterionId === ite.TrialReadingCriterionId}).PendingCount }}
|
{{
|
||||||
|
scope.row.CriterionCategoryList.find((v) => {
|
||||||
|
return (
|
||||||
|
v.TrialReadingCriterionId === ite.TrialReadingCriterionId
|
||||||
|
)
|
||||||
|
}).PendingCount
|
||||||
|
}}
|
||||||
/
|
/
|
||||||
{{ scope.row.CriterionCategoryList.find(v => {return v.TrialReadingCriterionId === ite.TrialReadingCriterionId}).ComplectedCount }}
|
{{
|
||||||
|
scope.row.CriterionCategoryList.find((v) => {
|
||||||
|
return (
|
||||||
|
v.TrialReadingCriterionId === ite.TrialReadingCriterionId
|
||||||
|
)
|
||||||
|
}).ComplectedCount
|
||||||
|
}}
|
||||||
/
|
/
|
||||||
{{ scope.row.CriterionCategoryList.find(v => {return v.TrialReadingCriterionId === ite.TrialReadingCriterionId}).TotalCount }}
|
{{
|
||||||
|
scope.row.CriterionCategoryList.find((v) => {
|
||||||
|
return (
|
||||||
|
v.TrialReadingCriterionId === ite.TrialReadingCriterionId
|
||||||
|
)
|
||||||
|
}).TotalCount
|
||||||
|
}}
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
|
|
||||||
</el-table>
|
</el-table>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|
@ -258,21 +382,38 @@
|
||||||
allow-create
|
allow-create
|
||||||
multiple
|
multiple
|
||||||
default-first-option
|
default-first-option
|
||||||
style="width: 50%;"
|
style="width: 50%"
|
||||||
>
|
>
|
||||||
<template v-for="item of $d.ReadingCategory">
|
<template v-for="item of $d.ReadingCategory">
|
||||||
<el-option v-if="item.value === 1" :key="item.id" :value="1" :label="$fd('ReadingCategory', 1) + ' & ' + $fd('ReadingCategory', 2)" />
|
<el-option
|
||||||
|
v-if="item.value === 1"
|
||||||
|
:key="item.id"
|
||||||
|
:value="1"
|
||||||
|
:label="
|
||||||
|
$fd('ReadingCategory', 1) + ' & ' + $fd('ReadingCategory', 2)
|
||||||
|
"
|
||||||
|
/>
|
||||||
</template>
|
</template>
|
||||||
<template v-for="item of $d.ReadingCategory">
|
<template v-for="item of $d.ReadingCategory">
|
||||||
<el-option v-if="item.value === 4 && IsArbitrationReading" :key="item.id" :value="item.value" :label="$fd('ReadingCategory', 4)" />
|
<el-option
|
||||||
|
v-if="item.value === 4 && IsArbitrationReading"
|
||||||
|
:key="item.id"
|
||||||
|
:value="item.value"
|
||||||
|
:label="$fd('ReadingCategory', 4)"
|
||||||
|
/>
|
||||||
</template>
|
</template>
|
||||||
<template v-for="item of $d.ReadingCategory">
|
<template v-for="item of $d.ReadingCategory">
|
||||||
<el-option v-if="item.value === 5 && IsOncologyReading" :key="item.id" :value="item.value" :label="$fd('ReadingCategory', 5)" />
|
<el-option
|
||||||
|
v-if="item.value === 5 && IsOncologyReading"
|
||||||
|
:key="item.id"
|
||||||
|
:value="item.value"
|
||||||
|
:label="$fd('ReadingCategory', 5)"
|
||||||
|
/>
|
||||||
</template>
|
</template>
|
||||||
</el-select>
|
</el-select>
|
||||||
</template>
|
</template>
|
||||||
<template slot="dialog-footer">
|
<template slot="dialog-footer">
|
||||||
<div style="margin-top:30px;">
|
<div style="margin-top: 30px">
|
||||||
<el-button
|
<el-button
|
||||||
:disabled="readingCategory_model.btnLoading"
|
:disabled="readingCategory_model.btnLoading"
|
||||||
type="primary"
|
type="primary"
|
||||||
|
|
@ -298,13 +439,19 @@
|
||||||
:model="updateStatusForm"
|
:model="updateStatusForm"
|
||||||
:rules="updateStatusFormrules"
|
:rules="updateStatusFormrules"
|
||||||
>
|
>
|
||||||
<el-form-item :label="$t('trials:enrolledReviews:label:enrollmentStatus')" prop="Status">
|
<el-form-item
|
||||||
<el-select
|
:label="$t('trials:enrolledReviews:label:enrollmentStatus')"
|
||||||
v-model="updateStatusForm.Status"
|
prop="Status"
|
||||||
style="width:60%;"
|
|
||||||
>
|
>
|
||||||
|
<el-select v-model="updateStatusForm.Status" style="width: 60%">
|
||||||
<!-- 0:回退;1:出组; -->
|
<!-- 0:回退;1:出组; -->
|
||||||
<el-option v-for="item of $d.OutOrInEnrollment" :key="`OutOrInEnrollment${item.value}`" :value="item.value" :label="item.label" :disabled="item.value === 0 && currentWorkload>0" />
|
<el-option
|
||||||
|
v-for="item of $d.OutOrInEnrollment"
|
||||||
|
:key="`OutOrInEnrollment${item.value}`"
|
||||||
|
:value="item.value"
|
||||||
|
:label="item.label"
|
||||||
|
:disabled="item.value === 0 && currentWorkload > 0"
|
||||||
|
/>
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item
|
<el-form-item
|
||||||
|
|
@ -346,10 +493,16 @@
|
||||||
label-width="120px"
|
label-width="120px"
|
||||||
size="small"
|
size="small"
|
||||||
>
|
>
|
||||||
<el-form-item :label="$t('trials:enrolledReviews:table:criterionName')" prop="CriterionType">
|
<el-form-item
|
||||||
|
:label="$t('trials:enrolledReviews:table:criterionName')"
|
||||||
|
prop="CriterionType"
|
||||||
|
>
|
||||||
<el-input v-model="form.CriterionName" disabled />
|
<el-input v-model="form.CriterionName" disabled />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item :label="$t('trials:enrolledReviews:table:file')" prop="FilePath">
|
<el-form-item
|
||||||
|
:label="$t('trials:enrolledReviews:table:file')"
|
||||||
|
prop="FilePath"
|
||||||
|
>
|
||||||
<el-upload
|
<el-upload
|
||||||
class="upload-demo"
|
class="upload-demo"
|
||||||
action
|
action
|
||||||
|
|
@ -358,19 +511,35 @@
|
||||||
:on-preview="handlePreview2"
|
:on-preview="handlePreview2"
|
||||||
:on-remove="handleRemoveFile2"
|
:on-remove="handleRemoveFile2"
|
||||||
:show-file-list="true"
|
:show-file-list="true"
|
||||||
|
accept=".pdf"
|
||||||
:limit="1"
|
:limit="1"
|
||||||
:file-list="fileList"
|
:file-list="fileList"
|
||||||
>
|
>
|
||||||
<el-button size="small" type="primary" :disabled="fileList.length > 0">{{$t('common:button:upload')}}</el-button>
|
<el-button
|
||||||
|
size="small"
|
||||||
|
type="primary"
|
||||||
|
:disabled="fileList.length > 0"
|
||||||
|
>{{ $t('common:button:upload') }}</el-button
|
||||||
|
>
|
||||||
</el-upload>
|
</el-upload>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-form>
|
</el-form>
|
||||||
</template>
|
</template>
|
||||||
<template slot="dialog-footer">
|
<template slot="dialog-footer">
|
||||||
<el-button :disabled="btnLoading" size="small" type="primary" @click="handleCancle">
|
<el-button
|
||||||
|
:disabled="btnLoading"
|
||||||
|
size="small"
|
||||||
|
type="primary"
|
||||||
|
@click="handleCancle"
|
||||||
|
>
|
||||||
{{ $t('common:button:cancel') }}
|
{{ $t('common:button:cancel') }}
|
||||||
</el-button>
|
</el-button>
|
||||||
<el-button size="small" type="primary" :loading="btnLoading" @click="handleSave">
|
<el-button
|
||||||
|
size="small"
|
||||||
|
type="primary"
|
||||||
|
:loading="btnLoading"
|
||||||
|
@click="handleSave"
|
||||||
|
>
|
||||||
{{ $t('common:button:save') }}
|
{{ $t('common:button:save') }}
|
||||||
</el-button>
|
</el-button>
|
||||||
</template>
|
</template>
|
||||||
|
|
@ -384,7 +553,7 @@ import {
|
||||||
updateReviewerReadingType,
|
updateReviewerReadingType,
|
||||||
enrollBackOrOut,
|
enrollBackOrOut,
|
||||||
setEnrollReadingCategory,
|
setEnrollReadingCategory,
|
||||||
batchSetCriterionJoinJoinAnalysis
|
batchSetCriterionJoinJoinAnalysis,
|
||||||
} from '@/api/trials'
|
} from '@/api/trials'
|
||||||
import { addDoctorCriterionFile } from '@/api/reviewers'
|
import { addDoctorCriterionFile } from '@/api/reviewers'
|
||||||
import { uploadFile } from '@/api/attachment'
|
import { uploadFile } from '@/api/attachment'
|
||||||
|
|
@ -405,7 +574,7 @@ export default {
|
||||||
PageIndex: 1,
|
PageIndex: 1,
|
||||||
PageSize: 100,
|
PageSize: 100,
|
||||||
Asc: false,
|
Asc: false,
|
||||||
SortField: ''
|
SortField: '',
|
||||||
},
|
},
|
||||||
doctorId: '',
|
doctorId: '',
|
||||||
currentRow: {},
|
currentRow: {},
|
||||||
|
|
@ -415,41 +584,59 @@ export default {
|
||||||
currentClickRowData: '',
|
currentClickRowData: '',
|
||||||
btnLoading: false,
|
btnLoading: false,
|
||||||
readingType: '',
|
readingType: '',
|
||||||
model_cfg: { visible: false, showClose: true, width: '600px', title: '', appendToBody: true },
|
model_cfg: {
|
||||||
|
visible: false,
|
||||||
|
showClose: true,
|
||||||
|
width: '600px',
|
||||||
|
title: '',
|
||||||
|
appendToBody: true,
|
||||||
|
},
|
||||||
sow_model: {
|
sow_model: {
|
||||||
visible: false,
|
visible: false,
|
||||||
title: this.$t('trials:enrolledReviews:dialogTitle:signedAckOfSow'),
|
title: this.$t('trials:enrolledReviews:dialogTitle:signedAckOfSow'),
|
||||||
showClose: true,
|
showClose: true,
|
||||||
width: '500px'
|
width: '500px',
|
||||||
},
|
},
|
||||||
readingType_model: {
|
readingType_model: {
|
||||||
visible: false,
|
visible: false,
|
||||||
title: this.$t('trials:enrolledReviews:dialogTitle:changeReadingType'),
|
title: this.$t('trials:enrolledReviews:dialogTitle:changeReadingType'),
|
||||||
showClose: true,
|
showClose: true,
|
||||||
width: '500px',
|
width: '500px',
|
||||||
btnLoading: false
|
btnLoading: false,
|
||||||
},
|
},
|
||||||
readingCategory_model: {
|
readingCategory_model: {
|
||||||
visible: false,
|
visible: false,
|
||||||
title: this.$t('trials:enrolledReviews:dialogTitle:changeReadingType'),
|
title: this.$t('trials:enrolledReviews:dialogTitle:changeReadingType'),
|
||||||
showClose: true,
|
showClose: true,
|
||||||
width: '600px',
|
width: '600px',
|
||||||
btnLoading: false
|
btnLoading: false,
|
||||||
},
|
},
|
||||||
reviewerStatus_model: {
|
reviewerStatus_model: {
|
||||||
visible: false,
|
visible: false,
|
||||||
title: this.$t('trials:enrolledReviews:dialogTitle:changeStatus'),
|
title: this.$t('trials:enrolledReviews:dialogTitle:changeStatus'),
|
||||||
showClose: true,
|
showClose: true,
|
||||||
width: '500px',
|
width: '500px',
|
||||||
btnLoading: false
|
btnLoading: false,
|
||||||
},
|
},
|
||||||
updateStatusForm: {
|
updateStatusForm: {
|
||||||
Status: '',
|
Status: '',
|
||||||
OutEnrollmentTime: ''
|
OutEnrollmentTime: '',
|
||||||
},
|
},
|
||||||
updateStatusFormrules: {
|
updateStatusFormrules: {
|
||||||
Status: [{ required: true, message: this.$t('common:ruleMessage:select'), trigger: ['blur', 'change'] }],
|
Status: [
|
||||||
OutEnrollmentTime: [{ required: true, message: this.$t('common:ruleMessage:select'), trigger: ['blur', 'change'] }]
|
{
|
||||||
|
required: true,
|
||||||
|
message: this.$t('common:ruleMessage:select'),
|
||||||
|
trigger: ['blur', 'change'],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
OutEnrollmentTime: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: this.$t('common:ruleMessage:select'),
|
||||||
|
trigger: ['blur', 'change'],
|
||||||
|
},
|
||||||
|
],
|
||||||
},
|
},
|
||||||
token: store.getters.token,
|
token: store.getters.token,
|
||||||
ReadingCategorys: [],
|
ReadingCategorys: [],
|
||||||
|
|
@ -460,15 +647,25 @@ export default {
|
||||||
fileList: [],
|
fileList: [],
|
||||||
form: {},
|
form: {},
|
||||||
rowData: {},
|
rowData: {},
|
||||||
moment
|
moment,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
currentWorkload() {
|
currentWorkload() {
|
||||||
if (Object.keys(this.currentRow).length === 0) return 0
|
if (Object.keys(this.currentRow).length === 0) return 0
|
||||||
var total = this.currentRow.Adjudication + this.currentRow.AdjudicationIn24H + this.currentRow.AdjudicationIn48H + this.currentRow.Timepoint + this.currentRow.TimepointIn24H + this.currentRow.TimepointIn48H + this.currentRow.TrainingTimes + this.currentRow.RefresherTraining + this.currentRow.Global + this.currentRow.Downtime
|
var total =
|
||||||
|
this.currentRow.Adjudication +
|
||||||
|
this.currentRow.AdjudicationIn24H +
|
||||||
|
this.currentRow.AdjudicationIn48H +
|
||||||
|
this.currentRow.Timepoint +
|
||||||
|
this.currentRow.TimepointIn24H +
|
||||||
|
this.currentRow.TimepointIn48H +
|
||||||
|
this.currentRow.TrainingTimes +
|
||||||
|
this.currentRow.RefresherTraining +
|
||||||
|
this.currentRow.Global +
|
||||||
|
this.currentRow.Downtime
|
||||||
return total
|
return total
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
this.trialId = this.$route.query.trialCode
|
this.trialId = this.$route.query.trialCode
|
||||||
|
|
@ -478,13 +675,15 @@ export default {
|
||||||
methods: {
|
methods: {
|
||||||
// 预览
|
// 预览
|
||||||
preview(row, TrialReadingCriterionId) {
|
preview(row, TrialReadingCriterionId) {
|
||||||
let file = row.CriterionCategoryList.find(v => {return v.TrialReadingCriterionId === TrialReadingCriterionId}).StatementCriterionFileList[0];
|
let file = row.CriterionCategoryList.find((v) => {
|
||||||
let arr = file.FilePath.split(".");
|
return v.TrialReadingCriterionId === TrialReadingCriterionId
|
||||||
|
}).StatementCriterionFileList[0]
|
||||||
|
let arr = file.FilePath.split('.')
|
||||||
|
|
||||||
this.$preview({
|
this.$preview({
|
||||||
path: file.FilePath,
|
path: file.FilePath,
|
||||||
type: arr[arr.length - 1],
|
type: arr[arr.length - 1],
|
||||||
title:file.FileName
|
title: file.FileName,
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
isConsistencyChange(row, ite, value, showMessage) {
|
isConsistencyChange(row, ite, value, showMessage) {
|
||||||
|
|
@ -492,39 +691,50 @@ export default {
|
||||||
},
|
},
|
||||||
batchSetCriterionJoinJoinAnalysis(row, ite, value, showMessage) {
|
batchSetCriterionJoinJoinAnalysis(row, ite, value, showMessage) {
|
||||||
let params
|
let params
|
||||||
if (row.DoctorCriterionStatusList && row.DoctorCriterionStatusList.length > 0) {
|
if (
|
||||||
|
row.DoctorCriterionStatusList &&
|
||||||
|
row.DoctorCriterionStatusList.length > 0
|
||||||
|
) {
|
||||||
if (ite) {
|
if (ite) {
|
||||||
let item = row.CriterionCategoryList.find(v => v.TrialReadingCriterionId === ite.TrialReadingCriterionId)
|
let item = row.CriterionCategoryList.find(
|
||||||
|
(v) => v.TrialReadingCriterionId === ite.TrialReadingCriterionId
|
||||||
|
)
|
||||||
if (item) {
|
if (item) {
|
||||||
params = [{
|
params = [
|
||||||
|
{
|
||||||
Id: item.Id,
|
Id: item.Id,
|
||||||
EnrollId: item.EnrollId,
|
EnrollId: item.EnrollId,
|
||||||
TrialReadingCriterionId: item.TrialReadingCriterionId,
|
TrialReadingCriterionId: item.TrialReadingCriterionId,
|
||||||
IsJoinAnalysis: value
|
IsJoinAnalysis: value,
|
||||||
}]
|
},
|
||||||
|
]
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
params = row.DoctorCriterionStatusList.map(v => {
|
params = row.DoctorCriterionStatusList.map((v) => {
|
||||||
return {
|
return {
|
||||||
Id: v.Id,
|
Id: v.Id,
|
||||||
EnrollId: v.EnrollId,
|
EnrollId: v.EnrollId,
|
||||||
TrialReadingCriterionId: v.TrialReadingCriterionId,
|
TrialReadingCriterionId: v.TrialReadingCriterionId,
|
||||||
IsJoinAnalysis: v.IsJoinAnalysis
|
IsJoinAnalysis: v.IsJoinAnalysis,
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
params = row.CriterionCategoryList.map(v => {
|
params = row.CriterionCategoryList.map((v) => {
|
||||||
return {
|
return {
|
||||||
EnrollId: v.EnrollId,
|
EnrollId: v.EnrollId,
|
||||||
TrialReadingCriterionId: v.TrialReadingCriterionId,
|
TrialReadingCriterionId: v.TrialReadingCriterionId,
|
||||||
IsJoinAnalysis: value
|
IsJoinAnalysis: value,
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
batchSetCriterionJoinJoinAnalysis(params).then(res => {
|
batchSetCriterionJoinJoinAnalysis(params).then((res) => {
|
||||||
if (showMessage) {
|
if (showMessage) {
|
||||||
this.$message.success(this.$t('trials:enrolledReviews:message:batchSetCriterionJoinJoinAnalysis1'))
|
this.$message.success(
|
||||||
|
this.$t(
|
||||||
|
'trials:enrolledReviews:message:batchSetCriterionJoinJoinAnalysis1'
|
||||||
|
)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
this.initPage()
|
this.initPage()
|
||||||
})
|
})
|
||||||
|
|
@ -532,17 +742,25 @@ export default {
|
||||||
go(path) {
|
go(path) {
|
||||||
window.open(path)
|
window.open(path)
|
||||||
},
|
},
|
||||||
beforeUpload() {
|
beforeUpload(file) {
|
||||||
if (this.fileList.length > 0) {
|
if (this.fileList.length > 0) {
|
||||||
// 只允许上传1个文件
|
// 只允许上传1个文件
|
||||||
this.$alert(this.$t('trials:enrolledReviews:message:uploadSowWaring1'))
|
this.$alert(this.$t('trials:enrolledReviews:message:uploadSowWaring1'))
|
||||||
return
|
return false
|
||||||
|
}
|
||||||
|
const fileName = file.name
|
||||||
|
var extendName = fileName
|
||||||
|
.substring(fileName.lastIndexOf('.'))
|
||||||
|
.toLocaleLowerCase()
|
||||||
|
if (extendName !== '.pdf') {
|
||||||
|
this.$alert(this.$t('trials:enrolledReviews:message:uploadSowWaring2'))
|
||||||
|
return false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
handleSave() {
|
handleSave() {
|
||||||
this.$refs['DictionaryTypeConfigForm'].validate(valid => {
|
this.$refs['DictionaryTypeConfigForm'].validate((valid) => {
|
||||||
if (!valid) return
|
if (!valid) return
|
||||||
addDoctorCriterionFile(this.form).then(res => {
|
addDoctorCriterionFile(this.form).then((res) => {
|
||||||
// 保存成功
|
// 保存成功
|
||||||
this.$message.success(this.$t('common:message:savedSuccessfully'))
|
this.$message.success(this.$t('common:message:savedSuccessfully'))
|
||||||
this.initPage()
|
this.initPage()
|
||||||
|
|
@ -560,11 +778,19 @@ export default {
|
||||||
this.btnLoading = true
|
this.btnLoading = true
|
||||||
var fileName = param.file.name
|
var fileName = param.file.name
|
||||||
let file = await this.fileToBlob(param.file)
|
let file = await this.fileToBlob(param.file)
|
||||||
let res = await this.OSSclient.put(`/SystemData/reviewer/${this.form.FileType === 0 ? '既往阅片情况声明' : '入项资格确认书'}/${this.rowData.DoctorId}/${fileName}`, file)
|
let res = await this.OSSclient.put(
|
||||||
|
`/SystemData/reviewer/${
|
||||||
|
this.form.FileType === 0 ? '既往阅片情况声明' : '入项资格确认书'
|
||||||
|
}/${this.rowData.DoctorId}/${fileName}`,
|
||||||
|
file
|
||||||
|
)
|
||||||
this.form.FileName = param.file.name
|
this.form.FileName = param.file.name
|
||||||
this.form.FilePath = this.$getObjectName(res.url)
|
this.form.FilePath = this.$getObjectName(res.url)
|
||||||
param.file.url = this.$getObjectName(res.url)
|
param.file.url = this.$getObjectName(res.url)
|
||||||
this.$set(this.fileList, 0, { name: this.form.FileName, url: this.$getObjectName(res.url) })
|
this.$set(this.fileList, 0, {
|
||||||
|
name: this.form.FileName,
|
||||||
|
url: this.$getObjectName(res.url),
|
||||||
|
})
|
||||||
this.btnLoading = false
|
this.btnLoading = false
|
||||||
|
|
||||||
// this.btnLoading = true
|
// this.btnLoading = true
|
||||||
|
|
@ -599,10 +825,13 @@ export default {
|
||||||
DoctorId: row.DoctorId,
|
DoctorId: row.DoctorId,
|
||||||
CriterionType: item.CriterionType,
|
CriterionType: item.CriterionType,
|
||||||
CriterionName: item.TrialReadingCriterionName,
|
CriterionName: item.TrialReadingCriterionName,
|
||||||
TrialReadingCriterionId: item.TrialReadingCriterionId
|
TrialReadingCriterionId: item.TrialReadingCriterionId,
|
||||||
}
|
}
|
||||||
this.handleRemoveFile2()
|
this.handleRemoveFile2()
|
||||||
this.model_cfg.title = fileType === 0 ? this.$t('trials:enrolledReviews:message:SOW') : this.$t('trials:enrolledReviews:message:EQC')// '既往阅片情况说明' : '入项资格确认书'
|
this.model_cfg.title =
|
||||||
|
fileType === 0
|
||||||
|
? this.$t('trials:enrolledReviews:message:SOW')
|
||||||
|
: this.$t('trials:enrolledReviews:message:EQC') // '既往阅片情况说明' : '入项资格确认书'
|
||||||
},
|
},
|
||||||
windowOpen(url) {
|
windowOpen(url) {
|
||||||
console.log(url)
|
console.log(url)
|
||||||
|
|
@ -614,12 +843,14 @@ export default {
|
||||||
updateTrialReviewerState({
|
updateTrialReviewerState({
|
||||||
TrialId: this.listQuery.TrialId,
|
TrialId: this.listQuery.TrialId,
|
||||||
IsEnable: v,
|
IsEnable: v,
|
||||||
EnrollId: row.EnrollId
|
EnrollId: row.EnrollId,
|
||||||
}).then(res => {
|
})
|
||||||
|
.then((res) => {
|
||||||
// '保存成功'
|
// '保存成功'
|
||||||
this.$message.success(this.$t('common:message:savedSuccessfully'))
|
this.$message.success(this.$t('common:message:savedSuccessfully'))
|
||||||
this.listLoading = false
|
this.listLoading = false
|
||||||
}).catch(() => {
|
})
|
||||||
|
.catch(() => {
|
||||||
this.listLoading = false
|
this.listLoading = false
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
@ -630,19 +861,20 @@ export default {
|
||||||
TrialId: this.$route.query.trialId,
|
TrialId: this.$route.query.trialId,
|
||||||
EnrollId: this.currentRow.EnrollId,
|
EnrollId: this.currentRow.EnrollId,
|
||||||
ReadingCategorys: Object.assign([], this.ReadingCategorys),
|
ReadingCategorys: Object.assign([], this.ReadingCategorys),
|
||||||
TrialReadingCriterionId: this.TrialReadingCriterionId
|
TrialReadingCriterionId: this.TrialReadingCriterionId,
|
||||||
}
|
}
|
||||||
if (~this.ReadingCategorys.indexOf(1)) {
|
if (~this.ReadingCategorys.indexOf(1)) {
|
||||||
params.ReadingCategorys.push(2)
|
params.ReadingCategorys.push(2)
|
||||||
}
|
}
|
||||||
setEnrollReadingCategory(params)
|
setEnrollReadingCategory(params)
|
||||||
.then(res => {
|
.then((res) => {
|
||||||
this.readingCategory_model.visible = false
|
this.readingCategory_model.visible = false
|
||||||
this.readingCategory_model.btnLoading = false
|
this.readingCategory_model.btnLoading = false
|
||||||
this.readingCategory_model.showClose = true
|
this.readingCategory_model.showClose = true
|
||||||
this.initPage()
|
this.initPage()
|
||||||
this.$message.success(this.$t('common:message:savedSuccessfully'))
|
this.$message.success(this.$t('common:message:savedSuccessfully'))
|
||||||
}).catch(_ => {
|
})
|
||||||
|
.catch((_) => {
|
||||||
this.readingCategory_model.btnLoading = false
|
this.readingCategory_model.btnLoading = false
|
||||||
this.readingCategory_model.showClose = true
|
this.readingCategory_model.showClose = true
|
||||||
})
|
})
|
||||||
|
|
@ -653,16 +885,20 @@ export default {
|
||||||
this.currentRow = row
|
this.currentRow = row
|
||||||
this.TrialReadingCriterionId = TrialReadingCriterionId
|
this.TrialReadingCriterionId = TrialReadingCriterionId
|
||||||
this.readingCategory_model.visible = true
|
this.readingCategory_model.visible = true
|
||||||
var o = row.CriterionCategoryList.find(v => {
|
var o = row.CriterionCategoryList.find((v) => {
|
||||||
return v.TrialReadingCriterionId === TrialReadingCriterionId
|
return v.TrialReadingCriterionId === TrialReadingCriterionId
|
||||||
}) ? row.CriterionCategoryList.find(v => {
|
})
|
||||||
|
? row.CriterionCategoryList.find((v) => {
|
||||||
return v.TrialReadingCriterionId === TrialReadingCriterionId
|
return v.TrialReadingCriterionId === TrialReadingCriterionId
|
||||||
}) : null
|
})
|
||||||
var i = row.TrialReadingCriterionList.find(v => {
|
: null
|
||||||
|
var i = row.TrialReadingCriterionList.find((v) => {
|
||||||
return v.TrialReadingCriterionId === TrialReadingCriterionId
|
return v.TrialReadingCriterionId === TrialReadingCriterionId
|
||||||
}) ? row.TrialReadingCriterionList.find(v => {
|
})
|
||||||
|
? row.TrialReadingCriterionList.find((v) => {
|
||||||
return v.TrialReadingCriterionId === TrialReadingCriterionId
|
return v.TrialReadingCriterionId === TrialReadingCriterionId
|
||||||
}) : null
|
})
|
||||||
|
: null
|
||||||
if (i) {
|
if (i) {
|
||||||
this.IsArbitrationReading = i.IsArbitrationReading
|
this.IsArbitrationReading = i.IsArbitrationReading
|
||||||
this.IsOncologyReading = i.IsOncologyReading
|
this.IsOncologyReading = i.IsOncologyReading
|
||||||
|
|
@ -678,17 +914,23 @@ export default {
|
||||||
// 获取入组医生列表数据
|
// 获取入组医生列表数据
|
||||||
initPage() {
|
initPage() {
|
||||||
this.listLoading = true
|
this.listLoading = true
|
||||||
getTrialEnrollmentWorkloadStats(this.listQuery).then((res) => {
|
getTrialEnrollmentWorkloadStats(this.listQuery)
|
||||||
|
.then((res) => {
|
||||||
this.listLoading = false
|
this.listLoading = false
|
||||||
let resArray = res.Result.CurrentPageData
|
let resArray = res.Result.CurrentPageData
|
||||||
try {
|
try {
|
||||||
resArray.forEach(v => {
|
resArray.forEach((v) => {
|
||||||
if (v.DoctorCriterionStatusList && v.DoctorCriterionStatusList.length === 0) {
|
if (
|
||||||
|
v.DoctorCriterionStatusList &&
|
||||||
|
v.DoctorCriterionStatusList.length === 0
|
||||||
|
) {
|
||||||
this.isConsistencyChange(v, null, true, false)
|
this.isConsistencyChange(v, null, true, false)
|
||||||
}
|
}
|
||||||
v.CriterionCategoryList.forEach(v1 => {
|
v.CriterionCategoryList.forEach((v1) => {
|
||||||
let o = v.DoctorCriterionStatusList.find(v2 => {
|
let o = v.DoctorCriterionStatusList.find((v2) => {
|
||||||
return v2.TrialReadingCriterionId === v1.TrialReadingCriterionId
|
return (
|
||||||
|
v2.TrialReadingCriterionId === v1.TrialReadingCriterionId
|
||||||
|
)
|
||||||
})
|
})
|
||||||
if (o) {
|
if (o) {
|
||||||
this.$set(v1, 'Id', o.Id)
|
this.$set(v1, 'Id', o.Id)
|
||||||
|
|
@ -702,7 +944,8 @@ export default {
|
||||||
}
|
}
|
||||||
this.list = resArray
|
this.list = resArray
|
||||||
if (this.list.length > 0) {
|
if (this.list.length > 0) {
|
||||||
this.TrialReadingCriterionList = this.list[0].TrialReadingCriterionList
|
this.TrialReadingCriterionList =
|
||||||
|
this.list[0].TrialReadingCriterionList
|
||||||
}
|
}
|
||||||
this.total = res.Result.TotalCount
|
this.total = res.Result.TotalCount
|
||||||
this.$nextTick(() => {
|
this.$nextTick(() => {
|
||||||
|
|
@ -711,7 +954,8 @@ export default {
|
||||||
this.$refs.myTable.doLayout()
|
this.$refs.myTable.doLayout()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}).catch(() => {
|
})
|
||||||
|
.catch(() => {
|
||||||
this.listLoading = false
|
this.listLoading = false
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
@ -719,7 +963,7 @@ export default {
|
||||||
// Enroll按钮回调
|
// Enroll按钮回调
|
||||||
handleEnroll() {
|
handleEnroll() {
|
||||||
this.$router.push({
|
this.$router.push({
|
||||||
path: `/trials/trials-panel/enrolled-reviewers/enroll?trialId=${this.listQuery.TrialId}&trialCode=${this.trialId}`
|
path: `/trials/trials-panel/enrolled-reviewers/enroll?trialId=${this.listQuery.TrialId}&trialCode=${this.trialId}`,
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
@ -731,12 +975,16 @@ export default {
|
||||||
|
|
||||||
// 更新医生状态信息
|
// 更新医生状态信息
|
||||||
handleUpdateReviewerStatus() {
|
handleUpdateReviewerStatus() {
|
||||||
this.$refs.updateStatusForm.validate(valid => {
|
this.$refs.updateStatusForm.validate((valid) => {
|
||||||
if (!valid) return
|
if (!valid) return
|
||||||
this.reviewerStatus_model.btnLoading = true
|
this.reviewerStatus_model.btnLoading = true
|
||||||
this.reviewerStatus_model.showClose = false
|
this.reviewerStatus_model.showClose = false
|
||||||
enrollBackOrOut(this.listQuery.TrialId, this.currentRow.DoctorId, this.updateStatusForm.Status)
|
enrollBackOrOut(
|
||||||
.then(res => {
|
this.listQuery.TrialId,
|
||||||
|
this.currentRow.DoctorId,
|
||||||
|
this.updateStatusForm.Status
|
||||||
|
)
|
||||||
|
.then((res) => {
|
||||||
this.$nextTick(() => {
|
this.$nextTick(() => {
|
||||||
this.$refs['updateStatusForm'].resetFields()
|
this.$refs['updateStatusForm'].resetFields()
|
||||||
})
|
})
|
||||||
|
|
@ -765,14 +1013,19 @@ export default {
|
||||||
handleUpdateReadingType() {
|
handleUpdateReadingType() {
|
||||||
this.readingType_model.btnLoading = true
|
this.readingType_model.btnLoading = true
|
||||||
this.readingType_model.showClose = false
|
this.readingType_model.showClose = false
|
||||||
updateReviewerReadingType(this.listQuery.TrialId, this.currentRow.DoctorId, this.readingType)
|
updateReviewerReadingType(
|
||||||
.then(res => {
|
this.listQuery.TrialId,
|
||||||
|
this.currentRow.DoctorId,
|
||||||
|
this.readingType
|
||||||
|
)
|
||||||
|
.then((res) => {
|
||||||
this.readingType_model.visible = false
|
this.readingType_model.visible = false
|
||||||
this.readingType_model.btnLoading = false
|
this.readingType_model.btnLoading = false
|
||||||
this.readingType_model.showClose = true
|
this.readingType_model.showClose = true
|
||||||
this.initPage()
|
this.initPage()
|
||||||
this.$message.success(this.$t('common:message:savedSuccessfully'))
|
this.$message.success(this.$t('common:message:savedSuccessfully'))
|
||||||
}).catch(_ => {
|
})
|
||||||
|
.catch((_) => {
|
||||||
this.readingType_model.btnLoading = false
|
this.readingType_model.btnLoading = false
|
||||||
this.readingType_model.showClose = true
|
this.readingType_model.showClose = true
|
||||||
})
|
})
|
||||||
|
|
@ -791,8 +1044,6 @@ export default {
|
||||||
this.initPage()
|
this.initPage()
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
handleTipCloseOK() {
|
handleTipCloseOK() {
|
||||||
zzSessionStorage.setItem(
|
zzSessionStorage.setItem(
|
||||||
'ReviewerName',
|
'ReviewerName',
|
||||||
|
|
@ -801,7 +1052,7 @@ export default {
|
||||||
this.currentClickRowData.LastName
|
this.currentClickRowData.LastName
|
||||||
)
|
)
|
||||||
this.$router.push({
|
this.$router.push({
|
||||||
path: `/trials/trials-panel/enrolled-reviewers/stats?doctorId=${this.currentClickRowData.DoctorId}&trialId=${this.listQuery.TrialId}&trialCode=${this.trialId}&doctorName=${this.currentClickRowData.LastName}/${this.currentClickRowData.FirstName}`
|
path: `/trials/trials-panel/enrolled-reviewers/stats?doctorId=${this.currentClickRowData.DoctorId}&trialId=${this.listQuery.TrialId}&trialCode=${this.trialId}&doctorName=${this.currentClickRowData.LastName}/${this.currentClickRowData.FirstName}`,
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
@ -827,8 +1078,8 @@ export default {
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
return sums
|
return sums
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
|
|
|
||||||
|
|
@ -70,54 +70,21 @@
|
||||||
width="150"
|
width="150"
|
||||||
>
|
>
|
||||||
<template slot-scope="scope">
|
<template slot-scope="scope">
|
||||||
<div
|
<div v-if="scope.row.VisitTaskInfoList[j.index].JudgeQuestionList[i].QuestionType === 1">
|
||||||
v-if="
|
<span v-if="scope.row.VisitTaskInfoList[j.index].JudgeQuestionList[i].DictionaryCode">
|
||||||
scope.row.VisitTaskInfoList[j.index].JudgeQuestionList[i]
|
{{ $fd(scope.row.VisitTaskInfoList[j.index].JudgeQuestionList[i].DictionaryCode,parseInt(scope.row.VisitTaskInfoList[j.index].JudgeQuestionList[i].Answer))
|
||||||
.QuestionType === 1
|
}}
|
||||||
"
|
</span>
|
||||||
>
|
<span v-else>
|
||||||
<span
|
{{ scope.row.VisitTaskInfoList[j.index].JudgeQuestionList[i].Answer }}
|
||||||
v-if="
|
</span>
|
||||||
scope.row.VisitTaskInfoList[j.index].JudgeQuestionList[i]
|
<span v-if="scope.row.VisitTaskInfoList[j.index].JudgeQuestionList[i].Unit && !isNaN(parseFloat(scope.row.VisitTaskInfoList[j.index].JudgeQuestionList[i].Answer))">{{ $fd('ValueUnit', parseInt(scope.row.VisitTaskInfoList[j.index].JudgeQuestionList[i].Unit)) }}</span>
|
||||||
.DictionaryCode
|
|
||||||
"
|
|
||||||
>{{
|
|
||||||
$fd(
|
|
||||||
scope.row.VisitTaskInfoList[j.index].JudgeQuestionList[
|
|
||||||
i
|
|
||||||
].DictionaryCode,
|
|
||||||
parseInt(
|
|
||||||
scope.row.VisitTaskInfoList[j.index]
|
|
||||||
.JudgeQuestionList[i].Answer
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}}</span
|
|
||||||
>
|
|
||||||
<span v-else>{{
|
|
||||||
scope.row.VisitTaskInfoList[j.index].JudgeQuestionList[i]
|
|
||||||
.Answer
|
|
||||||
}}</span>
|
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div v-else-if="scope.row.VisitTaskInfoList[j.index].JudgeQuestionList[i].QuestionType === 2">
|
||||||
v-else-if="
|
<div v-if="scope.row.VisitTaskInfoList[j.index].JudgeQuestionList[i].Answer">
|
||||||
scope.row.VisitTaskInfoList[j.index].JudgeQuestionList[i]
|
<span>
|
||||||
.QuestionType === 2
|
{{ $fd("YesOrNo",scope.row.VisitTaskInfoList[j.index].JudgeQuestionList[i].Answer) }}
|
||||||
"
|
</span>
|
||||||
>
|
|
||||||
<div
|
|
||||||
v-if="
|
|
||||||
scope.row.VisitTaskInfoList[j.index].JudgeQuestionList[i]
|
|
||||||
.Answer
|
|
||||||
"
|
|
||||||
>
|
|
||||||
<span>{{
|
|
||||||
$fd(
|
|
||||||
"YesOrNo",
|
|
||||||
scope.row.VisitTaskInfoList[j.index].JudgeQuestionList[
|
|
||||||
i
|
|
||||||
].Answer
|
|
||||||
)
|
|
||||||
}}</span>
|
|
||||||
<!-- 查看详情 -->
|
<!-- 查看详情 -->
|
||||||
<el-button
|
<el-button
|
||||||
type="text"
|
type="text"
|
||||||
|
|
@ -144,10 +111,7 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div v-else>
|
<div v-else>
|
||||||
{{
|
{{ scope.row.VisitTaskInfoList[j.index].JudgeQuestionList[i].Answer }}
|
||||||
scope.row.VisitTaskInfoList[j.index].JudgeQuestionList[i]
|
|
||||||
.Answer
|
|
||||||
}}
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
|
|
@ -321,7 +285,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 +399,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 +495,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 +756,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 +774,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 +782,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 +809,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 +817,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 +838,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 {
|
||||||
|
|
|
||||||
|
|
@ -41,7 +41,7 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="right-wrapper">
|
<div class="right-wrapper">
|
||||||
<div v-if="selected.type===1" class="right-content">
|
<div v-if="selected.type===1" class="right-content">
|
||||||
<iframe :src="`/static/pdfjs/web/viewer.html?file=${OSSclientConfig.basePath}${selected.filePath}?userName=${currentUser}`" width="100%" height="100%" frameborder="0" />
|
<iframe :src="`/static/pdfjs/web/viewer.html?file=${OSSclientConfig.basePath}${selected.filePath}?userName=${currentUser}&COMPANY=${COMPANY}`" width="100%" height="100%" frameborder="0" />
|
||||||
</div>
|
</div>
|
||||||
<div v-else-if="selected.type===2" class="right-content" style="padding: 10px">
|
<div v-else-if="selected.type===2" class="right-content" style="padding: 10px">
|
||||||
<clinicalDataQuestions
|
<clinicalDataQuestions
|
||||||
|
|
@ -216,7 +216,8 @@ export default {
|
||||||
otherInfo: {},
|
otherInfo: {},
|
||||||
moment,
|
moment,
|
||||||
loading: false,
|
loading: false,
|
||||||
currentUser: zzSessionStorage.getItem('userName')
|
currentUser: zzSessionStorage.getItem('userName'),
|
||||||
|
COMPANY:process.env.VUE_APP_COMPANY_NAME
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
|
|
|
||||||
|
|
@ -1039,7 +1039,7 @@ export default {
|
||||||
loadImageStack(dicomSeries) {
|
loadImageStack(dicomSeries) {
|
||||||
return new Promise(resolve => {
|
return new Promise(resolve => {
|
||||||
this.isCurrentTask = dicomSeries.isCurrentTask
|
this.isCurrentTask = dicomSeries.isCurrentTask
|
||||||
this.isBaseline = dicomSeries.isBaseline
|
this.isBaseline = dicomSeries.isBaseLineTask
|
||||||
this.readingTaskState = dicomSeries.readingTaskState
|
this.readingTaskState = dicomSeries.readingTaskState
|
||||||
if (this.isCurrentTask && this.readingTaskState < 2) {
|
if (this.isCurrentTask && this.readingTaskState < 2) {
|
||||||
this.activeTool = 1
|
this.activeTool = 1
|
||||||
|
|
@ -1088,16 +1088,16 @@ export default {
|
||||||
var frame = imageInfo.frame
|
var frame = imageInfo.frame
|
||||||
this.stack.frame = this.stack.isExistMutiFrames ? parseInt(frame) : null
|
this.stack.frame = this.stack.isExistMutiFrames ? parseInt(frame) : null
|
||||||
this.stack.instanceId = instanceId
|
this.stack.instanceId = instanceId
|
||||||
const ToolStateManager = cornerstoneTools.globalImageIdSpecificToolStateManager
|
|
||||||
ToolStateManager.clearImageIdToolState(dicomSeries.imageIds)
|
|
||||||
this.toggleClipPlay(false)
|
|
||||||
this.toolState.viewportInvert = false
|
|
||||||
this.toolState.dicomInfoVisible = false
|
|
||||||
|
|
||||||
const element = this.$refs.canvas
|
const element = this.$refs.canvas
|
||||||
cornerstone.enable(element)
|
cornerstone.enable(element)
|
||||||
element.tabIndex = 0
|
element.tabIndex = 0
|
||||||
element.focus()
|
element.focus()
|
||||||
|
const ToolStateManager = cornerstoneTools.globalImageIdSpecificToolStateManager
|
||||||
|
ToolStateManager.clearImageIdToolState(dicomSeries.imageIds)
|
||||||
|
this.toggleClipPlay(false)
|
||||||
|
this.toolState.viewportInvert = false
|
||||||
|
this.toolState.dicomInfoVisible = false
|
||||||
var scope = this
|
var scope = this
|
||||||
// var p = parseInt(new Date().getTime())
|
// var p = parseInt(new Date().getTime())
|
||||||
// requestPoolManager.loadAndCacheImagePlus(this.stack.imageIds[this.stack.currentImageIdIndex], this.stack.seriesId, p*100).then(image=>{
|
// requestPoolManager.loadAndCacheImagePlus(this.stack.imageIds[this.stack.currentImageIdIndex], this.stack.seriesId, p*100).then(image=>{
|
||||||
|
|
@ -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">
|
||||||
<!-- 手册 -->
|
<!-- 手册 -->
|
||||||
|
|
@ -397,8 +434,7 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div ref="form-container" class="form-container">
|
<div ref="form-container" class="form-container">
|
||||||
<!-- 激活canvas测量数据 -->
|
<div class="form-wrapper">
|
||||||
|
|
||||||
<RecistBMQuestionList
|
<RecistBMQuestionList
|
||||||
v-if="CriterionType === 17"
|
v-if="CriterionType === 17"
|
||||||
ref="measurementList"
|
ref="measurementList"
|
||||||
|
|
@ -433,13 +469,53 @@
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<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 v-if="iseCRFShowInDicomReading && currentReadingTaskState < 2" class="form-footer">
|
||||||
|
<el-button
|
||||||
|
type="primary"
|
||||||
|
size="small"
|
||||||
|
@click="skipTask"
|
||||||
|
>
|
||||||
|
<!-- 跳过 -->
|
||||||
|
{{ $t('trials:readingReport:button:skip') }}
|
||||||
|
</el-button>
|
||||||
|
<el-button
|
||||||
|
type="primary"
|
||||||
|
size="small"
|
||||||
|
@click="submit"
|
||||||
|
>
|
||||||
|
<!-- 提交 -->
|
||||||
|
{{ $t('common:button:submit') }}
|
||||||
|
</el-button>
|
||||||
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
@ -655,6 +731,37 @@
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-form>
|
</el-form>
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
|
<upload-dicom-and-nonedicom
|
||||||
|
v-if="uploadImageVisible"
|
||||||
|
:subject-id="uploadSubjectId"
|
||||||
|
:subject-code="uploadSubjectCode"
|
||||||
|
:criterion="uploadTrialCriterion"
|
||||||
|
:visible.sync="uploadImageVisible"
|
||||||
|
:visit-task-id="taskId"
|
||||||
|
:is-reading-task-view-in-order="isReadingTaskViewInOrder"
|
||||||
|
/>
|
||||||
|
<download-dicom-and-nonedicom
|
||||||
|
v-if="downloadImageVisible"
|
||||||
|
:subject-id="uploadSubjectId"
|
||||||
|
:subject-code="uploadSubjectCode"
|
||||||
|
:criterion="uploadTrialCriterion"
|
||||||
|
:task-id="taskId"
|
||||||
|
:visible.sync="downloadImageVisible"
|
||||||
|
/>
|
||||||
|
<!-- 签名框 -->
|
||||||
|
<el-dialog
|
||||||
|
v-if="signVisible"
|
||||||
|
:visible.sync="signVisible"
|
||||||
|
:close-on-click-modal="false"
|
||||||
|
width="600px"
|
||||||
|
custom-class="base-dialog-wrapper"
|
||||||
|
>
|
||||||
|
<div slot="title">
|
||||||
|
<span style="font-size:18px;">{{ $t('common:dialogTitle:sign') }}</span>
|
||||||
|
<span style="font-size:12px;margin-left:5px;user-select: text !important;">{{ `(${$t('common:label:sign')}${ currentUser })` }}</span>
|
||||||
|
</div>
|
||||||
|
<SignForm ref="signForm" :sign-code-enum="signCode" @closeDialog="closeSignDialog" />
|
||||||
|
</el-dialog>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script>
|
<script>
|
||||||
|
|
@ -677,6 +784,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 +793,14 @@ 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 SignForm from '@/views/trials/components/newSignForm'
|
||||||
|
import { getCriterionReadingInfo, verifyVisitTaskQuestions, submitDicomVisitTask } from '@/api/trials'
|
||||||
|
import { setSkipReadingCache } from '@/api/reading'
|
||||||
|
import { getAutoCutNextTask } from '@/api/user'
|
||||||
|
import const_ from '@/const/sign-code'
|
||||||
|
import { changeURLStatic } from '@/utils/history.js'
|
||||||
export default {
|
export default {
|
||||||
name: 'DicomViewer',
|
name: 'DicomViewer',
|
||||||
components: {
|
components: {
|
||||||
|
|
@ -698,7 +815,13 @@ export default {
|
||||||
PCWGQuestionList,
|
PCWGQuestionList,
|
||||||
RecistBMQuestionList,
|
RecistBMQuestionList,
|
||||||
IRecistQuestionList,
|
IRecistQuestionList,
|
||||||
LuganoQuestionList },
|
LuganoQuestionList,
|
||||||
|
IVUSList,
|
||||||
|
OCTList,
|
||||||
|
'download-dicom-and-nonedicom': downloadDicomAndNonedicom,
|
||||||
|
'upload-dicom-and-nonedicom': uploadDicomAndNonedicom,
|
||||||
|
SignForm
|
||||||
|
},
|
||||||
props: {
|
props: {
|
||||||
isShow: {
|
isShow: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
|
|
@ -724,6 +847,10 @@ export default {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
required: true
|
required: true
|
||||||
},
|
},
|
||||||
|
iseCRFShowInDicomReading: {
|
||||||
|
type: Boolean,
|
||||||
|
required: true
|
||||||
|
},
|
||||||
questionFormChangeState: {
|
questionFormChangeState: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default() {
|
default() {
|
||||||
|
|
@ -839,7 +966,19 @@ 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: '',
|
||||||
|
signVisible: false,
|
||||||
|
signCode: null,
|
||||||
|
currentUser: zzSessionStorage.getItem('userName')
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
@ -912,6 +1051,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 +1063,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 +1206,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||localStorage.getItem("subjectCode")
|
||||||
|
this.uploadSubjectId = this.$route.query.subjectId||localStorage.getItem("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 {
|
||||||
|
|
@ -2070,17 +2235,119 @@ export default {
|
||||||
this.isFullscreen = false
|
this.isFullscreen = false
|
||||||
this.manualsDialog.visible = true
|
this.manualsDialog.visible = true
|
||||||
},
|
},
|
||||||
|
async skipTask() {
|
||||||
|
// 是否确认跳过?
|
||||||
|
const confirm = await this.$confirm(
|
||||||
|
this.$t('trials:readingReport:message:skipConfirm'),
|
||||||
|
{
|
||||||
|
type: 'warning',
|
||||||
|
distinguishCancelAndClose: true
|
||||||
|
}
|
||||||
|
)
|
||||||
|
if (confirm !== 'confirm') return
|
||||||
|
// const loading = this.$loading({ fullscreen: true })
|
||||||
|
try {
|
||||||
|
const idx = this.visitTaskList.findIndex(i => i.IsCurrentTask)
|
||||||
|
if (idx > -1) {
|
||||||
|
var visitTaskId = this.visitTaskList[idx].VisitTaskId
|
||||||
|
const res = await setSkipReadingCache({ visitTaskId: visitTaskId })
|
||||||
|
if (res.IsSuccess) {
|
||||||
|
window.location.reload()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// loading.close()
|
||||||
|
} catch (e) {
|
||||||
|
// loading.close()
|
||||||
|
console.log(e)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
async submit() {
|
||||||
|
const loading = this.$loading({ fullscreen: true })
|
||||||
|
try {
|
||||||
|
const idx = this.visitTaskList.findIndex(i => i.IsCurrentTask)
|
||||||
|
if (idx > -1) {
|
||||||
|
var visitTaskId = this.visitTaskList[idx].VisitTaskId
|
||||||
|
this.taskId = visitTaskId
|
||||||
|
await verifyVisitTaskQuestions({ visitTaskId: visitTaskId })
|
||||||
|
const { ImageAssessmentReportConfirmation } = const_.processSignature
|
||||||
|
this.signCode = ImageAssessmentReportConfirmation
|
||||||
|
this.signVisible = true
|
||||||
|
}
|
||||||
|
loading.close()
|
||||||
|
} catch (e) {
|
||||||
|
loading.close()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// 关闭签名框
|
||||||
|
closeSignDialog(isSign, signInfo) {
|
||||||
|
if (isSign) {
|
||||||
|
this.signConfirm(signInfo)
|
||||||
|
} else {
|
||||||
|
this.signVisible = false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// 签名并确认
|
||||||
|
async signConfirm(signInfo) {
|
||||||
|
this.loading = true
|
||||||
|
try {
|
||||||
|
var params = {
|
||||||
|
data: {
|
||||||
|
visitTaskId: this.taskId
|
||||||
|
},
|
||||||
|
signInfo: signInfo
|
||||||
|
}
|
||||||
|
const res = await submitDicomVisitTask(params)
|
||||||
|
if (res.IsSuccess) {
|
||||||
|
this.$message.success(this.$t('common:message:savedSuccessfully'))
|
||||||
|
if (this.$refs['signForm']) {
|
||||||
|
this.$refs['signForm'].btnLoading = false
|
||||||
|
}
|
||||||
|
|
||||||
|
this.signVisible = false
|
||||||
|
|
||||||
|
// 设置当前任务阅片状态为已读
|
||||||
|
this.readingTaskState = 2
|
||||||
|
await store.dispatch('reading/setVisitTaskReadingTaskState', { visitTaskId: this.visitTaskId, readingTaskState: 2 })
|
||||||
|
await store.dispatch('reading/setCurrentReadingTaskState', 2)
|
||||||
|
const res = await getAutoCutNextTask()
|
||||||
|
var isAutoTask = res.Result.AutoCutNextTask
|
||||||
|
if (isAutoTask) {
|
||||||
|
window.location.reload()
|
||||||
|
} else {
|
||||||
|
// '当前阅片任务已完成,是否进入下一个阅片任务?'
|
||||||
|
this.$confirm(this.$t('trials:readingReport:message:msg4'), {
|
||||||
|
type: 'warning',
|
||||||
|
distinguishCancelAndClose: true
|
||||||
|
})
|
||||||
|
.then(() => {
|
||||||
|
window.location.reload()
|
||||||
|
})
|
||||||
|
.catch(action => {
|
||||||
|
changeURLStatic('visitTaskId', this.visitTaskId)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
window.opener.postMessage('refreshTaskList', window.location)
|
||||||
|
}
|
||||||
|
this.loading = false
|
||||||
|
} catch (e) {
|
||||||
|
this.loading = false
|
||||||
|
if (this.$refs['signForm'] && this.$refs['signForm'].btnLoading) {
|
||||||
|
this.$refs['signForm'].btnLoading = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
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
|
||||||
|
|
@ -2400,9 +2667,22 @@ export default {
|
||||||
.form-container{
|
.form-container{
|
||||||
// box-sizing: border-box;
|
// box-sizing: border-box;
|
||||||
width: 350px;
|
width: 350px;
|
||||||
height: 100%;
|
// height: 100vh;
|
||||||
border: 1px solid #727272;
|
border: 1px solid #727272;
|
||||||
// overflow-y: auto;
|
// position: relative;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
|
||||||
|
}
|
||||||
|
.form-wrapper{
|
||||||
|
flex-grow: 1;
|
||||||
|
height: 0;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
.form-footer{
|
||||||
|
background: #000;
|
||||||
|
padding: 10px 0;
|
||||||
|
text-align: center;
|
||||||
}
|
}
|
||||||
.viewer-container{
|
.viewer-container{
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="measurement-wrapper" :style="{'height':height+10+'px'}">
|
<div class="measurement-wrapper">
|
||||||
|
|
||||||
<div class="container" :style="{'height':height+'px'}">
|
<div class="container">
|
||||||
<div class="basic-info">
|
<div class="basic-info">
|
||||||
<h3 v-if="isReadingShowSubjectInfo">
|
<h3 v-if="isReadingShowSubjectInfo">
|
||||||
<span v-if="subjectCode">{{ subjectCode }} </span>
|
<span v-if="subjectCode">{{ subjectCode }} </span>
|
||||||
|
|
@ -203,7 +203,6 @@ export default {
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
height: window.innerHeight - 140,
|
|
||||||
questions: [],
|
questions: [],
|
||||||
activeName: '',
|
activeName: '',
|
||||||
activeItem: {
|
activeItem: {
|
||||||
|
|
@ -269,8 +268,6 @@ export default {
|
||||||
DicomEvent.$on('split', measureData => {
|
DicomEvent.$on('split', measureData => {
|
||||||
this.handleSplit(measureData.RowId, measureData.QuestionId)
|
this.handleSplit(measureData.RowId, measureData.QuestionId)
|
||||||
})
|
})
|
||||||
|
|
||||||
window.addEventListener('resize', this.setHeight)
|
|
||||||
},
|
},
|
||||||
beforeDestroy() {
|
beforeDestroy() {
|
||||||
DicomEvent.$off('setCollapseActive')
|
DicomEvent.$off('setCollapseActive')
|
||||||
|
|
@ -457,9 +454,6 @@ export default {
|
||||||
} catch (e) { console.log(e) }
|
} catch (e) { console.log(e) }
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
setHeight() {
|
|
||||||
this.height = window.innerHeight - 140
|
|
||||||
},
|
|
||||||
getQuestionAnswer(questions, questionMark, answers) {
|
getQuestionAnswer(questions, questionMark, answers) {
|
||||||
var idx = questions.findIndex(i => i.QuestionMark === questionMark)
|
var idx = questions.findIndex(i => i.QuestionMark === questionMark)
|
||||||
if (idx > -1) {
|
if (idx > -1) {
|
||||||
|
|
@ -1183,6 +1177,7 @@ export default {
|
||||||
</script>
|
</script>
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
.measurement-wrapper{
|
.measurement-wrapper{
|
||||||
|
height: 100%;
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
// overflow: hidden;
|
// overflow: hidden;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,874 @@
|
||||||
|
<template>
|
||||||
|
<div class="measurement-wrapper">
|
||||||
|
|
||||||
|
<div class="container">
|
||||||
|
<div class="basic-info">
|
||||||
|
<h3 v-if="isReadingShowSubjectInfo">
|
||||||
|
<span v-if="subjectCode">{{ subjectCode }} </span>
|
||||||
|
<span style="margin-left:5px;">{{ taskBlindName }}</span>
|
||||||
|
</h3>
|
||||||
|
<div v-if="readingTaskState < 2">
|
||||||
|
<el-tooltip class="item" effect="dark" :content="$t('trials:dicomReading:message:confirmReset')" placement="bottom">
|
||||||
|
<i
|
||||||
|
class="el-icon-refresh-left"
|
||||||
|
@click="resetMeasuredData"
|
||||||
|
/>
|
||||||
|
</el-tooltip>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 影像质量问题 -->
|
||||||
|
<div class="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">
|
||||||
|
<div v-for="(qs,index) in questions" :key="index" v-loading="loading" class="lesions lesions_wrapper" style="margin-bottom: 10px">
|
||||||
|
<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="table-wrapper">
|
||||||
|
<div v-for="item in qs.Childrens" :key="item.Id">
|
||||||
|
<div v-if="item.Type === 'basicTable'" class="flex-row" style="margin:3px 0;">
|
||||||
|
<div class="title">{{ item.QuestionName }}</div>
|
||||||
|
<div v-if="item.LesionType === 102 && readingTaskState < 2">
|
||||||
|
<div class="add-icon" @click.prevent="downloadTpl">
|
||||||
|
<i class="el-icon-download" />
|
||||||
|
</div>
|
||||||
|
<div class="add-icon" style="margin: 0 5px;" @click.prevent="uploadTpl(item.LesionType)">
|
||||||
|
<i class="el-icon-upload2" />
|
||||||
|
</div>
|
||||||
|
<div class="add-icon" @click.prevent="handleAddOrEdit('add',item)">
|
||||||
|
<i class="el-icon-plus" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<el-table
|
||||||
|
v-if="item.Type === 'basicTable' && item.TableQuestions"
|
||||||
|
:ref="item.Id"
|
||||||
|
:data="item.TableQuestions.Answers"
|
||||||
|
>
|
||||||
|
<!-- <el-table-column :label="$t('CustomizeQuestionFormItem:label:OrderMark')" width="60px" show-overflow-tooltip>
|
||||||
|
<template slot-scope="scope">
|
||||||
|
{{ getLesionName(item.OrderMark,scope.row.RowIndex) }}
|
||||||
|
</template>
|
||||||
|
</el-table-column> -->
|
||||||
|
<!-- <el-table-column
|
||||||
|
type="index"
|
||||||
|
width="40px"
|
||||||
|
/> -->
|
||||||
|
<el-table-column
|
||||||
|
v-for="q of item.TableQuestions.Questions"
|
||||||
|
:key="q.Id"
|
||||||
|
:prop="q.Id"
|
||||||
|
:label="q.QuestionName"
|
||||||
|
show-overflow-tooltip
|
||||||
|
:render-header="renderHeader"
|
||||||
|
>
|
||||||
|
<template slot-scope="scope">
|
||||||
|
<span v-if="q.Unit > 0 && !isNaN(parseFloat(scope.row[q.Id]))">
|
||||||
|
{{ `${scope.row[q.Id]} ${$fd('ValueUnit', parseInt(q.Unit))}` }}
|
||||||
|
</span>
|
||||||
|
<span v-else-if="q.DictionaryCode">
|
||||||
|
{{ `${$fd(q.DictionaryCode, parseInt(scope.row[q.Id]))}` }}
|
||||||
|
</span>
|
||||||
|
<span v-else>
|
||||||
|
{{ `${scope.row[q.Id]}` }}
|
||||||
|
</span>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column
|
||||||
|
v-if="readingTaskState < 2 && item.LesionType === 102"
|
||||||
|
:label="$t('common:action:action')"
|
||||||
|
width="90px"
|
||||||
|
fixed="right"
|
||||||
|
>
|
||||||
|
<template slot-scope="scope">
|
||||||
|
<el-button type="text" size="mini" @click="handleAddOrEdit('edit',item, scope.$index)">
|
||||||
|
{{ $t('common:button:edit') }}
|
||||||
|
</el-button>
|
||||||
|
<el-button type="text" size="mini" @click="handleDelete(item, scope.$index)">
|
||||||
|
{{ $t('common:button:delete') }}
|
||||||
|
</el-button>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
|
||||||
|
<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==='textarea'">
|
||||||
|
<el-input
|
||||||
|
v-model="questionForm[qs.Id]"
|
||||||
|
type="textarea"
|
||||||
|
:autosize="{ minRows: 2, maxRows: 4}"
|
||||||
|
:disabled="!isCurrentTask || readingTaskState>=2"
|
||||||
|
@change="((val)=>{formItemChange(val, qs)})"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
</el-form-item>
|
||||||
|
</template>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
v-if="isCurrentTask && readingTaskState<2 && qs.GroupClassify === 5"
|
||||||
|
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"
|
||||||
|
/>
|
||||||
|
<!-- 新增、编辑弹窗 -->
|
||||||
|
<el-dialog
|
||||||
|
v-if="addOrEdit.visible"
|
||||||
|
:visible.sync="addOrEdit.visible"
|
||||||
|
:close-on-click-modal="false"
|
||||||
|
:title="addOrEdit.title"
|
||||||
|
width="500px"
|
||||||
|
>
|
||||||
|
<el-form
|
||||||
|
ref="tableQsForm"
|
||||||
|
v-loading="loading"
|
||||||
|
:model="qsForm"
|
||||||
|
size="small"
|
||||||
|
>
|
||||||
|
<QuestionTableFormItem
|
||||||
|
v-for="item in qsList"
|
||||||
|
:key="item.Id"
|
||||||
|
:question="item"
|
||||||
|
:question-form="qsForm"
|
||||||
|
:reading-task-state="readingTaskState"
|
||||||
|
@setFormItemData="setFormItemData"
|
||||||
|
@resetFormItemData="resetFormItemData"
|
||||||
|
/>
|
||||||
|
<el-form-item style="text-align: right">
|
||||||
|
<el-button
|
||||||
|
size="small"
|
||||||
|
@click="addOrEdit.visible = false"
|
||||||
|
>
|
||||||
|
{{ $t('common:button:cancel') }}
|
||||||
|
</el-button>
|
||||||
|
<!-- 保存 -->
|
||||||
|
<el-button size="small" class="my_upload_btn" @click="saveFormData">
|
||||||
|
{{ $t('common:button:save') }}
|
||||||
|
</el-button>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
</el-dialog>
|
||||||
|
<!-- 导入 -->
|
||||||
|
<el-dialog
|
||||||
|
v-if="upload.visible"
|
||||||
|
:visible.sync="upload.visible"
|
||||||
|
:close-on-click-modal="false"
|
||||||
|
:title="upload.title"
|
||||||
|
width="500px"
|
||||||
|
>
|
||||||
|
<UploadExcel
|
||||||
|
:visit-task-id="visitTaskId"
|
||||||
|
@close="uploadDlgClose"
|
||||||
|
/>
|
||||||
|
</el-dialog>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<script>
|
||||||
|
import { saveTaskQuestion, submitTableQuestion, deleteReadingRowAnswer } from '@/api/trials'
|
||||||
|
import { resetReadingTask, getIVUSTemplate } from '@/api/reading'
|
||||||
|
import DicomEvent from './../DicomEvent'
|
||||||
|
import store from '@/store'
|
||||||
|
import { mapGetters } from 'vuex'
|
||||||
|
import Questions from './../Questions'
|
||||||
|
import QuestionTableFormItem from './QuestionTableFormItem'
|
||||||
|
import UploadExcel from './UploadExcel'
|
||||||
|
export default {
|
||||||
|
name: 'MeasurementList',
|
||||||
|
components: {
|
||||||
|
Questions,
|
||||||
|
QuestionTableFormItem,
|
||||||
|
UploadExcel
|
||||||
|
},
|
||||||
|
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 {
|
||||||
|
questions: [],
|
||||||
|
visitTaskId: '',
|
||||||
|
isCurrentTask: false,
|
||||||
|
loading: false,
|
||||||
|
readingTaskState: 2,
|
||||||
|
isBaseLineTask: false,
|
||||||
|
taskBlindName: '',
|
||||||
|
tableQuestions: [],
|
||||||
|
CriterionType: null,
|
||||||
|
subjectCode: '',
|
||||||
|
questionForm: {},
|
||||||
|
formChanged: false,
|
||||||
|
digitPlaces: 2,
|
||||||
|
addOrEdit: { visible: false, title: '' },
|
||||||
|
upload: { visible: false, title: '' },
|
||||||
|
qsList: [],
|
||||||
|
answersList: [],
|
||||||
|
qsForm: {},
|
||||||
|
diffId: '',
|
||||||
|
eemId: '',
|
||||||
|
lumenId: ''
|
||||||
|
}
|
||||||
|
},
|
||||||
|
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')
|
||||||
|
this.digitPlaces = Number(localStorage.getItem('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()
|
||||||
|
})
|
||||||
|
},
|
||||||
|
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
|
||||||
|
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)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
},
|
||||||
|
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.Type === 'basicTable') && 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.Type === 'basicTable') && 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
|
||||||
|
},
|
||||||
|
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
|
||||||
|
}
|
||||||
|
})
|
||||||
|
loading.close()
|
||||||
|
resolve()
|
||||||
|
} catch (e) { console.log(e) }
|
||||||
|
})
|
||||||
|
},
|
||||||
|
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: '' }
|
||||||
|
},
|
||||||
|
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
|
||||||
|
},
|
||||||
|
modifyMeasuredData(measureObj) {
|
||||||
|
},
|
||||||
|
// 设置测量数据
|
||||||
|
setMeasuredData(measureData) {
|
||||||
|
|
||||||
|
},
|
||||||
|
formItemChange() {
|
||||||
|
this.formChanged = true
|
||||||
|
},
|
||||||
|
limitBlur(qId, valueType) {
|
||||||
|
const value = this.questionForm[qId]
|
||||||
|
if (isNaN(parseInt(value))) {
|
||||||
|
this.$set(this.questionForm, qId, '')
|
||||||
|
} else {
|
||||||
|
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, this.numberToFixed(value))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
numberToFixed(v) {
|
||||||
|
if (this.digitPlaces > -1) {
|
||||||
|
return isNaN(parseFloat(v)) ? null : `${parseFloat(v).toFixed(this.digitPlaces)}`
|
||||||
|
} else {
|
||||||
|
return v
|
||||||
|
}
|
||||||
|
},
|
||||||
|
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()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
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) {
|
||||||
|
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 this.getReadingQuestionAndAnswer(this.visitTaskId)
|
||||||
|
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) {
|
||||||
|
},
|
||||||
|
resetFormItemData(v) {
|
||||||
|
this.qsForm[v] = null
|
||||||
|
},
|
||||||
|
setFormItemData(obj) {
|
||||||
|
this.qsForm[obj.key] = obj.val
|
||||||
|
if (obj.key === this.eemId || obj.key === this.lumenId) {
|
||||||
|
const eem = this.qsForm[this.eemId]
|
||||||
|
const lumen = this.qsForm[this.lumenId]
|
||||||
|
if (isNaN(parseFloat(eem)) || isNaN(parseFloat(lumen))) {
|
||||||
|
this.$set(this.qsForm, this.diffId, null)
|
||||||
|
} else {
|
||||||
|
const diff = parseFloat(eem) - parseFloat(lumen)
|
||||||
|
this.$set(this.qsForm, this.diffId, this.numberToFixed(diff))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
handleAddOrEdit(type, row, index) {
|
||||||
|
this.addOrEdit.title = row.QuestionName
|
||||||
|
this.qsList = row.TableQuestions.Questions
|
||||||
|
this.qsForm = {}
|
||||||
|
this.qsForm.questionId = row.Id
|
||||||
|
this.qsForm.rowId = type === 'add' ? null : row.TableQuestions.Answers && row.TableQuestions.Answers[index] ? row.TableQuestions.Answers[index].RowId : null
|
||||||
|
if (type === 'add') {
|
||||||
|
var maxIndex = this.getMaxRowIndex(row.TableQuestions.Answers)
|
||||||
|
this.qsForm.rowIndex = `${maxIndex + 1}.00`
|
||||||
|
} else {
|
||||||
|
this.qsForm.rowIndex = row.TableQuestions.Answers && row.TableQuestions.Answers[index] ? row.TableQuestions.Answers[index].RowIndex : null
|
||||||
|
}
|
||||||
|
row.TableQuestions.Questions.map(i => {
|
||||||
|
if (i.QuestionMark === 1001) {
|
||||||
|
this.eemId = i.Id
|
||||||
|
}
|
||||||
|
if (i.QuestionMark === 1002) {
|
||||||
|
this.lumenId = i.Id
|
||||||
|
}
|
||||||
|
if (i.QuestionMark === 1003) {
|
||||||
|
this.diffId = i.Id
|
||||||
|
}
|
||||||
|
let v = null
|
||||||
|
if (type === 'add') {
|
||||||
|
v = i.Type === 'number' ? undefined : null
|
||||||
|
} else {
|
||||||
|
v = row.TableQuestions.Answers && row.TableQuestions.Answers[index] ? row.TableQuestions.Answers[index][i.Id] : null
|
||||||
|
}
|
||||||
|
this.$set(this.qsForm, i.Id, v)
|
||||||
|
})
|
||||||
|
this.addOrEdit.visible = true
|
||||||
|
},
|
||||||
|
async saveFormData() {
|
||||||
|
const valid = await this.$refs.tableQsForm.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.qsForm) {
|
||||||
|
if (reg.test(k)) {
|
||||||
|
if (answers.findIndex(i => i.tableQuestionId === k) === -1) {
|
||||||
|
answers.push({ tableQuestionId: k, answer: this.qsForm[k] })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var params = {
|
||||||
|
questionId: this.qsForm.questionId,
|
||||||
|
rowId: this.qsForm.rowId,
|
||||||
|
rowIndex: this.qsForm.rowIndex,
|
||||||
|
visitTaskId: this.visitTaskId,
|
||||||
|
trialId: this.trialId,
|
||||||
|
answerList: answers
|
||||||
|
}
|
||||||
|
const res = await submitTableQuestion(params)
|
||||||
|
if (res.IsSuccess) {
|
||||||
|
// this.refreshQuestions()
|
||||||
|
await this.getReadingQuestionAndAnswer(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)
|
||||||
|
// 保存成功!
|
||||||
|
this.addOrEdit.visible = false
|
||||||
|
this.$message.success(this.$t('common:message:savedSuccessfully'))
|
||||||
|
}
|
||||||
|
loading.close()
|
||||||
|
} catch (e) {
|
||||||
|
console.log(e)
|
||||||
|
loading.close()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
async handleDelete(row, index) {
|
||||||
|
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 (row.TableQuestions.Answers[index].RowId) {
|
||||||
|
var param = {
|
||||||
|
visitTaskId: this.visitTaskId,
|
||||||
|
questionId: row.Id,
|
||||||
|
rowId: row.TableQuestions.Answers[index].RowId
|
||||||
|
}
|
||||||
|
const res = await deleteReadingRowAnswer(param)
|
||||||
|
if (res.IsSuccess) {
|
||||||
|
await this.getReadingQuestionAndAnswer(this.visitTaskId)
|
||||||
|
DicomEvent.$emit('getReportInfo', true)
|
||||||
|
// '删除成功!'
|
||||||
|
this.$message.success(this.$t('common:message:deletedSuccessfully'))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
loading.close()
|
||||||
|
} catch (e) {
|
||||||
|
loading.close()
|
||||||
|
console.log(e)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
uploadTpl(lesionType) {
|
||||||
|
this.upload.title = `导入( ${this.$fd('LesionType', lesionType)} )`
|
||||||
|
this.upload.visible = true
|
||||||
|
},
|
||||||
|
async downloadTpl() {
|
||||||
|
try {
|
||||||
|
const params = {
|
||||||
|
visitTaskId: this.visitTaskId
|
||||||
|
}
|
||||||
|
await getIVUSTemplate(params)
|
||||||
|
} catch (e) {
|
||||||
|
console.log(e)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
async uploadDlgClose() {
|
||||||
|
await this.getReadingQuestionAndAnswer(this.visitTaskId)
|
||||||
|
DicomEvent.$emit('getReportInfo', true)
|
||||||
|
this.upload.visible = false
|
||||||
|
},
|
||||||
|
renderHeader(h, { column, $index }) {
|
||||||
|
const span = document.createElement('span')
|
||||||
|
span.innerText = column.label
|
||||||
|
document.body.appendChild(span)
|
||||||
|
const w = span.getBoundingClientRect().width
|
||||||
|
column.minWidth = w > 65 ? w + 10 : w > 60 ? w + 15 : w + 20
|
||||||
|
document.body.removeChild(span)
|
||||||
|
return h('span', column.label)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.measurement-wrapper{
|
||||||
|
height: 100%;
|
||||||
|
overflow-y: auto;
|
||||||
|
.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{
|
||||||
|
display: inline-block;
|
||||||
|
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-textarea__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;
|
||||||
|
}
|
||||||
|
|
||||||
|
.el-form-item__content
|
||||||
|
.el-select{
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.table-wrapper {
|
||||||
|
::-webkit-scrollbar {
|
||||||
|
width: 5px;
|
||||||
|
height: 8px;
|
||||||
|
}
|
||||||
|
::-webkit-scrollbar-thumb {
|
||||||
|
border-radius: 10px;
|
||||||
|
background: #d0d0d0;
|
||||||
|
}
|
||||||
|
/deep/ .el-table,
|
||||||
|
.el-table__expanded-cell {
|
||||||
|
background-color: #000;
|
||||||
|
color: #fff;
|
||||||
|
border-color: #444444;
|
||||||
|
}
|
||||||
|
/deep/ .el-table th,
|
||||||
|
.el-table tr {
|
||||||
|
background-color: #000;
|
||||||
|
color: #fff;
|
||||||
|
border-color: #444444;
|
||||||
|
}
|
||||||
|
/deep/ .el-table__body tr > td {
|
||||||
|
background-color: #000 !important;
|
||||||
|
color: #fff;
|
||||||
|
border-color: #444444;
|
||||||
|
}
|
||||||
|
/deep/ .el-table__body tr:hover > td {
|
||||||
|
background-color: #858282 !important;
|
||||||
|
color: #fff;
|
||||||
|
border-color: #444444;
|
||||||
|
}
|
||||||
|
/deep/ .el-table--border th.gutter:last-of-type {
|
||||||
|
border: none;
|
||||||
|
}
|
||||||
|
/deep/ .el-table__fixed-right {
|
||||||
|
height: 100% !important;
|
||||||
|
}
|
||||||
|
// /deep/ .el-table .cell {
|
||||||
|
// line-height: 20px;
|
||||||
|
// }
|
||||||
|
/deep/ .el-table__cell {
|
||||||
|
padding: 5px 0;
|
||||||
|
}
|
||||||
|
/deep/.el-table__fixed-right-patch {
|
||||||
|
background-color: #000 !important;
|
||||||
|
border-color: #444444;
|
||||||
|
}
|
||||||
|
/deep/.el-table__fixed-body-wrapper tr:hover > td {
|
||||||
|
background-color: #000 !important;
|
||||||
|
}
|
||||||
|
/deep/.el-table--scrollable-x .el-table__body-wrapper {
|
||||||
|
z-index: 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
@ -0,0 +1,297 @@
|
||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<div
|
||||||
|
v-if="!!question.GroupName && question.Type==='group'"
|
||||||
|
>
|
||||||
|
<h4 style="color: #ddd;padding: 5px 0px;margin: 0;">
|
||||||
|
{{ language==='en'?question.GroupEnName:question.GroupName }}
|
||||||
|
</h4>
|
||||||
|
</div>
|
||||||
|
<template v-else>
|
||||||
|
<el-form-item
|
||||||
|
v-if="(question.ShowQuestion===1 && question.ParentTriggerValueList.includes(String(questionForm[question.ParentId]))) || question.ShowQuestion===0 "
|
||||||
|
:label="`${question.QuestionName}`"
|
||||||
|
:prop="question.Id"
|
||||||
|
:rules="[
|
||||||
|
{ required: (question.IsRequired === 0 || (question.IsRequired ===1 && question.RelevanceId && (questionForm[question.RelevanceId] === question.RelevanceValue))) && question.Type!=='group' && question.Type!=='summary',
|
||||||
|
message: ['radio', 'select', 'checkbox'].includes(question.Type) ? $t('common:ruleMessage:select') : $t('common:ruleMessage:specify'), trigger: ['blur', 'change']},
|
||||||
|
]"
|
||||||
|
:class="[question.Type==='group' ? 'mb' : (question.Type==='upload' || question.QuestionName.length > 15) ?'uploadWrapper' : '']"
|
||||||
|
>
|
||||||
|
<!-- 输入框 -->
|
||||||
|
<el-input
|
||||||
|
v-if="question.Type==='input'"
|
||||||
|
v-model="questionForm[question.Id]"
|
||||||
|
:disabled="readingTaskState >= 2"
|
||||||
|
@change="((val)=>{formItemChange(val, question)})"
|
||||||
|
/>
|
||||||
|
<!-- 多行文本输入框 -->
|
||||||
|
<el-input
|
||||||
|
v-else-if="question.Type==='textarea'"
|
||||||
|
v-model="questionForm[question.Id]"
|
||||||
|
type="textarea"
|
||||||
|
:autosize="{ minRows: 2, maxRows: 4}"
|
||||||
|
maxlength="500"
|
||||||
|
:disabled="readingTaskState >= 2"
|
||||||
|
@change="((val)=>{formItemChange(val, question)})"
|
||||||
|
/>
|
||||||
|
<!-- 下拉框 -->
|
||||||
|
<el-select
|
||||||
|
v-else-if="question.Type==='select'"
|
||||||
|
v-model="questionForm[question.Id]"
|
||||||
|
:disabled="readingTaskState >= 2 || ((question.TableQuestionType === 2 || question.QuestionGenre === 2) && !!question.DictionaryCode)"
|
||||||
|
clearable
|
||||||
|
@change="((val)=>{formItemChange(val, question)})"
|
||||||
|
>
|
||||||
|
<template v-if="question.TableQuestionType === 1">
|
||||||
|
<el-option
|
||||||
|
v-for="item in organList"
|
||||||
|
:key="item.Id"
|
||||||
|
:label="item[question.DataTableColumn]"
|
||||||
|
:value="item[question.DataTableColumn]"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
<template v-else-if="question.TableQuestionType === 3 || question.QuestionGenre === 3">
|
||||||
|
<el-option
|
||||||
|
v-for="item of $d[question.DictionaryCode]"
|
||||||
|
:key="item.id"
|
||||||
|
:value="String(item.value)"
|
||||||
|
:label="item.label"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
<template v-else-if="(question.TableQuestionType === 2 || question.QuestionGenre === 2) && question.DictionaryCode">
|
||||||
|
<el-option
|
||||||
|
v-for="item of $d[question.DictionaryCode]"
|
||||||
|
:key="item.id"
|
||||||
|
:value="String(item.value)"
|
||||||
|
:label="item.label"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
<template v-else>
|
||||||
|
<el-option
|
||||||
|
v-for="val in question.TypeValue.split('|')"
|
||||||
|
:key="val"
|
||||||
|
:label="val"
|
||||||
|
:value="val"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
</el-select>
|
||||||
|
<!-- 单选 -->
|
||||||
|
<el-radio-group
|
||||||
|
v-else-if="question.Type==='radio'"
|
||||||
|
v-model="questionForm[question.Id]"
|
||||||
|
:disabled="readingTaskState >= 2"
|
||||||
|
@change="((val)=>{formItemChange(val, question)})"
|
||||||
|
>
|
||||||
|
<template v-if="question.DictionaryCode">
|
||||||
|
<el-radio
|
||||||
|
v-for="item of $d[question.DictionaryCode]"
|
||||||
|
:key="item.id"
|
||||||
|
:label="String(item.value)"
|
||||||
|
>
|
||||||
|
{{ item.label }}
|
||||||
|
</el-radio>
|
||||||
|
</template>
|
||||||
|
<template v-else-if="question.TypeValue">
|
||||||
|
<el-radio
|
||||||
|
v-for="val in question.TypeValue.split('|')"
|
||||||
|
:key="val"
|
||||||
|
:label="val"
|
||||||
|
>
|
||||||
|
{{ val }}
|
||||||
|
</el-radio>
|
||||||
|
</template>
|
||||||
|
</el-radio-group>
|
||||||
|
<!-- 复选框 -->
|
||||||
|
<el-checkbox-group
|
||||||
|
v-else-if="question.Type==='checkbox'"
|
||||||
|
v-model="questionForm[question.Id]"
|
||||||
|
:disabled="readingTaskState >= 2"
|
||||||
|
@change="((val)=>{formItemChange(val, question)})"
|
||||||
|
>
|
||||||
|
<el-checkbox
|
||||||
|
v-for="val in question.TypeValue.split('|')"
|
||||||
|
:key="val"
|
||||||
|
:label="val"
|
||||||
|
>
|
||||||
|
{{ val }}
|
||||||
|
</el-checkbox>
|
||||||
|
</el-checkbox-group>
|
||||||
|
<!-- 数值 -->
|
||||||
|
<!-- <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"
|
||||||
|
style="width: 100%"
|
||||||
|
@change="((val)=>{formItemChange(val, question)})"
|
||||||
|
/>
|
||||||
|
<el-input-number
|
||||||
|
v-else-if="question.ValueType === 3"
|
||||||
|
v-model="questionForm[question.Id]"
|
||||||
|
:disabled="readingTaskState >= 2"
|
||||||
|
style="width: 100%"
|
||||||
|
@change="((val)=>{formItemChange(val, question)})"
|
||||||
|
/>
|
||||||
|
<el-input-number
|
||||||
|
v-else-if="question.ValueType === 1 || question.ValueType === 2"
|
||||||
|
v-model="questionForm[question.Id]"
|
||||||
|
:precision="digitPlaces"
|
||||||
|
:disabled="readingTaskState >= 2"
|
||||||
|
style="width: 100%"
|
||||||
|
@change="((val)=>{formItemChange(val, question)})"
|
||||||
|
/>
|
||||||
|
</template> -->
|
||||||
|
<!-- 数值类型 -->
|
||||||
|
<el-input
|
||||||
|
v-else-if="question.Type==='number'"
|
||||||
|
v-model="questionForm[question.Id]"
|
||||||
|
:disabled="readingTaskState>=2 "
|
||||||
|
type="number"
|
||||||
|
@change="((val)=>{formItemChange(val, question)})"
|
||||||
|
>
|
||||||
|
<template v-if="question.Unit" slot="append">
|
||||||
|
{{ $fd('ValueUnit', parseInt(question.Unit)) }}
|
||||||
|
</template>
|
||||||
|
</el-input>
|
||||||
|
|
||||||
|
<el-input
|
||||||
|
v-else-if="question.Type==='calculation'"
|
||||||
|
v-model="questionForm[question.Id]"
|
||||||
|
disabled
|
||||||
|
@change="((val)=>{formItemChange(val, question)})"
|
||||||
|
>
|
||||||
|
<template v-if="question.Unit" slot="append">
|
||||||
|
{{ $fd('ValueUnit', parseInt(question.Unit)) }}
|
||||||
|
</template>
|
||||||
|
</el-input>
|
||||||
|
</el-form-item>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<QuestionTableFormItem
|
||||||
|
v-for="item in question.Childrens"
|
||||||
|
:key="item.Id"
|
||||||
|
:question="item"
|
||||||
|
:question-form="questionForm"
|
||||||
|
:reading-task-state="readingTaskState"
|
||||||
|
@setFormItemData="setFormItemData"
|
||||||
|
@resetFormItemData="resetFormItemData"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<script>
|
||||||
|
import { mapGetters } from 'vuex'
|
||||||
|
export default {
|
||||||
|
name: 'QuestionTableFormItem',
|
||||||
|
props: {
|
||||||
|
questionForm: {
|
||||||
|
type: Object,
|
||||||
|
default() {
|
||||||
|
return {}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
question: {
|
||||||
|
type: Object,
|
||||||
|
default() {
|
||||||
|
return []
|
||||||
|
}
|
||||||
|
},
|
||||||
|
readingTaskState: {
|
||||||
|
type: Number,
|
||||||
|
required: true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
digitPlaces: 2
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
...mapGetters(['language'])
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this.digitPlaces = Number(localStorage.getItem('digitPlaces'))
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
formItemChange(v, question) {
|
||||||
|
if (question.Childrens && question.Childrens.length > 0) {
|
||||||
|
this.resetChild(question.Childrens)
|
||||||
|
} else {
|
||||||
|
if (question.Type === 'number') {
|
||||||
|
v = this.limitBlur(question.ValueType, v)
|
||||||
|
}
|
||||||
|
this.$emit('setFormItemData', { key: question.Id, val: v })
|
||||||
|
}
|
||||||
|
},
|
||||||
|
resetChild(obj) {
|
||||||
|
obj.forEach(i => {
|
||||||
|
this.$emit('resetFormItemData', i.Id)
|
||||||
|
if (i.Childrens && i.Childrens.length > 0) {
|
||||||
|
this.resetChild(i.Childrens)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
limitBlur(valueType, value) {
|
||||||
|
if (isNaN(parseInt(value))) {
|
||||||
|
value = null
|
||||||
|
} else {
|
||||||
|
if (valueType === 0) {
|
||||||
|
value = parseInt(value)
|
||||||
|
} else if (valueType === 3) {
|
||||||
|
value = parseFloat(value)
|
||||||
|
} else {
|
||||||
|
value = this.numberToFixed(value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return value
|
||||||
|
},
|
||||||
|
numberToFixed(v) {
|
||||||
|
if (this.digitPlaces > -1) {
|
||||||
|
return isNaN(parseFloat(v)) ? null : `${parseFloat(v).toFixed(this.digitPlaces)}`
|
||||||
|
} else {
|
||||||
|
return v
|
||||||
|
}
|
||||||
|
},
|
||||||
|
resetFormItemData(v) {
|
||||||
|
this.$emit('resetFormItemData', v)
|
||||||
|
},
|
||||||
|
setFormItemData(obj) {
|
||||||
|
this.$emit('setFormItemData', obj)
|
||||||
|
},
|
||||||
|
limitNumbersEvent(e) {
|
||||||
|
// 通过正则保留两位小数点
|
||||||
|
let val = e.target.value
|
||||||
|
if (val.length > 6) val = val.slice(0, 6)
|
||||||
|
e.target.value = (val.match(/^\d*(\.?\d{0,3})/g)[0]) || null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.mb{
|
||||||
|
margin-bottom: 0px;
|
||||||
|
}
|
||||||
|
.disabled{
|
||||||
|
/deep/ .el-upload--picture-card {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.uploadWrapper{
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column !important;
|
||||||
|
align-items: flex-start;
|
||||||
|
}
|
||||||
|
/deep/ .el-input.is-disabled .el-input__inner{
|
||||||
|
background-color: #646464a1;
|
||||||
|
}
|
||||||
|
/deep/ .el-input-group__append, .el-input-group__prepend{
|
||||||
|
padding: 0 10px;
|
||||||
|
}
|
||||||
|
/deep/ .el-form-item__content {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
/deep/ .el-select.is-disabled .el-input__inner{
|
||||||
|
background-color: #646464a1;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
@ -0,0 +1,117 @@
|
||||||
|
<template>
|
||||||
|
<el-form
|
||||||
|
ref="uploadExcel"
|
||||||
|
class="upload-excel-file"
|
||||||
|
>
|
||||||
|
<!-- 文件 -->
|
||||||
|
<el-form-item :label="$t('trials:consistencyCheck:label:file')">
|
||||||
|
<div class="upload-container">
|
||||||
|
<el-upload
|
||||||
|
class="upload-demo"
|
||||||
|
action
|
||||||
|
accept=".xlsx,.xls,.csv"
|
||||||
|
:before-upload="beforeUpload"
|
||||||
|
:http-request="handleUploadFile"
|
||||||
|
:on-preview="handlePreview"
|
||||||
|
:show-file-list="true"
|
||||||
|
:limit="1"
|
||||||
|
:on-exceed="handleExceed"
|
||||||
|
>
|
||||||
|
<el-button size="small" type="primary">
|
||||||
|
{{ $t('trials:consistencyCheck:dialogButton:upload') }}
|
||||||
|
</el-button>
|
||||||
|
<span
|
||||||
|
slot="tip"
|
||||||
|
style="margin-left:10px;"
|
||||||
|
class="el-upload__tip"
|
||||||
|
>
|
||||||
|
({{ $t('trials:consistencyCheck:message:excelFileOnly') }})
|
||||||
|
</span>
|
||||||
|
</el-upload>
|
||||||
|
</div>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
</template>
|
||||||
|
<script>
|
||||||
|
import { uploadIVUSTemplate } from '@/api/reading'
|
||||||
|
export default {
|
||||||
|
props: {
|
||||||
|
visitTaskId: {
|
||||||
|
type: String,
|
||||||
|
required: true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
beforeUpload(file) {
|
||||||
|
// 检测文件类型是否符合要求
|
||||||
|
if (this.checkFileSuffix(file.name)) {
|
||||||
|
return true
|
||||||
|
} else {
|
||||||
|
// Must be xls or xlsx format
|
||||||
|
this.$alert(this.$t('trials:consistencyCheck:message:xlsx'))
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
async handleUploadFile(param) {
|
||||||
|
const loading = this.$loading({ fullscreen: true })
|
||||||
|
try {
|
||||||
|
var data = new FormData()
|
||||||
|
data.append('file', param.file)
|
||||||
|
data.append('visitTaskId', this.visitTaskId)
|
||||||
|
await uploadIVUSTemplate(data)
|
||||||
|
this.$emit('close')
|
||||||
|
this.$message.success('导入成功!')
|
||||||
|
loading.close()
|
||||||
|
} catch (e) {
|
||||||
|
loading.close()
|
||||||
|
console.log(e)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
handlePreview(file) {
|
||||||
|
if (file.fullPath) {
|
||||||
|
window.open(file.fullPath, '_blank')
|
||||||
|
}
|
||||||
|
},
|
||||||
|
handleExceed(files, fileList) {
|
||||||
|
// Upload is currently limited to 1 file
|
||||||
|
this.$message.warning(this.$t('trials:consistencyCheck:message:onlyOneFile'))
|
||||||
|
},
|
||||||
|
checkFileSuffix(fileName) {
|
||||||
|
var typeArr = ['xls', 'xlsx', 'csv']
|
||||||
|
var extendName = fileName.substring(fileName.lastIndexOf('.') + 1).toLocaleLowerCase()
|
||||||
|
if (typeArr.indexOf(extendName) !== -1) {
|
||||||
|
return true
|
||||||
|
} else {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss">
|
||||||
|
.upload-excel-file{
|
||||||
|
.upload-container .el-upload--text {
|
||||||
|
border: none;
|
||||||
|
width: 80px;
|
||||||
|
height: 40px;
|
||||||
|
}
|
||||||
|
.upload-container .el-input--small {
|
||||||
|
margin-bottom: 5px;
|
||||||
|
}
|
||||||
|
.upload-container .el-icon-circle-check {
|
||||||
|
color: #428bca;
|
||||||
|
font-size: 13px;
|
||||||
|
}
|
||||||
|
.account_item_clear{
|
||||||
|
.el-tag__close{
|
||||||
|
display: none !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</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()
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="measurement-wrapper" :style="{'height':height+10+'px'}">
|
<div class="measurement-wrapper">
|
||||||
|
|
||||||
<div class="container" :style="{'height':height+'px'}">
|
<div class="container">
|
||||||
<div class="basic-info">
|
<div class="basic-info">
|
||||||
<h3 v-if="isReadingShowSubjectInfo">
|
<h3 v-if="isReadingShowSubjectInfo">
|
||||||
<span v-if="subjectCode">{{ subjectCode }} </span>
|
<span v-if="subjectCode">{{ subjectCode }} </span>
|
||||||
|
|
@ -262,7 +262,6 @@ export default {
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
height: window.innerHeight - 140,
|
|
||||||
questions: [],
|
questions: [],
|
||||||
activeName: '',
|
activeName: '',
|
||||||
activeItem: {
|
activeItem: {
|
||||||
|
|
@ -359,8 +358,6 @@ export default {
|
||||||
}
|
}
|
||||||
callback(true)
|
callback(true)
|
||||||
})
|
})
|
||||||
|
|
||||||
window.addEventListener('resize', this.setHeight)
|
|
||||||
},
|
},
|
||||||
beforeDestroy() {
|
beforeDestroy() {
|
||||||
DicomEvent.$off('setCollapseActive')
|
DicomEvent.$off('setCollapseActive')
|
||||||
|
|
@ -573,9 +570,6 @@ export default {
|
||||||
} catch (e) { console.log(e) }
|
} catch (e) { console.log(e) }
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
setHeight() {
|
|
||||||
this.height = window.innerHeight - 140
|
|
||||||
},
|
|
||||||
getQuestionAnswer(questions, questionMark, answers) {
|
getQuestionAnswer(questions, questionMark, answers) {
|
||||||
var idx = questions.findIndex(i => i.QuestionMark === questionMark)
|
var idx = questions.findIndex(i => i.QuestionMark === questionMark)
|
||||||
if (idx > -1) {
|
if (idx > -1) {
|
||||||
|
|
@ -1347,9 +1341,8 @@ export default {
|
||||||
</script>
|
</script>
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
.measurement-wrapper{
|
.measurement-wrapper{
|
||||||
|
height: 100%;
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
// overflow: hidden;
|
|
||||||
|
|
||||||
.container{
|
.container{
|
||||||
padding: 10px;
|
padding: 10px;
|
||||||
.basic-info{
|
.basic-info{
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,7 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="right-wrapper">
|
<div class="right-wrapper">
|
||||||
<div class="right-content">
|
<div class="right-content">
|
||||||
<iframe v-if="selected.filePath" :src="`/static/pdfjs/web/viewer.html?file=${OSSclientConfig.basePath}${selected.filePath}?userName=${currentUser}`" width="100%" height="100%" frameborder="0" />
|
<iframe v-if="selected.filePath" :src="`/static/pdfjs/web/viewer.html?file=${OSSclientConfig.basePath}${selected.filePath}?userName=${currentUser}&COMPANY=${COMPANY}`" width="100%" height="100%" frameborder="0" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -44,7 +44,8 @@ export default {
|
||||||
},
|
},
|
||||||
fileList: [],
|
fileList: [],
|
||||||
loading: false,
|
loading: false,
|
||||||
currentUser: zzSessionStorage.getItem('userName')
|
currentUser: zzSessionStorage.getItem('userName'),
|
||||||
|
COMPANY:process.env.VUE_APP_COMPANY_NAME
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,887 @@
|
||||||
|
<template>
|
||||||
|
<div class="measurement-wrapper">
|
||||||
|
<div class="container">
|
||||||
|
<div class="basic-info">
|
||||||
|
<h3 v-if="isReadingShowSubjectInfo">
|
||||||
|
<span v-if="subjectCode">{{ subjectCode }} </span>
|
||||||
|
<span style="margin-left:5px;">{{ taskBlindName }}</span>
|
||||||
|
</h3>
|
||||||
|
<div v-if="readingTaskState < 2">
|
||||||
|
<el-tooltip class="item" effect="dark" :content="$t('trials:dicomReading:message:confirmReset')" placement="bottom">
|
||||||
|
<i
|
||||||
|
class="el-icon-refresh-left"
|
||||||
|
@click="resetMeasuredData"
|
||||||
|
/>
|
||||||
|
</el-tooltip>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 影像质量问题 -->
|
||||||
|
<div class="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">
|
||||||
|
<div v-for="(qs,index) in questions" :key="index" v-loading="loading" class="lesions lesions_wrapper" style="margin-bottom: 10px">
|
||||||
|
<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="table-wrapper">
|
||||||
|
<div v-for="item in qs.Childrens" :key="item.Id">
|
||||||
|
<div v-if="item.Type === 'basicTable'" class="flex-row" style="margin:3px 0;">
|
||||||
|
<div class="title">{{ item.QuestionName }}</div>
|
||||||
|
<div v-if="(item.LesionType === 112 || item.LesionType === 111) && readingTaskState < 2">
|
||||||
|
<div class="add-icon" @click.prevent="downloadTpl(item.LesionType)">
|
||||||
|
<i class="el-icon-download" />
|
||||||
|
</div>
|
||||||
|
<div class="add-icon" style="margin: 0 5px;" @click.prevent="uploadTpl(item.LesionType)">
|
||||||
|
<i class="el-icon-upload2" />
|
||||||
|
</div>
|
||||||
|
<div class="add-icon" @click.prevent="handleAddOrEdit('add',item)">
|
||||||
|
<i class="el-icon-plus" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<el-table
|
||||||
|
v-if="item.Type === 'basicTable' && item.TableQuestions"
|
||||||
|
:ref="item.Id"
|
||||||
|
:data="item.TableQuestions.Answers"
|
||||||
|
max-height="600"
|
||||||
|
>
|
||||||
|
<!-- <el-table-column :label="$t('CustomizeQuestionFormItem:label:OrderMark')" width="60px" show-overflow-tooltip>
|
||||||
|
<template slot-scope="scope">
|
||||||
|
{{ getLesionName(item.OrderMark,scope.row.RowIndex) }}
|
||||||
|
</template>
|
||||||
|
</el-table-column> -->
|
||||||
|
<!-- <el-table-column
|
||||||
|
type="index"
|
||||||
|
width="40px"
|
||||||
|
/> -->
|
||||||
|
<el-table-column
|
||||||
|
v-for="q of item.TableQuestions.Questions"
|
||||||
|
:key="q.Id"
|
||||||
|
:prop="q.Id"
|
||||||
|
:label="q.QuestionName"
|
||||||
|
show-overflow-tooltip
|
||||||
|
:render-header="renderHeader"
|
||||||
|
>
|
||||||
|
<template slot-scope="scope">
|
||||||
|
<span v-if="q.Unit > 0 && !isNaN(parseFloat(scope.row[q.Id]))">
|
||||||
|
{{ `${scope.row[q.Id]} ${$fd('ValueUnit', parseInt(q.Unit))}` }}
|
||||||
|
</span>
|
||||||
|
<span v-else-if="q.DictionaryCode">
|
||||||
|
{{ `${$fd(q.DictionaryCode, parseInt(scope.row[q.Id]))}` }}
|
||||||
|
</span>
|
||||||
|
<span v-else>
|
||||||
|
{{ `${scope.row[q.Id]}` }}
|
||||||
|
</span>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column
|
||||||
|
v-if="readingTaskState < 2"
|
||||||
|
:label="$t('common:action:action')"
|
||||||
|
width="90px"
|
||||||
|
fixed="right"
|
||||||
|
>
|
||||||
|
<template slot-scope="scope">
|
||||||
|
<el-button type="text" size="mini" @click="handleAddOrEdit('edit',item, scope.$index)">
|
||||||
|
{{ $t('common:button:edit') }}
|
||||||
|
</el-button>
|
||||||
|
<el-button v-if="item.LesionType === 112 || item.LesionType === 111" type="text" size="mini" @click="handleDelete(item, scope.$index)">
|
||||||
|
{{ $t('common:button:delete') }}
|
||||||
|
</el-button>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
|
||||||
|
<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==='textarea'">
|
||||||
|
<el-input
|
||||||
|
v-model="questionForm[qs.Id]"
|
||||||
|
type="textarea"
|
||||||
|
:autosize="{ minRows: 2, maxRows: 4}"
|
||||||
|
:disabled="!isCurrentTask || readingTaskState>=2"
|
||||||
|
@change="((val)=>{formItemChange(val, qs)})"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
</el-form-item>
|
||||||
|
</template>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
v-if="isCurrentTask && readingTaskState<2 && qs.GroupClassify === 5"
|
||||||
|
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"
|
||||||
|
/>
|
||||||
|
<el-dialog
|
||||||
|
v-if="addOrEdit.visible"
|
||||||
|
:visible.sync="addOrEdit.visible"
|
||||||
|
:close-on-click-modal="false"
|
||||||
|
:title="addOrEdit.title"
|
||||||
|
width="500px"
|
||||||
|
>
|
||||||
|
<el-form
|
||||||
|
ref="tableQsForm"
|
||||||
|
v-loading="loading"
|
||||||
|
:model="qsForm"
|
||||||
|
size="small"
|
||||||
|
>
|
||||||
|
<QuestionTableFormItem
|
||||||
|
v-for="item in qsList"
|
||||||
|
:key="item.Id"
|
||||||
|
:question="item"
|
||||||
|
:question-form="qsForm"
|
||||||
|
:reading-task-state="readingTaskState"
|
||||||
|
@setFormItemData="setFormItemData"
|
||||||
|
@resetFormItemData="resetFormItemData"
|
||||||
|
/>
|
||||||
|
<el-form-item style="text-align: right">
|
||||||
|
<el-button
|
||||||
|
size="small"
|
||||||
|
@click="addOrEdit.visible = false"
|
||||||
|
>
|
||||||
|
{{ $t('common:button:cancel') }}
|
||||||
|
</el-button>
|
||||||
|
<!-- 保存 -->
|
||||||
|
<el-button size="small" class="my_upload_btn" @click="saveFormData">
|
||||||
|
{{ $t('common:button:save') }}
|
||||||
|
</el-button>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
</el-dialog>
|
||||||
|
<!-- 导入 -->
|
||||||
|
<el-dialog
|
||||||
|
v-if="upload.visible"
|
||||||
|
:visible.sync="upload.visible"
|
||||||
|
:close-on-click-modal="false"
|
||||||
|
:title="upload.title"
|
||||||
|
width="500px"
|
||||||
|
>
|
||||||
|
<UploadExcel
|
||||||
|
:visit-task-id="visitTaskId"
|
||||||
|
:lesion-type="upload.lesionType"
|
||||||
|
@close="uploadDlgClose"
|
||||||
|
/>
|
||||||
|
</el-dialog>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<script>
|
||||||
|
import { saveTaskQuestion, submitTableQuestion, deleteReadingRowAnswer } from '@/api/trials'
|
||||||
|
import { resetReadingTask, getOCTFCTTemplate, getOCTLipidAngleTemplate } from '@/api/reading'
|
||||||
|
import DicomEvent from './../DicomEvent'
|
||||||
|
import store from '@/store'
|
||||||
|
import { mapGetters } from 'vuex'
|
||||||
|
import Questions from './../Questions'
|
||||||
|
import QuestionTableFormItem from './QuestionTableFormItem'
|
||||||
|
import UploadExcel from './UploadExcel'
|
||||||
|
export default {
|
||||||
|
name: 'MeasurementList',
|
||||||
|
components: {
|
||||||
|
Questions,
|
||||||
|
QuestionTableFormItem,
|
||||||
|
UploadExcel
|
||||||
|
},
|
||||||
|
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 {
|
||||||
|
questions: [],
|
||||||
|
visitTaskId: '',
|
||||||
|
isCurrentTask: false,
|
||||||
|
loading: false,
|
||||||
|
readingTaskState: 2,
|
||||||
|
isBaseLineTask: false,
|
||||||
|
taskBlindName: '',
|
||||||
|
tableQuestions: [],
|
||||||
|
CriterionType: null,
|
||||||
|
subjectCode: '',
|
||||||
|
questionForm: {},
|
||||||
|
formChanged: false,
|
||||||
|
digitPlaces: 2,
|
||||||
|
addOrEdit: { visible: false, title: '', lesionType: null },
|
||||||
|
upload: { visible: false, title: '', lesionType: null },
|
||||||
|
qsList: [],
|
||||||
|
answersList: [],
|
||||||
|
qsForm: {},
|
||||||
|
m1Id: '',
|
||||||
|
m2Id: '',
|
||||||
|
m3Id: '',
|
||||||
|
avgId: ''
|
||||||
|
}
|
||||||
|
},
|
||||||
|
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')
|
||||||
|
this.digitPlaces = Number(localStorage.getItem('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()
|
||||||
|
})
|
||||||
|
},
|
||||||
|
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
|
||||||
|
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)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
},
|
||||||
|
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.Type === 'basicTable') && 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.Type === 'basicTable') && 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
|
||||||
|
},
|
||||||
|
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
|
||||||
|
}
|
||||||
|
})
|
||||||
|
loading.close()
|
||||||
|
resolve()
|
||||||
|
} catch (e) { console.log(e) }
|
||||||
|
})
|
||||||
|
},
|
||||||
|
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: '' }
|
||||||
|
},
|
||||||
|
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
|
||||||
|
},
|
||||||
|
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, this.numberToFixed(value))
|
||||||
|
}
|
||||||
|
},
|
||||||
|
numberToFixed(v) {
|
||||||
|
if (this.digitPlaces > -1) {
|
||||||
|
return isNaN(parseFloat(v)) ? null : `${parseFloat(v).toFixed(this.digitPlaces)}`
|
||||||
|
} else {
|
||||||
|
return v
|
||||||
|
}
|
||||||
|
},
|
||||||
|
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()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
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) {
|
||||||
|
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 this.getReadingQuestionAndAnswer(this.visitTaskId)
|
||||||
|
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) {
|
||||||
|
},
|
||||||
|
resetFormItemData(v) {
|
||||||
|
this.qsForm[v] = null
|
||||||
|
},
|
||||||
|
setFormItemData(obj) {
|
||||||
|
this.qsForm[obj.key] = obj.val
|
||||||
|
if (obj.key === this.m1Id || obj.key === this.m2Id || obj.key === this.m3Id) {
|
||||||
|
const m1 = this.qsForm[this.m1Id]
|
||||||
|
const m2 = this.qsForm[this.m2Id]
|
||||||
|
const m3 = this.qsForm[this.m3Id]
|
||||||
|
if (isNaN(parseFloat(m1)) || isNaN(parseFloat(m2)) || isNaN(parseFloat(m3))) {
|
||||||
|
this.$set(this.qsForm, this.avgId, null)
|
||||||
|
} else {
|
||||||
|
const avg = (parseFloat(m1) + parseFloat(m2) + parseFloat(m3)) / 3
|
||||||
|
this.$set(this.qsForm, this.avgId, this.numberToFixed(avg))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
handleAddOrEdit(type, row, index) {
|
||||||
|
this.addOrEdit.title = row.QuestionName
|
||||||
|
this.qsList = row.TableQuestions.Questions
|
||||||
|
this.qsForm = {}
|
||||||
|
this.qsForm.questionId = row.Id
|
||||||
|
this.qsForm.rowId = type === 'add' ? null : row.TableQuestions.Answers && row.TableQuestions.Answers[index] ? row.TableQuestions.Answers[index].RowId : null
|
||||||
|
if (type === 'add') {
|
||||||
|
var maxIndex = this.getMaxRowIndex(row.TableQuestions.Answers)
|
||||||
|
this.qsForm.rowIndex = `${maxIndex + 1}.00`
|
||||||
|
} else {
|
||||||
|
this.qsForm.rowIndex = row.TableQuestions.Answers && row.TableQuestions.Answers[index] ? row.TableQuestions.Answers[index].RowIndex : null
|
||||||
|
}
|
||||||
|
row.TableQuestions.Questions.map(i => {
|
||||||
|
if (i.QuestionMark === 1011) {
|
||||||
|
this.m1Id = i.Id
|
||||||
|
}
|
||||||
|
if (i.QuestionMark === 1012) {
|
||||||
|
this.m2Id = i.Id
|
||||||
|
}
|
||||||
|
if (i.QuestionMark === 1013) {
|
||||||
|
this.m3Id = i.Id
|
||||||
|
}
|
||||||
|
if (i.QuestionMark === 1015) {
|
||||||
|
this.avgId = i.Id
|
||||||
|
}
|
||||||
|
let v = null
|
||||||
|
if (type === 'add') {
|
||||||
|
v = i.Type === 'number' ? undefined : null
|
||||||
|
} else {
|
||||||
|
v = row.TableQuestions.Answers && row.TableQuestions.Answers[index] ? row.TableQuestions.Answers[index][i.Id] : null
|
||||||
|
}
|
||||||
|
this.$set(this.qsForm, i.Id, v)
|
||||||
|
})
|
||||||
|
this.addOrEdit.visible = true
|
||||||
|
this.addOrEdit.lesionType = row.LesionType
|
||||||
|
},
|
||||||
|
async saveFormData() {
|
||||||
|
const valid = await this.$refs.tableQsForm.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.qsForm) {
|
||||||
|
if (reg.test(k)) {
|
||||||
|
if (answers.findIndex(i => i.tableQuestionId === k) === -1) {
|
||||||
|
answers.push({ tableQuestionId: k, answer: this.qsForm[k] })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var params = {
|
||||||
|
questionId: this.qsForm.questionId,
|
||||||
|
rowId: this.qsForm.rowId,
|
||||||
|
rowIndex: this.qsForm.rowIndex,
|
||||||
|
visitTaskId: this.visitTaskId,
|
||||||
|
trialId: this.trialId,
|
||||||
|
answerList: answers
|
||||||
|
}
|
||||||
|
if (this.addOrEdit.lesionType === 101) {
|
||||||
|
params.computationTrigger = 9
|
||||||
|
}
|
||||||
|
const res = await submitTableQuestion(params)
|
||||||
|
if (res.IsSuccess) {
|
||||||
|
// this.refreshQuestions()
|
||||||
|
await this.getReadingQuestionAndAnswer(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)
|
||||||
|
// 保存成功!
|
||||||
|
this.addOrEdit.visible = false
|
||||||
|
this.$message.success(this.$t('common:message:savedSuccessfully'))
|
||||||
|
}
|
||||||
|
loading.close()
|
||||||
|
} catch (e) {
|
||||||
|
console.log(e)
|
||||||
|
loading.close()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
async handleDelete(row, index) {
|
||||||
|
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 (row.TableQuestions.Answers[index].RowId) {
|
||||||
|
var param = {
|
||||||
|
visitTaskId: this.visitTaskId,
|
||||||
|
questionId: row.Id,
|
||||||
|
rowId: row.TableQuestions.Answers[index].RowId
|
||||||
|
}
|
||||||
|
const res = await deleteReadingRowAnswer(param)
|
||||||
|
if (res.IsSuccess) {
|
||||||
|
await this.getReadingQuestionAndAnswer(this.visitTaskId)
|
||||||
|
DicomEvent.$emit('getReportInfo', true)
|
||||||
|
// '删除成功!'
|
||||||
|
this.$message.success(this.$t('common:message:deletedSuccessfully'))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
loading.close()
|
||||||
|
} catch (e) {
|
||||||
|
loading.close()
|
||||||
|
console.log(e)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
uploadTpl(lesionType) {
|
||||||
|
this.upload.lesionType = lesionType
|
||||||
|
this.upload.title = `导入( ${this.$fd('LesionType', lesionType)} )`
|
||||||
|
this.upload.visible = true
|
||||||
|
},
|
||||||
|
async downloadTpl(lesionType) {
|
||||||
|
try {
|
||||||
|
const params = {
|
||||||
|
visitTaskId: this.visitTaskId
|
||||||
|
}
|
||||||
|
if (lesionType === 112) {
|
||||||
|
await getOCTFCTTemplate(params)
|
||||||
|
} else {
|
||||||
|
await getOCTLipidAngleTemplate(params)
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
console.log(e)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
async uploadDlgClose() {
|
||||||
|
await this.getReadingQuestionAndAnswer(this.visitTaskId)
|
||||||
|
DicomEvent.$emit('getReportInfo', true)
|
||||||
|
this.upload.visible = false
|
||||||
|
},
|
||||||
|
renderHeader(h, { column, $index }) {
|
||||||
|
const span = document.createElement('span')
|
||||||
|
span.innerText = column.label
|
||||||
|
document.body.appendChild(span)
|
||||||
|
const w = span.getBoundingClientRect().width
|
||||||
|
column.minWidth = w > 65 ? w + 10 : w > 60 ? w + 15 : w + 30
|
||||||
|
document.body.removeChild(span)
|
||||||
|
return h('span', column.label)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.measurement-wrapper{
|
||||||
|
height: 100%;
|
||||||
|
overflow-y: auto;
|
||||||
|
// overflow: hidden;
|
||||||
|
|
||||||
|
.container{
|
||||||
|
padding: 10px;
|
||||||
|
.basic-info{
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
h3{
|
||||||
|
color: #ddd;
|
||||||
|
padding: 5px 0px;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
i{
|
||||||
|
color: #fff;
|
||||||
|
font-size: 22px;
|
||||||
|
font-weight: bold;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.title{
|
||||||
|
padding: 5px;
|
||||||
|
font-weight: bold;
|
||||||
|
color: #ddd;
|
||||||
|
font-size: 15px;
|
||||||
|
|
||||||
|
}
|
||||||
|
.add-icon{
|
||||||
|
display: inline-block;
|
||||||
|
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-textarea__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;
|
||||||
|
}
|
||||||
|
|
||||||
|
.el-form-item__content
|
||||||
|
.el-select{
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.table-wrapper {
|
||||||
|
::-webkit-scrollbar {
|
||||||
|
width: 5px;
|
||||||
|
height: 8px;
|
||||||
|
}
|
||||||
|
::-webkit-scrollbar-thumb {
|
||||||
|
border-radius: 10px;
|
||||||
|
background: #d0d0d0;
|
||||||
|
}
|
||||||
|
/deep/ .el-table,
|
||||||
|
.el-table__expanded-cell {
|
||||||
|
background-color: #000;
|
||||||
|
color: #fff;
|
||||||
|
border-color: #444444;
|
||||||
|
}
|
||||||
|
/deep/ .el-table th,
|
||||||
|
.el-table tr {
|
||||||
|
background-color: #000;
|
||||||
|
color: #fff;
|
||||||
|
border-color: #444444;
|
||||||
|
}
|
||||||
|
/deep/ .el-table__body tr > td {
|
||||||
|
background-color: #000 !important;
|
||||||
|
color: #fff;
|
||||||
|
border-color: #444444;
|
||||||
|
}
|
||||||
|
/deep/ .el-table__body tr:hover > td {
|
||||||
|
background-color: #858282 !important;
|
||||||
|
color: #fff;
|
||||||
|
border-color: #444444;
|
||||||
|
}
|
||||||
|
/deep/ .el-table--border th.gutter:last-of-type {
|
||||||
|
border: none;
|
||||||
|
}
|
||||||
|
/deep/ .el-table__fixed-right {
|
||||||
|
height: 100% !important;
|
||||||
|
}
|
||||||
|
// /deep/ .el-table .cell {
|
||||||
|
// line-height: 20px;
|
||||||
|
// }
|
||||||
|
/deep/ .el-table__cell {
|
||||||
|
padding: 5px 0;
|
||||||
|
}
|
||||||
|
/deep/.el-table__fixed-right-patch {
|
||||||
|
background-color: #000 !important;
|
||||||
|
border-color: #444444;
|
||||||
|
}
|
||||||
|
/deep/.el-table__fixed-body-wrapper tr:hover > td {
|
||||||
|
background-color: #000 !important;
|
||||||
|
}
|
||||||
|
/deep/.el-table--scrollable-x .el-table__body-wrapper {
|
||||||
|
z-index: 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
@ -0,0 +1,297 @@
|
||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<div
|
||||||
|
v-if="!!question.GroupName && question.Type==='group'"
|
||||||
|
>
|
||||||
|
<h4 style="color: #ddd;padding: 5px 0px;margin: 0;">
|
||||||
|
{{ language==='en'?question.GroupEnName:question.GroupName }}
|
||||||
|
</h4>
|
||||||
|
</div>
|
||||||
|
<template v-else>
|
||||||
|
<el-form-item
|
||||||
|
v-if="(question.ShowQuestion===1 && question.ParentTriggerValueList.includes(String(questionForm[question.ParentId]))) || question.ShowQuestion===0 "
|
||||||
|
:label="`${question.QuestionName}`"
|
||||||
|
:prop="question.Id"
|
||||||
|
:rules="[
|
||||||
|
{ required: (question.IsRequired === 0 || (question.IsRequired ===1 && question.RelevanceId && (questionForm[question.RelevanceId] === question.RelevanceValue))) && question.Type!=='group' && question.Type!=='summary',
|
||||||
|
message: ['radio', 'select', 'checkbox'].includes(question.Type) ? $t('common:ruleMessage:select') : $t('common:ruleMessage:specify'), trigger: ['blur', 'change']},
|
||||||
|
]"
|
||||||
|
:class="[question.Type==='group' ? 'mb' : (question.Type==='upload' || question.QuestionName.length > 15) ?'uploadWrapper' : '']"
|
||||||
|
>
|
||||||
|
<!-- 输入框 -->
|
||||||
|
<el-input
|
||||||
|
v-if="question.Type==='input'"
|
||||||
|
v-model="questionForm[question.Id]"
|
||||||
|
:disabled="readingTaskState >= 2"
|
||||||
|
@change="((val)=>{formItemChange(val, question)})"
|
||||||
|
/>
|
||||||
|
<!-- 多行文本输入框 -->
|
||||||
|
<el-input
|
||||||
|
v-else-if="question.Type==='textarea'"
|
||||||
|
v-model="questionForm[question.Id]"
|
||||||
|
type="textarea"
|
||||||
|
:autosize="{ minRows: 2, maxRows: 4}"
|
||||||
|
maxlength="500"
|
||||||
|
:disabled="readingTaskState >= 2"
|
||||||
|
@change="((val)=>{formItemChange(val, question)})"
|
||||||
|
/>
|
||||||
|
<!-- 下拉框 -->
|
||||||
|
<el-select
|
||||||
|
v-else-if="question.Type==='select'"
|
||||||
|
v-model="questionForm[question.Id]"
|
||||||
|
:disabled="readingTaskState >= 2 || ((question.TableQuestionType === 2 || question.QuestionGenre === 2) && !!question.DictionaryCode)"
|
||||||
|
clearable
|
||||||
|
@change="((val)=>{formItemChange(val, question)})"
|
||||||
|
>
|
||||||
|
<template v-if="question.TableQuestionType === 1">
|
||||||
|
<el-option
|
||||||
|
v-for="item in organList"
|
||||||
|
:key="item.Id"
|
||||||
|
:label="item[question.DataTableColumn]"
|
||||||
|
:value="item[question.DataTableColumn]"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
<template v-else-if="question.TableQuestionType === 3 || question.QuestionGenre === 3">
|
||||||
|
<el-option
|
||||||
|
v-for="item of $d[question.DictionaryCode]"
|
||||||
|
:key="item.id"
|
||||||
|
:value="String(item.value)"
|
||||||
|
:label="item.label"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
<template v-else-if="(question.TableQuestionType === 2 || question.QuestionGenre === 2) && question.DictionaryCode">
|
||||||
|
<el-option
|
||||||
|
v-for="item of $d[question.DictionaryCode]"
|
||||||
|
:key="item.id"
|
||||||
|
:value="String(item.value)"
|
||||||
|
:label="item.label"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
<template v-else>
|
||||||
|
<el-option
|
||||||
|
v-for="val in question.TypeValue.split('|')"
|
||||||
|
:key="val"
|
||||||
|
:label="val"
|
||||||
|
:value="val"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
</el-select>
|
||||||
|
<!-- 单选 -->
|
||||||
|
<el-radio-group
|
||||||
|
v-else-if="question.Type==='radio'"
|
||||||
|
v-model="questionForm[question.Id]"
|
||||||
|
:disabled="readingTaskState >= 2"
|
||||||
|
@change="((val)=>{formItemChange(val, question)})"
|
||||||
|
>
|
||||||
|
<template v-if="question.DictionaryCode">
|
||||||
|
<el-radio
|
||||||
|
v-for="item of $d[question.DictionaryCode]"
|
||||||
|
:key="item.id"
|
||||||
|
:label="String(item.value)"
|
||||||
|
>
|
||||||
|
{{ item.label }}
|
||||||
|
</el-radio>
|
||||||
|
</template>
|
||||||
|
<template v-else-if="question.TypeValue">
|
||||||
|
<el-radio
|
||||||
|
v-for="val in question.TypeValue.split('|')"
|
||||||
|
:key="val"
|
||||||
|
:label="val"
|
||||||
|
>
|
||||||
|
{{ val }}
|
||||||
|
</el-radio>
|
||||||
|
</template>
|
||||||
|
</el-radio-group>
|
||||||
|
<!-- 复选框 -->
|
||||||
|
<el-checkbox-group
|
||||||
|
v-else-if="question.Type==='checkbox'"
|
||||||
|
v-model="questionForm[question.Id]"
|
||||||
|
:disabled="readingTaskState >= 2"
|
||||||
|
@change="((val)=>{formItemChange(val, question)})"
|
||||||
|
>
|
||||||
|
<el-checkbox
|
||||||
|
v-for="val in question.TypeValue.split('|')"
|
||||||
|
:key="val"
|
||||||
|
:label="val"
|
||||||
|
>
|
||||||
|
{{ val }}
|
||||||
|
</el-checkbox>
|
||||||
|
</el-checkbox-group>
|
||||||
|
<!-- 数值 -->
|
||||||
|
<!-- <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"
|
||||||
|
style="width: 100%"
|
||||||
|
@change="((val)=>{formItemChange(val, question)})"
|
||||||
|
/>
|
||||||
|
<el-input-number
|
||||||
|
v-else-if="question.ValueType === 3"
|
||||||
|
v-model="questionForm[question.Id]"
|
||||||
|
:disabled="readingTaskState >= 2"
|
||||||
|
style="width: 100%"
|
||||||
|
@change="((val)=>{formItemChange(val, question)})"
|
||||||
|
/>
|
||||||
|
<el-input-number
|
||||||
|
v-else-if="question.ValueType === 1 || question.ValueType === 2"
|
||||||
|
v-model="questionForm[question.Id]"
|
||||||
|
:precision="digitPlaces"
|
||||||
|
:disabled="readingTaskState >= 2"
|
||||||
|
style="width: 100%"
|
||||||
|
@change="((val)=>{formItemChange(val, question)})"
|
||||||
|
/>
|
||||||
|
</template> -->
|
||||||
|
<!-- 数值类型 -->
|
||||||
|
<el-input
|
||||||
|
v-else-if="question.Type==='number'"
|
||||||
|
v-model="questionForm[question.Id]"
|
||||||
|
:disabled="readingTaskState>=2 "
|
||||||
|
type="number"
|
||||||
|
@change="((val)=>{formItemChange(val, question)})"
|
||||||
|
>
|
||||||
|
<template v-if="question.Unit" slot="append">
|
||||||
|
{{ $fd('ValueUnit', parseInt(question.Unit)) }}
|
||||||
|
</template>
|
||||||
|
</el-input>
|
||||||
|
|
||||||
|
<el-input
|
||||||
|
v-else-if="question.Type==='calculation'"
|
||||||
|
v-model="questionForm[question.Id]"
|
||||||
|
disabled
|
||||||
|
@change="((val)=>{formItemChange(val, question)})"
|
||||||
|
>
|
||||||
|
<template v-if="question.Unit" slot="append">
|
||||||
|
{{ $fd('ValueUnit', parseInt(question.Unit)) }}
|
||||||
|
</template>
|
||||||
|
</el-input>
|
||||||
|
</el-form-item>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<QuestionTableFormItem
|
||||||
|
v-for="item in question.Childrens"
|
||||||
|
:key="item.Id"
|
||||||
|
:question="item"
|
||||||
|
:question-form="questionForm"
|
||||||
|
:reading-task-state="readingTaskState"
|
||||||
|
@setFormItemData="setFormItemData"
|
||||||
|
@resetFormItemData="resetFormItemData"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<script>
|
||||||
|
import { mapGetters } from 'vuex'
|
||||||
|
export default {
|
||||||
|
name: 'QuestionTableFormItem',
|
||||||
|
props: {
|
||||||
|
questionForm: {
|
||||||
|
type: Object,
|
||||||
|
default() {
|
||||||
|
return {}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
question: {
|
||||||
|
type: Object,
|
||||||
|
default() {
|
||||||
|
return []
|
||||||
|
}
|
||||||
|
},
|
||||||
|
readingTaskState: {
|
||||||
|
type: Number,
|
||||||
|
required: true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
digitPlaces: 2
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
...mapGetters(['language'])
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this.digitPlaces = Number(localStorage.getItem('digitPlaces'))
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
formItemChange(v, question) {
|
||||||
|
if (question.Childrens && question.Childrens.length > 0) {
|
||||||
|
this.resetChild(question.Childrens)
|
||||||
|
} else {
|
||||||
|
if (question.Type === 'number') {
|
||||||
|
v = this.limitBlur(question.ValueType, v)
|
||||||
|
}
|
||||||
|
this.$emit('setFormItemData', { key: question.Id, val: v })
|
||||||
|
}
|
||||||
|
},
|
||||||
|
resetChild(obj) {
|
||||||
|
obj.forEach(i => {
|
||||||
|
this.$emit('resetFormItemData', i.Id)
|
||||||
|
if (i.Childrens && i.Childrens.length > 0) {
|
||||||
|
this.resetChild(i.Childrens)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
limitBlur(valueType, value) {
|
||||||
|
if (isNaN(parseInt(value))) {
|
||||||
|
value = null
|
||||||
|
} else {
|
||||||
|
if (valueType === 0) {
|
||||||
|
value = parseInt(value)
|
||||||
|
} else if (valueType === 3) {
|
||||||
|
value = parseFloat(value)
|
||||||
|
} else {
|
||||||
|
value = this.numberToFixed(value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return value
|
||||||
|
},
|
||||||
|
numberToFixed(v) {
|
||||||
|
if (this.digitPlaces > -1) {
|
||||||
|
return isNaN(parseFloat(v)) ? null : `${parseFloat(v).toFixed(this.digitPlaces)}`
|
||||||
|
} else {
|
||||||
|
return v
|
||||||
|
}
|
||||||
|
},
|
||||||
|
resetFormItemData(v) {
|
||||||
|
this.$emit('resetFormItemData', v)
|
||||||
|
},
|
||||||
|
setFormItemData(obj) {
|
||||||
|
this.$emit('setFormItemData', obj)
|
||||||
|
},
|
||||||
|
limitNumbersEvent(e) {
|
||||||
|
// 通过正则保留两位小数点
|
||||||
|
let val = e.target.value
|
||||||
|
if (val.length > 6) val = val.slice(0, 6)
|
||||||
|
e.target.value = (val.match(/^\d*(\.?\d{0,3})/g)[0]) || null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.mb{
|
||||||
|
margin-bottom: 0px;
|
||||||
|
}
|
||||||
|
.disabled{
|
||||||
|
/deep/ .el-upload--picture-card {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.uploadWrapper{
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column !important;
|
||||||
|
align-items: flex-start;
|
||||||
|
}
|
||||||
|
/deep/ .el-input.is-disabled .el-input__inner{
|
||||||
|
background-color: #646464a1;
|
||||||
|
}
|
||||||
|
/deep/ .el-input-group__append, .el-input-group__prepend{
|
||||||
|
padding: 0 10px;
|
||||||
|
}
|
||||||
|
/deep/ .el-form-item__content {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
/deep/ .el-select.is-disabled .el-input__inner{
|
||||||
|
background-color: #646464a1;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
@ -0,0 +1,125 @@
|
||||||
|
<template>
|
||||||
|
<el-form
|
||||||
|
ref="uploadExcel"
|
||||||
|
class="upload-excel-file"
|
||||||
|
>
|
||||||
|
<!-- 文件 -->
|
||||||
|
<el-form-item :label="$t('trials:consistencyCheck:label:file')">
|
||||||
|
<div class="upload-container">
|
||||||
|
<el-upload
|
||||||
|
class="upload-demo"
|
||||||
|
action
|
||||||
|
accept=".xlsx,.xls,.csv"
|
||||||
|
:before-upload="beforeUpload"
|
||||||
|
:http-request="handleUploadFile"
|
||||||
|
:on-preview="handlePreview"
|
||||||
|
:show-file-list="true"
|
||||||
|
:limit="1"
|
||||||
|
:on-exceed="handleExceed"
|
||||||
|
>
|
||||||
|
<el-button size="small" type="primary">
|
||||||
|
{{ $t('trials:consistencyCheck:dialogButton:upload') }}
|
||||||
|
</el-button>
|
||||||
|
<span
|
||||||
|
slot="tip"
|
||||||
|
style="margin-left:10px;"
|
||||||
|
class="el-upload__tip"
|
||||||
|
>
|
||||||
|
({{ $t('trials:consistencyCheck:message:excelFileOnly') }})
|
||||||
|
</span>
|
||||||
|
</el-upload>
|
||||||
|
</div>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
</template>
|
||||||
|
<script>
|
||||||
|
import { uploadOCTFCTTemplate, uploadOCTLipidAngleTemplate } from '@/api/reading'
|
||||||
|
export default {
|
||||||
|
props: {
|
||||||
|
visitTaskId: {
|
||||||
|
type: String,
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
lesionType: {
|
||||||
|
type: Number,
|
||||||
|
required: true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
beforeUpload(file) {
|
||||||
|
// 检测文件类型是否符合要求
|
||||||
|
if (this.checkFileSuffix(file.name)) {
|
||||||
|
return true
|
||||||
|
} else {
|
||||||
|
// Must be xls or xlsx format
|
||||||
|
this.$alert(this.$t('trials:consistencyCheck:message:xlsx'))
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
async handleUploadFile(param) {
|
||||||
|
const loading = this.$loading({ fullscreen: true })
|
||||||
|
try {
|
||||||
|
var data = new FormData()
|
||||||
|
data.append('file', param.file)
|
||||||
|
data.append('visitTaskId', this.visitTaskId)
|
||||||
|
if (this.lesionType === 112) {
|
||||||
|
await uploadOCTFCTTemplate(data)
|
||||||
|
} else {
|
||||||
|
await uploadOCTLipidAngleTemplate(data)
|
||||||
|
}
|
||||||
|
this.$emit('close')
|
||||||
|
this.$message.success('导入成功!')
|
||||||
|
loading.close()
|
||||||
|
} catch (e) {
|
||||||
|
loading.close()
|
||||||
|
console.log(e)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
handlePreview(file) {
|
||||||
|
if (file.fullPath) {
|
||||||
|
window.open(file.fullPath, '_blank')
|
||||||
|
}
|
||||||
|
},
|
||||||
|
handleExceed(files, fileList) {
|
||||||
|
// Upload is currently limited to 1 file
|
||||||
|
this.$message.warning(this.$t('trials:consistencyCheck:message:onlyOneFile'))
|
||||||
|
},
|
||||||
|
checkFileSuffix(fileName) {
|
||||||
|
var typeArr = ['xls', 'xlsx', 'csv']
|
||||||
|
var extendName = fileName.substring(fileName.lastIndexOf('.') + 1).toLocaleLowerCase()
|
||||||
|
if (typeArr.indexOf(extendName) !== -1) {
|
||||||
|
return true
|
||||||
|
} else {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss">
|
||||||
|
.upload-excel-file{
|
||||||
|
.upload-container .el-upload--text {
|
||||||
|
border: none;
|
||||||
|
width: 80px;
|
||||||
|
height: 40px;
|
||||||
|
}
|
||||||
|
.upload-container .el-input--small {
|
||||||
|
margin-bottom: 5px;
|
||||||
|
}
|
||||||
|
.upload-container .el-icon-circle-check {
|
||||||
|
color: #428bca;
|
||||||
|
font-size: 13px;
|
||||||
|
}
|
||||||
|
.account_item_clear{
|
||||||
|
.el-tag__close{
|
||||||
|
display: none !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="measurement-wrapper" :style="{'height':height+10+'px'}">
|
<div class="measurement-wrapper">
|
||||||
|
|
||||||
<div class="container" :style="{'height':height+'px'}">
|
<div class="container">
|
||||||
<div class="basic-info">
|
<div class="basic-info">
|
||||||
<h3 v-if="isReadingShowSubjectInfo">
|
<h3 v-if="isReadingShowSubjectInfo">
|
||||||
<span v-if="subjectCode">{{ subjectCode }} </span>
|
<span v-if="subjectCode">{{ subjectCode }} </span>
|
||||||
|
|
@ -147,7 +147,6 @@ export default {
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
height: window.innerHeight - 140,
|
|
||||||
questions: [],
|
questions: [],
|
||||||
activeName: '',
|
activeName: '',
|
||||||
activeItem: {
|
activeItem: {
|
||||||
|
|
@ -212,8 +211,6 @@ export default {
|
||||||
callback(list)
|
callback(list)
|
||||||
console.log('getAllUnSaveLesions')
|
console.log('getAllUnSaveLesions')
|
||||||
})
|
})
|
||||||
|
|
||||||
window.addEventListener('resize', this.setHeight)
|
|
||||||
},
|
},
|
||||||
beforeDestroy() {
|
beforeDestroy() {
|
||||||
DicomEvent.$off('setCollapseActive')
|
DicomEvent.$off('setCollapseActive')
|
||||||
|
|
@ -802,6 +799,7 @@ export default {
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
.measurement-wrapper{
|
.measurement-wrapper{
|
||||||
|
height: 100%;
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
// overflow: hidden;
|
// overflow: hidden;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
|
||||||
|
|
@ -57,6 +57,7 @@
|
||||||
:is-reading-show-subject-info="isReadingShowSubjectInfo"
|
:is-reading-show-subject-info="isReadingShowSubjectInfo"
|
||||||
:is-reading-task-view-in-order="isReadingTaskViewInOrder"
|
:is-reading-task-view-in-order="isReadingTaskViewInOrder"
|
||||||
:is-exists-manual="isExistsManual"
|
:is-exists-manual="isExistsManual"
|
||||||
|
:iseCRFShowInDicomReading="iseCRFShowInDicomReading"
|
||||||
@previewCD="previewCD"
|
@previewCD="previewCD"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -136,6 +137,10 @@ export default {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
required: true
|
required: true
|
||||||
},
|
},
|
||||||
|
iseCRFShowInDicomReading: {
|
||||||
|
type: Boolean,
|
||||||
|
required: true
|
||||||
|
},
|
||||||
questionFormChangeState: {
|
questionFormChangeState: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default() {
|
default() {
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="measurement-wrapper" :style="{'height':height+10+'px'}">
|
<div class="measurement-wrapper">
|
||||||
|
|
||||||
<div class="container" :style="{'height':height+'px'}">
|
<div class="container">
|
||||||
<div class="basic-info">
|
<div class="basic-info">
|
||||||
<h3 v-if="isReadingShowSubjectInfo">
|
<h3 v-if="isReadingShowSubjectInfo">
|
||||||
<span v-if="subjectCode">{{ subjectCode }} </span>
|
<span v-if="subjectCode">{{ subjectCode }} </span>
|
||||||
|
|
@ -169,7 +169,6 @@ export default {
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
height: window.innerHeight - 140,
|
|
||||||
questions: [],
|
questions: [],
|
||||||
activeName: '',
|
activeName: '',
|
||||||
activeItem: {
|
activeItem: {
|
||||||
|
|
@ -234,8 +233,6 @@ export default {
|
||||||
DicomEvent.$on('split', measureData => {
|
DicomEvent.$on('split', measureData => {
|
||||||
this.handleSplit(measureData.RowId, measureData.QuestionId)
|
this.handleSplit(measureData.RowId, measureData.QuestionId)
|
||||||
})
|
})
|
||||||
|
|
||||||
window.addEventListener('resize', this.setHeight)
|
|
||||||
},
|
},
|
||||||
beforeDestroy() {
|
beforeDestroy() {
|
||||||
DicomEvent.$off('setCollapseActive')
|
DicomEvent.$off('setCollapseActive')
|
||||||
|
|
@ -416,9 +413,6 @@ export default {
|
||||||
} catch (e) { console.log(e) }
|
} catch (e) { console.log(e) }
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
setHeight() {
|
|
||||||
this.height = window.innerHeight - 140
|
|
||||||
},
|
|
||||||
getQuestionAnswer(questions, questionMark, answers) {
|
getQuestionAnswer(questions, questionMark, answers) {
|
||||||
var idx = questions.findIndex(i => i.QuestionMark === questionMark)
|
var idx = questions.findIndex(i => i.QuestionMark === questionMark)
|
||||||
if (idx > -1) {
|
if (idx > -1) {
|
||||||
|
|
@ -1065,6 +1059,7 @@ export default {
|
||||||
</script>
|
</script>
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
.measurement-wrapper{
|
.measurement-wrapper{
|
||||||
|
height: 100%;
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
// overflow: hidden;
|
// overflow: hidden;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="measurement-wrapper" :style="{'height':height+10+'px'}">
|
<div class="measurement-wrapper">
|
||||||
|
|
||||||
<div class="container" :style="{'height':height+'px'}">
|
<div class="container">
|
||||||
<div class="basic-info">
|
<div class="basic-info">
|
||||||
<h3 v-if="isReadingShowSubjectInfo">
|
<h3 v-if="isReadingShowSubjectInfo">
|
||||||
<span v-if="subjectCode">{{ subjectCode }} </span>
|
<span v-if="subjectCode">{{ subjectCode }} </span>
|
||||||
|
|
@ -165,7 +165,6 @@ export default {
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
height: window.innerHeight - 140,
|
|
||||||
questions: [],
|
questions: [],
|
||||||
activeName: '',
|
activeName: '',
|
||||||
activeItem: {
|
activeItem: {
|
||||||
|
|
@ -229,8 +228,6 @@ export default {
|
||||||
DicomEvent.$on('split', measureData => {
|
DicomEvent.$on('split', measureData => {
|
||||||
this.handleSplit(measureData.RowId, measureData.QuestionId)
|
this.handleSplit(measureData.RowId, measureData.QuestionId)
|
||||||
})
|
})
|
||||||
|
|
||||||
window.addEventListener('resize', this.setHeight)
|
|
||||||
},
|
},
|
||||||
beforeDestroy() {
|
beforeDestroy() {
|
||||||
DicomEvent.$off('loadMeasurementList')
|
DicomEvent.$off('loadMeasurementList')
|
||||||
|
|
@ -409,9 +406,6 @@ export default {
|
||||||
} catch (e) { console.log(e) }
|
} catch (e) { console.log(e) }
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
setHeight() {
|
|
||||||
this.height = window.innerHeight - 140
|
|
||||||
},
|
|
||||||
getQuestionAnswer(questions, questionMark, answers) {
|
getQuestionAnswer(questions, questionMark, answers) {
|
||||||
var idx = questions.findIndex(i => i.QuestionMark === questionMark)
|
var idx = questions.findIndex(i => i.QuestionMark === questionMark)
|
||||||
if (idx > -1) {
|
if (idx > -1) {
|
||||||
|
|
@ -994,6 +988,7 @@ export default {
|
||||||
</script>
|
</script>
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
.measurement-wrapper{
|
.measurement-wrapper{
|
||||||
|
height: 100%;
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
// overflow: hidden;
|
// overflow: hidden;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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) {
|
const studyList = this.visitTaskList[idx].StudyList.filter(i => i.IsDicom)
|
||||||
// 基线
|
const seriesArr = studyList.map(s => s.SeriesList).flat()
|
||||||
|
if (isReadingTaskViewInOrder === 2) {
|
||||||
|
// 受试者内随机
|
||||||
|
if (seriesArr.length === 1) {
|
||||||
|
seriesList.push(seriesArr[0], seriesArr[0])
|
||||||
|
this.studyIndex = seriesArr[0].studyIndex
|
||||||
|
this.seriesIndex = seriesArr[0].seriesIndex
|
||||||
|
this.activeNames = [`${seriesArr[0].studyId}`]
|
||||||
|
} else if (seriesArr.length > 1) {
|
||||||
|
seriesList.push(seriesArr[0], seriesArr[1])
|
||||||
|
this.studyIndex = seriesArr[1].studyIndex
|
||||||
|
this.seriesIndex = seriesArr[1].seriesIndex
|
||||||
|
this.activeNames = [`${seriesArr[1].studyId}`]
|
||||||
|
}
|
||||||
|
} else if (this.visitTaskList[idx].IsBaseLineTask || isReadingTaskViewInOrder === 0) {
|
||||||
|
// 基线任务或完全随机
|
||||||
const obj = this.getFirstMarkedSeries(this.visitTaskList[idx].MeasureData, [...this.visitTaskList[idx].StudyList])
|
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
|
||||||
|
|
@ -387,9 +410,13 @@ export default {
|
||||||
this.activeNames = [`${this.studyList[ this.studyIndex].StudyId}`]
|
this.activeNames = [`${this.studyList[ this.studyIndex].StudyId}`]
|
||||||
this.studyList[ obj.studyIndex].SeriesList[obj.seriesIndex].isFirstRender = true
|
this.studyList[ obj.studyIndex].SeriesList[obj.seriesIndex].isFirstRender = true
|
||||||
} else {
|
} else {
|
||||||
// 初始化问题表单
|
|
||||||
if (this.studyList.length > 0) {
|
if (this.studyList.length > 0) {
|
||||||
this.activeNames = [`${this.studyList[0].StudyId}`]
|
// 初始化问题表单
|
||||||
|
this.studyIndex = seriesArr[0].studyIndex
|
||||||
|
this.seriesIndex = seriesArr[0].seriesIndex
|
||||||
|
this.activeNames = [`${seriesArr[0].studyId}`]
|
||||||
|
seriesList.push(seriesArr[0])
|
||||||
|
// this.activeNames = [`${this.studyList[0].StudyId}`]
|
||||||
}
|
}
|
||||||
|
|
||||||
// DicomEvent.$emit('loadMeasurementList', { visitTaskId: this.visitTaskList[idx].VisitTaskId, taskBlindName: this.visitTaskList[idx].TaskBlindName })
|
// DicomEvent.$emit('loadMeasurementList', { visitTaskId: this.visitTaskList[idx].VisitTaskId, taskBlindName: this.visitTaskList[idx].TaskBlindName })
|
||||||
|
|
@ -413,6 +440,7 @@ export default {
|
||||||
|
|
||||||
const firstObj = this.getFirstMarkedSeries(this.visitTaskList[bsIdx].MeasureData, [...this.visitTaskList[bsIdx].StudyList])
|
const firstObj = this.getFirstMarkedSeries(this.visitTaskList[bsIdx].MeasureData, [...this.visitTaskList[bsIdx].StudyList])
|
||||||
seriesList.push(firstObj.series)
|
seriesList.push(firstObj.series)
|
||||||
|
|
||||||
const secondObj = this.getSecondMarkedSeries(firstObj, { ...this.visitTaskList[idx] })
|
const secondObj = this.getSecondMarkedSeries(firstObj, { ...this.visitTaskList[idx] })
|
||||||
this.studyIndex = secondObj.studyIndex
|
this.studyIndex = secondObj.studyIndex
|
||||||
this.seriesIndex = secondObj.seriesIndex
|
this.seriesIndex = secondObj.seriesIndex
|
||||||
|
|
@ -552,22 +580,20 @@ export default {
|
||||||
obj.series = seriesObj.series
|
obj.series = seriesObj.series
|
||||||
obj.seriesId = seriesObj.series.seriesId
|
obj.seriesId = seriesObj.series.seriesId
|
||||||
obj.isMarked = false
|
obj.isMarked = false
|
||||||
} else {
|
}
|
||||||
|
}
|
||||||
|
if (Object.keys(obj).length === 0) {
|
||||||
const sIdx = studyList.findIndex(s => s.IsDicom)
|
const sIdx = studyList.findIndex(s => s.IsDicom)
|
||||||
if (sIdx > -1) {
|
if (sIdx > -1) {
|
||||||
// 判断是否存在层厚为5的序列,否则显示第一个检查的第一个序列
|
|
||||||
const series = studyList[sIdx].SeriesList[0]
|
|
||||||
var imageIdIndex = series.imageIds.length > 1 ? Math.floor(series.imageIds.length / 2) - 1 : 0
|
|
||||||
obj.studyIndex = sIdx
|
obj.studyIndex = sIdx
|
||||||
obj.seriesIndex = 0
|
obj.seriesIndex = 0
|
||||||
obj.series = series
|
obj.series = studyList[obj.studyIndex].SeriesList[obj.seriesIndex]
|
||||||
|
const imageIdIndex = Math.floor(obj.series.imageIds.length / 2)
|
||||||
obj.series.imageIdIndex = imageIdIndex >= 0 ? imageIdIndex : 0
|
obj.series.imageIdIndex = imageIdIndex >= 0 ? imageIdIndex : 0
|
||||||
obj.seriesId = series.seriesId
|
// obj.seriesId = series.seriesId
|
||||||
obj.isMarked = false
|
obj.isMarked = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return obj
|
return obj
|
||||||
},
|
},
|
||||||
strSimilarity2Number(s, t) {
|
strSimilarity2Number(s, t) {
|
||||||
|
|
@ -668,7 +694,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}`)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1064,16 +1064,15 @@ export default {
|
||||||
var frame = imageInfo.frame
|
var frame = imageInfo.frame
|
||||||
this.stack.frame = this.stack.isExistMutiFrames ? parseInt(frame) : null
|
this.stack.frame = this.stack.isExistMutiFrames ? parseInt(frame) : null
|
||||||
this.stack.instanceId = instanceId
|
this.stack.instanceId = instanceId
|
||||||
|
const element = this.$refs.canvas
|
||||||
|
cornerstone.enable(element)
|
||||||
|
element.tabIndex = 0
|
||||||
|
element.focus()
|
||||||
const ToolStateManager = cornerstoneTools.globalImageIdSpecificToolStateManager
|
const ToolStateManager = cornerstoneTools.globalImageIdSpecificToolStateManager
|
||||||
ToolStateManager.clearImageIdToolState(dicomSeries.imageIds)
|
ToolStateManager.clearImageIdToolState(dicomSeries.imageIds)
|
||||||
this.toggleClipPlay(false)
|
this.toggleClipPlay(false)
|
||||||
this.toolState.viewportInvert = false
|
this.toolState.viewportInvert = false
|
||||||
this.toolState.dicomInfoVisible = false
|
this.toolState.dicomInfoVisible = false
|
||||||
|
|
||||||
const element = this.$refs.canvas
|
|
||||||
cornerstone.enable(element)
|
|
||||||
element.tabIndex = 0
|
|
||||||
element.focus()
|
|
||||||
var scope = this
|
var scope = this
|
||||||
// var p = parseInt(new Date().getTime())
|
// var p = parseInt(new Date().getTime())
|
||||||
// requestPoolManager.loadAndCacheImagePlus(this.stack.imageIds[this.stack.currentImageIdIndex], this.stack.seriesId, p*100).then(image=>{
|
// requestPoolManager.loadAndCacheImagePlus(this.stack.imageIds[this.stack.currentImageIdIndex], this.stack.seriesId, p*100).then(image=>{
|
||||||
|
|
@ -1637,7 +1636,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,13 @@
|
||||||
<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 +486,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 +509,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 +519,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 +631,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 +652,29 @@
|
||||||
<!-- <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"
|
||||||
|
:VisitTaskId="taskId"
|
||||||
|
:isReadingTaskViewInOrder="isReadingTaskViewInOrder"
|
||||||
|
/>
|
||||||
|
<download-dicom-and-nonedicom
|
||||||
|
v-if="downloadImageVisible"
|
||||||
|
:SubjectId="uploadSubjectId"
|
||||||
|
:SubjectCode="uploadSubjectCode"
|
||||||
|
:Criterion="uploadTrialCriterion"
|
||||||
|
:TaskId="taskId"
|
||||||
|
:visible.sync="downloadImageVisible"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
@ -676,7 +699,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 +712,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 +763,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 +772,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 +780,8 @@ export default {
|
||||||
currentDicomCanvasIndex: 0,
|
currentDicomCanvasIndex: 0,
|
||||||
currentDicomCanvas: {
|
currentDicomCanvas: {
|
||||||
toolState: {
|
toolState: {
|
||||||
clipPlaying: false
|
clipPlaying: false,
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
colormapsList: [],
|
colormapsList: [],
|
||||||
rotateList: [],
|
rotateList: [],
|
||||||
|
|
@ -773,7 +798,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 +806,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 +814,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 +822,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 +830,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 +843,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 +869,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 +886,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 +918,7 @@ export default {
|
||||||
this.activeTool = ''
|
this.activeTool = ''
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
currentDicomCanvasIndex: {
|
currentDicomCanvasIndex: {
|
||||||
immediate: true,
|
immediate: true,
|
||||||
|
|
@ -905,8 +935,8 @@ export default {
|
||||||
this.clipPlaying = false
|
this.clipPlaying = false
|
||||||
this.fps = 15
|
this.fps = 15
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
this.getTrialCriterion()
|
this.getTrialCriterion()
|
||||||
|
|
@ -919,7 +949,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 +959,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 +976,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 +1071,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 +1079,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||localStorage.getItem("subjectCode")
|
||||||
|
this.uploadSubjectId = this.$route.query.subjectId||localStorage.getItem("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 +1098,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,7 +1120,7 @@ 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()
|
||||||
|
|
@ -1105,7 +1141,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 +1184,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 +1193,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 +1323,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 +1423,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 +1454,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
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
@ -1502,7 +1532,7 @@ export default {
|
||||||
activeSeries,
|
activeSeries,
|
||||||
activeSeries,
|
activeSeries,
|
||||||
activeSeries,
|
activeSeries,
|
||||||
activeSeries
|
activeSeries,
|
||||||
]
|
]
|
||||||
this.currentDicomCanvasIndex = 3
|
this.currentDicomCanvasIndex = 3
|
||||||
store.dispatch(
|
store.dispatch(
|
||||||
|
|
@ -1521,9 +1551,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 +1613,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 +1724,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 +1733,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 +1770,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 +1852,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 +1871,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 +2053,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 +2115,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 +2191,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 +2208,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 +2326,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>
|
||||||
|
|
|
||||||
|
|
@ -25,14 +25,14 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="questions-footer">
|
<div class="questions-footer">
|
||||||
<i class="el-icon-question feedback-icon" @click="openFeedBackTable" />
|
<i class="el-icon-question feedback-icon" @click="openFeedBackTable" />
|
||||||
<el-button v-if="readingTaskState<2" style="margin-right: 10px" size="small" @click="handleSave(true)">
|
<el-button v-if="readingTaskState<2" style="margin-right: 10px" type="primary" size="small" @click="handleSave(true)">
|
||||||
{{$t('common:button:save')}}
|
{{$t('common:button:save')}}
|
||||||
</el-button>
|
</el-button>
|
||||||
<el-button v-if="readingTaskState<2 && IseCRFShowInDicomReading" type="primary" size="small" @click="skipTask">
|
<el-button v-if="readingTaskState<2 && IseCRFShowInDicomReading" type="primary" style="margin-right: 10px" size="small" @click="skipTask">
|
||||||
<!-- 跳过 -->
|
<!-- 跳过 -->
|
||||||
{{ $t('trials:readingReport:button:skip') }}
|
{{ $t('trials:readingReport:button:skip') }}
|
||||||
</el-button>
|
</el-button>
|
||||||
<el-button style="margin-right: 10px" size="small" v-if="readingTaskState<2 && IseCRFShowInDicomReading" @click="handleConfirm">
|
<el-button style="margin-right: 10px" type="primary" size="small" v-if="readingTaskState<2 && IseCRFShowInDicomReading" @click="handleConfirm">
|
||||||
{{ $t('common:button:submit') }}</el-button>
|
{{ $t('common:button:submit') }}</el-button>
|
||||||
</div>
|
</div>
|
||||||
<!-- 签名框 -->
|
<!-- 签名框 -->
|
||||||
|
|
@ -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()
|
||||||
}
|
}
|
||||||
|
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -82,7 +82,7 @@ export default {
|
||||||
var answers = []
|
var answers = []
|
||||||
for (const k in this.questionForm) {
|
for (const k in this.questionForm) {
|
||||||
if (this.questionForm[k] instanceof Array) {} else {
|
if (this.questionForm[k] instanceof Array) {} else {
|
||||||
answers.push({ id: k, answer: this.questionForm[k].toString() })
|
answers.push({ id: k, answer: this.questionForm[k] })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
var params = {
|
var params = {
|
||||||
|
|
|
||||||
|
|
@ -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) {
|
||||||
|
|
@ -533,21 +555,20 @@ export default {
|
||||||
obj.series = seriesObj.series
|
obj.series = seriesObj.series
|
||||||
obj.seriesId = seriesObj.series.seriesId
|
obj.seriesId = seriesObj.series.seriesId
|
||||||
obj.isMarked = false
|
obj.isMarked = false
|
||||||
} else {
|
}
|
||||||
|
}
|
||||||
|
if (Object.keys(obj).length === 0) {
|
||||||
const sIdx = studyList.findIndex(s => s.IsDicom)
|
const sIdx = studyList.findIndex(s => s.IsDicom)
|
||||||
if (sIdx > -1) {
|
if (sIdx > -1) {
|
||||||
// 判断是否存在层厚为5的序列,否则显示第一个检查的第一个序列
|
|
||||||
const series = studyList[sIdx].SeriesList[0]
|
|
||||||
var imageIdIndex = series.imageIds.length > 1 ? Math.floor(series.imageIds.length / 2) - 1 : 0
|
|
||||||
obj.studyIndex = sIdx
|
obj.studyIndex = sIdx
|
||||||
obj.seriesIndex = 0
|
obj.seriesIndex = 0
|
||||||
obj.series = series
|
obj.series = studyList[obj.studyIndex].SeriesList[obj.seriesIndex]
|
||||||
|
const imageIdIndex = Math.floor(obj.series.imageIds.length / 2)
|
||||||
obj.series.imageIdIndex = imageIdIndex >= 0 ? imageIdIndex : 0
|
obj.series.imageIdIndex = imageIdIndex >= 0 ? imageIdIndex : 0
|
||||||
obj.seriesId = series.seriesId
|
// obj.seriesId = series.seriesId
|
||||||
obj.isMarked = false
|
obj.isMarked = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return obj
|
return obj
|
||||||
},
|
},
|
||||||
|
|
@ -652,7 +673,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}`)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue