8 Commits

Author SHA1 Message Date
wangxiaoshuang 662cc93d85 稽查文档管理
continuous-integration/drone/push Build is failing
2025-04-01 17:59:24 +08:00
caiyiling e3ad114207 Merge branch 'main' of https://gitea.frp.extimaging.com/XCKJ/irc_web into main
continuous-integration/drone/push Build is passing
2025-04-01 16:48:50 +08:00
caiyiling 0960b480a6 阅片页面更改 2025-04-01 16:48:04 +08:00
wangxiaoshuang 9a4eb1b210 工作台稽查文档
continuous-integration/drone/push Build is passing
2025-03-28 18:01:45 +08:00
wangxiaoshuang 0567534367 Merge branch 'main' of https://gitea.frp.extimaging.com/XCKJ/irc_web
continuous-integration/drone/push Build is passing
2025-03-27 13:31:59 +08:00
wangxiaoshuang 481a436169 项目文档确认收入项问题解决 2025-03-27 13:31:54 +08:00
caiyiling 4188c0110f 非dicom阅片受试者内随机初始化图像逻辑更改
continuous-integration/drone/push Build is passing
2025-03-26 15:23:29 +08:00
wangxiaoshuang 01206716ab 1
continuous-integration/drone/push Build is passing
2025-03-24 16:56:27 +08:00
40 changed files with 4796 additions and 346 deletions
-1
View File
@@ -56,7 +56,6 @@
"pdfobject": "^2.3.0",
"qrcodejs2": "^0.0.2",
"screenfull": "^6.0.2",
"sortablejs": "^1.15.5",
"streamsaver": "^2.0.6",
"svg-sprite-loader": "^4.1.3",
"svgo": "^1.2.2",
+32
View File
@@ -3995,3 +3995,35 @@ export function deleteTrialFileType(id) {
})
}
// 工作台-获取稽查文档
export function getAuditDocumentData(data) {
return request({
url: `/AuditDocument/getAuditDocumentData`,
method: 'post',
data
})
}
// 工作台-新增稽查文档
export function addAuditDocument(data) {
return request({
url: `/AuditDocument/addAuditDocument`,
method: 'post',
data
})
}
// 工作台-获取当前目录层级
export function getBreadcrumbData(data) {
return request({
url: `/AuditDocument/getBreadcrumbData`,
method: 'post',
data
})
}
// 工作台-修改稽查文档
export function updateAuditDocument(data) {
return request({
url: `/AuditDocument/updateAuditDocument`,
method: 'post',
data
})
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 175 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 665 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.8 KiB

+2
View File
@@ -21,6 +21,8 @@ service.interceptors.request.use(
async config => {
path = router && router.app && router.app._route && router.app._route.path
config.headers['Content-Type'] = 'application/json;charset=UTF-8'
config.baseURL = process.env.NODE_ENV === 'prod' ? "https://api.irc.extimaging.com" : '/api'
config.headers['Self-Referer'] = window.location.href
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['TimeZoneId'] = moment.tz.guess()
@@ -277,7 +277,7 @@ export default {
}
}
</script>
<style lang="scss">
<style lang="scss" scoped>
.preview-wrapper{
display: flex;
flex-direction: row !important;
@@ -1,7 +1,10 @@
<template>
<div ref="container" style="width:100%;height:100%" class="dicom-container">
<!-- 访视阅片 -->
<div v-if="(isReadingTaskViewInOrder === 1 || ((isReadingTaskViewInOrder !== 1) && isShow)) && readingCategory=== 1 && CriterionType !== 0" class="reading-wrapper">
<div v-if="readingCategory=== 1 && (CriterionType === 7)" class="reading-wrapper">
<VisitReview />
</div>
<div v-else-if="(isReadingTaskViewInOrder === 1 || ((isReadingTaskViewInOrder !== 1) && isShow)) && readingCategory=== 1 && CriterionType !== 0" class="reading-wrapper">
<el-tabs v-model="activeName" v-loading="loading" :before-leave="beforeLeave">
<!-- 阅片 -->
<el-tab-pane :label="$t('trials:reading:tabTitle:review')" name="read">
@@ -29,7 +32,7 @@
</el-tab-pane>
</el-tabs>
</div>
<div v-if="(isReadingTaskViewInOrder === 1 || ((isReadingTaskViewInOrder !== 1) && isShow)) && readingCategory=== 1 && CriterionType === 0" class="reading-wrapper">
<div v-else-if="(isReadingTaskViewInOrder === 1 || ((isReadingTaskViewInOrder !== 1) && isShow)) && readingCategory=== 1 && CriterionType === 0" class="reading-wrapper">
<el-tabs v-model="activeName" v-loading="loading" :before-leave="beforeLeaveCustomize">
<!-- 阅片 -->
<el-tab-pane :label="$t('trials:reading:tabTitle:review')" name="read">
@@ -171,6 +174,7 @@
</template>
<script>
import { getNextTask, readClinicalData, verifyDefaultQuestionBeAnswer } from '@/api/trials'
import VisitReview from './../dicoms3D/components/VisitReview'
import ReadPage from './components/ReadPage'
import CustomizeReadPage from './customize/CustomizeReadPage'
import ReportPage from './components/ReportPage'
@@ -187,6 +191,7 @@ import requestPoolManager from '@/utils/request-pool'
export default {
name: 'Reading',
components: {
VisitReview,
ReadPage,
ReportPage,
GlobalReview,
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,273 @@
<template>
<div v-loading="loading" class="study-wrapper">
<div class="study-info">
<div
v-if="taskInfo && taskInfo.IsReadingShowSubjectInfo"
:title="taskInfo.SubjectCode"
>
{{ taskInfo.SubjectCode }}
</div>
<div
v-if="taskInfo && taskInfo.IsReadingShowSubjectInfo"
:title="visitTaskInfo.TaskBlindName"
>
{{ visitTaskInfo.TaskBlindName }}
</div>
</div>
<div class="ps">
<el-collapse v-model="activeNames">
<el-collapse-item v-for="(study, index) in studyList" :key="`${study.StudyId}`" :name="`${study.StudyId}`">
<template slot="title">
<div
v-if="!study.IsCriticalSequence"
class="dicom-desc"
>
<template v-if="taskInfo && taskInfo.IsShowStudyName">
<div style="text-overflow: ellipsis;overflow: hidden;">
<span :title="study.StudyCode">{{ study.StudyCode }}</span>
<span v-if="study.StudyName" :title="study.StudyName" style="margin-left: 5px;">{{ study.StudyName }}</span>
<span v-else :title="study.Modalities" style="margin-left: 5px;">{{ `${study.Modalities} (${study.SeriesCount})` }}</span>
</div>
<div style="text-overflow: ellipsis;overflow: hidden;" v-if="study.StudyName" >
<span :title="study.Modalities">{{ `${study.Modalities} (${study.SeriesCount})` }}</span>
</div>
</template>
<template v-else-if="taskInfo && !taskInfo.IsShowStudyName">
<div style="text-overflow: ellipsis;overflow: hidden;">
<span :title="study.StudyCode">{{ study.StudyCode }}</span>
<span :title="study.Modalities">{{ `${study.Modalities} (${study.SeriesCount})` }}</span>
</div>
</template>
</div>
<div v-else>
<!-- 关键序列 -->
{{ $t('trials:reading:title:keySeries') }}
</div>
</template>
<div class="dicom-list-container">
<div
v-for="(series, i) in study.SeriesList"
:key="i"
style="position:relative;margin-top:1px;"
@click="activeSeries(series, i, index)"
>
<div
:class="{'series-active': index === activeStudyIndex && i === activeSeriesIndex}"
class="series-wrapper"
>
<div class="series-image">
<el-image
style="width: 100%;height: 100%;"
:src="`${OSSclientConfig.basePath}${series.ImageResizePath}`"
fit="fill"
crossorigin="anonymous"
/>
</div>
<div class="series-text" >
<div class="text-desc" v-if="!study.IsCriticalSequence" :title="series.SeriesNumber">
#{{ series.SeriesNumber }}
</div>
<div class="text-desc" v-if="series.Description" :title="series.Description">
{{ series.Description }}
</div>
<div class="text-desc" v-if="series.SliceThickness && !study.IsCriticalSequence">
T: {{ parseFloat(series.SliceThickness).toFixed(digitPlaces) }}
</div>
<div class="text-desc">
<span v-show="series.LoadedImageCount < series.InstanceCount">
{{ series.Modality }}: {{ series.LoadedImageCount }}/{{ series.InstanceCount }} image
</span>
<span v-show="series.LoadedImageCount >= series.InstanceCount">{{ series.Modality }}: {{ series.InstanceCount }} image</span>
</div>
<div v-show="series.IsBeMark">
<i class="el-icon-star-on" style="font-size: 16px;color: #ff5722;" />
</div>
</div>
</div>
<div v-if="series.IsDicom && series.LoadedImageProgress>0 && series.LoadedImageProgress<100" style="width: 100%;">
<el-progress
:percentage="parseInt((series.LoadedImageProgress).toFixed(2))"
/>
</div>
</div>
</div>
</el-collapse-item>
</el-collapse>
</div>
</div>
</template>
<script>
export default {
name: 'StudyList',
props: {
visitTaskInfo: {
type: Object,
default() {
return {}
}
}
},
data() {
return {
loading: false,
activeNames: [],
activeStudyIndex: -1,
activeSeriesIndex: -1,
taskInfo: null,
studyList: [],
digitPlaces: 2
}
},
mounted() {
this.taskInfo = JSON.parse(localStorage.getItem('taskInfo'))
let digitPlaces = Number(localStorage.getItem('digitPlaces'))
this.digitPlaces = digitPlaces === -1 ? this.digitPlaces : digitPlaces
this.studyList = this.visitTaskInfo.StudyList
if (this.studyList.length === 0) return
this.$nextTick(() => {
this.activeStudy(this.studyList[0].StudyId)
})
},
methods: {
activeSeries(series, seriesIndex, studyIndex) {
this.activeStudyIndex = studyIndex
this.activeSeriesIndex = seriesIndex
this.$emit('activeSeries', series)
},
activeStudy(id) {
if (this.activeNames.indexOf(id) > -1) return
this.activeNames.push(id)
},
setSeriesActive(studyIndex, seriesIndex) {
this.activeStudyIndex = studyIndex
this.activeSeriesIndex = seriesIndex
let studyId = this.studyList[studyIndex].StudyId
if (!studyId) return
this.activeStudy(studyId)
},
getPreviousOrNextSeries(type, series) {
let seriseList = this.studyList.map(s => s.SeriesList).flat()
let i = seriseList.findIndex(i => i.Id === series.Id && i.StudyId === series.StudyId)
if (i === -1) return
let newIndex = null
if (type === -1) {
newIndex = i === 0 ? i : i - 1
} else {
newIndex = i >= seriseList.length - 1 ? i : i +1
}
let studyIndex = seriseList[newIndex].StudyIndex
let seriesIndex = seriseList[newIndex].SeriesIndex
this.setSeriesActive(studyIndex, seriesIndex)
this.activeSeries(seriseList[newIndex], seriesIndex, studyIndex)
}
}
}
</script>
<style lang="scss" scoped>
.study-wrapper{
width:100%;
height: 100%;
overflow-y: hidden;
overflow-x: hidden;
display: flex;
flex-direction: column;
.study-info {
font-size: 16px;
font-weight: bold;
color: #ddd;
padding: 5px 0px;
margin: 0;
text-align: center;
background-color: #4c4c4c;
height: 50px;
}
.dicom-desc{
font-weight: bold;
font-size: 13px;
text-align: left;
color: #d0d0d0;
padding: 2px;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.ps {
flex: 1;
overflow-anchor: none;
touch-action: auto;
overflow-y: auto;
}
.series-active {
background-color: #607d8b!important;
border: 1px solid #607d8b!important;
}
::v-deep.el-progress__text{
color: #ccc;
font-size: 12px;
}
.dicom-list-container{
width: 100%;
display: flex;
flex-direction: column;
justify-content: flex-start;
.series-wrapper {
width: 100%;
padding: 5px;
display: flex;
flex-direction: row;
align-items: center;
cursor: pointer;
background-color: #3a3a3a;
.el-progress__text{
display: none;
}
.el-progress-bar{
padding-right:0px;
}
.series-image {
width: 50px;
height: 50px;
}
.series-text {
flex: 1;
padding-left: 5px;
color: #ddd;
.text-desc {
width: 100px;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
font-size: 12px;
line-height: 16px;
}
}
}
}
::v-deep.el-collapse{
border: none;
.el-collapse-item{
background-color: #000!important;
color: #ddd;
}
.el-collapse-item__content{
padding-bottom:0px;
background-color: #000!important;
}
.el-collapse-item__header{
background-color: #000!important;
color: #ddd;
border-bottom-color:#5a5a5a;
padding-left: 5px;
// height: 50px;
line-height: 20px;
}
}
::v-deep .el-progress-bar__inner{
transition: width 0s ease;
}
}
</style>
@@ -0,0 +1,551 @@
<template>
<div
ref="viewport"
class="viewport-wrapper"
@mouseup="sliderMouseup"
@mousemove="sliderMousemove"
@mouseleave="sliderMouseleave"
>
<div class="left-top-text" v-if="series && taskInfo">
<div
v-if="taskInfo.IsExistsClinicalData"
class="cd-info"
:title="$t('trials:reading:button:clinicalData')"
>
<svg-icon
style="cursor: pointer;"
icon-class="documentation"
class="svg-icon"
@click.stop="viewCD(series.TaskInfo.VisitTaskId)" />
</div>
<h2
v-if="taskInfo.IsReadingShowSubjectInfo"
class="subject-info"
>
{{ `${series.TaskInfo.SubjectCode} ${series.TaskInfo.TaskBlindName} ` }}
</h2>
<div>Series: #{{ series.SeriesNumber }}</div>
<div>Image: #{{ `${series.SliceIndex + 1}/${series.ImageIds.length}` }}</div>
<div>{{series.Modality}}</div>
</div>
<div
v-if="series && taskInfo && taskInfo.IsReadingTaskViewInOrder === 1"
class="top-center-tool"
>
<div class="toggle-visit-container">
<div
class="arrw_icon"
:style="{ cursor: series.TaskInfo.VisitTaskNum !== 0 ? 'pointer' : 'not-allowed', color: series.TaskInfo.VisitTaskNum !== 0 ? '#fff': '#6b6b6b' }"
@click.stop.prevent="toggleTask($event, series.TaskInfo.VisitTaskNum, -1)"
@dblclick.stop="preventDefault($event)"
>
<i class="el-icon-caret-left" />
</div>
<div class="arrow_text">
{{ series.TaskInfo.TaskBlindName }}
</div>
<div
class="arrw_icon"
:style="{ cursor: series.TaskInfo.VisitTaskNum < taskInfo.VisitNum ? 'pointer' : 'not-allowed', color: series.TaskInfo.VisitTaskNum < taskInfo.VisitNum ? '#fff': '#6b6b6b' }"
@click.stop.prevent="toggleTask($event, series.TaskInfo.VisitTaskNum, 1)"
@dblclick.stop="preventDefault($event)"
>
<i class="el-icon-caret-right" />
</div>
</div>
</div>
<div class="right-top-text" v-if="series">
<div>{{ series.Description }}</div>
</div>
<div class="left-bottom-text" v-if="series">
<div v-show="mousePosition.index.length > 0">
Pos: {{ mousePosition.index[0] }}, {{ mousePosition.index[1] }}, {{ mousePosition.index[2] }}
</div>
<div v-if="(series.Modality === 'CT' || series.Modality === 'DR' || series.Modality === 'CR') && mousePosition.value">
HU: {{ mousePosition.value }}
</div>
<div v-else-if="(series.Modality === 'PT' && mousePosition.value)">
SUVbw(g/ml): {{ digitPlaces === -1 ?mousePosition.value.toFixed(3) :mousePosition.value.toFixed(digitPlaces) }}
</div>
<div v-else-if="mousePosition.value">
Density: {{ mousePosition.value }}
</div>
<div v-show="imageInfo.size">
W*H: {{ imageInfo.size }}
</div>
</div>
<div class="right-bottom-text" v-if="series">
<div v-show="imageInfo.location">Location: {{ `${Number(imageInfo.location).toFixed(digitPlaces)} mm` }}</div>
<div v-show="series.SliceThickness">Slice Thickness: {{ `${Number(series.SliceThickness).toFixed(digitPlaces)} mm` }}</div>
<div v-show="imageInfo.wwwc ">WW/WL: {{ imageInfo.wwwc }}</div>
</div>
<div class="orientation-top">
{{ markers.top }}
</div>
<div class="orientation-right">
{{ markers.right }}
</div>
<div class="orientation-bottom">
{{ markers.bottom }}
</div>
<div class="orientation-left">
{{ markers.left }}
</div>
<div ref="sliderBox" class="right-slider-box" @click.stop="clickSlider($event)">
<div :style="{top: sliderInfo.height + '%'}" class="slider" @click.stop.prevent="() => {return}" @mousedown.stop="sliderMousedown($event)" />
</div>
</div>
</template>
<script>
import * as cornerstonejs from '@cornerstonejs/core'
import {
RenderingEngine,
Enums,
imageLoader,
metaData,
getRenderingEngine,
eventTarget,
utilities as csUtils
} from '@cornerstonejs/core'
import * as cornerstoneTools from '@cornerstonejs/tools'
import { vec3, mat4 } from 'gl-matrix'
export default {
name: 'Viewport',
props: {
renderingEngineId: {
type: String,
required: true
},
viewportId: {
type: String,
required: true
},
viewportIndex: {
type: Number,
required: true
}
},
data(){
return {
element: '',
series: null,
taskInfo: null,
sliderInfo: {
oldB: null,
oldM: null,
isMove: false,
height: 0
},
mousePosition: {
index: [],
value: null,
modalityUnit: '',
world: []
},
imageInfo: {
zoom: null,
size: null,
location: null,
sliceThickness: null,
wwwc: null
},
digitPlaces: 2,
orientationMarkers: [],
originalMarkers: [],
markers: { top: '', right: '', bottom: '', left: '' },
playClipState: false,
wwwcIdx: 2
}
},
mounted() {
this.taskInfo = JSON.parse(localStorage.getItem('taskInfo'))
let digitPlaces = Number(localStorage.getItem('digitPlaces'))
this.digitPlaces = digitPlaces === -1 ? this.digitPlaces : digitPlaces
this.$nextTick(()=>{
this.initViewport()
})
console.log(cornerstonejs)
},
methods: {
initViewport() {
this.element = this.$refs['viewport']
const resizeObserver = new ResizeObserver(() => {
const renderingEngine = getRenderingEngine(this.renderingEngineId)
if (renderingEngine) {
renderingEngine.resize(true, false)
}
})
this.element.oncontextmenu = (e) => e.preventDefault()
resizeObserver.observe(this.element)
this.element.addEventListener('CORNERSTONE_STACK_NEW_IMAGE', this.stackNewImage)
this.element.addEventListener('CORNERSTONE_VOI_MODIFIED', this.voiModified)
this.element.addEventListener('CORNERSTONE_TOOLS_MOUSE_MOVE', this.cornerstoneToolsMouseMove)
this.element.addEventListener('mouseleave', () => {
this.mousePosition.index = []
})
// console.log(cornerstonejs,cornerstoneTools)
// element.addEventListener('CORNERSTONE_STACK_NEW_IMAGE', this.stackNewImage)
},
stackNewImage(e) {
const { detail } = e
this.series.SliceIndex = detail.imageIdIndex
this.sliderInfo.height = detail.imageIdIndex * 100 / (this.series.ImageIds.length - 1)
const renderingEngine = getRenderingEngine(this.renderingEngineId)
const viewport = renderingEngine.getViewport(this.viewportId)
let zoom = viewport.getZoom()
this.imageInfo.zoom = zoom.toFixed(4)
this.imageInfo.size = `${detail.image.columns}*${detail.image.rows}`
const imagePlaneModule = metaData.get('imagePlaneModule', detail.imageId)
this.imageInfo.location = imagePlaneModule.sliceLocation
// this.imageInfo.wwwc = `${Math.round(detail.image.windowWidth)}/${Math.round(detail.image.windowCenter)}`
this.getOrientationMarker()
},
voiModified(e) {
const renderingEngine = getRenderingEngine(this.renderingEngineId)
const viewport = renderingEngine.getViewport(this.viewportId)
const properties = viewport.getProperties()
if (properties && properties.voiRange) {
var { lower, upper } = properties.voiRange
const { windowWidth, windowCenter } = csUtils.windowLevel.toWindowLevel(
lower,
upper
)
this.imageInfo.wwwc = `${Math.round(windowWidth)}/${Math.round(windowCenter)}`
}
},
getOrientationMarker() {
const renderingEngine = getRenderingEngine(this.renderingEngineId)
const viewport = renderingEngine.getViewport(this.viewportId)
const { viewUp, viewPlaneNormal } = viewport.getCamera()
const viewRight = vec3.create()
vec3.cross(viewRight, viewUp, viewPlaneNormal)
const columnCosines = [-viewUp[0], -viewUp[1], -viewUp[2]]
const rowCosines = viewRight
const rowString = cornerstoneTools.utilities.orientation.getOrientationStringLPS(rowCosines)
const columnString = cornerstoneTools.utilities.orientation.getOrientationStringLPS(columnCosines)
const oppositeRowString = cornerstoneTools.utilities.orientation.invertOrientationStringLPS(rowString)
const oppositeColumnString = cornerstoneTools.utilities.orientation.invertOrientationStringLPS(columnString)
this.markers.top = oppositeColumnString
this.markers.right = rowString
this.markers.bottom = columnString
this.markers.left = oppositeRowString
this.orientationMarkers = [oppositeColumnString, rowString, columnString, oppositeRowString]
if (this.originalMarkers.length === 0) {
this.originalMarkers = [...this.orientationMarkers]
}
},
setMarkers() {
let markers = [...this.orientationMarkers]
for (const key in this.markers) {
let v = markers.shift(0)
this.markers[key] = v
}
},
resetOrientationMarkers() {
if (this.originalMarkers.length > 0) {
console.log(this.originalMarkers)
this.orientationMarkers = [...this.originalMarkers]
this.setMarkers()
}
},
rotateOrientationMarkers(type) {
if (this.orientationMarkers.length > 0) {
if (type === 1) {
this.resetOrientationMarkers()
return
}
let markers = [...this.orientationMarkers]
if (type === 2) {
// 垂直翻转
this.orientationMarkers[0] = markers[2]
this.orientationMarkers[2] = markers[0]
} else if (type === 3) {
// 水平翻转
this.orientationMarkers[1] = markers[3]
this.orientationMarkers[3] = markers[1]
} else if (type === 4) {
// 左转90度
this.orientationMarkers = markers.slice(1, 4).concat(markers[0])
} else if (type === 5) {
// 右转90度
this.orientationMarkers = [markers[3]].concat(markers.slice(0, 3))
}
this.setMarkers()
}
},
toggleClipPlay(isPlay, framesPerSecond) {
this.playClipState = isPlay
const renderingEngine = getRenderingEngine(this.renderingEngineId)
const viewport = renderingEngine.getViewport(this.viewportId)
if (isPlay) {
cornerstoneTools.utilities.cine.playClip(viewport.element, { framesPerSecond })
} else {
cornerstoneTools.utilities.cine.stopClip(viewport.element)
}
},
scrollPage(type) {
const renderingEngine = getRenderingEngine(this.renderingEngineId)
const viewport = renderingEngine.getViewport(this.viewportId)
const currentImageIdIndex = viewport.getCurrentImageIdIndex();
const numImages = viewport.getImageIds().length;
let newImageIdIndex = null;
if (type === 0) {
newImageIdIndex = 0
} else if (type === -1) {
newImageIdIndex = currentImageIdIndex === 0 ? currentImageIdIndex : currentImageIdIndex - 1
} else if (type === 1) {
newImageIdIndex = currentImageIdIndex === numImages - 1 ? currentImageIdIndex : currentImageIdIndex + 1
} else if (type === 99999) {
newImageIdIndex = numImages -1
}
viewport.setImageIdIndex(newImageIdIndex);
},
setZoom(ratio) {
const renderingEngine = getRenderingEngine(this.renderingEngineId);
const viewport = renderingEngine.getViewport(this.viewportId);
const zoom = viewport.getZoom();
if (ratio > 0) {
viewport.setZoom(zoom * 1.05);
} else {
viewport.setZoom(zoom / 1.05);
}
viewport.render();
},
resize(forceFitToWindow) {
console.log('resize: ', forceFitToWindow)
const renderingEngine = getRenderingEngine(this.renderingEngineId);
renderingEngine.resize(true, forceFitToWindow)
},
async setSeriesInfo(obj){
if (this.series && obj.Id === this.series.Id && obj.Description === this.series.Description) return
this.series = {...obj}
const renderingEngine = getRenderingEngine(this.renderingEngineId)
const viewport = renderingEngine.getViewport(this.viewportId)
await viewport.setStack(obj.ImageIds, obj.SliceIndex)
cornerstoneTools.utilities.stackPrefetch.enable(viewport.element);
viewport.render()
},
cornerstoneToolsMouseMove(e) {
const { currentPoints } = e.detail
const worldPoint = currentPoints.world
const renderingEngine = getRenderingEngine(this.renderingEngineId)
const viewport = renderingEngine.getViewport(this.viewportId)
const imageData = viewport.getImageData()
if (!imageData) return
const index = imageData.imageData.worldToIndex(worldPoint)
index[0] = Math.floor(index[0])
index[1] = Math.floor(index[1])
index[2] = Math.floor(index[2])
this.mousePosition.index = index
},
toggleTask(evt, visitTaskNum, i) {
this.$emit('activeViewport', this.viewportIndex)
const num = visitTaskNum + i
if (num >= 0 && num <= this.taskInfo.VisitNum) {
this.$emit('toggleTaskByViewport', {series: this.series, visitTaskNum: num})
}
evt.stopImmediatePropagation()
evt.stopPropagation()
evt.preventDefault()
},
viewCD(taskId) {
this.$emit('previewCD', taskId)
},
setWwwcIdx(idx) {
this.wwwcIdx = idx
},
clickSlider(e) {
const height = e.offsetY * 100 / this.$refs['sliderBox'].clientHeight
this.sliderInfo.height = height
let sliceIdx = Math.trunc(this.series.ImageIds.length * height / 100)
sliceIdx = sliceIdx >= this.series.ImageIds.length ? this.series.ImageIds.length - 1 : sliceIdx < 0 ? 0 : sliceIdx
const renderingEngine = getRenderingEngine(this.renderingEngineId)
const viewport = renderingEngine.getViewport(
this.viewportId
)
viewport.setImageIdIndex(sliceIdx)
viewport.render()
},
sliderMouseup(e) {
this.sliderInfo.isMove = false
},
sliderMousedown(e) {
const boxHeight = this.$refs['sliderBox'].clientHeight
this.sliderInfo.oldB = parseInt(e.srcElement.style.top) * boxHeight / 100
this.sliderInfo.oldM = e.clientY
this.sliderInfo.isMove = true
e.stopImmediatePropagation()
e.stopPropagation()
e.preventDefault()
},
sliderMousemove(e) {
if (!this.sliderInfo.isMove) return
const delta = this.sliderInfo.oldB - (this.sliderInfo.oldM - e.clientY)
const boxHeight = this.$refs['sliderBox'].clientHeight
if (delta < 0) return
if (delta > boxHeight) return
const height = delta * 100 / boxHeight
let sliceIdx = Math.trunc(this.series.ImageIds.length * height / 100)
sliceIdx = sliceIdx >= this.series.ImageIds.length ? this.series.ImageIds.length - 1 : sliceIdx < 0 ? 0 : sliceIdx
this.sliderInfo.height = height
const renderingEngine = getRenderingEngine(this.renderingEngineId)
const viewport = renderingEngine.getViewport(
this.viewportId
)
viewport.setImageIdIndex(sliceIdx)
viewport.render()
},
sliderMouseleave(e) {
if (!this.sliderInfo.isMove) return
this.sliderInfo.isMove = false
},
preventDefault(e) {
e.stopImmediatePropagation()
e.stopPropagation()
e.preventDefault()
},
}
}
</script>
<style lang="scss" scoped>
.viewport-wrapper {
width:100%;
height:100%;
position: relative;
.left-top-text {
position: absolute;
left: 5px;
top: 5px;
color: #ddd;
z-index: 1;
font-size: 12px;
.cd-info {
color: #ddd;
font-size: 18px;
}
.subject-info {
color:#f44336;
padding: 5px 0px;
margin: 0;
}
}
.top-center-tool {
position: absolute;
left:50%;
top: 5px;
transform: translateX(-50%);
z-index: 1;
.toggle-visit-container {
display: flex;
}
.arrw_icon{
width: 20px;
height: 20px;
background-color: #3f3f3f;
text-align: center;
line-height: 20px;
border-radius: 10%;
}
.arrow_text{
height: 20px;
line-height: 20px;
background-color: #00000057;
color: #fff;
padding:0 10px;
font-size: 14px;
}
}
.right-top-text {
position: absolute;
right: 5px;
top: 5px;
color: #ddd;
z-index: 1;
font-size: 12px;
}
.left-bottom-text {
position: absolute;
left: 5px;
bottom: 5px;
color: #ddd;
z-index: 1;
font-size: 12px;
}
.right-bottom-text {
position: absolute;
right: 5px;
bottom: 5px;
color: #ddd;
z-index: 1;
font-size: 12px;
}
.right-slider-box {
position: absolute;
right: 1px;
height: calc(100% - 140px);
transform: translateY(-50%);
top: calc(50% - 30px);
width: 10px;
background: #333;
z-index: 1;
cursor: pointer;
}
.right-slider-box:after{
content: '';
position: absolute;
bottom: -20px;
left: 0;
height: 20px;
width: 100%;
background: #333;
}
.slider {
height: 20px;
width: 100%;
position: absolute;
top: 0;
z-index:10;
background: #9e9e9e;
cursor: move
}
.orientation-top {
position: absolute;
left: 50%;
top: 30px;
color: #f44336;
transform: translateX(-50%);
z-index: 1;
}
.orientation-bottom {
position: absolute;
left: 50%;
bottom: 15px;
color: #f44336;
transform: translateX(-50%);
z-index: 1;
}
.orientation-left {
position: absolute;
top: 50%;
left: 15px;
color: #f44336;
transform: translateY(-50%);
z-index: 1;
}
.orientation-right {
position: absolute;
top: 50%;
right: 15px;
color: #f44336;
transform: translateY(-50%);
z-index: 1;
}
}
</style>
@@ -0,0 +1,79 @@
<template>
<div class="visit-review-container">
<el-tabs
v-model="activeName"
>
<!-- 阅片 -->
<el-tab-pane
v-if="taskInfo"
:label="$t('trials:reading:tabTitle:review')"
name="read"
>
<read-page />
</el-tab-pane>
<!-- 报告 -->
<el-tab-pane
v-if="taskInfo && !taskInfo.IseCRFShowInDicomReading"
:label="$t('trials:reading:tabTitle:report')"
name="report"
>
<report-page v-if="activeName === 'report'" />
</el-tab-pane>
</el-tabs>
</div>
</template>
<script>
import ReadPage from './ReadPage'
import ReportPage from './ReportPage'
export default {
name: 'VisitReview',
components: {
ReadPage,
ReportPage
},
data() {
return {
activeName: 'read',
taskInfo: null
}
},
mounted() {
this.taskInfo = JSON.parse(localStorage.getItem('taskInfo'))
}
}
</script>
<style lang="scss" scoped>
.visit-review-container {
height: 100vh;
display: flex;
flex-direction: column;
background-color: #000;
padding: 5px;
::v-deep .el-tabs {
height: 100%;
display: flex;
flex-direction: column;
.el-tabs__item {
color: #fff;
}
.el-tabs__item.is-active {
color: #428bca;
}
.el-tabs__item:hover {
color: #428bca;
}
.el-tabs__header {
height: 50px;
margin:0px;
}
.el-tabs__content {
flex: 1;
margin:0px;
}
.el-tab-pane {
height: 100%;
}
}
}
</style>
@@ -0,0 +1,193 @@
const config = {
"standards": [
{
"type": 1,
"name": "RECIST 1.1",
"tools": [
{
"name": "直径测量工具",
"icon": "length",
"toolName": "Length",
"i18nKey": "trials:reading:button:length"
},
{
"name": "长短径测量工具",
"icon": "bidirection",
"toolName": "Bidirectional",
"i18nKey": "trials:reading:button:bidirectional"
},
{
"name": "矩形工具",
"icon": "rectangle",
"toolName": "RectangleRoi",
"i18nKey": "trials:reading:button:rectangle"
},
{
"name": "箭头工具",
"icon": "arrow",
"toolName": "ArrowAnnotate",
"i18nKey": "trials:reading:button:arrowAnnotate"
}
]
},
{
"type": 2,
"name": "Lugano 2014",
"tools": [
{
"name": "直径测量工具",
"icon": "length",
"toolName": "Length",
"i18nKey": "trials:reading:button:length"
},
{
"name": "长短径测量工具",
"icon": "bidirection",
"toolName": "Bidirectional",
"i18nKey": "trials:reading:button:bidirectional"
},
{
"name": "矩形工具",
"icon": "rectangle",
"toolName": "RectangleRoi",
"i18nKey": "trials:reading:button:rectangle"
},
{
"name": "箭头工具",
"icon": "arrow",
"toolName": "ArrowAnnotate",
"i18nKey": "trials:reading:button:arrowAnnotate"
}
]
},
{
"type": 3,
"name": "iRECIST",
"tools": [
{
"name": "直径测量工具",
"icon": "length",
"toolName": "Length",
"i18nKey": "trials:reading:button:length"
},
{
"name": "长短径测量工具",
"icon": "bidirection",
"toolName": "Bidirectional",
"i18nKey": "trials:reading:button:bidirectional"
},
{
"name": "矩形工具",
"icon": "rectangle",
"toolName": "RectangleRoi",
"i18nKey": "trials:reading:button:rectangle"
},
{
"name": "箭头工具",
"icon": "arrow",
"toolName": "ArrowAnnotate",
"i18nKey": "trials:reading:button:arrowAnnotate"
}
]
},
{
"type": 7,
"name": "mRECIST HCC",
"tools": [
{
"name": "直径测量工具",
"icon": "length",
"toolName": "Length",
"i18nKey": "trials:reading:button:length"
},
{
"name": "长短径测量工具",
"icon": "bidirection",
"toolName": "Bidirectional",
"i18nKey": "trials:reading:button:bidirectional"
},
{
"name": "矩形工具",
"icon": "rectangle",
"toolName": "RectangleRoi",
"i18nKey": "trials:reading:button:rectangle"
},
{
"name": "箭头工具",
"icon": "arrow",
"toolName": "ArrowAnnotate",
"i18nKey": "trials:reading:button:arrowAnnotate"
}
]
},
{
"type": 10,
"name": "PCWG3",
"tools": [
{
"name": "矩形工具",
"icon": "rectangle",
"toolName": "RectangleRoi",
"i18nKey": "trials:reading:button:rectangle"
},
{
"name": "箭头工具",
"icon": "arrow",
"toolName": "ArrowAnnotate",
"i18nKey": "trials:reading:button:arrowAnnotate"
}
]
},
{
"type": 17,
"name": "PCWG3",
"tools": [
{
"name": "直径测量工具",
"icon": "length",
"toolName": "Length",
"i18nKey": "trials:reading:button:length"
},
{
"name": "矩形工具",
"icon": "rectangle",
"toolName": "RectangleRoi",
"i18nKey": "trials:reading:button:rectangle"
},
{
"name": "箭头工具",
"icon": "arrow",
"toolName": "ArrowAnnotate",
"i18nKey": "trials:reading:button:arrowAnnotate"
}
]
},
{
"type": 19,
"name": "IVUS定量评估",
"tools": []
},
{
"type": 20,
"name": "OCT定量评估",
"tools": []
},
{
"type": 21,
"name": "MRI-PDFF",
"tools": [
{
"name": "圆形测量",
"icon": "oval",
"toolName": "Probe",
"i18nKey": "trials:reading:button:circle"
}
]
}
]
}
const getTools = (criterionType) => {
const standard = config.standards.find(s => s.type === criterionType);
return standard?.tools || [];
};
export {config, getTools}
@@ -0,0 +1,113 @@
<template>
<div v-loading="loading" class="reading-viewer-container">
<!-- 访视阅片 -->
<visit-review
v-if="taskInfo && taskInfo.ReadingCategory=== 1"
/>
<!-- 临床数据 -->
<el-dialog
:visible.sync="clinicalDataVisible"
:custom-class="isClinicalDataFullscreen?'full-dialog-container':'dialog-container'"
:show-close="false"
:close-on-click-modal="false"
:fullscreen="isClinicalDataFullscreen"
>
<span slot="title" class="dialog-footer">
<!-- 当前阅片任务存在临床数据请查看若已查看请点击确认 -->
<span v-if="!closeCDVisible">{{ $t('trials:reading:dagTitle:msg1') }}</span>
<div style="position: absolute;right: 20px;top: 10px;">
<svg-icon :icon-class="isClinicalDataFullscreen?'exit-fullscreen':'fullscreen'" style="cursor: pointer;font-size: 20px;" @click="isClinicalDataFullscreen=!isClinicalDataFullscreen" />
<svg-icon v-if="closeCDVisible" icon-class="dClose" style="cursor: pointer;font-size: 25px;margin-left: 10px;" @click="clinicalDataVisible = false" />
</div>
</span>
<div style="height: 100%;margin:0;display: flex;flex-direction: column;">
<clinical-data
v-if="clinicalDataVisible"
style="flex: 1"
:trial-id="trialId"
:subject-id="taskInfo.SubjectId"
:visit-task-id="cdVisitTaskId"
:is-reading-show-subject-info="taskInfo.IsReadingShowSubjectInfo"
/>
<div v-if="!closeCDVisible" style="text-align:right">
<el-button type="primary" @click="handleConfirmCD">{{ $t('trials:reading:button:confirm') }}</el-button>
</div>
</div>
</el-dialog>
</div>
</template>
<script>
import VisitReview from './components/VisitReview'
import ClinicalData from '@/views/trials/trials-panel/reading/clinical-data'
export default {
name:'Dicoms3d',
components: { VisitReview,ClinicalData },
data() {
return {
taskInfo: null,
trialId: '',
loading: false,
clinicalDataVisible: false,
isClinicalDataFullscreen: false,
closeCDVisible: false,
cdVisitTaskId: ''
}
},
mounted() {
this.trialId = this.$route.query.trialId
this.getTaskInfo()
},
methods: {
async getTaskInfo() {
this.loading = true
try {
const params = {
subjectId: this.$route.query.subjectId,
trialId: this.$route.query.trialId,
subjectCode: this.$route.query.subjectCode,
visitTaskId: this.$route.query.visitTaskId,
trialReadingCriterionId: this.$route.query.TrialReadingCriterionId
}
const res = await getNextTask(params)
this.taskInfo = res.Result
localStorage.setItem('taskInfo', JSON.stringify(res.Result))
localStorage.setItem('digitPlaces', JSON.stringify(res.Result.DigitPlaces))
this.loading = false
this.$nextTick(() => {
if (this.taskInfo.IsExistsClinicalData && this.taskInfo.IsNeedReadClinicalData && !this.taskInfo.IsReadClinicalData) {
this.isClinicalDataFullscreen = false
this.clinicalDataVisible = true
this.cdVisitTaskId = this.taskInfo.VisitTaskId
}
})
} catch (e) {
console.log(e)
this.loading = false
}
},
}
}
</script>
<style lang="scss" scoped>
.reading-viewer-container {
width: 100%;
height: 100%;
// ::v-deep .dialog-container{
// margin-top: 50px !important;
// width:75%;
// height:80%;
// }
// ::v-deep .el-dialog__body{
// padding: 10px;
// height: calc(100% - 70px);
// }
// .el-dialog__header{
// position: relative;
// }
// .full-dialog-container{
// ::v-deep .is-fullscreen .el-dialog__body{
// height: calc(100% - 70px);
// }
// }
}
</style>
@@ -390,7 +390,7 @@ export default {
mounted() {
this.taskInfo = JSON.parse(localStorage.getItem('taskInfo'))
this.readingTaskState = this.taskInfo.ReadingTaskState
if (this.taskInfo.VisitNum > 0 && this.taskInfo.IsReadingTaskViewInOrder !== 0) {
if (!this.taskInfo.IsBaseLine && this.taskInfo.IsReadingTaskViewInOrder !== 0) {
this.rows = 1
this.cols = 2
this.activeCanvasIndex = 1
@@ -200,7 +200,8 @@ export default {
this.$refs[res.Result[idx].VisitTaskId][0].setInitActiveFile()
})
}
if (this.taskInfo.IsReadingTaskViewInOrder !== 0 && res.Result.length > 1) {
if (this.taskInfo.IsReadingTaskViewInOrder === 1 && res.Result.length > 1) {
//
const i = this.visitTaskList.findIndex(i => i.IsBaseLineTask)
if (i > -1) {
await this.getReadingImageFile(res.Result[i].VisitTaskId, i)
@@ -215,6 +216,14 @@ export default {
}
}
}
if (this.taskInfo.IsReadingTaskViewInOrder === 2) {
//
const studyList = this.visitTaskList[idx].StudyList
if (studyList.length > 0) {
const fileInfo = studyList[0].NoneDicomStudyFileList[0]
this.relatedStudyInfo = { fileInfo, visitTaskInfo: this.visitTaskList[idx], fileList: studyList[0].NoneDicomStudyFileList, fileIndex: 0, studyId: studyList[0].Id }
}
}
this.loading = false
} catch (e) {
console.log(e)
@@ -286,8 +295,8 @@ export default {
async toggleTaskByViewer(visitTaskNum) {
const i = this.visitTaskList.findIndex(v => v.VisitTaskNum === visitTaskNum)
if (i === -1) return
const visistTaskId = this.visitTaskList[i].VisitTaskId
this.setActiveTaskVisitId(visistTaskId, true)
const visitTaskId = this.visitTaskList[i].VisitTaskId
this.setActiveTaskVisitId(visitTaskId, true)
},
// 访
async setActiveTaskVisitId(id, isInitActiveFile = false) {
@@ -770,11 +770,12 @@ export default {
},
immediate: true,
},
'rowData.IsEnable': {
'rowData': {
handler() {
this.DATA = Object.assign({}, this.rowData)
},
immediate: true,
deep:true
},
},
created() {
@@ -766,11 +766,12 @@ export default {
},
immediate: true,
},
'rowData.IsEnable': {
'rowData': {
handler() {
this.DATA = Object.assign({}, this.rowData)
},
immediate: true,
deep:true
},
},
computed: {
@@ -722,11 +722,12 @@ export default {
},
immediate: true,
},
'rowData.IsEnable': {
'rowData': {
handler() {
this.DATA = Object.assign({}, this.rowData)
},
immediate: true,
deep:true
},
},
created() {
@@ -865,11 +865,12 @@ export default {
},
immediate: true,
},
'rowData.IsEnable': {
'rowData': {
handler() {
this.DATA = Object.assign({}, this.rowData)
},
immediate: true,
deep:true
},
},
created() {
@@ -10,43 +10,20 @@
)
}}</el-divider>
<div class="form-group">
<div
class="upload"
style="margin-right: 10px"
:disabled="limitLength"
v-if="!limitLength"
>
<input
multiple="multiple"
webkitdirectory=""
directory
accept="*/*"
type="file"
name="uploadFolder"
class="select-file"
title=""
@change="beginScanFiles($event)"
v-if="
<div class="upload" style="margin-right: 10px" :disabled="limitLength" v-if="!limitLength">
<input multiple="multiple" webkitdirectory="" directory accept="*/*" type="file" name="uploadFolder"
class="select-file" title="" @change="beginScanFiles($event)" v-if="
!loading &&
(!limitLength ||
(fileList.length < limitLength && limitLength > 1))
"
/>
" />
<div class="btn-select">
{{ $t('trials:trialDocument: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="!loading && (!limitLength || fileList.length < limitLength)"
/>
<input class="select-file" multiple="" :accept="faccept.join(',')" type="file" name="uploadFile" title=""
@change="beginScanFiles($event)" v-if="!loading && (!limitLength || fileList.length < limitLength)" />
<div class="btn-select">
{{ $t('trials:trialDocument:button:select') }}
</div>
@@ -54,30 +31,14 @@
</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 && !loading"
/>
<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 && !loading" />
<el-table-column type="index" width="50" />
<!-- 文件名称 -->
<el-table-column
prop="name"
:label="$t('trials:trialDocument:table:fileName')"
min-width="100"
/>
<el-table-column prop="name" :label="$t('trials:trialDocument:table:fileName')" min-width="100" />
<!-- 文件大小 -->
<el-table-column
prop="size"
:label="$t('trials:trialDocument:table:fileSize')"
>
<el-table-column prop="size" :label="$t('trials:trialDocument:table:fileSize')">
<template slot-scope="scope">
<span>{{
scope.row.size && scope.row.size > 0
@@ -87,49 +48,27 @@
</template>
</el-table-column>
<!-- 文件类型 -->
<el-table-column
prop="type"
:label="$t('trials:trialDocument:table:fileType')"
/>
<el-table-column prop="type" :label="$t('trials:trialDocument:table:fileType')" />
<!-- 上传状态 -->
<el-table-column
prop="status"
:label="$t('trials:trialDocument:table:uploadStatus')"
min-width="100"
>
<el-table-column prop="status" :label="$t('trials:trialDocument: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 :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:trialDocument:table:failedFileCount')"
min-width="150"
show-overflow-tooltip
>
<el-table-column :label="$t('trials:trialDocument: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
"
/>
<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="loading"
:title="$t('trials:trialDocument:action:delete')"
@click="handleRemoveFile(scope.row)"
/>
<el-button size="mini" icon="el-icon-delete" circle :disabled="loading"
:title="$t('trials:trialDocument:action:delete')" @click="handleRemoveFile(scope.row)" />
</template>
</el-table-column>
</el-table>
@@ -139,13 +78,8 @@
<span style="margin-right: 10px">{{
$store.state.trials.uploadTip
}}</span>
<el-button
size="small"
type="primary"
:disabled="selectArr.length == 0"
:loading="loading"
@click="beginUpload"
>
<el-button size="small" type="primary" :disabled="selectArr.length == 0" :loading="loading"
@click="beginUpload">
{{ $t('trials:trialDocument:action:upload') }}
</el-button>
</div>
@@ -265,11 +199,11 @@ export default {
type: extendName.split('.')[1],
status: 0,
file: files[i],
id: `${files[i].lastModified}${
files[i].name
}${new Date().getTime()}${i + 1}`,
id: `${files[i].lastModified}${files[i].name
}${new Date().getTime()}${i + 1}`,
fileType: files[i].type,
uploadFileSize: 0,
webkitRelativePath: files[i].webkitRelativePath
}
this.fileList.push(obj)
this.$refs.filesTable.toggleRowSelection(obj, true)
@@ -300,7 +234,7 @@ export default {
)
}
})
.catch(() => {})
.catch(() => { })
},
//
async beginUpload() {
@@ -348,7 +282,8 @@ export default {
FileName: file.name,
FilePath: this.$getObjectName(res.url),
FileSize: file.size,
FileFormat: fileType,
FileFormat: fileType.split('.')[1],
catalogue: file.webkitRelativePath
})
let flag = arr.every((item) => item.status === 2)
if (flag) {
@@ -431,7 +366,6 @@ export default {
} else {
this.fileInput.accept = this.faccept.join(',')
}
console.log(this.fileInput)
this.fileInput.click()
},
},
@@ -481,6 +415,7 @@ export default {
background: #428bca;
border-color: #428bca;
color: #fff;
.select-file {
height: 30px;
width: 90px;
@@ -491,6 +426,7 @@ export default {
opacity: 0;
font-size: 0;
}
.btn-select {
//
width: 90px;
@@ -253,4 +253,11 @@ export default {
::v-deep .box-body .search .base-search-form .el-form-item {
margin-bottom: 15px;
}
::v-deep .el-radio__original {
display: none !important; /* 隐藏原生 radio 输入,但仍然允许交互 */
}
::v-deep .el-radio:focus:not(.is-focus):not(:active):not(.is-disabled) .el-radio__inner {
box-shadow: none !important;
}
</style>
@@ -375,6 +375,7 @@
<el-tab-pane
:label="$t('trials:audit:tab:nonDicoms')"
name="none-dicom"
v-if="noneDicomStudyList.length > 0"
>
<el-row>
<!-- 检查信息 -->
@@ -0,0 +1,246 @@
<template>
<div id="contextmenu" class="contextmenu" v-show="visible" :style="{
'z-index': zIndex
}">
<div class="contextmenu__item" @click="handleMenu('open')" v-show="checkList.length <= 1">
<i class="icon el-icon-right icon_open" />
<span>{{ $t('trials:trials-workbench:auditDocument:menu:open') }}</span>
</div>
<div class="contextmenu__item" @click="handleMenu('download')">
<i class="icon icon_download" />
<span>{{ $t('trials:trials-workbench:auditDocument:menu:download') }}</span>
</div>
<template v-if="type === 'file'">
<div class="line"></div>
<div class="contextmenu__item" @click="handleMenu('copy')">
<i class="icon icon_copy" />
<span>{{ $t('trials:trials-workbench:auditDocument:menu:copy') }}</span>
</div>
<div class="contextmenu__item" @click="handleMenu('shear')">
<i class="icon icon_shear" />
<span>{{ $t('trials:trials-workbench:auditDocument:menu:shear') }}</span>
</div>
<div class="contextmenu__item" @click="handleMenu('rename')" v-show="checkList.length <= 1">
<i class="icon icon_rename" />
<span>{{ $t('trials:trials-workbench:auditDocument:menu:rename') }}</span>
</div>
<div class="contextmenu__item" @click="handleMenu('del')">
<i class="icon icon_del" />
<span>{{ $t('trials:trials-workbench:auditDocument:menu:del') }}</span>
</div>
</template>
<template v-if="checkList.length <= 1 && type === 'file'">
<div class="line"></div>
<div class="contextmenu__item" @click="handleMenu('Stats')">
<i class="icon el-icon-warning-outline icon_Stats" />
<span>{{ $t('trials:trials-workbench:auditDocument:menu:Stats') }}</span>
</div>
</template>
<template v-if="type === 'version' || type === 'c_version'">
<div class="line"></div>
<div class="contextmenu__item" @click="handleMenu('setVersion')" v-if="type === 'version'">
<i class="icon el-icon-document-checked icon_Stats" />
<span>{{ $t('trials:trials-workbench:auditDocument:menu:setVersion') }}</span>
</div>
<div class="contextmenu__item" @click="handleMenu('delVersion')">
<i class="icon el-icon-delete icon_Stats" />
<span>{{ $t('trials:trials-workbench:auditDocument:menu:delVersion') }}</span>
</div>
<div class="contextmenu__item" @click="handleMenu('delAllVersion')">
<i class="icon el-icon-delete-solid icon_Stats" />
<span>{{ $t('trials:trials-workbench:auditDocument:menu:delAllVersion') }}</span>
</div>
</template>
</div>
</template>
<script>
export default {
name: "index",
props: {
checkList: {
type: Array,
default: () => {
return []
}
},
},
data() {
return {
visible: false,
type: 'file',
zIndex: 9
};
},
methods: {
init(event, row, type, zIndex = 9) {
this.type = type
this.zIndex = zIndex
//
//
this.visible = true
let menu = document.querySelector("#contextmenu");
let chaY = document.body.clientHeight - event.clientY;
let chaX = document.body.clientWidth - event.clientX;
//
if (chaY < 150) {
menu.style.top = event.clientY - 220 + "px";
} else {
menu.style.top = event.clientY + "px";
}
if (chaX < 150) {
menu.style.left = event.clientX - 200 + "px";
} else {
menu.style.left = event.clientX + 15 + "px";
}
document.addEventListener("click", this.foo); // documentfoo
},
foo() {
this.visible = false
this.$emit("foo");
},
handleMenu(item) {
this.$emit("handleMenu", item);
},
},
};
</script>
<style lang="scss" scoped>
.contextmenu__item {
display: block;
cursor: pointer;
white-space: nowrap;
clear: both;
border-radius: 4px;
line-height: 30px;
height: 30px;
position: relative;
overflow: hidden;
text-overflow: ellipsis;
border: none;
color: #444;
transition: background-color .15s;
padding: 0px 15px 0 15px;
}
.contextmenu {
min-width: 180px;
max-width: 250px;
font-size: 14px;
display: inline-block;
background: #fff;
border-radius: 4px;
position: fixed;
padding: 10px 6px;
list-style-type: none;
max-height: 80vh;
overflow: hidden;
overflow-y: auto;
box-sizing: border-box;
background-image: url(@/assets/color-bg.png);
background-size: 100% auto;
background-position: top 0 right 0;
background-repeat: no-repeat;
box-shadow: 0 0 0 .5px #88888830, 0 10px 40px 0 #88888840;
}
.contextmenu__item:hover {
cursor: pointer;
background: #99999920;
color: #444;
}
.line {
border-bottom: 1px solid #66666630;
height: 2px;
line-height: 0;
margin: 2px 0 4px;
margin-left: 16px;
margin-right: -5px;
cursor: default;
padding: 0px 15px 0 15px;
color: #444;
display: block;
white-space: nowrap;
clear: both;
border-radius: 4px;
position: relative;
overflow: hidden;
text-overflow: ellipsis;
}
.icon {
font-style: normal;
vertical-align: middle;
text-align: center;
color: #aaa;
font-size: 17px;
margin-top: -2px;
width: 16px;
line-height: 16px;
display: inline-block;
height: 16px;
margin-right: 8px;
}
/*打开*/
.icon_open {
color: #1890ff;
}
/*下载*/
.icon_download {
display: inline-block;
background-image: url(@/assets/menu_icon.png);
background-position: -16px -48px;
background-size: auto !important;
background-repeat: no-repeat;
height: 16px;
margin-right: 8px;
}
/**剪切*/
.icon_shear {
background-size: cover !important;
background: url(data:image/svg+xml;base64,PHN2ZyB2aWV3Qm94PScwIDAgMTAyNCAxMDI0JyB2ZXJzaW9uPScxLjEnIHhtbG5zPSdodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Zycgd2lkdGg9JzIwMCcgaGVpZ2h0PScyMDAnPjxwYXRoIGQ9J001NjkuNyAzODguM0w3NDMuMiAxNDNjMTYtMjcuNyA2LjUtNjMtMjEuMi03OUw1MTIgMzE4LjMgMzAyIDY0Yy0yNy44IDE2LTM3LjMgNTEuMy0yMS4yIDc5bDE3My41IDI0NS4zTDI3MyA2MDcuOWw5NS45IDYwLjEgNjEuNS04Mi43TDUxMiA0NjkuOWw4MS42IDExNS40IDYxLjUgODIuNyA5NS45LTYwLjEtMTgxLjMtMjE5LjZ6JyBmaWxsPScjN0Y4MDgwJz48L3BhdGg+PHBhdGggZD0nTTI3MyA2MDZjLTk3LjYgMC0xNzcgNzkuNC0xNzcgMTc3czc5LjQgMTc3IDE3NyAxNzcgMTc3LTc5LjQgMTc3LTE3Ny03OS40LTE3Ny0xNzctMTc3eiBtMSAyOTBjLTYyLjMgMC0xMTMtNTAuNy0xMTMtMTEzczUwLjctMTEzIDExMy0xMTMgMTEzIDUwLjcgMTEzIDExMy01MC43IDExMy0xMTMgMTEzek03NTEgNjA2Yy05Ny42IDAtMTc3IDc5LjQtMTc3IDE3N3M3OS40IDE3NyAxNzcgMTc3IDE3Ny03OS40IDE3Ny0xNzctNzkuNC0xNzctMTc3LTE3N3ogbTAgMjkwYy02Mi4zIDAtMTEzLTUwLjctMTEzLTExM3M1MC43LTExMyAxMTMtMTEzIDExMyA1MC43IDExMyAxMTMtNTAuNyAxMTMtMTEzIDExM3onIGZpbGw9JyM0OTdDQUQnPjwvcGF0aD48L3N2Zz4=);
}
/**复制*/
.icon_copy {
background-size: cover !important;
background: url(data:image/svg+xml;base64,PHN2ZyB2aWV3Qm94PScwIDAgMTAyNCAxMDI0JyB2ZXJzaW9uPScxLjEnIHhtbG5zPSdodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Zyc+PHBhdGggZD0nTTcwNCAyNTZoNjguMDk2bDE0Ny4zOTIgMTU5LjA0YTMyIDMyIDAgMCAxIDguNTEyIDIxLjc2Vjg5NmEzMiAzMiAwIDAgMS0zMiAzMkgzNTJhMzIgMzIgMCAwIDEtMzItMzJ2LTEyOEgxMjhhMzIgMzIgMCAwIDEtMzItMzJWMTI4YTMyIDMyIDAgMCAxIDMyLTMyaDU0NGEzMiAzMiAwIDAgMSAzMiAzMnYxMjh6JyBmaWxsPScjRkZGRkZGJz48L3BhdGg+PHBhdGggZD0nTTI1NiA3MzZ2MzJIMTI4YTMyIDMyIDAgMCAxLTMyLTMyVjEyOGEzMiAzMiAwIDAgMSAzMi0zMmg1NDRhMzIgMzIgMCAwIDEgMzIgMzJ2NjRoLTMyVjEyOEgxMjh2NjA4aDEyOHonIGZpbGw9JyM1RDZEN0UnPjwvcGF0aD48cGF0aCBkPSdNNzY4IDI1Ny4xODRsMC4zMi0wLjMyIDE2MC41NDQgMTU3LjYtMS41MDQgMS41MzZIOTI4djQ4MGEzMiAzMiAwIDAgMS0zMiAzMkgzNTJhMzIgMzIgMCAwIDEtMzItMzJWMjg4YTMyIDMyIDAgMCAxIDMyLTMyaDQxNnYxLjE4NHogbTAgNDQuMjI0VjQxNmgxMTYuNzM2TDc2OCAzMDEuNDR6TTczNiAyODhIMzUydjYwOGg1NDRWNDQ4aC0xNjBWMjg4eicgZmlsbD0nIzUwODRiZSc+PC9wYXRoPjxwYXRoIGQ9J000NDggNDE2aDE5MnYzMmgtMTkydi0zMnogbTAgMTYwaDM1MnYzMkg0NDh2LTMyeiBtMCAxNjBoMzUydjMySDQ0OHYtMzJ6JyBmaWxsPScjQUNCNEMwJz48L3BhdGg+PC9zdmc+);
}
/*重命名*/
.icon_rename {
display: inline-block;
background-image: url(@/assets/menu_icon.png);
background-position: 0 -64px;
background-size: auto !important;
background-repeat: no-repeat;
height: 16px;
margin-right: 8px;
width: 16px;
}
/*删除*/
.icon_del {
color: #1890ff;
display: inline-block;
background-image: url(@/assets/menu_icon.png);
background-position: 0 -80px;
background-size: auto !important;
background-repeat: no-repeat;
height: 16px;
margin-right: 8px;
}
/*属性*/
.icon_Stats {
color: #1890ff;
}
</style>
@@ -0,0 +1,370 @@
<template>
<el-dialog title="" :visible.sync="visible" :close-on-click-modal="false" :close-on-press-escape="false"
:before-close="handleClose" width="450px" center>
<div class="auditDocumentDetail">
<div class="header">
<div class="file_icon">
<i class="name_docx"></i>
</div>
<div class="file_name">
<div class="name">
<span class="name-text">但是决定把尖酸刻薄的喀巴水电局咯不到就案板白沙卡萨丁你卢卡斯拿到了看到了上的尽快把世界第八款不打瞌睡的</span>
</div>
<div class="desc">
<span class="size">100kb</span>
<span>, </span>
<span class="time">2025-03-31 15:36</span>
</div>
</div>
</div>
<div class="main">
<el-tabs v-model="activeName" @tab-click="handleClick">
<el-tab-pane :label="$t('trials:trials-workbench:auditDocument:detail:tabs:Stats')" name="Stats">
<div class="p">
<div class="title">{{ $t('trials:trials-workbench:auditDocument:detail:title:path') }}</div>
<div class="content">{shareItem:8}/周会/20250324-工作总结及后续工作.pptx</div>
</div>
<div class="p">
<div class="title">{{ $t('trials:trials-workbench:auditDocument:detail:title:contain') }}
</div>
<div class="content">4 (2文件, 2文件夹)</div>
</div>
<div class="p">
<div class="title">{{ $t('trials:trials-workbench:auditDocument:detail:title:size') }}</div>
<div class="content">123333</div>
</div>
<div class="p">
<div class="title">{{ $t('trials:trials-workbench:auditDocument:detail:title:updateTime') }}
</div>
<div class="content">123333</div>
</div>
</el-tab-pane>
<el-tab-pane :label="$t('trials:trials-workbench:auditDocument:detail:tabs:versions')"
name="versions">
<div class="versions_top">
<div class="title">{{
$t('trials:trials-workbench:auditDocument:detail:title:historicalVersion') }}
</div>
<div class="btnBox">
<el-button icon="el-icon-refresh" circle size="small" />
<el-button icon="el-icon-upload2" plain size="small">{{
$t('trials:trials-workbench:auditDocument:detail:title:uploadNewVersion')
}}</el-button>
</div>
</div>
<div class="versions_content">
<div class="item">
<div class="item_line">
<div class="version current_version">
<span>{{
$t('trials:trials-workbench:auditDocument:detail:title:currentVersion')
}}</span>
</div>
<div class="mtime">2025-03-31 15:36</div>
<div class="size">375KB</div>
<div class="add_desc" @click.stop="openMenu($event, {}, 'c_version')">
<i class="el-icon-more" />
</div>
</div>
</div>
<div class="item">
<div class="item_line">
<div class="version">
<span>v1</span>
</div>
<div class="mtime">2025-03-31 15:36</div>
<div class="size">375KB</div>
<div class="add_desc" @click.stop="openMenu($event, {}, 'version')">
<i class="el-icon-more" />
</div>
</div>
</div>
</div>
</el-tab-pane>
</el-tabs>
</div>
</div>
</el-dialog>
</template>
<script>
export default {
name: "auditDocumentDetail",
props: {
visible: {
type: Boolean,
default: false
},
rowData: {
type: Object,
default: () => {
return {}
}
}
},
data() {
return {
activeName: 'Stats'
}
},
methods: {
handleClick() { },
openMenu(e, row, type) {
this.$emit('openContextmenu', { e, row, type, zIndex: 3000 })
},
handleClose() {
this.$emit("update:visible", false)
}
}
}
</script>
<style lang="scss" scoped>
::v-deep .el-dialog__header {
padding: 0;
}
::v-deep .el-dialog__body {
padding: 20px 0;
}
::v-deep .el-tabs__nav-wrap::after {
height: 1px;
}
.auditDocumentDetail {
.header {
padding: 0 20px;
display: flex;
align-items: center;
border-bottom: 1px solid #f6f8ff;
.file_icon {
width: 50px;
height: 50px;
i {
display: inline-block;
width: 100%;
height: 100%;
font-size: 42px;
line-height: 60px;
background-repeat: no-repeat;
background-position: center;
background-size: cover;
border-radius: 5px;
font-style: normal;
pointer-events: none;
}
.name_pdf {
background-image: url(@/assets/file_icon/pdf.png);
}
.name_docx {
background-image: url(@/assets/file_icon/docx.png);
}
.name_doc {
background-image: url(@/assets/file_icon/doc.png);
}
.name_zip {
background-image: url(@/assets/file_icon/zip.png);
}
.name_pptx {
background-image: url(@/assets/file_icon/pptx.png);
}
.name_ppt {
background-image: url(@/assets/file_icon/ppt.png);
}
.name_xlsx {
background-image: url(@/assets/file_icon/xlsx.png);
}
.name_xls {
background-image: url(@/assets/file_icon/xls.png);
}
.name_folder {
background-image: url(@/assets/file_icon/folder.png);
}
}
.file_name {
font-size: 14px;
color: #666;
word-break: break-word;
display: table-cell;
vertical-align: middle;
height: 60px;
line-height: 18px;
margin-top: 7px;
width: calc(100% - 170px);
.name {
max-height: 35px;
line-height: 18px;
overflow: hidden;
text-overflow: ellipsis;
.name-text {
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 2;
}
}
.desc {
font-size: 13px;
color: #aaa;
padding-top: 1px;
white-space: nowrap;
}
}
}
.main {
padding: 10px;
font-size: 14px;
max-height: 500px;
.p {
width: 100%;
display: flex;
.title {
color: #999;
text-align: left;
padding: 0;
margin: 0;
line-height: 25px;
width: 27%;
margin-right: 1%;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.content {
word-break: break-word;
color: #444;
width: 72%;
margin: 0;
padding: 5px 0 0 0;
position: relative;
}
}
.versions_top {
width: 100%;
display: flex;
align-items: center;
justify-content: space-between;
height: 40px;
border-bottom: 1px solid #f3f3f3;
margin-bottom: 10px;
.title {
width: 30%;
}
.btnBox {
flex: 1 0 0%;
text-align: right;
}
}
.versions_content {
max-height: calc(100% - 50px);
.item {
padding: 0;
border: 1px solid #eee;
margin-bottom: 4px;
border-radius: 4px;
position: relative;
overflow: hidden;
transition: all .2s;
cursor: pointer;
&:hover {
border-color: #91d5ff;
}
.item_line {
background: #fafafa;
padding: 5px 10px;
font-size: 12px;
overflow: hidden;
white-space: nowrap;
transition: all .2s;
&:hover {
background: #e6f7ff;
border-color: #e6f7ff;
}
.version {
display: inline-block;
margin-right: 5px;
width: auto;
span {
background: #22b66c;
border-color: #1c9458;
color: #fff;
padding: 3px 4px;
min-width: 25px;
}
}
.current_version {
span {
background: #1890ff;
border-color: #007cee;
color: #fff;
}
}
.mtime {
color: #999;
margin-right: 0;
line-height: 22px;
display: inline-block;
}
.size {
border-radius: 20px;
padding: 1px 1px 1px 5px;
font-size: 12px;
display: inline-block;
margin-right: 5px;
}
.add_desc {
position: absolute;
right: 5px;
top: 3px;
width: 25px;
height: 25px;
line-height: 25px;
color: #666;
background: #77777715;
border-radius: 2px;
text-align: center;
cursor: pointer;
&:hover {
background: #c3e2ff;
color: #1890ff;
}
}
}
}
}
}
}
</style>
@@ -0,0 +1,679 @@
<template>
<div class="auditDocument">
<el-row>
<el-col :span="12">
<h3>{{ isManage ? $t('trials:tab:updateAuditDocument') : $t('trials:tab:viewAuditDocument') }}</h3>
</el-col>
<el-col :span="12" style="text-align:right;">
<h3>
<Pagination class="page" :total="total" :page.sync="searchData.pageIndex"
:limit.sync="searchData.pageSize" layout="total, sizes, prev, pager, next" :background="false"
style="display: inline-block;" @pagination="getList" />
<el-button icon="el-icon-refresh-left" size="small" circle :title="$t('common:button:reset')"
@click="handleReset" />
</h3>
</el-col>
</el-row>
<el-form :inline="true" class="base-search-form">
<el-form-item>
<el-input v-model="searchData.Name" clearable></el-input>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search" @click="handleSearch">
{{ $t('common:button:search') }}
</el-button>
<el-button type="primary" icon="el-icon-refresh-left" @click="handleReset">
{{ $t('common:button:reset') }}
</el-button>
</el-form-item>
<el-form-item>
<el-button type="primary">
{{ $t('trials:trials-workbench:auditDocument:button:addFolder') }}
</el-button>
<el-button type="primary" @click.stop="openFile(false)">
{{ $t('trials:trials-workbench:auditDocument:button:uploadFile') }}
</el-button>
<el-button type="primary" @click.stop="openFile(true)">
{{ $t('trials:trials-workbench:auditDocument:button:uploadFolder') }}
</el-button>
<el-button type="primary">
{{ $t('trials:trials-workbench:auditDocument:button:download') }}
</el-button>
<el-button type="primary">
{{ $t('trials:trials-workbench:auditDocument:button:del') }}
</el-button>
</el-form-item>
</el-form>
<div class="catalogue">
<span>{{ $t('trials:trials-workbench:auditDocument:catalogue:title') }}</span>
<el-breadcrumb separator-class="el-icon-arrow-right">
<el-breadcrumb-item v-for="item of catalogueData" :key="item.Id"><span class="catalogue_name"
@click.stop="toCatalogue(item)">{{ item.Name }}</span></el-breadcrumb-item>
</el-breadcrumb>
</div>
<el-table :data="tableData" style="width: 99%" row-key="Id" :loading="loading" :row-style="setRowStyle"
v-adaptive="{ bottomOffset: 75 }" height="100" :border="true" :expand-row-keys="expandedRows"
:tree-props="{ children: 'Children', hasChildren: 'hasChildren' }" @expand-change="handleExpandChange"
@row-click="handleRowClick" @cell-mouse-enter="handleCellMouseEnter"
@cell-mouse-leave="handleCellMouseLeave" @row-contextmenu="handleRowContextmenu"
@row-dblclick="handleRowDblclick">
<el-table-column prop="date" :label="$t('trials:trials-workbench:auditDocument:table:name')" sortable
min-width="300" class-name="catalogue_box">
<template slot-scope="scope">
<div class="name_layout_box">
<div class="name_layout" v-if="renameId !== scope.row.Id">
<span class="name_box">
<i class="icon icon_folder" v-if="!scope.row.AuditDocumentTypeEnum" />
<i v-else :class="`icon icon_file icon_${scope.row.FileFormat}`" />
<span class="name">{{ scope.row.Name }}</span>
<i class="el-icon-edit icon_edit" v-if="hoverId === scope.row.Id"
@click="addRenameId(scope.row)"
:title="$t('trials:trials-workbench:auditDocument:icon:rename')" />
</span>
<i :class="{ 'el-icon-circle-check': true, 'icon_check': true, isCheck: checkList.includes(scope.row.Id) }"
@click.stop="addCheck(scope.row)"
v-if="hoverId === scope.row.Id || checkList.includes(scope.row.Id)" />
</div>
<el-input v-model="scope.row.Name" :ref="`renameInp_${scope.row.Id}`" :autofocus="true"
class="renameInp" @blur="rename(scope.row)" v-else />
</div>
</template>
</el-table-column>
<el-table-column prop="FileFormat" :label="$t('trials:trials-workbench:auditDocument:table:fileType')">
<template slot-scope="scope">
<span>{{ formatFileType(scope.row) }}</span>
</template>
</el-table-column>
<el-table-column prop="FileSize" :label="$t('trials:trials-workbench:auditDocument:table:fileSize')">
<template slot-scope="scope">
<span>{{ formatFileSize(scope.row) }}</span>
</template>
</el-table-column>
<el-table-column prop="UpdateTime" :label="$t('trials:trials-workbench:auditDocument:table:updateTime')">
</el-table-column>
<el-table-column prop="CreateTime" :label="$t('trials:trials-workbench:auditDocument:table:createTime')">
</el-table-column>
</el-table>
<contextmenu ref="contextmenu" :checkList="checkList" @handleMenu="handleMenu" />
<upload-files :config="config" :faccept="faccept" :uploadPath="uploadPath" :limitLength="limitLength"
v-if="config.visible" @close="close" @uplaodFile="uplaodFile" />
<detail v-if="visible" :visible.sync="visible" :rowData="rowData" @openContextmenu="openContextmenu" />
</div>
</template>
<script>
import { getAuditDocumentData, addAuditDocument, getBreadcrumbData, updateAuditDocument } from '@/api/trials'
import Pagination from '@/components/Pagination'
import contextmenu from './contextmenu.vue'
import uploadFiles from '@/views/trials/trials-panel/trial-summary/trial-document/components/uploadFiles.vue'
import detail from './detail.vue'
const searchDataDefault = () => {
return {
Name: null,
pageIndex: 1,
pageSize: 20,
asc: false,
sortField: ''
}
}
export default {
name: "auditDocument",
components: { Pagination, contextmenu, uploadFiles, detail },
props: {
isManage: {
type: Boolean,
default: false
}
},
data() {
return {
searchData: searchDataDefault(),
total: 0,
Id: null,
loading: false,
expandedRows: [],
tableData: [],
catalogueData: [], //
visible: false, //
rowData: {}, //
config: {
visible: false,
showClose: true,
width: '800px',
title: '',
appendToBody: false,
isFolder: false,
},
uploadPath: '/System/AuditDocument',
faccept: ['.pdf'],
limitLength: 0,
checkList: [], //
hoverId: null, // hover
renameId: null, //
copyList: [], //
shearList: [], //
type: null, //
ctrlKey: false, // ctrl
}
},
methods: {
//
async getBreadcrumbData() {
if (!this.Id) return false
try {
let data = {
Id: this.Id
}
let res = await getBreadcrumbData(data)
if (res.IsSuccess) {
this.catalogueData = res.Result
}
} catch (err) { console.log(err) }
},
async getList() {
try {
if (this.Id) {
this.searchData.Id = this.Id
}
this.loading = true
let res = await getAuditDocumentData(this.searchData)
this.loading = false
if (res.IsSuccess) {
this.tableData = res.Result.CurrentPageData
this.total = res.Result.TotalCount
}
} catch (err) {
this.loading = false
console.log(err)
}
},
handleSearch() {
this.getList()
},
handleReset() {
this.searchData = searchDataDefault()
this.getList()
},
addCheck(row) {
this.checkList.push(row.Id)
},
addRenameId(row) {
this.renameId = row.Id
this.$nextTick(() => {
if (this.$refs[`renameInp_${row.Id}`]) {
this.$refs[`renameInp_${row.Id}`].focus()
}
})
},
rename(row) {
this.renameId = null
this.updateData(row)
},
handleExpandChange(row, expanded) {
console.log(this.expandedRows)
if (expanded && !this.expandedRows.find(Id => Id === row.Id)) {
this.expandedRows.push(row.Id)
}
if (!expanded) {
let index = this.expandedRows.indexOf(row.Id)
if (!!~index) {
this.expandedRows.splice(index, 1)
}
}
},
//
toCatalogue(row) {
this.Id = row.Id
this.expandedRows = []
this.getList()
this.getBreadcrumbData()
},
//
async updateData(row) {
try {
let data = {
AuditDocumentTypeEnum: row.AuditDocumentTypeEnum,
FileFormat: row.FileFormat,
FilePath: row.FilePath,
FileSize: row.FileSize,
Id: row.Id,
IsAuthorization: row.IsAuthorization,
Name: row.Name,
ParentId: row.ParentId
}
let res = await updateAuditDocument(row);
} catch (err) {
this.getList()
console.log(err)
}
},
//
async uplaodFile(list) {
let data = this.formatData(list)
console.log(data, 'data')
try {
let res = await addAuditDocument(JSON.stringify(data))
if (res.IsSuccess) {
this.getList()
}
} catch (err) {
console.log(err)
}
},
//
formatData(arr) {
let list = [], strObj = {}
arr.forEach(item => {
if (item.catalogue) {
let catalogueStr = item.catalogue.split("/")
catalogueStr.pop()
let obj = {}, strKey = []
catalogueStr.forEach((str, index) => {
strKey.forEach((key, i) => {
if (i === 0) {
obj = strObj[key]
} else {
obj = obj[key]
}
})
if (index === 0) {
if (!strObj[str]) {
strObj[str] = {
children: []
}
}
} else {
if (!obj[str]) {
obj[str] = {
children: []
}
}
}
obj = obj[str]
strKey.push(str)
})
obj.children.push({
ParentId: null,
Name: item.FileName,
IsAuthorization: false,
FileSize: item.FileSize,
filePath: item.FilePath,
FileFormat: item.FileFormat,
AuditDocumentTypeEnum: 1
})
} else {
list.push({
ParentId: null,
Name: item.FileName,
IsAuthorization: false,
FileSize: item.FileSize,
filePath: item.FilePath,
FileFormat: item.FileFormat,
AuditDocumentTypeEnum: 1
})
}
})
let ARRAY = this.objToArr(strObj)
list = list.concat(ARRAY)
return list
},
objToArr(obj, list = []) {
Object.keys(obj).forEach(key => {
if (key !== 'children') {
let item = list.find(d => d.Name === key)
if (!item) {
let data = {
ParentId: null,
Name: key,
IsAuthorization: false,
AuditDocumentTypeEnum: 0,
children: obj[key].children
}
list.push(data)
}
this.objToArr(obj[key], obj[key].children)
}
})
return list;
},
//
formatFileType(row) {
if (!row.AuditDocumentTypeEnum) {
return this.$t('trials:trials-workbench:auditDocument:fileType:folder')
} else {
return `${row.FileFormat}${this.$t('trials:trials-workbench:auditDocument:fileType:file')}`
}
},
//
formatFileSize(row) {
if (!row.FileSize) return ''
if (row.FileSize < 1000) {
return row.FileSize + "B"
}
if (row.FileSize < 1000 * 1024) {
return (row.FileSize / 1024).toFixed(2) + "KB"
}
if (row.FileSize < 1000 * 1000 * 1024) {
return (row.FileSize / 1000 / 1024).toFixed(2) + "MB"
}
if (row.FileSize < 1000 * 1000 * 1000 * 1024) {
return (row.FileSize / 1000 / 1000 / 1024).toFixed(2) + "GB"
}
},
openFile(isFolder = false) {
this.faccept = [
'.jpg',
'.jpeg',
'.png',
'.pdf',
'.ppt',
'.pptx',
'.zip',
'.doc',
'.docx',
'.xls',
'.xlsx',
]
this.limitLength = 0
this.config.title = this.$t(
'trials:trials-workbench:auditDocument:form:title:uploadFile'
)
this.config.visible = true
this.config.isFolder = isFolder
},
close() {
this.config.visible = false
this.faccept = ['.pdf']
this.limitLength = 0
},
//
openContextmenu(data) {
let { e, row, type, zIndex } = data
this.$refs.contextmenu.init(e, row, type, zIndex)
},
//
handleRowContextmenu(row, column, e) {
e.preventDefault();
if (!this.checkList.includes(row.Id)) this.handleRowClick(row)
this.$refs.contextmenu.init(e, row, 'file')
},
//
handleRowDblclick(row) {
if (!row.AuditDocumentTypeEnum) {
this.Id = row.Id
this.getList()
this.getBreadcrumbData()
}
},
//
handleRowClick(row) {
if (this.ctrlKey) {
this.checkList.push(row.Id)
} else {
this.checkList = [row.Id]
}
},
// hover
handleCellMouseEnter(row) {
this.hoverId = row.Id
},
// hover
handleCellMouseLeave() { this.hoverId = null },
//
handleMenu(key) {
this.type = key;
if (key === 'rename') {
this.renameId = this.checkList[0]
}
if (key === 'Stats') {
this.rowData = this.tableData.find(item => item.Id === this.checkList[0])
this.visible = true
}
},
setRowStyle({ row, rowIndex }) {
if (this.checkList.includes(row.Id)) {
return {
backgroundColor: '#cce8ff', //
}
}
},
//
copy() { },
//
shear() { },
//
stickup() { },
//
keydown(e) {
this.ctrlKey = e.ctrlKey
if (e.key === 'Control') {
e.preventDefault();
}
if (e.ctrlKey && e.key === 'c') {
e.preventDefault();
this.type = 'copy'
this.copy()
}
if (e.ctrlKey && e.key === 'v') {
e.preventDefault();
this.type = 'stickup'
this.stickup()
}
if (e.ctrlKey && e.key === 'x') {
e.preventDefault();
this.type = 'shear'
this.shear()
}
},
//
keyup(e) {
this.ctrlKey = e.ctrlKey
}
},
mounted() {
document.addEventListener('keydown', this.keydown);
document.addEventListener('keyup', this.keyup);
this.getList()
this.getBreadcrumbData()
},
destroyed() {
document.removeEventListener('keydown', this.keydown);
document.removeEventListener('keyup', this.keyup);
}
}
</script>
<style lang="scss" scoped>
.auditDocument {
// position: relative;
::v-deep .catalogue_box.el-table__cell {
.cell {
display: flex;
align-items: center;
}
}
}
.renameInp {
::v-deep .el-input__inner {
line-height: 23px;
height: 23px;
}
}
.name_layout_box {
display: inline-block;
flex: 1 1 0%;
min-width: 0;
}
.catalogue {
display: flex;
align-items: center;
margin: 0 0 22px;
span {
font-size: 16px;
}
.catalogue_name {
cursor: pointer;
font-size: 16px;
&:hover {
color: #3b8cff;
}
}
}
.name_layout {
width: 100%;
display: flex;
align-items: center;
justify-content: space-between;
.name_box {
display: flex;
align-items: center;
width: calc(100% - 20px);
.name {
max-width: calc(100% - 60px);
white-space: nowrap;
/* 文本不换行 */
overflow: hidden;
/* 超出部分隐藏 */
text-overflow: ellipsis;
}
}
}
.icon_edit {
cursor: pointer;
color: rgba(0, 0, 0, 0.3);
margin-left: 2px;
&:hover {
color: rgba(0, 0, 0, 0.5);
}
}
.icon_check {
font-size: 18px;
cursor: pointer;
color: rgba(0, 0, 0, 0.3);
&:hover {
color: rgba(0, 0, 0, 0.5);
}
}
.isCheck {
color: #3b8cff;
}
::v-deep .el-table--enable-row-hover .el-table__body tr:hover>td.el-table__cell {
background-color: #e5f3ff
}
.icon {
height: 20px;
width: 20px;
padding: 0px;
line-height: 20px;
// min-width: 20px;
margin-right: 6px;
margin-top: 6px;
}
/*文件*/
.icon_file {
width: 16px !important;
height: 16px !important;
margin-right: 6px;
background-size: inherit;
background-image: url(@/assets/0.file-16.png);
background-position: 0 0;
margin-top: -2px;
background-repeat: no-repeat;
font-style: normal;
display: inline-block;
pointer-events: none;
font-size: 85%;
}
/*文件夹*/
.icon_folder {
background-image: url(@/assets/folder_win11_small.png);
margin-top: -6px;
margin-left: 2px;
margin-right: 6px;
background-repeat: no-repeat;
}
/*docx*/
.icon_docx {
background-position: -81px -560px !important;
margin-top: 0;
margin-left: 2px;
}
/*doc*/
.icon_doc {
background-position: -81px -592px !important;
margin-top: 0;
margin-left: 2px;
}
/*xlsx*/
.icon_xlsx {
background-position: -81px -48px !important;
margin-top: 0;
margin-left: 2px;
}
/*pdf*/
.icon_pdf {
background-position: -81px -352px !important;
margin-top: 0;
margin-left: 2px;
}
/*pptx*/
.icon_pptx {
background-position: -81px -288px !important;
margin-top: 0;
margin-left: 2px;
}
/*zip*/
.icon_zip {
background-position: 0 0 !important;
margin-top: -2px;
margin-left: 2px;
}
/*ppt*/
.icon_ppt {
background-position: -81px -304px !important;
margin-top: 0;
margin-left: 2px;
}
/*xls*/
.icon_xls {
background-position: -81px -96px !important;
margin-top: 0;
margin-left: 2px;
}
</style>
@@ -238,7 +238,7 @@
:reading-id="selected.ReadingId"
:clinical-form-id="selected.ClinicalFormId"
:open-type="'look'"
@close=""
@close="false"
/>
</div>
</div>
@@ -0,0 +1,3 @@
<template>
<div>viewGeneralTraining</div>
</template>
+398 -237
View File
@@ -1,5 +1,5 @@
<style>
.user-status-item{
.user-status-item {
width: 100px;
height: 32px;
line-height: 1;
@@ -14,7 +14,8 @@
cursor: pointer;
padding: 0 8px;
}
.my_select_box{
.my_select_box {
margin-bottom: 12px;
margin-top: 12px;
padding: 0 12px 0 20px;
@@ -24,31 +25,37 @@
align-items: center;
border-radius: 5px;
}
.my_select_box_content{
.my_select_box_content {
color: #333;
font-size: .875rem;
white-space:nowrap;
white-space: nowrap;
display: flex;
align-items: center;
}
.my_select_box_content_text{
.my_select_box_content_text {
display: inline-block;
white-space:nowrap;
overflow:hidden;
text-overflow:ellipsis;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
max-width: 150px;
}
.my_select_box:hover{
.my_select_box:hover {
background: #f5f5f5;
}
.my_select_box.selected {
color:#6698ff;
color: #6698ff;
background: rgba(102, 152, 255, .1);
}
.my_select_box.selected .my_select_box_content {
color:#6698ff;
color: #6698ff;
}
.my_select_title{
.my_select_title {
height: 48px;
padding: 0 8px;
display: flex;
@@ -56,173 +63,228 @@
align-items: center;
color: #999;
}
.my_select .my_select_box {
margin-top: 0!important;
margin-top: 0 !important;
}
</style>
<template>
<div class="workbench-container">
<!-- <div class="workbench-stats">-->
<!-- <PanelCount ref="panelCount" @getSignSystemDocCount="getSignSystemDocCount" />-->
<!-- </div>-->
<div class="workbench-content" style="height: 100%;display: flex">
<div class="workbench-content-left" style="width: 259px;border-right: 1px solid #eee;background: #fbfbfb">
<div style="padding: 12px">
<div class="user-profile-wrapper" style="padding: 24px 0 24px 12px;">
<div style="display: flex;align-items: center;margin-bottom: 20px;" class="user-info">
<div style="margin-right: 0.75rem;background: #428bca;width: 44px;height: 44px;border-radius: 50%;line-height: 44px;text-align: center;font-size: 12px;color:#fff;overflow: hidden">
{{ user.LastName }}
</div>
<div class="user-description" style="">
<div style="font-size: .875rem;color: #333;line-height: 22px;display: flex;margin-bottom: 0.25rem;"><span style="overflow: hidden;text-overflow: ellipsis;white-space: nowrap;max-width: 150px">{{user.RealName}}</span></div>
<div style="font-size: .75rem;line-height: 18px;color:#999">{{new Date().getFullYear()}}{{$t('common:date:today')}}{{new Date().getMonth() + 1}}{{$t('common:date:month')}}{{new Date().getDate()}}{{$t('common:date:day')}}{{ dayOfWeek }}</div>
</div>
<!-- <div class="workbench-stats">-->
<!-- <PanelCount ref="panelCount" @getSignSystemDocCount="getSignSystemDocCount" />-->
<!-- </div>-->
<div class="workbench-content" style="height: 100%;display: flex">
<div class="workbench-content-left"
style="height:100%;width: 259px;border-right: 1px solid #eee;background: #fbfbfb">
<div style="padding: 12px;height:100%;">
<div class="user-profile-wrapper" style="padding: 24px 0 24px 12px;">
<div style="display: flex;align-items: center;margin-bottom: 20px;" class="user-info">
<div
style="margin-right: 0.75rem;background: #428bca;width: 44px;height: 44px;border-radius: 50%;line-height: 44px;text-align: center;font-size: 12px;color:#fff;overflow: hidden">
{{ user.LastName }}
</div>
<div class="user-status" style="display: flex">
<div class="user-status-item" @click="$router.push('/trials/trials-myinfo')" style="margin-right: 0.75rem">
<span class="el-icon-setting" style="margin-right: 0.5rem"></span>
<span>{{$t('trials:trials-myinfo:title:accountInfo')}}</span>
<div class="user-description" style="">
<div style="font-size: .875rem;color: #333;line-height: 22px;display: flex;margin-bottom: 0.25rem;">
<span style="overflow: hidden;text-overflow: ellipsis;white-space: nowrap;max-width: 150px">{{
user.RealName }}</span>
</div>
<div class="user-status-item" @click="$router.push('/trials/trials-notice')">
<span class="el-icon-bell" style="margin-right: 0.5rem"></span>
<span style="margin-right: 0.5rem"></span>
<span>{{ tabList.SysNoticeUnReadCount }}</span>
<div style="font-size: .75rem;line-height: 18px;color:#999">{{ new
Date().getFullYear() }}{{ $t('common:date:today') }}{{ new Date().getMonth() +
1 }}{{ $t('common:date:month') }}{{ new Date().getDate() }}{{ $t('common:date:day') }}{{ dayOfWeek }}
</div>
</div>
</div>
<!-- <div class="thy-divider" style="border-top: 1px solid #eee;margin: 0;"></div>-->
<!-- <div class="my_select_box" @click="$router.push('/trials/trials-list')">-->
<!-- <div class="my_select_box_content">-->
<!-- <span class="el-icon-box" style="padding: 4px;margin: 4px;color: #6698ff"></span>-->
<!-- <span>{{ $t('trials:tab:trials') }}</span>-->
<!-- </div>-->
<!-- </div>-->
<div class="user-status" style="display: flex">
<div class="user-status-item" @click="$router.push('/trials/trials-myinfo')"
style="margin-right: 0.75rem">
<span class="el-icon-setting" style="margin-right: 0.5rem"></span>
<span>{{ $t('trials:trials-myinfo:title:accountInfo') }}</span>
</div>
<div class="user-status-item" @click="$router.push('/trials/trials-notice')">
<span class="el-icon-bell" style="margin-right: 0.5rem"></span>
<span style="margin-right: 0.5rem"></span>
<span>{{ tabList.SysNoticeUnReadCount }}</span>
</div>
</div>
</div>
<!-- <div class="thy-divider" style="border-top: 1px solid #eee;margin: 0;"></div>-->
<!-- <div class="my_select_box" @click="$router.push('/trials/trials-list')">-->
<!-- <div class="my_select_box_content">-->
<!-- <span class="el-icon-box" style="padding: 4px;margin: 4px;color: #6698ff"></span>-->
<!-- <span>{{ $t('trials:tab:trials') }}</span>-->
<!-- </div>-->
<!-- </div>-->
<div class="menuBox">
<div class="thy-divider" style="border-top: 1px solid #eee;margin: 0;"></div>
<div class="my_select_title" style="font-size: 18px">{{ $t('trials:workbench:title:padding') }}</div>
<div class="my_select">
<!-- PM/APM -->
<!-- 阅片期 -->
<div class="my_select_box" :class="{selected: selected === 'consistencyCheck'}" tab-data="consistencyCheck" @click="selected = 'consistencyCheck'" v-if="hasPermi(['trials:trials-workbench:consistencyCheck'])">
<div class="my_select_box" :class="{ selected: selected === 'consistencyCheck' }"
tab-data="consistencyCheck" @click="selected = 'consistencyCheck'"
v-if="hasPermi(['trials:trials-workbench:consistencyCheck'])">
<div class="my_select_box_content">
<span class="el-icon-folder-checked" style="padding: 4px;margin: 4px;color: #6698ff"></span>
<span class="my_select_box_content_text">{{ $t('trials:tab:consistencyCheck') }}</span><span style="margin:0 0.25rem">·</span><span>{{tabList.PM_CheckCount}}</span>
<span class="my_select_box_content_text">{{ $t('trials:tab:consistencyCheck') }}</span><span
style="margin:0 0.25rem">·</span><span>{{ tabList.PM_CheckCount }}</span>
</div>
</div>
<!-- 重阅审批 -->
<div class="my_select_box" :class="{selected: selected === 'RereadApproval'}" tab-data="RereadApproval" @click="selected = 'RereadApproval'" v-if="hasPermi(['trials:trials-workbench:rereadApproval'])">
<div class="my_select_box" :class="{ selected: selected === 'RereadApproval' }" tab-data="RereadApproval"
@click="selected = 'RereadApproval'" v-if="hasPermi(['trials:trials-workbench:rereadApproval'])">
<div class="my_select_box_content">
<span class="el-icon-document-checked" style="padding: 4px;margin: 4px;color: #6698ff"></span>
<span class="my_select_box_content_text">{{ $t('trials:trials-panel:attachments:reReadingTracking') }}</span><span style="margin:0 0.25rem">·</span><span>{{ tabList.PM_ReReadingApprovalCount }}</span>
<span class="my_select_box_content_text">{{ $t('trials:trials-panel:attachments:reReadingTracking')
}}</span><span style="margin:0 0.25rem">·</span><span>{{ tabList.PM_ReReadingApprovalCount }}</span>
</div>
</div>
<!-- 阅片人筛选 -->
<div class="my_select_box" :class="{selected: selected === 'ReviewerScreen'}" tab-data="ReviewerScreen" @click="selected = 'ReviewerScreen'" v-if="hasPermi(['trials:trials-workbench:reviewerScreen'])">
<div class="my_select_box" :class="{ selected: selected === 'ReviewerScreen' }" tab-data="ReviewerScreen"
@click="selected = 'ReviewerScreen'" v-if="hasPermi(['trials:trials-workbench:reviewerScreen'])">
<div class="my_select_box_content">
<span class="el-icon-user" style="padding: 4px;margin: 4px;color: #6698ff"></span>
<span class="my_select_box_content_text">{{ $t('trials:trials-list:PendingDetails:ReviewerSelection') }}</span><span style="margin:0 0.25rem">·</span><span>{{ tabList.PM_ReviewerSelectCount }}</span>
<span class="my_select_box_content_text">{{ $t('trials:trials-list:PendingDetails:ReviewerSelection')
}}</span><span style="margin:0 0.25rem">·</span><span>{{ tabList.PM_ReviewerSelectCount }}</span>
</div>
</div>
<!-- 中心调研 -->
<div class="my_select_box" :class="{selected: selected === 'SiteResearch'}" tab-data="SiteResearch" @click="selected = 'SiteResearch'" v-if="hasPermi(['trials:trials-workbench:attachments:site-research'])&&!hasPermi(['role:admin'])">
<div class="my_select_box" :class="{ selected: selected === 'SiteResearch' }" tab-data="SiteResearch"
@click="selected = 'SiteResearch'"
v-if="hasPermi(['trials:trials-workbench:attachments:site-research']) && !hasPermi(['role:admin'])">
<div class="my_select_box_content">
<span class="el-icon-edit-outline" style="padding: 4px;margin: 4px;color: #6698ff"></span>
<span class="my_select_box_content_text">{{ $t('trials:workbench:title:pendingSiteResearch') }}</span><span style="margin:0 0.25rem">·</span><span>{{hasPermi(['role:pm','role:apm'])? tabList.PM_SiteSurveryCount : tabList.SPM_SiteSurveryCount }}</span>
<span class="my_select_box_content_text">{{ $t('trials:workbench:title:pendingSiteResearch')
}}</span><span style="margin:0 0.25rem">·</span><span>{{ hasPermi(['role:pm', 'role:apm']) ?
tabList.PM_SiteSurveryCount : tabList.SPM_SiteSurveryCount }}</span>
</div>
</div>
<!-- SPM/CPM -->
<!-- 阅片人审批 -->
<div class="my_select_box" :class="{selected: selected === 'ReviewerApproval'}" tab-data="ReviewerApproval" @click="selected = 'ReviewerApproval'" v-if="hasPermi(['trials:trials-workbench:reviewerApproval'])">
<div class="my_select_box" :class="{ selected: selected === 'ReviewerApproval' }"
tab-data="ReviewerApproval" @click="selected = 'ReviewerApproval'"
v-if="hasPermi(['trials:trials-workbench:reviewerApproval'])">
<div class="my_select_box_content">
<span class="el-icon-user" style="padding: 4px;margin: 4px;color: #6698ff"></span>
<span class="my_select_box_content_text">{{ $t('trials:sysDocBeSigned:table:reviewerApproval') }}</span><span style="margin:0 0.25rem">·</span><span>{{ tabList.SPM_ReviewerApprovalCount }}</span>
<span class="my_select_box_content_text">{{ $t('trials:sysDocBeSigned:table:reviewerApproval')
}}</span><span style="margin:0 0.25rem">·</span><span>{{ tabList.SPM_ReviewerApprovalCount }}</span>
</div>
</div>
<!-- 重阅审批 -->
<div class="my_select_box" :class="{selected: selected === 'SpmRereadApproval'}" tab-data="SpmRereadApproval" @click="selected = 'SpmRereadApproval'" v-if="hasPermi(['trials:trials-workbench:spmRereadApproval'])">
<div class="my_select_box" :class="{ selected: selected === 'SpmRereadApproval' }"
tab-data="SpmRereadApproval" @click="selected = 'SpmRereadApproval'"
v-if="hasPermi(['trials:trials-workbench:spmRereadApproval'])">
<div class="my_select_box_content">
<span class="el-icon-document-checked" style="padding: 4px;margin: 4px;color: #6698ff"></span>
<span class="my_select_box_content_text">{{ $t('trials:trials-panel:attachments:reReadingTracking') }}</span><span style="margin:0 0.25rem">·</span><span>{{ tabList.SPM_ReReadingApprovalCount }}</span>
<span class="my_select_box_content_text">{{ $t('trials:trials-panel:attachments:reReadingTracking')
}}</span><span style="margin:0 0.25rem">·</span><span>{{ tabList.SPM_ReReadingApprovalCount
}}</span>
</div>
</div>
<!-- CRC -->
<!-- 加急影像提交 -->
<div class="my_select_box" :class="{selected: selected === 'ImageSubmission'}" tab-data="ImageSubmission" @click="selected = 'ImageSubmission'" v-if="hasPermi(['trials:trials-workbenck:imageSubmission'])">
<div class="my_select_box" :class="{ selected: selected === 'ImageSubmission' }"
tab-data="ImageSubmission" @click="selected = 'ImageSubmission'"
v-if="hasPermi(['trials:trials-workbenck:imageSubmission'])">
<div class="my_select_box_content">
<span class="el-icon-circle-check" style="padding: 4px;margin: 4px;color: #6698ff"></span>
<span class="my_select_box_content_text">{{ $t('trials:workbench:title:ExpeditedImageSubmission') }}</span><span style="margin:0 0.25rem">·</span><span>{{ tabList.CRC_ImageSubmitCount }}</span>
<span class="my_select_box_content_text">{{ $t('trials:workbench:title:ExpeditedImageSubmission')
}}</span><span style="margin:0 0.25rem">·</span><span>{{ tabList.CRC_ImageSubmitCount }}</span>
</div>
</div>
<!-- 影像质疑 -->
<div class="my_select_box" :class="{selected: selected === 'ImageQuestion'}" tab-data="ImageQuestion" @click="selected = 'ImageQuestion'" v-if="hasPermi(['trials:trials-workbench:imageQuestion'])">
<div class="my_select_box" :class="{ selected: selected === 'ImageQuestion' }" tab-data="ImageQuestion"
@click="selected = 'ImageQuestion'" v-if="hasPermi(['trials:trials-workbench:imageQuestion'])">
<div class="my_select_box_content">
<span class="el-icon-chat-dot-square" style="padding: 4px;margin: 4px;color: #6698ff"></span>
<span class="my_select_box_content_text">{{ $t('trials:tab:crcQuality') }}</span><span style="margin:0 0.25rem">·</span><span>{{ tabList.CRC_ImageQuestionCount }}</span>
<span class="my_select_box_content_text">{{ $t('trials:tab:crcQuality') }}</span><span
style="margin:0 0.25rem">·</span><span>{{ tabList.CRC_ImageQuestionCount }}</span>
</div>
</div>
<!-- 核查质疑 -->
<div class="my_select_box" :class="{selected: selected === 'ImageVerification'}" tab-data="ImageVerification" @click="selected = 'ImageVerification'" v-if="hasPermi(['trials:trials-workbenck:imageVerification'])">
<div class="my_select_box" :class="{ selected: selected === 'ImageVerification' }"
tab-data="ImageVerification" @click="selected = 'ImageVerification'"
v-if="hasPermi(['trials:trials-workbenck:imageVerification'])">
<div class="my_select_box_content">
<span class="el-icon-money" style="padding: 4px;margin: 4px;color: #6698ff"></span>
<span class="my_select_box_content_text">{{ $t('trials:sysDocBeSigned:table:ImageCheck') }}</span><span style="margin:0 0.25rem">·</span><span>{{ tabList.CRC_CheckQuestionCount }}</span>
<span class="my_select_box_content_text">{{ $t('trials:sysDocBeSigned:table:ImageCheck')
}}</span><span style="margin:0 0.25rem">·</span><span>{{ tabList.CRC_CheckQuestionCount }}</span>
</div>
</div>
<!-- 影像重传 -->
<div class="my_select_box" :class="{selected: selected === 'ImageReupload'}" tab-data="ImageReupload" @click="selected = 'ImageReupload'" v-if="hasPermi(['trials:trials-workbenck:imageReupload'])">
<div class="my_select_box" :class="{ selected: selected === 'ImageReupload' }" tab-data="ImageReupload"
@click="selected = 'ImageReupload'" v-if="hasPermi(['trials:trials-workbenck:imageReupload'])">
<div class="my_select_box_content">
<span class="el-icon-upload" style="padding: 4px;margin: 4px;color: #6698ff"></span>
<span class="my_select_box_content_text">{{ $t('trials:workbench:title:ImageRetransmission') }}</span><span style="margin:0 0.25rem">·</span><span>{{ tabList.CRC_ImageReUploadCount }}</span>
<span class="my_select_box_content_text">{{ $t('trials:workbench:title:ImageRetransmission')
}}</span><span style="margin:0 0.25rem">·</span><span>{{ tabList.CRC_ImageReUploadCount }}</span>
</div>
</div>
<!-- IQC -->
<!-- 影像质控 -->
<div class="my_select_box" :class="{selected: selected === 'ImageQualityControl'}" tab-data="ImageQualityControl" @click="selected = 'ImageQualityControl'" v-if="hasPermi(['trials:trials-workbenck:imageQC'])">
<div class="my_select_box" :class="{ selected: selected === 'ImageQualityControl' }"
tab-data="ImageQualityControl" @click="selected = 'ImageQualityControl'"
v-if="hasPermi(['trials:trials-workbenck:imageQC'])">
<div class="my_select_box_content">
<span class="el-icon-document-checked" style="padding: 4px;margin: 4px;color: #6698ff"></span>
<span class="my_select_box_content_text">{{ $t('trials:tab:dicomsQuality') }}<span style="margin:0 0.25rem"></span>·</span><span>{{ tabList.IQC_IamgeQCCount }}</span>
<span class="my_select_box_content_text">{{ $t('trials:tab:dicomsQuality') }}<span
style="margin:0 0.25rem"></span>·</span><span>{{ tabList.IQC_IamgeQCCount }}</span>
</div>
</div>
<!-- QC质疑 -->
<div class="my_select_box" :class="{selected: selected === 'QcQuestion'}" tab-data="QcQuestion" @click="selected = 'QcQuestion'" v-if="hasPermi(['trials:trials-workbenck:qcQuestion'])">
<div class="my_select_box" :class="{ selected: selected === 'QcQuestion' }" tab-data="QcQuestion"
@click="selected = 'QcQuestion'" v-if="hasPermi(['trials:trials-workbenck:qcQuestion'])">
<div class="my_select_box_content">
<span class="el-icon-chat-dot-square" style="padding: 4px;margin: 4px;color: #6698ff"></span>
<span class="my_select_box_content_text">{{ $t('trials:tab:qcQuality') }}</span><span style="margin:0 0.25rem">·</span><span>{{ tabList.IQC_QCQuestionCount }}</span>
<span class="my_select_box_content_text">{{ $t('trials:tab:qcQuality') }}</span><span
style="margin:0 0.25rem">·</span><span>{{ tabList.IQC_QCQuestionCount }}</span>
</div>
</div>
<!-- IR -->
<!-- 影像待阅 -->
<div class="my_select_box" :class="{selected: selected === 'ImagesToRead'}" tab-data="ImagesToRead" @click="selected = 'ImagesToRead'" v-if="hasPermi(['trials:trials-workbenck:imagesToRead'])">
<div class="my_select_box" :class="{ selected: selected === 'ImagesToRead' }" tab-data="ImagesToRead"
@click="selected = 'ImagesToRead'" v-if="hasPermi(['trials:trials-workbenck:imagesToRead'])">
<div class="my_select_box_content">
<span class="el-icon-collection" style="padding: 4px;margin: 4px;color: #6698ff"></span>
<span class="my_select_box_content_text">{{ $t('trials:tab:pendingReadingTasks') }}</span><span style="margin:0 0.25rem">·</span><span>{{ tabList.IR_IamgeWaitReadingCount }}</span>
<span class="my_select_box_content_text">{{ $t('trials:tab:pendingReadingTasks') }}</span><span
style="margin:0 0.25rem">·</span><span>{{ tabList.IR_IamgeWaitReadingCount }}</span>
</div>
</div>
<!-- 医学反馈 -->
<div class="my_select_box" :class="{selected: selected === 'MedicalFeedback'}" tab-data="MedicalFeedback" @click="selected = 'MedicalFeedback'" v-if="hasPermi(['trials:trials-workbenck:medicalFeedback'])">
<div class="my_select_box" :class="{ selected: selected === 'MedicalFeedback' }"
tab-data="MedicalFeedback" @click="selected = 'MedicalFeedback'"
v-if="hasPermi(['trials:trials-workbenck:medicalFeedback'])">
<div class="my_select_box_content">
<span class="el-icon-document-checked" style="padding: 4px;margin: 4px;color: #6698ff"></span>
<span class="my_select_box_content_text">{{ $t('trials:trials-panel:tab:medicalFeedback') }}</span><span style="margin:0 0.25rem">·</span><span>{{ tabList.IR_MedicalReviewCount }}</span>
<span class="my_select_box_content_text">{{ $t('trials:trials-panel:tab:medicalFeedback')
}}</span><span style="margin:0 0.25rem">·</span><span>{{ tabList.IR_MedicalReviewCount }}</span>
</div>
</div>
<!-- MIM -->
<!-- 医学审核 -->
<div class="my_select_box" :class="{selected: selected === 'MedicalAudit'}" tab-data="MedicalAudit" @click="selected = 'MedicalAudit'" v-if="hasPermi(['trials:trials-workbenck:medicalAudit'])">
<div class="my_select_box" :class="{ selected: selected === 'MedicalAudit' }" tab-data="MedicalAudit"
@click="selected = 'MedicalAudit'" v-if="hasPermi(['trials:trials-workbenck:medicalAudit'])">
<div class="my_select_box_content">
<span class="el-icon-document-checked" style="padding: 4px;margin: 4px;color: #6698ff"></span>
<span class="my_select_box_content_text">{{ $t('trials:trials-panel:tab:pmMedicalFeedback') }}</span><span style="margin:0 0.25rem">·</span><span>{{ tabList.MIM_MedicalReviewCount }}</span>
<span class="my_select_box_content_text">{{ $t('trials:trials-panel:tab:pmMedicalFeedback')
}}</span><span style="margin:0 0.25rem">·</span><span>{{ tabList.MIM_MedicalReviewCount }}</span>
</div>
</div>
<!-- 项目签署文件 -->
<div class="my_select_box" :class="{selected: selected === 'NeedSignTrialDoc'}" tab-data="NeedSignTrialDoc" @click="selected = 'NeedSignTrialDoc'" v-if="!hasPermi(['role:zys'])">
<div class="my_select_box" :class="{ selected: selected === 'NeedSignTrialDoc' }"
tab-data="NeedSignTrialDoc" @click="selected = 'NeedSignTrialDoc'" v-if="!hasPermi(['role:zys'])">
<div class="my_select_box_content">
<span class="el-icon-receiving" style="padding: 4px;margin: 4px;color: #6698ff"></span>
<span class="my_select_box_content_text">{{ $t('trials:workbench:title:trialDocBeSigned') }}</span><span style="margin:0 0.25rem">·</span><span>{{ tabList.TrialWaitSignDocCount }}</span>
<span class="my_select_box_content_text">{{ $t('trials:workbench:title:trialDocBeSigned')
}}</span><span style="margin:0 0.25rem">·</span><span>{{ tabList.TrialWaitSignDocCount }}</span>
</div>
</div>
<!-- 系统签署文件 -->
<div class="my_select_box" :class="{selected: selected === 'NeedSignSysDoc'}" tab-data="NeedSignSysDoc" @click="$nextTick(() => selected = 'NeedSignSysDoc')" v-if="!hasPermi(['role:zys'])">
<div class="my_select_box" :class="{ selected: selected === 'NeedSignSysDoc' }" tab-data="NeedSignSysDoc"
@click="$nextTick(() => selected = 'NeedSignSysDoc')" v-if="!hasPermi(['role:zys'])">
<div class="my_select_box_content">
<span class="el-icon-data-line" style="padding: 4px;margin: 4px;color: #6698ff"></span>
<span class="my_select_box_content_text">{{ $t('trials:workbench:title:sysDocBeSigned') }}</span><span style="margin:0 0.25rem">·</span><span>{{ tabList.SysWaitSignDocCount }}</span>
<span class="my_select_box_content_text">{{ $t('trials:workbench:title:sysDocBeSigned') }}</span><span
style="margin:0 0.25rem">·</span><span>{{ tabList.SysWaitSignDocCount }}</span>
</div>
</div>
</div>
@@ -230,168 +292,244 @@
<div class="my_select_title" style="font-size: 18px">{{ $t('trials:workbench:title:my') }}</div>
<div class="my_select">
<!-- 项目已签署文件 -->
<div class="my_select_box" :class="{selected: selected === 'NeedSignedTrialDoc'}" tab-data="NeedSignedTrialDoc" @click="selected = 'NeedSignedTrialDoc'" v-if="!hasPermi(['role:zys'])">
<div class="my_select_box" :class="{ selected: selected === 'NeedSignedTrialDoc' }"
tab-data="NeedSignedTrialDoc" @click="selected = 'NeedSignedTrialDoc'" v-if="!hasPermi(['role:zys'])">
<div class="my_select_box_content">
<span class="el-icon-receiving" style="padding: 4px;margin: 4px;color: #6698ff"></span>
<span class="my_select_box_content_text" :title="$t('trials:workbench:title:trialDocSigned')">{{ $t('trials:workbench:title:trialDocSigned') }}</span><span style="margin:0 0.25rem">·</span><span>{{ tabList.TrialSignedDocCount }}</span>
<span class="my_select_box_content_text" :title="$t('trials:workbench:title:trialDocSigned')">{{
$t('trials:workbench:title:trialDocSigned') }}</span><span style="margin:0 0.25rem">·</span><span>{{
tabList.TrialSignedDocCount }}</span>
</div>
</div>
<!-- 系统已签署文件 -->
<div class="my_select_box" :class="{selected: selected === 'NeedSignedSysDoc'}" tab-data="NeedSignedSysDoc" @click="$nextTick(() => selected = 'NeedSignedSysDoc')" v-if="!hasPermi(['role:zys'])">
<div class="my_select_box" :class="{ selected: selected === 'NeedSignedSysDoc' }"
tab-data="NeedSignedSysDoc" @click="$nextTick(() => selected = 'NeedSignedSysDoc')"
v-if="!hasPermi(['role:zys'])">
<div class="my_select_box_content">
<span class="el-icon-data-line" style="padding: 4px;margin: 4px;color: #6698ff"></span>
<span class="my_select_box_content_text" :title="$t('trials:workbench:title:sysDocSigned')">{{ $t('trials:workbench:title:sysDocSigned') }}</span><span style="margin:0 0.25rem">·</span><span>{{ tabList.SysSignedDocCount }}</span>
<span class="my_select_box_content_text" :title="$t('trials:workbench:title:sysDocSigned')">{{
$t('trials:workbench:title:sysDocSigned') }}</span><span style="margin:0 0.25rem">·</span><span>{{
tabList.SysSignedDocCount }}</span>
</div>
</div>
</div>
<!--稽查文档-->
<template
v-if="hasPermi(['trials:trials-workbench:updateGeneralTraining', 'trials:trials-workbench:viewGeneralTraining', 'trials:trials-workbench:updateAuditDocument', 'trials:trials-workbench:viewAuditDocument'])">
<div class="thy-divider" style="border-top: 1px solid #eee;margin: 0;"></div>
<div class="my_select_title" style="font-size: 18px">{{ $t('trials:workbench:title:auditDocument') }}
</div>
<div class="my_select">
<!-- 通用培训管理 -->
<div class="my_select_box" :class="{ selected: selected === 'viewGeneralTraining' }"
tab-data="viewGeneralTraining" @click="selected = 'viewGeneralTraining'"
v-if="hasPermi(['trials:trials-workbench:viewGeneralTraining'])">
<div class="my_select_box_content">
<span class="el-icon-folder-checked" style="padding: 4px;margin: 4px;color: #6698ff"></span>
<span class="my_select_box_content_text">{{ $t('trials:tab:viewGeneralTraining') }}</span>
</div>
</div>
<!-- 稽查文档 -->
<div class="my_select_box" :class="{ selected: selected === 'viewAuditDocument' }"
tab-data="viewAuditDocument" @click="selected = 'viewAuditDocument'"
v-if="hasPermi(['trials:trials-workbench:viewAuditDocument'])">
<div class="my_select_box_content">
<span class="el-icon-folder-checked" style="padding: 4px;margin: 4px;color: #6698ff"></span>
<span class="my_select_box_content_text">{{ $t('trials:tab:viewAuditDocument') }}</span>
</div>
</div>
<!-- 培训课程管理 -->
<div class="my_select_box" :class="{ selected: selected === 'updateGeneralTraining' }"
tab-data="updateGeneralTraining" @click="selected = 'updateGeneralTraining'"
v-if="hasPermi(['trials:trials-workbench:updateGeneralTraining'])">
<div class="my_select_box_content">
<span class="el-icon-folder-checked" style="padding: 4px;margin: 4px;color: #6698ff"></span>
<span class="my_select_box_content_text">{{ $t('trials:tab:updateGeneralTraining') }}</span>
</div>
</div>
<!-- 稽查文档管理 -->
<div class="my_select_box" :class="{ selected: selected === 'updateAuditDocument' }"
tab-data="updateAuditDocument" @click="selected = 'updateAuditDocument'"
v-if="hasPermi(['trials:trials-workbench:updateAuditDocument'])">
<div class="my_select_box_content">
<span class="el-icon-folder-checked" style="padding: 4px;margin: 4px;color: #6698ff"></span>
<span class="my_select_box_content_text">{{ $t('trials:tab:updateAuditDocument') }}</span>
</div>
</div>
</div>
</template>
</div>
</div>
<div style="width: auto;flex:1;padding: 0 20px">
<!-- 加急影像提交 -->
<ImageSubmission v-if="selected === 'ImageSubmission'" :trial-id-list="trialIdList" :is-sign-system-doc="tabList.SysWaitSignDocCount > 0 && !isTestUser" />
<!-- PM/APM -->
<!-- 阅片期 -->
<!-- <el-tab-pane name="clinicalDataPM" v-if="hasPermi(['trials:trials-panel:subject:readingPeriod:edit'])" :label="`${$t('trials:crcUpload:label:clinicalData')} (${tabList.PM_ClinicalDataCount})`">-->
<!-- <clinicalDataPM v-if="activeName === 'clinicalDataPM'" :trial-id-list="trialIdList" :is-sign-system-doc="isSignSystemDoc" />-->
<!-- </el-tab-pane>-->
<consistencyCheck v-if="selected === 'consistencyCheck'" :trial-id-list="trialIdList" :is-sign-system-doc="tabList.SysWaitSignDocCount > 0 && !isTestUser" />
<!-- 重阅审批 -->
<RereadApproval v-if="selected === 'RereadApproval'" :trial-id-list="trialIdList" :is-sign-system-doc="tabList.SysWaitSignDocCount > 0 && !isTestUser" />
<!-- 阅片人筛选 -->
<ReviewerScreen v-if="selected === 'ReviewerScreen'" :trial-id-list="trialIdList" :is-sign-system-doc="tabList.SysWaitSignDocCount > 0 && !isTestUser" />
<!-- 中心调研 -->
<SiteResearch v-if="selected === 'SiteResearch'" :trial-id-list="trialIdList" :is-sign-system-doc="tabList.SysWaitSignDocCount > 0 && !isTestUser" />
<!-- SPM/CPM -->
<!-- 阅片人审批 -->
<ReviewerApproval v-if="selected === 'ReviewerApproval'" :trial-id-list="trialIdList" :is-sign-system-doc="tabList.SysWaitSignDocCount > 0 && !isTestUser" />
<!-- 重阅审批 -->
<SpmRereadApproval v-if="selected === 'SpmRereadApproval'" :trial-id-list="trialIdList" :is-sign-system-doc="tabList.SysWaitSignDocCount > 0 && !isTestUser" />
<!-- CRC -->
<!-- 临床数据录入 -->
<!-- <clinicalData v-if="selected === 'clinicalData'" :trial-id-list="trialIdList" :is-sign-system-doc="isSignSystemDoc" />-->
<!-- 临床数据确认 -->
<!-- <clinicalDataConfirm v-if="selected === 'clinicalDataConfirm'" :trial-id-list="trialIdList" :is-sign-system-doc="isSignSystemDoc" />-->
<!-- 影像质疑 -->
<ImageQuestion v-if="selected === 'ImageQuestion'" :trial-id-list="trialIdList" :is-sign-system-doc="tabList.SysWaitSignDocCount > 0 && !isTestUser" />
<!-- 核查质疑 -->
<ImageVerification v-if="selected === 'ImageVerification'" :trial-id-list="trialIdList" :is-sign-system-doc="tabList.SysWaitSignDocCount > 0 && !isTestUser" />
<!-- 影像重传 -->
<ImageReupload v-if="selected === 'ImageReupload'" :trial-id-list="trialIdList" :is-sign-system-doc="tabList.SysWaitSignDocCount > 0 && !isTestUser" />
<!-- IQC -->
<!-- 影像质控 -->
<ImageQualityControl v-if="selected === 'ImageQualityControl'" :trial-id-list="trialIdList" :is-sign-system-doc="tabList.SysWaitSignDocCount > 0 && !isTestUser" />
<!-- QC质疑 -->
<QcQuestion v-if="selected === 'QcQuestion'" :trial-id-list="trialIdList" :is-sign-system-doc="tabList.SysWaitSignDocCount > 0" />
<!-- IR -->
<!-- 影像待阅 -->
<ImagesToRead v-if="selected === 'ImagesToRead'" :trial-id-list="trialIdList" :is-sign-system-doc="tabList.SysWaitSignDocCount > 0 && !isTestUser" />
<!-- 医学反馈 -->
<MedicalFeedback v-if="selected === 'MedicalFeedback'" :trial-id-list="trialIdList" :is-sign-system-doc="tabList.SysWaitSignDocCount > 0 && !isTestUser" />
<!-- MIM -->
<!-- 医学审核 -->
<MedicalAudit v-if="selected === 'MedicalAudit'" :trial-id-list="trialIdList" :is-sign-system-doc="tabList.SysWaitSignDocCount > 0 && !isTestUser" />
<!-- 项目签署文件 -->
<NeedSignTrialDoc v-if="selected === 'NeedSignTrialDoc'" :is-sign-system-doc="isSignSystemDoc" />
<!-- 系统签署文件 -->
<NeedSignSysDoc v-if="selected === 'NeedSignSysDoc'" @refreshStats="refreshSysData" />
<!-- 项目签署文件 -->
<NeedSignedTrialDoc v-if="selected === 'NeedSignedTrialDoc'" :is-sign-system-doc="isSignSystemDoc" />
<!-- 系统签署文件 -->
<NeedSignedSysDoc v-if="selected === 'NeedSignedSysDoc'" :is-signed="true" @refreshStats="refreshStats" />
</div>
<!-- <div v-show="false" style="height: 100%;position: relative">-->
<!-- <div style="font-weight:900;font-size: 20px;position: absolute;line-height: 60px;text-align: left;white-space: nowrap;padding-left: 20px" :style="{width: width + 'px'}">-->
<!-- {{ $t('trials:workbench:label:pendingTasksStats') }} ({{tabList.TotalCount}})-->
<!-- </div>-->
<!-- <el-tabs v-model="activeName" style="height: 100%" tab-position="left">-->
<!-- &lt;!&ndash; PM/APM &ndash;&gt;-->
<!-- &lt;!&ndash; 阅片期 &ndash;&gt;-->
<!--&lt;!&ndash; <el-tab-pane name="clinicalDataPM" v-if="hasPermi(['trials:trials-panel:subject:readingPeriod:edit'])" :label="`${$t('trials:crcUpload:label:clinicalData')} (${tabList.PM_ClinicalDataCount})`">&ndash;&gt;-->
<!--&lt;!&ndash; <clinicalDataPM v-if="activeName === 'clinicalDataPM'" :trial-id-list="trialIdList" :is-sign-system-doc="isSignSystemDoc" />&ndash;&gt;-->
<!--&lt;!&ndash; </el-tab-pane>&ndash;&gt;-->
<!-- <el-tab-pane name="consistencyCheck" v-if="hasPermi(['trials:trials-workbench:consistencyCheck'])" :label="`${$t('trials:tab:consistencyCheck')} (${tabList.PM_CheckCount})`">-->
<!-- <consistencyCheck v-if="activeName === 'consistencyCheck'" :trial-id-list="trialIdList" :is-sign-system-doc="isSignSystemDoc" />-->
<!-- </el-tab-pane>-->
<!--&lt;!&ndash; 重阅审批 &ndash;&gt;-->
<!-- <el-tab-pane name="RereadApproval" v-if="hasPermi(['trials:trials-workbench:rereadApproval'])" :label="`${$t('trials:trials-panel:attachments:reReadingTracking')} (${tabList.PM_ReReadingApprovalCount})`">-->
<!-- <RereadApproval v-if="activeName === 'RereadApproval'" :trial-id-list="trialIdList" :is-sign-system-doc="isSignSystemDoc" />-->
<!-- </el-tab-pane>-->
<!--&lt;!&ndash; 阅片人筛选 &ndash;&gt;-->
<!-- <el-tab-pane name="ReviewerScreen" v-if="hasPermi(['trials:trials-workbench:reviewerScreen'])" :label="`${$t('trials:trials-list:PendingDetails:ReviewerSelection')} (${tabList.PM_ReviewerSelectCount})`">-->
<!-- <ReviewerScreen v-if="activeName === 'ReviewerScreen'" :trial-id-list="trialIdList" :is-sign-system-doc="isSignSystemDoc" />-->
<!-- </el-tab-pane>-->
<!--&lt;!&ndash; 中心调研 &ndash;&gt;-->
<!-- <el-tab-pane name="SiteResearch" v-if="hasPermi(['trials:trials-workbench:reviewerScreen'])" :label="`${$t('trials:workbench:title:pendingSiteResearch')} (${tabList.PM_SiteSurveryCount})`">-->
<!-- <SiteResearch v-if="activeName === 'SiteResearch'" :trial-id-list="trialIdList" :is-sign-system-doc="isSignSystemDoc" />-->
<!-- </el-tab-pane>-->
<!--&lt;!&ndash; SPM/CPM &ndash;&gt;-->
<!--&lt;!&ndash; 阅片人审批 &ndash;&gt;-->
<!-- <el-tab-pane name="ReviewerApproval" v-if="hasPermi(['trials:trials-workbench:reviewerApproval'])" :label="`${$t('trials:sysDocBeSigned:table:reviewerApproval')} (${tabList.SPM_ReviewerApprovalCount})`">-->
<!-- <ReviewerApproval v-if="activeName === 'ReviewerApproval'" :trial-id-list="trialIdList" :is-sign-system-doc="isSignSystemDoc" />-->
<!-- </el-tab-pane>-->
<!--&lt;!&ndash; 重阅审批 &ndash;&gt;-->
<!-- <el-tab-pane name="SpmRereadApproval" v-if="hasPermi(['trials:trials-workbench:spmRereadApproval'])" :label="`${$t('trials:trials-panel:attachments:reReadingTracking')} (${tabList.SPM_ReReadingApprovalCount})`">-->
<!-- <SpmRereadApproval v-if="activeName === 'SpmRereadApproval'" :trial-id-list="trialIdList" :is-sign-system-doc="isSignSystemDoc" />-->
<!-- </el-tab-pane>-->
<!--&lt;!&ndash; CRC &ndash;&gt;-->
<!--&lt;!&ndash; 临床数据录入 &ndash;&gt;-->
<!-- <el-tab-pane name="clinicalData" v-if="hasPermi(['trials:trials-workbench:clinicalDataEntry'])" :label="`${$t('trials:workbench:title:ClinicalDataEnter')} (${tabList.CRC_ClinicalDataTobeDoneCount})`">-->
<!-- <clinicalData v-if="activeName === 'clinicalData'" :trial-id-list="trialIdList" :is-sign-system-doc="isSignSystemDoc" />-->
<!-- </el-tab-pane>-->
<!--&lt;!&ndash; 临床数据确认 &ndash;&gt;-->
<!-- <el-tab-pane name="consistencyCheck" v-if="hasPermi(['trials:trials-workbench:clinicalDataEntry'])" :label="`${$t('trials:audit:tab:clinicalDataconfirm')} (${tabList.CRC_ClinialDataTobeConfirmCount})`">-->
<!-- <clinicalDataConfirm v-if="activeName === 'clinicalDataConfirm'" :trial-id-list="trialIdList" :is-sign-system-doc="isSignSystemDoc" />-->
<!-- </el-tab-pane>-->
<!-- &lt;!&ndash; 影像质疑 &ndash;&gt;-->
<!-- <el-tab-pane name="ImageQuestion" v-if="hasPermi(['trials:trials-workbench:imageQuestion'])" :label="`${$t('trials:tab:crcQuality')} (${tabList.CRC_ImageQuestionCount})`">-->
<!-- <ImageQuestion v-if="activeName === 'ImageQuestion'" :trial-id-list="trialIdList" :is-sign-system-doc="isSignSystemDoc" />-->
<!-- </el-tab-pane>-->
<!-- &lt;!&ndash; 核查质疑 &ndash;&gt;-->
<!-- <el-tab-pane name="ImageVerification" v-if="hasPermi(['trials:trials-workbenck:imageVerification'])" :label="`${$t('trials:sysDocBeSigned:table:ImageCheck')} (${tabList.CRC_CheckQuestionCount})`">-->
<!-- <ImageVerification v-if="activeName === 'ImageVerification'" :trial-id-list="trialIdList" :is-sign-system-doc="isSignSystemDoc" />-->
<!-- </el-tab-pane>-->
<!-- &lt;!&ndash; 影像重传 &ndash;&gt;-->
<!-- <el-tab-pane name="ImageReupload" v-if="hasPermi(['trials:trials-workbenck:imageReupload'])" :label="`${$t('trials:workbench:title:ImageRetransmission')} (${tabList.CRC_ImageReUploadCount})`">-->
<!-- <ImageReupload v-if="activeName === 'ImageReupload'" :trial-id-list="trialIdList" :is-sign-system-doc="isSignSystemDoc" />-->
<!-- </el-tab-pane>-->
<!-- &lt;!&ndash; 加急影像提交 &ndash;&gt;-->
<!-- <el-tab-pane name="ImageSubmission" v-if="hasPermi(['trials:trials-workbenck:imageSubmission'])" :label="`${$t('trials:workbench:title:ExpeditedImageSubmission')} (${tabList.CRC_ImageSubmitCount})`">-->
<!-- <ImageSubmission v-if="activeName === 'ImageSubmission'" :trial-id-list="trialIdList" :is-sign-system-doc="isSignSystemDoc" />-->
<!-- </el-tab-pane>-->
<!-- &lt;!&ndash; IQC &ndash;&gt;-->
<!-- &lt;!&ndash; 影像质控 &ndash;&gt;-->
<!-- <el-tab-pane name="ImageQualityControl" v-if="hasPermi(['trials:trials-workbenck:imageQC'])" :label="`${$t('trials:tab:dicomsQuality')} (${tabList.IQC_IamgeQCCount})`">-->
<!-- <ImageQualityControl v-if="activeName === 'ImageQualityControl'" :trial-id-list="trialIdList" :is-sign-system-doc="isSignSystemDoc" />-->
<!-- </el-tab-pane>-->
<!-- &lt;!&ndash; QC质疑 &ndash;&gt;-->
<!-- <el-tab-pane name="QcQuestion" v-if="hasPermi(['trials:trials-workbenck:qcQuestion'])" :label="`${$t('trials:tab:qcQuality')} (${tabList.IQC_QCQuestionCount})`">-->
<!-- <QcQuestion v-if="activeName === 'QcQuestion'" :trial-id-list="trialIdList" :is-sign-system-doc="isSignSystemDoc" />-->
<!-- </el-tab-pane>-->
<!-- &lt;!&ndash; IR &ndash;&gt;-->
<!-- &lt;!&ndash; 影像待阅 &ndash;&gt;-->
<!-- <el-tab-pane name="ImagesToRead" v-if="hasPermi(['trials:trials-workbenck:imagesToRead'])" :label="`${$t('trials:tab:pendingReadingTasks')} (${tabList.IR_IamgeWaitReadingCount})`">-->
<!-- <ImagesToRead v-if="activeName === 'ImagesToRead'" :trial-id-list="trialIdList" :is-sign-system-doc="isSignSystemDoc" />-->
<!-- </el-tab-pane>-->
<!-- &lt;!&ndash; 医学反馈 &ndash;&gt;-->
<!-- <el-tab-pane name="MedicalFeedback" v-if="hasPermi(['trials:trials-workbenck:medicalFeedback'])" :label="`${$t('trials:trials-panel:tab:medicalFeedback')} (${tabList.IR_MedicalReviewCount})`">-->
<!-- <MedicalFeedback v-if="activeName === 'MedicalFeedback'" :trial-id-list="trialIdList" :is-sign-system-doc="isSignSystemDoc" />-->
<!-- </el-tab-pane>-->
<!-- &lt;!&ndash; MIM &ndash;&gt;-->
<!-- &lt;!&ndash; 医学审核 &ndash;&gt;-->
<!-- <el-tab-pane name="MedicalAudit" v-if="hasPermi(['trials:trials-workbenck:medicalAudit'])" :label="`${$t('trials:trials-panel:tab:pmMedicalFeedback')} (${tabList.MIM_MedicalReviewCount})`">-->
<!-- <MedicalAudit v-if="activeName === 'MedicalAudit'" :trial-id-list="trialIdList" :is-sign-system-doc="isSignSystemDoc" />-->
<!-- </el-tab-pane>-->
<!-- &lt;!&ndash; 项目签署文件 &ndash;&gt;-->
<!-- <el-tab-pane name="NeedSignTrialDoc" v-if="!hasPermi(['role:zys'])" :label="`${$t('trials:workbench:title:trialDocBeSigned')} (${tabList.TrialWaitSignDocCount})`">-->
<!-- <NeedSignTrialDoc v-if="activeName === 'NeedSignTrialDoc'" :is-sign-system-doc="isSignSystemDoc" />-->
<!-- </el-tab-pane>-->
<!-- &lt;!&ndash; 系统签署文件 &ndash;&gt;-->
<!-- <el-tab-pane name="NeedSignSysDoc" v-if="!hasPermi(['role:zys'])" :label="`${$t('trials:workbench:title:sysDocBeSigned')} (${tabList.SysWaitSignDocCount})`">-->
<!-- <NeedSignSysDoc v-if="activeName === 'NeedSignSysDoc'" @refreshStats="refreshStats" />-->
<!-- </el-tab-pane>-->
<!-- </el-tabs>-->
<!-- </div>-->
</div>
<div style="width: auto;flex:1;padding: 0 20px">
<!-- 加急影像提交 -->
<ImageSubmission v-if="selected === 'ImageSubmission'" :trial-id-list="trialIdList"
:is-sign-system-doc="tabList.SysWaitSignDocCount > 0 && !isTestUser" />
<!-- PM/APM -->
<!-- 阅片期 -->
<!-- <el-tab-pane name="clinicalDataPM" v-if="hasPermi(['trials:trials-panel:subject:readingPeriod:edit'])" :label="`${$t('trials:crcUpload:label:clinicalData')} (${tabList.PM_ClinicalDataCount})`">-->
<!-- <clinicalDataPM v-if="activeName === 'clinicalDataPM'" :trial-id-list="trialIdList" :is-sign-system-doc="isSignSystemDoc" />-->
<!-- </el-tab-pane>-->
<consistencyCheck v-if="selected === 'consistencyCheck'" :trial-id-list="trialIdList"
:is-sign-system-doc="tabList.SysWaitSignDocCount > 0 && !isTestUser" />
<!-- 重阅审批 -->
<RereadApproval v-if="selected === 'RereadApproval'" :trial-id-list="trialIdList"
:is-sign-system-doc="tabList.SysWaitSignDocCount > 0 && !isTestUser" />
<!-- 阅片人筛选 -->
<ReviewerScreen v-if="selected === 'ReviewerScreen'" :trial-id-list="trialIdList"
:is-sign-system-doc="tabList.SysWaitSignDocCount > 0 && !isTestUser" />
<!-- 中心调研 -->
<SiteResearch v-if="selected === 'SiteResearch'" :trial-id-list="trialIdList"
:is-sign-system-doc="tabList.SysWaitSignDocCount > 0 && !isTestUser" />
<!-- SPM/CPM -->
<!-- 阅片人审批 -->
<ReviewerApproval v-if="selected === 'ReviewerApproval'" :trial-id-list="trialIdList"
:is-sign-system-doc="tabList.SysWaitSignDocCount > 0 && !isTestUser" />
<!-- 重阅审批 -->
<SpmRereadApproval v-if="selected === 'SpmRereadApproval'" :trial-id-list="trialIdList"
:is-sign-system-doc="tabList.SysWaitSignDocCount > 0 && !isTestUser" />
<!-- CRC -->
<!-- 临床数据录入 -->
<!-- <clinicalData v-if="selected === 'clinicalData'" :trial-id-list="trialIdList" :is-sign-system-doc="isSignSystemDoc" />-->
<!-- 临床数据确认 -->
<!-- <clinicalDataConfirm v-if="selected === 'clinicalDataConfirm'" :trial-id-list="trialIdList" :is-sign-system-doc="isSignSystemDoc" />-->
<!-- 影像质疑 -->
<ImageQuestion v-if="selected === 'ImageQuestion'" :trial-id-list="trialIdList"
:is-sign-system-doc="tabList.SysWaitSignDocCount > 0 && !isTestUser" />
<!-- 核查质疑 -->
<ImageVerification v-if="selected === 'ImageVerification'" :trial-id-list="trialIdList"
:is-sign-system-doc="tabList.SysWaitSignDocCount > 0 && !isTestUser" />
<!-- 影像重传 -->
<ImageReupload v-if="selected === 'ImageReupload'" :trial-id-list="trialIdList"
:is-sign-system-doc="tabList.SysWaitSignDocCount > 0 && !isTestUser" />
<!-- IQC -->
<!-- 影像质控 -->
<ImageQualityControl v-if="selected === 'ImageQualityControl'" :trial-id-list="trialIdList"
:is-sign-system-doc="tabList.SysWaitSignDocCount > 0 && !isTestUser" />
<!-- QC质疑 -->
<QcQuestion v-if="selected === 'QcQuestion'" :trial-id-list="trialIdList"
:is-sign-system-doc="tabList.SysWaitSignDocCount > 0" />
<!-- IR -->
<!-- 影像待阅 -->
<ImagesToRead v-if="selected === 'ImagesToRead'" :trial-id-list="trialIdList"
:is-sign-system-doc="tabList.SysWaitSignDocCount > 0 && !isTestUser" />
<!-- 医学反馈 -->
<MedicalFeedback v-if="selected === 'MedicalFeedback'" :trial-id-list="trialIdList"
:is-sign-system-doc="tabList.SysWaitSignDocCount > 0 && !isTestUser" />
<!-- MIM -->
<!-- 医学审核 -->
<MedicalAudit v-if="selected === 'MedicalAudit'" :trial-id-list="trialIdList"
:is-sign-system-doc="tabList.SysWaitSignDocCount > 0 && !isTestUser" />
<!-- 项目签署文件 -->
<NeedSignTrialDoc v-if="selected === 'NeedSignTrialDoc'" :is-sign-system-doc="isSignSystemDoc" />
<!-- 系统签署文件 -->
<NeedSignSysDoc v-if="selected === 'NeedSignSysDoc'" @refreshStats="refreshSysData" />
<!-- 项目签署文件 -->
<NeedSignedTrialDoc v-if="selected === 'NeedSignedTrialDoc'" :is-sign-system-doc="isSignSystemDoc" />
<!-- 系统签署文件 -->
<NeedSignedSysDoc v-if="selected === 'NeedSignedSysDoc'" :is-signed="true" @refreshStats="refreshStats" />
<!--通用培训记录-->
<generalTraining v-if="selected === 'viewGeneralTraining'" :isManage="false" />
<!--稽查文档-->
<auditDocument v-if="selected === 'viewAuditDocument'" :isManage="false" />
<!--培训课程管理-->
<generalTraining v-if="selected === 'updateGeneralTraining'" :isManage="true" />
<!--稽查文档管理-->
<auditDocument v-if="selected === 'updateAuditDocument'" :isManage="true" />
</div>
<!-- <div v-show="false" style="height: 100%;position: relative">-->
<!-- <div style="font-weight:900;font-size: 20px;position: absolute;line-height: 60px;text-align: left;white-space: nowrap;padding-left: 20px" :style="{width: width + 'px'}">-->
<!-- {{ $t('trials:workbench:label:pendingTasksStats') }} ({{tabList.TotalCount}})-->
<!-- </div>-->
<!-- <el-tabs v-model="activeName" style="height: 100%" tab-position="left">-->
<!-- &lt;!&ndash; PM/APM &ndash;&gt;-->
<!-- &lt;!&ndash; 阅片期 &ndash;&gt;-->
<!--&lt;!&ndash; <el-tab-pane name="clinicalDataPM" v-if="hasPermi(['trials:trials-panel:subject:readingPeriod:edit'])" :label="`${$t('trials:crcUpload:label:clinicalData')} (${tabList.PM_ClinicalDataCount})`">&ndash;&gt;-->
<!--&lt;!&ndash; <clinicalDataPM v-if="activeName === 'clinicalDataPM'" :trial-id-list="trialIdList" :is-sign-system-doc="isSignSystemDoc" />&ndash;&gt;-->
<!--&lt;!&ndash; </el-tab-pane>&ndash;&gt;-->
<!-- <el-tab-pane name="consistencyCheck" v-if="hasPermi(['trials:trials-workbench:consistencyCheck'])" :label="`${$t('trials:tab:consistencyCheck')} (${tabList.PM_CheckCount})`">-->
<!-- <consistencyCheck v-if="activeName === 'consistencyCheck'" :trial-id-list="trialIdList" :is-sign-system-doc="isSignSystemDoc" />-->
<!-- </el-tab-pane>-->
<!--&lt;!&ndash; 重阅审批 &ndash;&gt;-->
<!-- <el-tab-pane name="RereadApproval" v-if="hasPermi(['trials:trials-workbench:rereadApproval'])" :label="`${$t('trials:trials-panel:attachments:reReadingTracking')} (${tabList.PM_ReReadingApprovalCount})`">-->
<!-- <RereadApproval v-if="activeName === 'RereadApproval'" :trial-id-list="trialIdList" :is-sign-system-doc="isSignSystemDoc" />-->
<!-- </el-tab-pane>-->
<!--&lt;!&ndash; 阅片人筛选 &ndash;&gt;-->
<!-- <el-tab-pane name="ReviewerScreen" v-if="hasPermi(['trials:trials-workbench:reviewerScreen'])" :label="`${$t('trials:trials-list:PendingDetails:ReviewerSelection')} (${tabList.PM_ReviewerSelectCount})`">-->
<!-- <ReviewerScreen v-if="activeName === 'ReviewerScreen'" :trial-id-list="trialIdList" :is-sign-system-doc="isSignSystemDoc" />-->
<!-- </el-tab-pane>-->
<!--&lt;!&ndash; 中心调研 &ndash;&gt;-->
<!-- <el-tab-pane name="SiteResearch" v-if="hasPermi(['trials:trials-workbench:reviewerScreen'])" :label="`${$t('trials:workbench:title:pendingSiteResearch')} (${tabList.PM_SiteSurveryCount})`">-->
<!-- <SiteResearch v-if="activeName === 'SiteResearch'" :trial-id-list="trialIdList" :is-sign-system-doc="isSignSystemDoc" />-->
<!-- </el-tab-pane>-->
<!--&lt;!&ndash; SPM/CPM &ndash;&gt;-->
<!--&lt;!&ndash; 阅片人审批 &ndash;&gt;-->
<!-- <el-tab-pane name="ReviewerApproval" v-if="hasPermi(['trials:trials-workbench:reviewerApproval'])" :label="`${$t('trials:sysDocBeSigned:table:reviewerApproval')} (${tabList.SPM_ReviewerApprovalCount})`">-->
<!-- <ReviewerApproval v-if="activeName === 'ReviewerApproval'" :trial-id-list="trialIdList" :is-sign-system-doc="isSignSystemDoc" />-->
<!-- </el-tab-pane>-->
<!--&lt;!&ndash; 重阅审批 &ndash;&gt;-->
<!-- <el-tab-pane name="SpmRereadApproval" v-if="hasPermi(['trials:trials-workbench:spmRereadApproval'])" :label="`${$t('trials:trials-panel:attachments:reReadingTracking')} (${tabList.SPM_ReReadingApprovalCount})`">-->
<!-- <SpmRereadApproval v-if="activeName === 'SpmRereadApproval'" :trial-id-list="trialIdList" :is-sign-system-doc="isSignSystemDoc" />-->
<!-- </el-tab-pane>-->
<!--&lt;!&ndash; CRC &ndash;&gt;-->
<!--&lt;!&ndash; 临床数据录入 &ndash;&gt;-->
<!-- <el-tab-pane name="clinicalData" v-if="hasPermi(['trials:trials-workbench:clinicalDataEntry'])" :label="`${$t('trials:workbench:title:ClinicalDataEnter')} (${tabList.CRC_ClinicalDataTobeDoneCount})`">-->
<!-- <clinicalData v-if="activeName === 'clinicalData'" :trial-id-list="trialIdList" :is-sign-system-doc="isSignSystemDoc" />-->
<!-- </el-tab-pane>-->
<!--&lt;!&ndash; 临床数据确认 &ndash;&gt;-->
<!-- <el-tab-pane name="consistencyCheck" v-if="hasPermi(['trials:trials-workbench:clinicalDataEntry'])" :label="`${$t('trials:audit:tab:clinicalDataconfirm')} (${tabList.CRC_ClinialDataTobeConfirmCount})`">-->
<!-- <clinicalDataConfirm v-if="activeName === 'clinicalDataConfirm'" :trial-id-list="trialIdList" :is-sign-system-doc="isSignSystemDoc" />-->
<!-- </el-tab-pane>-->
<!-- &lt;!&ndash; 影像质疑 &ndash;&gt;-->
<!-- <el-tab-pane name="ImageQuestion" v-if="hasPermi(['trials:trials-workbench:imageQuestion'])" :label="`${$t('trials:tab:crcQuality')} (${tabList.CRC_ImageQuestionCount})`">-->
<!-- <ImageQuestion v-if="activeName === 'ImageQuestion'" :trial-id-list="trialIdList" :is-sign-system-doc="isSignSystemDoc" />-->
<!-- </el-tab-pane>-->
<!-- &lt;!&ndash; 核查质疑 &ndash;&gt;-->
<!-- <el-tab-pane name="ImageVerification" v-if="hasPermi(['trials:trials-workbenck:imageVerification'])" :label="`${$t('trials:sysDocBeSigned:table:ImageCheck')} (${tabList.CRC_CheckQuestionCount})`">-->
<!-- <ImageVerification v-if="activeName === 'ImageVerification'" :trial-id-list="trialIdList" :is-sign-system-doc="isSignSystemDoc" />-->
<!-- </el-tab-pane>-->
<!-- &lt;!&ndash; 影像重传 &ndash;&gt;-->
<!-- <el-tab-pane name="ImageReupload" v-if="hasPermi(['trials:trials-workbenck:imageReupload'])" :label="`${$t('trials:workbench:title:ImageRetransmission')} (${tabList.CRC_ImageReUploadCount})`">-->
<!-- <ImageReupload v-if="activeName === 'ImageReupload'" :trial-id-list="trialIdList" :is-sign-system-doc="isSignSystemDoc" />-->
<!-- </el-tab-pane>-->
<!-- &lt;!&ndash; 加急影像提交 &ndash;&gt;-->
<!-- <el-tab-pane name="ImageSubmission" v-if="hasPermi(['trials:trials-workbenck:imageSubmission'])" :label="`${$t('trials:workbench:title:ExpeditedImageSubmission')} (${tabList.CRC_ImageSubmitCount})`">-->
<!-- <ImageSubmission v-if="activeName === 'ImageSubmission'" :trial-id-list="trialIdList" :is-sign-system-doc="isSignSystemDoc" />-->
<!-- </el-tab-pane>-->
<!-- &lt;!&ndash; IQC &ndash;&gt;-->
<!-- &lt;!&ndash; 影像质控 &ndash;&gt;-->
<!-- <el-tab-pane name="ImageQualityControl" v-if="hasPermi(['trials:trials-workbenck:imageQC'])" :label="`${$t('trials:tab:dicomsQuality')} (${tabList.IQC_IamgeQCCount})`">-->
<!-- <ImageQualityControl v-if="activeName === 'ImageQualityControl'" :trial-id-list="trialIdList" :is-sign-system-doc="isSignSystemDoc" />-->
<!-- </el-tab-pane>-->
<!-- &lt;!&ndash; QC质疑 &ndash;&gt;-->
<!-- <el-tab-pane name="QcQuestion" v-if="hasPermi(['trials:trials-workbenck:qcQuestion'])" :label="`${$t('trials:tab:qcQuality')} (${tabList.IQC_QCQuestionCount})`">-->
<!-- <QcQuestion v-if="activeName === 'QcQuestion'" :trial-id-list="trialIdList" :is-sign-system-doc="isSignSystemDoc" />-->
<!-- </el-tab-pane>-->
<!-- &lt;!&ndash; IR &ndash;&gt;-->
<!-- &lt;!&ndash; 影像待阅 &ndash;&gt;-->
<!-- <el-tab-pane name="ImagesToRead" v-if="hasPermi(['trials:trials-workbenck:imagesToRead'])" :label="`${$t('trials:tab:pendingReadingTasks')} (${tabList.IR_IamgeWaitReadingCount})`">-->
<!-- <ImagesToRead v-if="activeName === 'ImagesToRead'" :trial-id-list="trialIdList" :is-sign-system-doc="isSignSystemDoc" />-->
<!-- </el-tab-pane>-->
<!-- &lt;!&ndash; 医学反馈 &ndash;&gt;-->
<!-- <el-tab-pane name="MedicalFeedback" v-if="hasPermi(['trials:trials-workbenck:medicalFeedback'])" :label="`${$t('trials:trials-panel:tab:medicalFeedback')} (${tabList.IR_MedicalReviewCount})`">-->
<!-- <MedicalFeedback v-if="activeName === 'MedicalFeedback'" :trial-id-list="trialIdList" :is-sign-system-doc="isSignSystemDoc" />-->
<!-- </el-tab-pane>-->
<!-- &lt;!&ndash; MIM &ndash;&gt;-->
<!-- &lt;!&ndash; 医学审核 &ndash;&gt;-->
<!-- <el-tab-pane name="MedicalAudit" v-if="hasPermi(['trials:trials-workbenck:medicalAudit'])" :label="`${$t('trials:trials-panel:tab:pmMedicalFeedback')} (${tabList.MIM_MedicalReviewCount})`">-->
<!-- <MedicalAudit v-if="activeName === 'MedicalAudit'" :trial-id-list="trialIdList" :is-sign-system-doc="isSignSystemDoc" />-->
<!-- </el-tab-pane>-->
<!-- &lt;!&ndash; 项目签署文件 &ndash;&gt;-->
<!-- <el-tab-pane name="NeedSignTrialDoc" v-if="!hasPermi(['role:zys'])" :label="`${$t('trials:workbench:title:trialDocBeSigned')} (${tabList.TrialWaitSignDocCount})`">-->
<!-- <NeedSignTrialDoc v-if="activeName === 'NeedSignTrialDoc'" :is-sign-system-doc="isSignSystemDoc" />-->
<!-- </el-tab-pane>-->
<!-- &lt;!&ndash; 系统签署文件 &ndash;&gt;-->
<!-- <el-tab-pane name="NeedSignSysDoc" v-if="!hasPermi(['role:zys'])" :label="`${$t('trials:workbench:title:sysDocBeSigned')} (${tabList.SysWaitSignDocCount})`">-->
<!-- <NeedSignSysDoc v-if="activeName === 'NeedSignSysDoc'" @refreshStats="refreshStats" />-->
<!-- </el-tab-pane>-->
<!-- </el-tabs>-->
<!-- </div>-->
</div>
</div>
</template>
@@ -419,16 +557,20 @@ import ImagesToRead from './components/imagesToRead'
import MedicalFeedback from './components/medicalFeedback'
import MedicalAudit from './components/medicalAudit'
import NeedSignedTrialDoc from './components/NeedSignedTrialDoc'
import auditDocument from "./components/auditDocument"
import generalTraining from "./components/generalTraining"
import store from '@/store'
import './index.css'
import {getUserTobeDoneRecord, getNeedSignTrialDocTrialIdList,getWaitSignSysDocList, getTrialSignDocumentList} from '@/api/trials'
import { getUserTobeDoneRecord, getNeedSignTrialDocTrialIdList } from '@/api/trials'
import { getUser } from '@/api/admin'
import {mapGetters, mapState} from "vuex";
import { mapGetters, mapState } from "vuex";
export default {
name: 'WorkBench',
components: {
auditDocument,
generalTraining,
clinicalDataConfirm,
clinicalDataPM,
PanelCount,
@@ -477,14 +619,14 @@ export default {
const days = [this.$t('common:date:Sunday'), this.$t('common:date:Monday'), this.$t('common:date:Tuesday'), this.$t('common:date:Wednesday'), this.$t('common:date:Thursday'), this.$t('common:date:Friday'), this.$t('common:date:Saturday')];
const date = new Date();
this.dayOfWeek = days[date.getDay()];
let date2=(new Date()).getHours();
let date2 = (new Date()).getHours();
let hoursTip = "";
if(date2>=6&&date2<12){
hoursTip= this.$t('common:date:good morning')
}else if(date2>=12&&date2<18){
hoursTip=this.$t('common:date:good afternoon')
}else{
hoursTip=this.$t('common:date:good evening')
if (date2 >= 6 && date2 < 12) {
hoursTip = this.$t('common:date:good morning')
} else if (date2 >= 12 && date2 < 18) {
hoursTip = this.$t('common:date:good afternoon')
} else {
hoursTip = this.$t('common:date:good evening')
}
this.hoursTip = hoursTip
this.$EventBus.$on("reload", (data) => {
@@ -521,7 +663,7 @@ export default {
})
})
},
refreshSysData(){
refreshSysData() {
// this.tabList.SysWaitSignDocCount = this.tabList.SysWaitSignDocCount - 1
// this.tabList.SysSignedDocCount = this.tabList.SysWaitSignDocCount + 1
// store.dispatch('user/setTotalNeedSignSystemDocCount', this.tabList.SysWaitSignDocCount)
@@ -539,7 +681,26 @@ export default {
}
</script>
<style lang="scss">
<style lang="scss" scoped>
.menuBox {
width: 100%;
height: calc(100% - 150px);
overflow-y: auto;
&::-webkit-scrollbar {
//display: none; /* Chrome Safari */
width: 8px;
height: 8px;
background-color: #e4e4e4;
border-radius: 6px;
}
&::-webkit-scrollbar-thumb {
background-color: #a1a3a9;
border-radius: 6px;
}
}
.workbench-container {
.el-tabs__nav {
transform: translateY(60px) !important;