4 Commits

Author SHA1 Message Date
wangxiaoshuang e0321bae72 影像预览问题解决
continuous-integration/drone/push Build encountered an error
2025-04-12 12:04:20 +08:00
wangxiaoshuang 1e720e399d 确认收入项,修改选项后,其他文件也改了
continuous-integration/drone/push Build encountered an error
2025-04-03 11:15:54 +08:00
wangxiaoshuang 1368397da9 项目总览—>上传记录:中心编号 查询条件,查询结果不对 2025-04-03 11:15:36 +08:00
wangxiaoshuang c8c049b5d0 DICOM影像中,存在Tag最大像素值、最小像素值等,但是和实际的数据统计结果不同 2025-04-03 11:15:22 +08:00
65 changed files with 4047 additions and 14482 deletions
+1 -116
View File
@@ -1035,27 +1035,7 @@ export function getQCVisitList(param) {
data: param
})
}
export function getImageBackList(param) {
return request({
url: `/QCList/getImageBackList`,
method: 'post',
data: param
})
}
export function getImageBackApplyUserList(params) {
return request({
url: `/QCList/getImageBackApplyUserList`,
method: 'get',
params
})
}
export function auditImageBack(params) {
return request({
url: `/QCOperation/auditImageBack`,
method: 'put',
params
})
}
export function getQCChallengeList(param) {
return request({
url: `/QCList/getQCChallengeList`,
@@ -3328,13 +3308,6 @@ export function getReReadingApplyToBeDoneList(param) {
data: param
})
}
export function getPMImageBackToBeDoneList(param) {
return request({
url: `/PersonalWorkstation/getPMImageBackToBeDoneList`,
method: 'post',
data: param
})
}
export function deleteClinicalForm(param) {
return request({
@@ -4022,91 +3995,3 @@ 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
})
}
// 工作台-删除稽查文档
export function deleteAuditDocument(data) {
return request({
url: `/AuditDocument/deleteAuditDocument`,
method: 'post',
data
})
}
// 工作台-稽查文档获取历史版本
export function getHistoricalVersion(data) {
return request({
url: `/AuditDocument/getHistoricalVersion`,
method: 'post',
data
})
}
// 工作台-稽查文档设置当前版本
export function setCurrentVersion(data) {
return request({
url: `/AuditDocument/setCurrentVersion`,
method: 'post',
data
})
}
// 工作台-稽查文档移动
export function movieFileOrFolder(data) {
return request({
url: `/AuditDocument/movieFileOrFolder`,
method: 'post',
data
})
}
// 工作台-稽查文档复制
export function copyFileOrFolder(data) {
return request({
url: `/AuditDocument/copyFileOrFolder`,
method: 'post',
data
})
}
// 工作台-稽查文档授权
export function setIsAuthorization(data) {
return request({
url: `/AuditDocument/setIsAuthorization`,
method: 'post',
data
})
}
// 工作台-稽查文档新增文件夹
export function addFolder(data) {
return request({
url: `/AuditDocument/addFolder`,
method: 'post',
data
})
}
-8
View File
@@ -287,12 +287,4 @@ export function forwardSVDicomImage(param) {
data: param
})
}
// crc、iqc申请影像退回
export function requestImageBack(params) {
return request({
url: `/QCOperation/requestImageBack`,
method: 'put',
params
})
}
-8
View File
@@ -209,11 +209,3 @@ export function loginSelectUserRole(params) {
params,
})
}
// 忽略异地登录
export function setIsIgnoreUncommonly(data) {
return request({
url: `/User/setIsIgnoreUncommonly`,
method: 'post',
data,
})
}
Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 175 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 665 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.9 KiB

-23
View File
@@ -1,23 +0,0 @@
import Vue from "vue";
import OnlyOffice from "./index.vue";
const PreviewConstructor = Vue.extend(OnlyOffice);
const onlyOffice = options => {
const { path, type, title } = options;
if (!path) throw `path is requred.but ${path}`
const id = `OnlyOffice_${new Date().getTime()}`;
const instance = new PreviewConstructor();
instance.id = id;
instance.vm = instance.$mount();
if (instance.vm.visible) return;
document.body.appendChild(instance.vm.$el);
instance.vm.open(path, type, title);
instance.vm.$on("closed", () => {
instance.vm.docEditor = null
document.body.removeChild(instance.vm.$el);
instance.vm.$destroy();
});
return instance.vm;
}
export default onlyOffice;
@@ -1,7 +0,0 @@
import OnlyOffice from "./index.vue";
import onlyOffice from "./fun";
export default Vue => {
Vue.component(OnlyOffice.name, OnlyOffice);
Vue.prototype.$onlyOffice = onlyOffice;
};
@@ -1,45 +0,0 @@
<template>
<el-dialog v-if="visible" :visible.sync="visible" :title="title" :fullscreen="true" append-to-body
custom-class="base-dialog-wrapper" @close="handleClose">
<div class="base-modal-body" style="border: 2px solid #ccc; padding: 10px">
<iframe v-if="visible"
:src="`/static/onlyOffice/viewer.html?url=${OSSclientConfig.basePath}${path}?type=${type}&title=${title}&documentType=${documentType}&userName=${currentUser}`"
width="100%" height="99%" frameborder="0" crossorigin="anonymous" />
</div>
</el-dialog>
</template>
<script>
import DOCUMENTTYPE from "@/utils/onlyOffice_type.js"
export default {
name: "OnlyOffice",
data() {
return {
visible: false,
path: null,
type: null,
title: null,
documentType: null,
currentUser: zzSessionStorage.getItem('userName'),
};
},
methods: {
open(path, type, title) {
this.path = path;
this.type = type.toLowerCase();
this.documentType = DOCUMENTTYPE[`.${this.type}`]
this.title = title;
this.visible = true;
},
handleClose() {
this.$emit("closed");
},
},
};
</script>
<style lang="scss" scoped>
#placeholder {
width: 100%;
height: 100%;
}
</style>
@@ -8,25 +8,61 @@
</div>
</div>
<!--检查列表-->
<el-table :data="list" style="width: 100%" v-adaptive="{ bottomOffset: 60 }" :loading="loading"
@sort-change="handleSortByColumn" :default-sort="{ prop: 'TaskBlindName', order: 'descending' }">
<el-table
:data="list"
style="width: 100%"
v-adaptive="{ bottomOffset: 60 }"
:loading="loading"
@sort-change="handleSortByColumn"
:default-sort="{ prop: 'TaskBlindName', order: 'descending' }"
>
<!--受试者-->
<el-table-column prop="SubjectCode" :label="$t('upload:nonedicom:table:subject')" />
<el-table-column
prop="SubjectCode"
:label="$t('upload:nonedicom:table:subject')"
/>
<!--任务名称-->
<el-table-column prop="TaskBlindName" :label="$t('upload:nonedicom:table:taskName')" sortable="custom" />
<el-table-column
prop="TaskBlindName"
:label="$t('upload:nonedicom:table:taskName')"
sortable="custom"
/>
<!--检查类型-->
<el-table-column prop="Modality" :label="$t('upload:nonedicom:table:molityType')" sortable="custom">
<el-table-column
prop="Modality"
:label="$t('upload:nonedicom:table:molityType')"
sortable="custom"
>
</el-table-column>
<!--检查部位-->
<el-table-column prop="BodyPart" :label="$t('upload:nonedicom:table:bodyPart')" sortable="custom" />
<el-table-column
prop="BodyPart"
:label="$t('upload:nonedicom:table:bodyPart')"
sortable="custom"
/>
<!--原文件数-->
<el-table-column prop="FileCount" :label="$t('upload:nonedicom:table:fileCount')">
<el-table-column
prop="FileCount"
:label="$t('upload:nonedicom:table:fileCount')"
>
<template slot-scope="scope">
<el-popover v-if="scope.row.FileCount" trigger="click" placement="bottom">
<el-popover
v-if="scope.row.FileCount"
trigger="click"
placement="bottom"
>
<el-table :data="scope.row.FileList" height="300" size="small">
<!-- 文件名称 -->
<el-table-column prop="FileName" :label="$t('trials:audit:table:nonDicomsFileName')" width="200" />
<el-table-column prop="FileSize" :label="$t('trials:audit:table:nonDicomsFileSize')" width="100">
<el-table-column
prop="FileName"
:label="$t('trials:audit:table:nonDicomsFileName')"
width="200"
/>
<el-table-column
prop="FileSize"
:label="$t('trials:audit:table:nonDicomsFileSize')"
width="100"
>
<template slot-scope="scope">
<span>{{
scope.row.FileSize && scope.row.FileSize > 0
@@ -38,13 +74,27 @@
<el-table-column :label="$t('common:action:action')" width="120">
<template slot-scope="files">
<!-- 预览 -->
<viewer :ref="files.row.Path" style="margin: 0 10px"
:images="[`${OSSclientConfig.basePath}${files.row.Path}`]">
<el-button circle icon="el-icon-view" :title="$t('upload:nonedicom:button:preview')" :disabled="files.row.FileType &&
files.row.FileType.indexOf('zip') >= 0
" @click.native.prevent="previewFile(files.row)" />
<img v-show="false" crossorigin="anonymous" :src="`${OSSclientConfig.basePath}${files.row.Path}`"
alt="Image" />
<viewer
:ref="files.row.Path"
style="margin: 0 10px"
:images="[`${OSSclientConfig.basePath}${files.row.Path}`]"
>
<el-button
circle
icon="el-icon-view"
:title="$t('upload:nonedicom:button:preview')"
:disabled="
files.row.FileType &&
files.row.FileType.indexOf('zip') >= 0
"
@click.native.prevent="previewFile(files.row)"
/>
<img
v-show="false"
crossorigin="anonymous"
:src="`${OSSclientConfig.basePath}${files.row.Path}`"
alt="Image"
/>
</viewer>
</template>
</el-table-column>
@@ -59,13 +109,32 @@
</template>
</el-table-column>
<!--后处理文件数-->
<el-table-column prop="UploadedFileCount" :label="$t('upload:nonedicom:table:uploadFileCount')">
<el-table-column
prop="UploadedFileCount"
:label="$t('upload:nonedicom:table:uploadFileCount')"
>
<template slot-scope="scope">
<el-popover v-if="scope.row.UploadedFileCount" trigger="click" placement="bottom">
<el-table :data="scope.row.UploadedFileList" height="300" size="small">
<el-popover
v-if="scope.row.UploadedFileCount"
trigger="click"
placement="bottom"
>
<el-table
:data="scope.row.UploadedFileList"
height="300"
size="small"
>
<!-- 文件名称 -->
<el-table-column prop="FileName" :label="$t('trials:audit:table:nonDicomsFileName')" width="200" />
<el-table-column prop="FileSize" :label="$t('trials:audit:table:nonDicomsFileSize')" width="100">
<el-table-column
prop="FileName"
:label="$t('trials:audit:table:nonDicomsFileName')"
width="200"
/>
<el-table-column
prop="FileSize"
:label="$t('trials:audit:table:nonDicomsFileSize')"
width="100"
>
<template slot-scope="scope">
<span>{{
scope.row.FileSize && scope.row.FileSize > 0
@@ -77,13 +146,27 @@
<el-table-column :label="$t('common:action:action')" width="120">
<template slot-scope="files">
<!-- 预览 -->
<viewer :ref="files.row.Path" style="margin: 0 10px"
:images="[`${OSSclientConfig.basePath}${files.row.Path}`]">
<el-button circle icon="el-icon-view" :title="$t('upload:nonedicom:button:preview')" :disabled="files.row.FileType &&
files.row.FileType.indexOf('zip') >= 0
" @click.native.prevent="previewFile(files.row)" />
<img v-show="false" crossorigin="anonymous" :src="`${OSSclientConfig.basePath}${files.row.Path}`"
alt="Image" />
<viewer
:ref="files.row.Path"
style="margin: 0 10px"
:images="[`${OSSclientConfig.basePath}${files.row.Path}`]"
>
<el-button
circle
icon="el-icon-view"
:title="$t('upload:nonedicom:button:preview')"
:disabled="
files.row.FileType &&
files.row.FileType.indexOf('zip') >= 0
"
@click.native.prevent="previewFile(files.row)"
/>
<img
v-show="false"
crossorigin="anonymous"
:src="`${OSSclientConfig.basePath}${files.row.Path}`"
alt="Image"
/>
</viewer>
</template>
</el-table-column>
@@ -97,34 +180,75 @@
<span v-else>{{ scope.row.UploadedFileCount }}</span>
</template>
</el-table-column>
<el-table-column :label="$t('common:action:action')" fixed="right" width="180">
<el-table-column
:label="$t('common:action:action')"
fixed="right"
width="180"
>
<template slot-scope="scope">
<!--预览--->
<el-button circle :disabled="scope.row.UploadedFileCount <= 0" icon="el-icon-view"
:title="$t('upload:nonedicom:button:preview')" @click.stop="handlePreviewNoneDicomFiles(scope.row)" />
<el-button
circle
:disabled="scope.row.UploadedFileCount <= 0"
icon="el-icon-view"
:title="$t('upload:nonedicom:button:preview')"
@click.stop="handlePreviewNoneDicomFiles(scope.row)"
/>
<!--上传--->
<el-button circle icon="el-icon-upload2" :title="$t('upload:nonedicom:button:upload')"
@click.native.prevent="handleUpload(scope.row)" />
<el-button
circle
icon="el-icon-upload2"
:title="$t('upload:nonedicom:button:upload')"
@click.native.prevent="handleUpload(scope.row)"
/>
<!--删除--->
<el-button :disabled="scope.row.UploadedFileCount <= 0 ||
scope.row.ReadingTaskState === 2
" circle icon="el-icon-delete" :title="$t('upload:nonedicom:button:delete')"
@click.stop="remove(scope.row)" />
<el-button
:disabled="
scope.row.UploadedFileCount <= 0 ||
scope.row.ReadingTaskState === 2
"
circle
icon="el-icon-delete"
:title="$t('upload:nonedicom:button:delete')"
@click.stop="remove(scope.row)"
/>
</template>
</el-table-column>
</el-table>
<!-- 预览单个图像 -->
<el-dialog v-if="imgObj.visible" :visible.sync="imgObj.visible" :title="$t('upload:nonedicom:dialogTitle:preview')"
append-to-body width="565px">
<div v-loading="imgObj.loading" class="base-modal-body" style="border: 2px solid #ccc; padding: 10px">
<el-image :src="`${OSSclientConfig.basePath}${imgObj.url}`" crossorigin="anonymous" fit="fit"
style="height: 500px; width: 500px" @error="imgObj.loading = false" @load="imgObj.loading = false" />
<el-dialog
v-if="imgObj.visible"
:visible.sync="imgObj.visible"
:title="$t('upload:nonedicom:dialogTitle:preview')"
append-to-body
width="565px"
>
<div
v-loading="imgObj.loading"
class="base-modal-body"
style="border: 2px solid #ccc; padding: 10px"
>
<el-image
:src="`${OSSclientConfig.basePath}${imgObj.url}`"
crossorigin="anonymous"
fit="fit"
style="height: 500px; width: 500px"
@error="imgObj.loading = false"
@load="imgObj.loading = false"
/>
</div>
</el-dialog>
<!-- 上传非dicom文件 -->
<el-dialog v-if="uploadVisible" :visible.sync="uploadVisible" :close-on-click-modal="false"
:title="$t('trials:uploadNonDicoms:dialogTitle:upload')" width="800px" append-to-body
custom-class="base-dialog-wrapper" @close="resetFileDiaolg">
<el-dialog
v-if="uploadVisible"
:visible.sync="uploadVisible"
:close-on-click-modal="false"
:title="$t('trials:uploadNonDicoms:dialogTitle:upload')"
width="800px"
append-to-body
custom-class="base-dialog-wrapper"
@close="resetFileDiaolg"
>
<!-- 多文件上传 -->
<form id="inputForm" ref="uploadForm">
<el-divider content-position="left">{{
@@ -132,15 +256,33 @@
}}</el-divider>
<div class="form-group">
<div class="upload" style="margin-right: 10px">
<input multiple="multiple" webkitdirectory="" directory accept="*/*" type="file" name="uploadFolder"
class="select-file" title="" @change="beginScanFiles($event)" v-if="!btnLoading" />
<input
multiple="multiple"
webkitdirectory=""
directory
accept="*/*"
type="file"
name="uploadFolder"
class="select-file"
title=""
@change="beginScanFiles($event)"
v-if="!btnLoading"
/>
<div class="btn-select">
{{ $t('trials:uploadNonDicoms:button:selectFolder') }}
</div>
</div>
<div class="upload">
<input class="select-file" multiple="" :accept="faccept.join(',')" type="file" name="uploadFile" title=""
@change="beginScanFiles($event)" v-if="!btnLoading" />
<input
class="select-file"
multiple=""
:accept="faccept.join(',')"
type="file"
name="uploadFile"
title=""
@change="beginScanFiles($event)"
v-if="!btnLoading"
/>
<div class="btn-select">
{{ $t('trials:uploadNonDicoms:button:select') }}
</div>
@@ -151,46 +293,82 @@
</div>
</form>
<!-- 文件列表 -->
<el-table ref="filesTable" :data="fileList" class="dicomFiles-table" height="300"
@selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" :selectable="(row, index) => row.status !== 2 && !btnLoading" />
<el-table
ref="filesTable"
:data="fileList"
class="dicomFiles-table"
height="300"
@selection-change="handleSelectionChange"
>
<el-table-column
type="selection"
width="55"
:selectable="(row, index) => row.status !== 2 && !btnLoading"
/>
<el-table-column type="index" width="50" />
<!-- 文件名称 -->
<el-table-column prop="name" :label="$t('trials:uploadNonDicoms:table:fileName')" min-width="100" />
<el-table-column
prop="name"
:label="$t('trials:uploadNonDicoms:table:fileName')"
min-width="100"
/>
<!-- 文件大小 -->
<el-table-column prop="size" :label="$t('trials:uploadNonDicoms:table:fileSize')">
<el-table-column
prop="size"
:label="$t('trials:uploadNonDicoms:table:fileSize')"
>
<template slot-scope="scope">
<span>{{
scope.row.size && scope.row.size > 0
? `${(scope.row.size / 1024 / 1024).toFixed(3)}MB`
: '0MB'
: ''
}}</span>
</template>
</el-table-column>
<!-- 文件类型 -->
<el-table-column prop="type" :label="$t('trials:uploadNonDicoms:table:fileType')" />
<el-table-column
prop="type"
:label="$t('trials:uploadNonDicoms:table:fileType')"
/>
<!-- 上传状态 -->
<el-table-column prop="status" :label="$t('trials:uploadNonDicoms:table:uploadStatus')" min-width="100">
<el-table-column
prop="status"
:label="$t('trials:uploadNonDicoms:table:uploadStatus')"
min-width="100"
>
<template slot-scope="scope">
<el-tag :type="['warning', 'info', 'success', 'danger'][scope.row.status]"
v-if="scope.row.status || scope.row.status === 0">{{ $fd('NoneDicomUploadStatus', scope.row.status) }}
<el-tag
:type="['warning', 'info', 'success', 'danger'][scope.row.status]"
v-if="scope.row.status || scope.row.status === 0"
>{{ $fd('NoneDicomUploadStatus', scope.row.status) }}
</el-tag>
</template>
</el-table-column>
<el-table-column :label="$t('trials:uploadNonDicoms:table:failedFileCount')" min-width="150"
show-overflow-tooltip>
<el-table-column
:label="$t('trials:uploadNonDicoms:table:failedFileCount')"
min-width="150"
show-overflow-tooltip
>
<template slot-scope="scope">
<el-progress color="#409eff" :percentage="scope.row.size && scope.row.size > 0 ? ((scope.row.uploadFileSize * 100) / scope.row.size).toFixed(2) *
1
: ((scope.row.uploadFileSize * 100) / 1).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="btnLoading"
:title="$t('trials:crcUpload:action:delete')" @click="handleRemoveFile(scope.row)" />
<el-button
size="mini"
icon="el-icon-delete"
circle
:disabled="btnLoading"
:title="$t('trials:crcUpload:action:delete')"
@click="handleRemoveFile(scope.row)"
/>
</template>
</el-table-column>
</el-table>
@@ -198,8 +376,13 @@
<span style="margin-right: 10px">{{
$store.state.trials.uploadTip
}}</span>
<el-button size="small" type="primary" :disabled="selectArr.length == 0" :loading="btnLoading"
@click="beginUpload">
<el-button
size="small"
type="primary"
:disabled="selectArr.length == 0"
:loading="btnLoading"
@click="beginUpload"
>
{{ $t('trials:uploadNonDicoms:action:upload') }}
</el-button>
</div>
@@ -405,7 +588,7 @@ export default {
)
}
})
.catch(() => { })
.catch(() => {})
},
resetUploadForm() {
this.$nextTick(() => {
@@ -531,10 +714,11 @@ export default {
if (!this.uploadVisible) return
let file = this.fileList.filter((item) => item.id === arr[index].id)[0]
file.status = 1
let path = `/${this.$route.query.trialId}/TaskImage/${this.currentRow.SubjectId
}/${this.currentRow.VisitTaskId}/${this.$guid()}${file.name
.substring(file.name.lastIndexOf('.'))
.toLocaleLowerCase()}`
let path = `/${this.$route.query.trialId}/TaskImage/${
this.currentRow.SubjectId
}/${this.currentRow.VisitTaskId}/${this.$guid()}${file.name
.substring(file.name.lastIndexOf('.'))
.toLocaleLowerCase()}`
file.curPath = path
const fileData = await this.fileToBlob(file.file)
let res = await this.fileToOss(path, fileData, file)
@@ -588,7 +772,7 @@ export default {
(percentage, checkpoint, lastPer) => {
item.uploadFileSize += checkpoint.size * (percentage - lastPer)
if (item.uploadFileSize > file.fileSize) {
item.uploadFileSize = file.fileSize > 0 ? file.fileSize : 1
item.uploadFileSize = file.fileSize
}
}
)
@@ -685,7 +869,6 @@ export default {
.top {
margin: 10px 0;
}
.upload {
display: inline-block;
height: 30px;
@@ -700,7 +883,6 @@ export default {
background: #428bca;
border-color: #428bca;
color: #fff;
.select-file {
height: 30px;
width: 90px;
@@ -711,7 +893,6 @@ export default {
opacity: 0;
font-size: 0;
}
.btn-select {
//给显示在页面上的按钮写样式
width: 90px;
@@ -727,12 +908,10 @@ export default {
pointer-events: none; //pointer-events:none用来控制该标签的点击穿透事件
}
}
.tip {
display: flex;
align-items: flex-start;
margin-top: 5px;
i {
margin: 3px 5px 0 0;
}
File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 26 KiB

-2
View File
@@ -54,8 +54,6 @@ import upload from '@/components/element-ui/upload'
Vue.use(upload)
import Preview from '@/components/Preview/index'
Vue.use(Preview)
import Onlyoffice from '@/components/Preview_onlyoffice/index'
Vue.use(Onlyoffice)
import MFA from '@/components/MFA/index'
Vue.use(MFA)
import FB from '@/components/feedBack/index'
+137 -10
View File
@@ -39,6 +39,108 @@ function getNumberValues(dataSet, tag, minimumLength) {
return values;
}
function getLutDescriptor(dataSet, tag) {
if (!dataSet.elements[tag] || dataSet.elements[tag].length !== 6) {
return;
}
return [
dataSet.uint16(tag, 0),
dataSet.uint16(tag, 1),
dataSet.uint16(tag, 2),
];
}
function getLutData(lutDataSet, tag, lutDescriptor) {
const lut = [];
const lutData = lutDataSet.elements[tag];
for (let i = 0; i < lutDescriptor[0]; i++) {
// Output range is always unsigned
if (lutDescriptor[2] === 16) {
lut[i] = lutDataSet.uint16(tag, i);
} else {
lut[i] = lutDataSet.byteArray[i + lutData.dataOffset];
}
}
return lut;
}
function populateSmallestLargestPixelValues(dataSet, imagePixelModule) {
const pixelRepresentation = dataSet.uint16('x00280103');
if (pixelRepresentation === 0) {
imagePixelModule.smallestPixelValue = dataSet.uint16('x00280106');
imagePixelModule.largestPixelValue = dataSet.uint16('x00280107');
} else {
imagePixelModule.smallestPixelValue = dataSet.int16('x00280106');
imagePixelModule.largestPixelValue = dataSet.int16('x00280107');
}
imagePixelModule.largestPixelValue = imagePixelModule.largestPixelValue === 0 ? undefined : imagePixelModule.largestPixelValue;
}
function populatePaletteColorLut(dataSet, imagePixelModule) {
imagePixelModule.redPaletteColorLookupTableDescriptor = getLutDescriptor(
dataSet,
'x00281101'
);
imagePixelModule.greenPaletteColorLookupTableDescriptor = getLutDescriptor(
dataSet,
'x00281102'
);
imagePixelModule.bluePaletteColorLookupTableDescriptor = getLutDescriptor(
dataSet,
'x00281103'
);
// The first Palette Color Lookup Table Descriptor value is the number of entries in the lookup table.
// When the number of table entries is equal to 2ˆ16 then this value shall be 0.
// See http://dicom.nema.org/MEDICAL/DICOM/current/output/chtml/part03/sect_C.7.6.3.html#sect_C.7.6.3.1.5
if (imagePixelModule.redPaletteColorLookupTableDescriptor[0] === 0) {
imagePixelModule.redPaletteColorLookupTableDescriptor[0] = 65536;
imagePixelModule.greenPaletteColorLookupTableDescriptor[0] = 65536;
imagePixelModule.bluePaletteColorLookupTableDescriptor[0] = 65536;
}
// The third Palette Color Lookup Table Descriptor value specifies the number of bits for each entry in the Lookup Table Data.
// It shall take the value of 8 or 16.
// The LUT Data shall be stored in a format equivalent to 8 bits allocated when the number of bits for each entry is 8, and 16 bits allocated when the number of bits for each entry is 16, where in both cases the high bit is equal to bits allocated-1.
// The third value shall be identical for each of the Red, Green and Blue Palette Color Lookup Table Descriptors.
//
// Note: Some implementations have encoded 8 bit entries with 16 bits allocated, padding the high bits;
// this can be detected by comparing the number of entries specified in the LUT Descriptor with the actual value length of the LUT Data entry.
// The value length in bytes should equal the number of entries if bits allocated is 8, and be twice as long if bits allocated is 16.
const numLutEntries =
imagePixelModule.redPaletteColorLookupTableDescriptor[0];
const lutData = dataSet.elements.x00281201;
const lutBitsAllocated = lutData.length === numLutEntries ? 8 : 16;
// If the descriptors do not appear to have the correct values, correct them
if (
imagePixelModule.redPaletteColorLookupTableDescriptor[2] !==
lutBitsAllocated
) {
imagePixelModule.redPaletteColorLookupTableDescriptor[2] = lutBitsAllocated;
imagePixelModule.greenPaletteColorLookupTableDescriptor[2] =
lutBitsAllocated;
imagePixelModule.bluePaletteColorLookupTableDescriptor[2] =
lutBitsAllocated;
}
imagePixelModule.redPaletteColorLookupTableData = getLutData(
dataSet,
'x00281201',
imagePixelModule.redPaletteColorLookupTableDescriptor
);
imagePixelModule.greenPaletteColorLookupTableData = getLutData(
dataSet,
'x00281202',
imagePixelModule.greenPaletteColorLookupTableDescriptor
);
imagePixelModule.bluePaletteColorLookupTableData = getLutData(
dataSet,
'x00281203',
imagePixelModule.bluePaletteColorLookupTableDescriptor
);
}
function metaDataProvider(type, imageId) {
const parsedImageId = parseImageId(imageId);
const dataSet = cornerstoneWADOImageLoader.wadouri.dataSetCacheManager.get(parsedImageId.url);
@@ -100,7 +202,7 @@ function metaDataProvider(type, imageId) {
};
}
if (type === 'imagePixelModule') {
return {
const imagePixelModule = {
samplesPerPixel: dataSet.uint16('x00280002'),
photometricInterpretation: dataSet.string('x00280004'),
rows: dataSet.uint16('x00280010'),
@@ -110,16 +212,41 @@ function metaDataProvider(type, imageId) {
highBit: dataSet.uint16('x00280102'),
pixelRepresentation: dataSet.uint16('x00280103'),
planarConfiguration: dataSet.uint16('x00280006'),
pixelAspectRatio: dataSet.uint16('x00280034'),
smallestPixelValue: null,
largestPixelValue: null,
redPaletteColorLookupTableDescriptor: dataSet.string('x00281101'),
greenPaletteColorLookupTableDescriptor: dataSet.string('x00281102'),
bluePaletteColorLookupTableDescriptor: dataSet.string('x00281103'),
redPaletteColorLookupTableData: dataSet.string('x00281201'),
greenPaletteColorLookupTableData: dataSet.string('x00281202'),
bluePaletteColorLookupTableData: dataSet.string('x00281203')
pixelAspectRatio: dataSet.string('x00280034'),
};
populateSmallestLargestPixelValues(dataSet, imagePixelModule);
if (
imagePixelModule.photometricInterpretation === 'PALETTE COLOR' &&
dataSet.elements.x00281101
) {
populatePaletteColorLut(dataSet, imagePixelModule);
}
return imagePixelModule;
}
// if (type === 'imagePixelModule') {
// return {
// samplesPerPixel: dataSet.uint16('x00280002'),
// photometricInterpretation: dataSet.string('x00280004'),
// rows: dataSet.uint16('x00280010'),
// columns: dataSet.uint16('x00280011'),
// bitsAllocated: dataSet.uint16('x00280100'),
// bitsStored: dataSet.uint16('x00280101'),
// highBit: dataSet.uint16('x00280102'),
// pixelRepresentation: dataSet.uint16('x00280103'),
// planarConfiguration: dataSet.uint16('x00280006'),
// pixelAspectRatio: dataSet.uint16('x00280034'),
// smallestPixelValue: null,
// largestPixelValue: null,
// // smallestPixelValue: dataSet.uint16('x00280106'),
// // largestPixelValue: dataSet.uint16('x00280107'),
// redPaletteColorLookupTableDescriptor: dataSet.string('x00281101'),
// greenPaletteColorLookupTableDescriptor: dataSet.string('x00281102'),
// bluePaletteColorLookupTableDescriptor: dataSet.string('x00281103'),
// redPaletteColorLookupTableData: dataSet.string('x00281201'),
// greenPaletteColorLookupTableData: dataSet.string('x00281202'),
// bluePaletteColorLookupTableData: dataSet.string('x00281203')
// }
// }
}
export default metaDataProvider;
-66
View File
@@ -1,66 +0,0 @@
let TYPES = ['word', 'cell', 'slide', 'pdf']
let DOCUMENTTYPE = {
'.doc': TYPES[0],
'.docm': TYPES[0],
'.docx': TYPES[0],
'.dot': TYPES[0],
'.dotm': TYPES[0],
'.dotx': TYPES[0],
'.epub': TYPES[0],
'.fb2': TYPES[0],
'.fodt': TYPES[0],
'.htm': TYPES[0],
'.html': TYPES[0],
'.mht': TYPES[0],
'.mhtml': TYPES[0],
'.odt': TYPES[0],
'.ott': TYPES[0],
'.pages': TYPES[0],
'.rtf': TYPES[0],
'.stw': TYPES[0],
'.sxw': TYPES[0],
'.txt': TYPES[0],
'.wps': TYPES[0],
'.wpt': TYPES[0],
'.xml': TYPES[0],
'.csv': TYPES[1],
'.et': TYPES[1],
'.ett': TYPES[1],
'.fods': TYPES[1],
'.numbers': TYPES[1],
'.ods': TYPES[1],
'.ots': TYPES[1],
'.sxc': TYPES[1],
'.xls': TYPES[1],
'.xlsb': TYPES[1],
'.xlsm': TYPES[1],
'.xlsx': TYPES[1],
'.xlt': TYPES[1],
'.xltm': TYPES[1],
'.xltx': TYPES[1],
'.xml': TYPES[1],
'.dps': TYPES[2],
'.dpt': TYPES[2],
'.fodp': TYPES[2],
'.key': TYPES[2],
'.odp': TYPES[2],
'.otp': TYPES[2],
'.pot': TYPES[2],
'.potm': TYPES[2],
'.potx': TYPES[2],
'.pps': TYPES[2],
'.ppsm': TYPES[2],
'.ppsx': TYPES[2],
'.ppt': TYPES[2],
'.pptm': TYPES[2],
'.pptx': TYPES[2],
'.sxi': TYPES[2],
'.djvu': TYPES[3],
'.docxf': TYPES[3],
'.oform': TYPES[3],
'.oxps': TYPES[3],
'.pdf': TYPES[3],
'.xps': TYPES[3]
}
export default DOCUMENTTYPE
-2
View File
@@ -21,8 +21,6 @@ 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()
@@ -4,160 +4,319 @@
<el-form :inline="true" class="base-search-form">
<!-- 是否需要回执 -->
<el-form-item :label="$t('trials:emailManageCfg:title:isReturnRequired')" v-if="!systemLevel">
<el-select v-model="searchData.IsReturnRequired" clearable style="width: 100px">
<el-option v-for="item of $d.YesOrNo" :value="item.value" :label="item.label" :key="item.id" />
<el-select
v-model="searchData.IsReturnRequired"
clearable
style="width: 100px"
>
<el-option
v-for="item of $d.YesOrNo"
:value="item.value"
:label="item.label"
:key="item.id"
/>
</el-select>
</el-form-item>
<!-- 是否加急 -->
<el-form-item :label="$t('dictionary:email:label:IsUrgent')" v-if="!systemLevel">
<el-select v-model="searchData.IsUrgent" clearable style="width: 100px">
<el-option v-for="item of $d.YesOrNo" :value="item.value" :label="item.label" :key="item.id" />
<el-select
v-model="searchData.IsUrgent"
clearable
style="width: 100px"
>
<el-option
v-for="item of $d.YesOrNo"
:value="item.value"
:label="item.label"
:key="item.id"
/>
</el-select>
</el-form-item>
<!-- 是否启用 -->
<el-form-item :label="$t('trials:emailManageCfg:table:IsEnable')" v-if="!systemLevel">
<el-select v-model="searchData.IsEnable" clearable style="width: 100px">
<el-option v-for="item of $d.YesOrNo" :value="item.value" :label="item.label" :key="item.id" />
<el-select
v-model="searchData.IsEnable"
clearable
style="width: 100px"
>
<el-option
v-for="item of $d.YesOrNo"
:value="item.value"
:label="item.label"
:key="item.id"
/>
</el-select>
</el-form-item>
<el-form-item :label="$t('trials:auditRecord:table:criterion')" v-if="isDistinguishCriteria && !systemLevel">
<el-select v-model="searchData.CriterionTypeEnum" clearable style="width: 100px">
<el-option v-for="item of $d.CriterionType" :value="item.value" :label="item.label" :key="item.id" />
<el-form-item
:label="$t('trials:auditRecord:table:criterion')"
v-if="isDistinguishCriteria && !systemLevel"
>
<el-select
v-model="searchData.CriterionTypeEnum"
clearable
style="width: 100px"
>
<el-option
v-for="item of $d.CriterionType"
:value="item.value"
:label="item.label"
:key="item.id"
/>
</el-select>
</el-form-item>
<el-form-item :label="$t('trials:emailManageCfg:form:BusinessModule')">
<el-select v-model="searchData.BusinessModuleEnum" clearable style="width: 100px">
<el-option v-for="item of $d.BusinessModule" :value="item.value" :label="item.label" :key="item.id" />
<el-select
v-model="searchData.BusinessModuleEnum"
clearable
style="width: 100px"
>
<el-option
v-for="item of $d.BusinessModule"
:value="item.value"
:label="item.label"
:key="item.id"
/>
</el-select>
</el-form-item>
<el-form-item :label="$t('trials:emailManageCfg:form:BusinessScenario')">
<el-select v-model="searchData.BusinessScenarioEnum" clearable style="width: 100px">
<el-option v-for="item of $d.Email_BusinessScenario" :value="item.value" :label="item.label"
:key="item.id" />
<el-form-item
:label="$t('trials:emailManageCfg:form:BusinessScenario')"
>
<el-select
v-model="searchData.BusinessScenarioEnum"
clearable
style="width: 100px"
>
<el-option
v-for="item of $d.Email_BusinessScenario"
:value="item.value"
:label="item.label"
:key="item.id"
/>
</el-select>
</el-form-item>
<el-form-item :label="$t('trials:emailManageCfg:form:ToUserType')">
<el-select v-model="searchData.ToUserType" clearable style="width: 100px">
<el-option v-for="item of UserTypeList" :value="item.value" :label="item.label" :key="item.id" />
<el-select
v-model="searchData.ToUserType"
clearable
style="width: 100px"
>
<el-option
v-for="item of UserTypeList"
:value="item.value"
:label="item.label"
:key="item.id"
/>
</el-select>
</el-form-item>
<el-form-item :label="$t('trials:emailManageCfg:form:EmailUrgent')" v-if="systemLevel === 1">
<el-select v-model="searchData.EmailUrgentEnum" clearable style="width: 100px">
<el-option v-for="item of $d.EmailUrgent" :value="item.value" :label="item.label" :key="item.id" />
<el-form-item
:label="$t('trials:emailManageCfg:form:EmailUrgent')"
v-if="systemLevel === 1"
>
<el-select
v-model="searchData.EmailUrgentEnum"
clearable
style="width: 100px"
>
<el-option
v-for="item of $d.EmailUrgent"
:value="item.value"
:label="item.label"
:key="item.id"
/>
</el-select>
</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">
<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" @click="handleExport">
{{ $t('common:button:export') }}
</el-button>
<!-- <el-button
</el-form>
<span style="margin-left: auto">
<el-button type="primary" @click="handleExport">
{{ $t('common:button:export') }}
</el-button>
<!-- <el-button
type="primary"
size="mini"
>
场景配置
</el-button> -->
<el-button type="primary" @click="handleAdd">
{{ $t('common:button:new') }}
</el-button>
</el-form-item>
</el-form>
<el-button type="primary" @click="handleAdd">
{{ $t('common:button:new') }}
</el-button>
</span>
</div>
<!-- 受试者列表 -->
<el-table v-loading="loading" v-adaptive="{ bottomOffset: 45 }" :data="list" stripe height="100" style="width: 100%"
@sort-change="handleSortByColumn">
<el-table
v-loading="loading"
v-adaptive="{ bottomOffset: 45 }"
:data="list"
stripe
height="100"
style="width: 100%"
@sort-change="handleSortByColumn"
>
<el-table-column type="index" width="40" />
<!-- Code -->
<el-table-column prop="Code" :label="$t('trials:emailManageCfg:title:code')" sortable="custom"
show-overflow-tooltip min-width="100" />
<el-table-column v-if="isDistinguishCriteria" prop="TrialReadingCriterionId"
:label="$t('trials:reviewTrack:table:criterionName')" show-overflow-tooltip sortable="custom" min-width="120">
<el-table-column
prop="Code"
:label="$t('trials:emailManageCfg:title:code')"
sortable="custom"
show-overflow-tooltip
min-width="100"
/>
<el-table-column
v-if="isDistinguishCriteria"
prop="TrialReadingCriterionId"
:label="$t('trials:reviewTrack:table:criterionName')"
show-overflow-tooltip
sortable="custom"
min-width="120"
>
<template slot-scope="scope">
{{ $fd('CriterionType', scope.row.CriterionTypeEnum) }}
</template>
</el-table-column>
<!-- 邮件主题中文 -->
<el-table-column prop="EmailTopicCN" :label="$t('trials:emailManageCfg:table:EmailTopicCN')" sortable="custom"
show-overflow-tooltip min-width="160" />
<el-table-column
prop="EmailTopicCN"
:label="$t('trials:emailManageCfg:table:EmailTopicCN')"
sortable="custom"
show-overflow-tooltip
min-width="160"
/>
<!-- 邮件主题英文 -->
<el-table-column prop="EmailTopic" :label="$t('trials:emailManageCfg:table:EmailTopic')" sortable="custom"
show-overflow-tooltip min-width="160" />
<el-table-column
prop="EmailTopic"
:label="$t('trials:emailManageCfg:table:EmailTopic')"
sortable="custom"
show-overflow-tooltip
min-width="160"
/>
<!-- 业务层级 -->
<el-table-column prop="BusinessLevelEnum" :label="$t('dictionary:email:label:businessLevel')" sortable="custom"
show-overflow-tooltip min-width="150">
<el-table-column
prop="BusinessLevelEnum"
:label="$t('dictionary:email:label:businessLevel')"
sortable="custom"
show-overflow-tooltip
min-width="150"
>
<template slot-scope="scope">
{{ $fd('BusinessLevel', scope.row.BusinessLevelEnum) }}
</template>
</el-table-column>
<!-- 业务模块 -->
<el-table-column prop="BusinessModuleEnum" :label="$t('dictionary:email:label:businessModule')" sortable="custom"
show-overflow-tooltip min-width="160">
<el-table-column
prop="BusinessModuleEnum"
:label="$t('dictionary:email:label:businessModule')"
sortable="custom"
show-overflow-tooltip
min-width="160"
>
<template slot-scope="scope">
{{ $fd('BusinessModule', scope.row.BusinessModuleEnum) }}
</template>
</el-table-column>
<!-- 业务场景 -->
<el-table-column prop="BusinessScenarioEnum" :label="$t('trials:emailManageCfg:table:BusinessScenarioEnum')"
sortable="custom" show-overflow-tooltip min-width="130">
<el-table-column
prop="BusinessScenarioEnum"
:label="$t('trials:emailManageCfg:table:BusinessScenarioEnum')"
sortable="custom"
show-overflow-tooltip
min-width="130"
>
<template slot-scope="scope">
{{ $fd('Email_BusinessScenario', scope.row.BusinessScenarioEnum) }}
</template>
</el-table-column>
<!-- 收件人v-if="systemLevel !== 1" -->
<el-table-column prop="ToUserTypeList" :label="$t('trials:emailManageCfg:title:toUserTypeList')"
show-overflow-tooltip min-width="100">
<el-table-column
prop="ToUserTypeList"
:label="$t('trials:emailManageCfg:title:toUserTypeList')"
show-overflow-tooltip
min-width="100"
>
<template slot-scope="scope">
{{
scope.row.ToUserTypeList.length > 0
? scope.row.ToUserTypeList.map((v) => $fd('UserType', v)).join(
'、'
)
'、'
)
: ''
}}
</template>
</el-table-column>
<!-- 抄送人v-if="!systemLevel" -->
<el-table-column prop="CopyUserTypeList" :label="$t('trials:emailManageCfg:title:copyUserTypeList')"
show-overflow-tooltip min-width="100">
<el-table-column
prop="CopyUserTypeList"
:label="$t('trials:emailManageCfg:title:copyUserTypeList')"
show-overflow-tooltip
min-width="100"
>
<template slot-scope="scope">
{{
scope.row.CopyUserTypeList.length > 0
? scope.row.CopyUserTypeList.map((v) => $fd('UserType', v)).join(
'、'
)
'、'
)
: ''
}}
</template>
</el-table-column>
<!-- 加急状态 -->
<el-table-column prop="EmailUrgentEnum" :label="$t('dictionary:email:label:IsUrgent')" sortable="custom"
show-overflow-tooltip min-width="110">
<el-table-column
prop="EmailUrgentEnum"
:label="$t('dictionary:email:label:IsUrgent')"
sortable="custom"
show-overflow-tooltip
min-width="110"
>
<template slot-scope="scope">
{{ $fd('EmailUrgent', scope.row.EmailUrgentEnum) }}
</template>
</el-table-column>
<!-- 发送周期和时间 -->
<el-table-column prop="EmailCron" :label="$t('trials:emailManageCfg:table:EmailCron')" sortable="custom"
show-overflow-tooltip min-width="180" />
<el-table-column
prop="EmailCron"
:label="$t('trials:emailManageCfg:table:EmailCron')"
sortable="custom"
show-overflow-tooltip
min-width="180"
/>
<!-- 附件 -->
<el-table-column prop="FileName" :label="$t('trials:emailManageCfg:title:fileName')" show-overflow-tooltip
min-width="100" v-if="!systemLevel">
<el-table-column
prop="FileName"
:label="$t('trials:emailManageCfg:title:fileName')"
show-overflow-tooltip
min-width="100"
v-if="!systemLevel"
>
<template slot-scope="scope">
<el-button v-if="scope.row.FilePath" type="text" @click="handlePreview(scope.row.FilePath)">
<el-button
v-if="scope.row.FilePath"
type="text"
@click="handlePreview(scope.row.FilePath)"
>
{{ scope.row.FileName }}
</el-button>
</template>
</el-table-column>
<!-- 是否需要回执 -->
<el-table-column prop="IsReturnRequired" :label="$t('trials:emailManageCfg:title:isReturnRequired')"
show-overflow-tooltip sortable="custom" min-width="160" v-if="!systemLevel">
<el-table-column
prop="IsReturnRequired"
:label="$t('trials:emailManageCfg:title:isReturnRequired')"
show-overflow-tooltip
sortable="custom"
min-width="160"
v-if="!systemLevel"
>
<template slot-scope="scope">
<el-tag v-if="scope.row.IsReturnRequired" type="danger">
{{ $fd('YesOrNo', scope.row.IsReturnRequired) }}
@@ -168,8 +327,14 @@
</template>
</el-table-column>
<!-- 是否自动发送 -->
<el-table-column prop="IsAutoSend" :label="$t('trials:emailManageCfg:title:isAutoSend')" show-overflow-tooltip
sortable="custom" min-width="160" v-if="!systemLevel">
<el-table-column
prop="IsAutoSend"
:label="$t('trials:emailManageCfg:title:isAutoSend')"
show-overflow-tooltip
sortable="custom"
min-width="160"
v-if="!systemLevel"
>
<template slot-scope="scope">
<el-tag v-if="scope.row.IsAutoSend" type="danger">
{{ $fd('YesOrNo', scope.row.IsAutoSend) }}
@@ -179,8 +344,14 @@
}}</el-tag>
</template>
</el-table-column>
<el-table-column prop="IsEnable" :label="$t('trials:emailManageCfg:table:IsEnable')" show-overflow-tooltip
sortable="custom" min-width="160" v-if="!systemLevel">
<el-table-column
prop="IsEnable"
:label="$t('trials:emailManageCfg:table:IsEnable')"
show-overflow-tooltip
sortable="custom"
min-width="160"
v-if="!systemLevel"
>
<template slot-scope="scope">
<el-tag v-if="scope.row.IsEnable" type="danger">
{{ $fd('YesOrNo', scope.row.IsEnable) }}
@@ -191,12 +362,22 @@
</template>
</el-table-column>
<!-- 更新时间 -->
<el-table-column prop="UpdateTime" :label="$t('trials:emailManageCfg:title:updateTime')" show-overflow-tooltip
sortable="custom" min-width="160" />
<el-table-column
prop="UpdateTime"
:label="$t('trials:emailManageCfg:title:updateTime')"
show-overflow-tooltip
sortable="custom"
min-width="160"
/>
<!-- 创建时间 -->
<el-table-column prop="CreateTime" :label="$t('trials:emailManageCfg:title:createTime')" show-overflow-tooltip
sortable="custom" min-width="160" />
<el-table-column :label="$t('common:action:action')" min-width="180" fixed="right">
<el-table-column
prop="CreateTime"
:label="$t('trials:emailManageCfg:title:createTime')"
show-overflow-tooltip
sortable="custom"
min-width="160"
/>
<el-table-column label="Action" min-width="180" fixed="right">
<template slot-scope="scope">
<el-button type="text" @click="handleEdit(scope.row)">
{{ $t('common:button:edit') }}
@@ -205,38 +386,77 @@
<el-button type="text" @click="handleDelete(scope.row)">
{{ $t('common:button:delete') }}
</el-button>
<el-button type="text" @click="
preview(scope.row.EmailHtmlContentCN, scope.row.EmailHtmlContent)
">{{ $t('common:button:preview') }}</el-button>
<el-button
type="text"
@click="
preview(scope.row.EmailHtmlContentCN, scope.row.EmailHtmlContent)
"
>{{ $t('common:button:preview') }}</el-button>
</template>
</el-table-column>
</el-table>
<!-- 分页组件 -->
<pagination class="page" :total="total" :page.sync="searchData.PageIndex" :limit.sync="searchData.PageSize"
@pagination="getList" />
<pagination
class="page"
:total="total"
:page.sync="searchData.PageIndex"
:limit.sync="searchData.PageSize"
@pagination="getList"
/>
<!-- 搜索框 -->
<!-- 修改受试者状态 -->
<el-dialog v-if="editVisible" :visible.sync="editVisible" :close-on-click-modal="false" :title="title" width="700px"
fullscreen custom-class="base-dialog-wrapper">
<EmailForm :data="rowData" :system-level="systemLevel" :isDistinguishCriteria="isDistinguishCriteria"
@closeDialog="closeDialog" @getList="getList" @PreviewHTML="preview" />
<el-dialog
v-if="editVisible"
:visible.sync="editVisible"
:close-on-click-modal="false"
:title="title"
width="700px"
fullscreen
custom-class="base-dialog-wrapper"
>
<EmailForm
:data="rowData"
:system-level="systemLevel"
:isDistinguishCriteria="isDistinguishCriteria"
@closeDialog="closeDialog"
@getList="getList"
@PreviewHTML="preview"
/>
</el-dialog>
<!-- 修改受试者状态 -->
<el-dialog v-if="attachmentVisible" :visible.sync="attachmentVisible" :close-on-click-modal="false"
:title="$t('trials:emailManageCfg:title:fileName')" width="80%" custom-class="base-dialog-wrapper" append-to-body>
<AttachmentList :business-scenario-enum="rowData.BusinessScenarioEnum"
:is-distinguish-criteria="rowData.IsDistinguishCriteria" @getList="getList" />
<el-dialog
v-if="attachmentVisible"
:visible.sync="attachmentVisible"
:close-on-click-modal="false"
:title="$t('trials:emailManageCfg:title:fileName')"
width="80%"
custom-class="base-dialog-wrapper"
append-to-body
>
<AttachmentList
:business-scenario-enum="rowData.BusinessScenarioEnum"
:is-distinguish-criteria="rowData.IsDistinguishCriteria"
@getList="getList"
/>
</el-dialog>
<!-- 预览模板 -->
<el-dialog v-if="previewVisible" :visible.sync="previewVisible" :close-on-click-modal="false"
:title="$t('common:button:preview')" fullscreen custom-class="base-dialog-wrapper">
<div style="
<el-dialog
v-if="previewVisible"
:visible.sync="previewVisible"
:close-on-click-modal="false"
:title="$t('common:button:preview')"
fullscreen
custom-class="base-dialog-wrapper"
>
<div
style="
display: flex;
align-items: flex-start;
justify-content: space-around;
flex-wrap: wrap;
">
"
>
<div style="min-width: 50%">
<!-- 邮件内容模版CN -->
<h3>{{ $t('dictionary:email:title:title1') }}</h3>
@@ -410,8 +630,3 @@ export default {
},
}
</script>
<style lang="scss" scoped>
.box-body .search .base-search-form .el-form-item {
margin-bottom: 10px;
}
</style>
+67 -24
View File
@@ -9,36 +9,71 @@
<!-- Reset Password -->
<div class="box-wrapper" v-if="active === 0">
<el-form ref="resetForm" v-loading="formLoading" :model="form" label-width="130px" :rules="rules"
class="demo-ruleForm" size="small">
<el-form
ref="resetForm"
v-loading="formLoading"
:model="form"
label-width="130px"
:rules="rules"
class="demo-ruleForm"
size="small"
>
<!-- 邮箱 -->
<el-form-item :label="$t('passwordReset:form:email')" prop="EmailOrPhone">
<el-form-item
:label="$t('passwordReset:form:email')"
prop="EmailOrPhone"
>
<el-col :span="18">
<el-input v-model="form.EmailOrPhone" autocomplete="off" @change="handleEmailChange" />
<el-input
v-model="form.EmailOrPhone"
autocomplete="off"
@change="handleEmailChange"
/>
</el-col>
</el-form-item>
<!-- 验证码 -->
<el-form-item :label="$t('trials:researchForm:form:verifyCode')" required>
<el-form-item
:label="$t('trials:researchForm:form:verifyCode')"
required
>
<el-col :span="18">
<el-form-item prop="VerificationCode">
<el-input v-model="form.VerificationCode" autocomplete="off" />
</el-form-item>
</el-col>
<el-col :span="6" style="text-align: right">
<el-button size="small" type="primary" style="width: 80%" :disabled="sendDisabled"
@click="handleSendCode">{{ sendTitle }}</el-button>
<el-button
size="small"
type="primary"
style="width: 80%"
:disabled="sendDisabled"
@click="handleSendCode"
>{{ sendTitle }}</el-button
>
</el-col>
</el-form-item>
</el-form>
<!-- 校验 -->
<el-button size="small" type="primary" style="width: 50%; margin: auto; display: block"
:disabled="form.VerificationCode === '' || form.EmailOrPhone === ''" @click="verifyCode">
<el-button
size="small"
type="primary"
style="width: 50%; margin: auto; display: block"
:disabled="form.VerificationCode === '' || form.EmailOrPhone === ''"
@click="verifyCode"
>
{{ $t('passwordReset:button:verify') }}
</el-button>
</div>
<div class="box-wrapper" v-show="active === 1">
<el-form ref="resetForm2" v-loading="formLoading" :model="form"
:label-width="$i18n.locale === 'en' ? '180px' : '100px'" :rules="rules2" class="demo-ruleForm" size="small">
<el-form
ref="resetForm2"
v-loading="formLoading"
:model="form"
:label-width="$i18n.locale === 'en' ? '180px' : '100px'"
:rules="rules2"
class="demo-ruleForm"
size="small"
>
<!-- 用户名 -->
<el-form-item :label="$t('passwordReset:form:userName')" prop="UserId">
<el-input v-model="form.UserName" disabled />
@@ -70,17 +105,27 @@
<el-input v-model="form.UserType" disabled />
</el-form-item> -->
<!-- 新密码 -->
<el-form-item class="my_new_pwd" :label="$t('passwordReset:form:password')" prop="NewPwd"
style="position: relative">
<el-form-item
class="my_new_pwd"
:label="$t('passwordReset:form:password')"
prop="NewPwd"
style="position: relative"
>
<el-input v-model="form.NewPwd" show-password autocomplete="off" />
<span style="position: absolute; right: -30px">
<el-tooltip :content="$t('passwordReset:form:passwordCentent')" placement="top">
<el-tooltip
:content="$t('passwordReset:form:passwordCentent')"
placement="top"
>
<i class="el-icon-question" />
</el-tooltip>
</span>
</el-form-item>
<!-- 确认密码 -->
<el-form-item :label="$t('passwordReset:form:confirmPassword')" prop="CheckPass">
<el-form-item
:label="$t('passwordReset:form:confirmPassword')"
prop="CheckPass"
>
<el-input v-model="form.CheckPass" show-password autocomplete="off" />
</el-form-item>
</el-form>
@@ -90,7 +135,12 @@
{{ $t('passwordReset:button:cancel') }}
</el-button>
<!-- 提交 -->
<el-button size="small" type="primary" @click="onSubmit" style="width: 46%">
<el-button
size="small"
type="primary"
@click="onSubmit"
style="width: 46%"
>
{{ $t('passwordReset:button:submit') }}
</el-button>
</div>
@@ -338,14 +388,10 @@ export default {
}
},
onCancel() {
// this.$refs['resetForm'].resetFields()
this.$refs['resetForm'].resetFields()
Object.keys(this.form).forEach((key) => {
this.form[key] = ''
})
this.sendDisabled = false
this.sendTitle = this.$t('passwordReset:button:send')
countdown = 60
clearTimeout(timer)
this.active = 0
},
goBack() {
@@ -358,14 +404,12 @@ export default {
.reset-wrapper {
padding: 20px;
}
.reset-wrapper .el-page-header {
line-height: 50px;
border: 1px solid #ebeef5;
border-radius: 4px;
background-color: #fff;
}
.reset-wrapper .box-wrapper {
width: 700px;
margin: 20px auto;
@@ -381,7 +425,6 @@ export default {
.is-error.my_new_pwd {
margin-bottom: 45px;
}
.flexBox {
display: flex;
justify-content: center;
+159 -82
View File
@@ -2,76 +2,152 @@
<div class="log">
<div ref="leftContainer" class="left">
<el-form :inline="true">
<el-form-item :label="$t('system:loginLog:label:OptType')" prop="OptType">
<el-select v-model="searchData.OptTypeList" clearable style="width: 200px" multiple :collapse-tags="true">
<el-option v-for="item of $d.UserOptType" :key="'UserOptType' + item.label" :value="item.value"
:label="item.label" />
<el-form-item
:label="$t('system:loginLog:label:OptType')"
prop="OptType"
>
<el-select
v-model="searchData.OptType"
clearable
style="width: 120px"
>
<el-option
v-for="item of $d.UserOptType"
:key="'UserOptType' + item.label"
:value="item.value"
:label="item.label"
/>
</el-select>
</el-form-item>
<el-form-item label="IP" prop="IP">
<el-input v-model="searchData.IP" size="small" clearable style="width: 120px" />
<el-input
v-model="searchData.IP"
size="small"
clearable
style="width: 120px"
/>
</el-form-item>
<el-form-item :label="$t('system:loginLog:label:LoginFaildName')" prop="LoginFaildName">
<el-input v-model="searchData.LoginFaildName" size="small" clearable style="width: 120px" />
<el-form-item
:label="$t('system:loginLog:label:LoginFaildName')"
prop="LoginFaildName"
>
<el-input
v-model="searchData.LoginFaildName"
size="small"
clearable
style="width: 120px"
/>
</el-form-item>
<el-form-item :label="$t('system:loginLog:table:LoginUserName')" prop="LoginFaildName">
<el-input v-model="searchData.LoginUserName" size="small" clearable style="width: 120px" />
<el-form-item
:label="$t('system:loginLog:table:LoginUserName')"
prop="LoginFaildName"
>
<el-input
v-model="searchData.LoginUserName"
size="small"
clearable
style="width: 120px"
/>
</el-form-item>
<el-form-item :label="$t('system:loginLog:table:LoginUserType')" prop="LoginUserTypeEnum">
<el-select v-model="searchData.LoginUserTypeEnum" clearable style="width: 120px">
<el-option v-for="item of $d.UserType" :key="'UserType' + item.label" :value="item.value"
:label="item.label" />
</el-select>
</el-form-item>
<el-form-item :label="$t('system:loginLog:label:IsLoginUncommonly')" prop="IsLoginUncommonly ">
<el-select v-model="searchData.IsLoginUncommonly" clearable style="width: 120px">
<el-option v-for="item of $d.YesOrNo" :key="item.id" :value="item.value" :label="item.label" />
<el-form-item
:label="$t('system:loginLog:table:LoginUserType')"
prop="LoginUserTypeEnum"
>
<el-select
v-model="searchData.LoginUserTypeEnum"
clearable
style="width: 120px"
>
<el-option
v-for="item of $d.UserType"
:key="'UserType' + item.label"
:value="item.value"
:label="item.label"
/>
</el-select>
</el-form-item>
<el-form-item :label="$t('system:loginLog:label:CreateTime')">
<el-date-picker v-model="datetimerange" type="datetimerange" value-format="yyyy-MM-dd HH:mm:ss"
:default-time="['00:00:00', '23:59:59']" @change="handleDatetimeChange" style="width: 380px" />
<el-date-picker
v-model="datetimerange"
type="datetimerange"
value-format="yyyy-MM-dd HH:mm:ss"
:default-time="['00:00:00', '23:59:59']"
@change="handleDatetimeChange"
style="width: 380px"
/>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search" @click="getList">
{{ $t('common:button:search') }}
</el-button>
<el-button type="primary" icon="el-icon-refresh-left" @click="handleReset">
<el-button
type="primary"
icon="el-icon-refresh-left"
@click="handleReset"
>
{{ $t('common:button:reset') }}
</el-button>
</el-form-item>
</el-form>
<el-table v-loading="loading" v-adaptive="{ bottomOffset: 45 }" height="100" :data="list" class="table"
@sort-change="handleSortByColumn">
<el-table
v-loading="loading"
v-adaptive="{ bottomOffset: 45 }"
height="100"
:data="list"
class="table"
@sort-change="handleSortByColumn"
>
<el-table-column type="index" width="50">
<template slot-scope="scope">
<span style="
<span
style="
display: flex;
align-items: center;
justify-content: flex-end;
">
<el-tooltip class="item" effect="dark" :content="$t('system:loginLog:label:IsLoginUncommonly')"
placement="top" style="margin-right: 3px" v-if="scope.row.IsIgnoreUncommonly">
<i v-if="scope.row.IsLoginUncommonly" class="el-icon-warning icon-i icon-success"></i>
</el-tooltip>
<el-tooltip class="item" effect="dark" :content="$t('system:loginLog:label:IsLoginUncommonly')"
placement="top" style="margin-right: 3px" v-else-if="scope.row.IsLoginUncommonly">
<i v-if="scope.row.IsLoginUncommonly" class="el-icon-warning icon-i"
@click.stop="setIsIgnoreUncommonly(scope.row)"></i>
"
>
<el-tooltip
class="item"
effect="dark"
:content="$t('system:loginLog:label:IsLoginUncommonly')"
placement="top"
style="margin-right: 3px"
v-if="scope.row.IsLoginUncommonly"
>
<i
v-if="scope.row.IsLoginUncommonly"
class="el-icon-warning icon-i"
></i>
</el-tooltip>
<span>{{ scope.$index + 1 }}</span>
</span>
</template>
</el-table-column>
<el-table-column :label="$t('system:loginLog:table:OptType')" prop="OptType" min-width="150"
show-overflow-tooltip sortable="custom">
<el-table-column
:label="$t('system:loginLog:table:OptType')"
prop="OptType"
min-width="150"
show-overflow-tooltip
sortable="custom"
>
<template slot-scope="scope">
{{ $fd('UserOptType', scope.row.OptType) }}
</template>
</el-table-column>
<el-table-column label="IP" prop="IP" min-width="150" sortable="custom" show-overflow-tooltip />
<el-table-column :label="$t('trials:loginLog:table:IPRegion')" prop="IPRegion" min-width="120"
show-overflow-tooltip sortable="custom" />
<el-table-column
label="IP"
prop="IP"
min-width="150"
sortable="custom"
show-overflow-tooltip
/>
<el-table-column
:label="$t('trials:loginLog:table:IPRegion')"
prop="IPRegion"
min-width="120"
show-overflow-tooltip
sortable="custom"
/>
<!-- <el-table-column
:label="$t('system:loginLog:table:LoginFaildName')"
prop="LoginFaildName"
@@ -79,10 +155,20 @@
show-overflow-tooltip
sortable="custom"
/> -->
<el-table-column :label="$t('system:loginLog:table:LoginUserName')" prop="ActionUserName" min-width="140"
show-overflow-tooltip sortable="custom" />
<el-table-column :label="$t('system:loginLog:table:Aetionlserlype')" prop="ActionUserType" min-width="100"
show-overflow-tooltip sortable="custom" />
<el-table-column
:label="$t('system:loginLog:table:LoginUserName')"
prop="ActionUserName"
min-width="140"
show-overflow-tooltip
sortable="custom"
/>
<el-table-column
:label="$t('system:loginLog:table:Aetionlserlype')"
prop="ActionUserType"
min-width="100"
show-overflow-tooltip
sortable="custom"
/>
<!-- <el-table-column
:label="$t('system:loginLog:table:LoginUserType')"
prop="LoginUserTypeEnum"
@@ -94,8 +180,13 @@
{{ $fd("UserType", scope.row.LoginUserTypeEnum) }}
</template>
</el-table-column> -->
<el-table-column :label="$t('system:loginLog:table:OptUserName')" prop="TargetIdentityUserName" min-width="200"
sortable="custom" show-overflow-tooltip />
<el-table-column
:label="$t('system:loginLog:table:OptUserName')"
prop="TargetIdentityUserName"
min-width="200"
sortable="custom"
show-overflow-tooltip
/>
<!-- <el-table-column
:label="$t('system:loginLog:table:OptUserType')"
prop="OptUserTypeEnum"
@@ -107,36 +198,51 @@
{{ $fd("UserType", scope.row.OptUserTypeEnum) }}
</template>
</el-table-column> -->
<el-table-column :label="$t('system:loginLog:table:detail')" min-width="120" show-overflow-tooltip>
<el-table-column
:label="$t('system:loginLog:table:detail')"
min-width="120"
show-overflow-tooltip
>
<template slot-scope="scope">
<el-button v-if="scope.row.JsonObj" type="text" @click="handleOpenDialog(scope.row)">
<el-button
v-if="scope.row.JsonObj"
type="text"
@click="handleOpenDialog(scope.row)"
>
<span>{{ $t('system:loginLog:message:detail') }}</span>
</el-button>
</template>
</el-table-column>
<el-table-column :label="$t('system:loginLog:table:CreateTime')" prop="CreateTime" min-width="180"
sortable="custom" show-overflow-tooltip />
<el-table-column
:label="$t('system:loginLog:table:CreateTime')"
prop="CreateTime"
min-width="180"
sortable="custom"
show-overflow-tooltip
/>
</el-table>
<div class="pagination" style="text-align: right; margin-top: 5px">
<pagination :total="total" :page.sync="searchData.PageIndex" :limit.sync="searchData.PageSize"
@pagination="getList" />
<pagination
:total="total"
:page.sync="searchData.PageIndex"
:limit.sync="searchData.PageSize"
@pagination="getList"
/>
</div>
</div>
<detail :config="config" :JsonObj="JsonObj" />
</div>
</template>
<script>
import { getUserLogList, setIsIgnoreUncommonly } from '@/api/user'
import { getUserLogList } from '@/api/user'
import Pagination from '@/components/Pagination'
import detail from './detail.vue'
import moment from 'moment'
const searchDataDefault = () => {
return {
OptType: null,
OptTypeList: [],
Ip: '',
LoginFaildName: '',
IsLoginUncommonly: null,
LoginUserName: '',
LoginUserTypeEnum: null,
BeginDate: '',
@@ -170,26 +276,6 @@ export default {
this.getList()
},
methods: {
// 忽略异地登录
async setIsIgnoreUncommonly(row) {
try {
let confirm = await this.$confirm(this.$t("system:loginLog:confirmMessage:setIsIgnoreUncommonly"))
if (!confirm) return false
let data = {
IsIgnoreUncommonly: true,
Id: row.Id
}
this.loading = true
let res = await setIsIgnoreUncommonly(data)
this.loading = false
if (res.IsSuccess) {
this.getList()
}
} catch (err) {
this.loading = false
console.log(err)
}
},
handleOpenDialog(row) {
if (!row.JsonObj)
return this.$message.warning(this.$t('system:loginLog:message:noJSON'))
@@ -248,37 +334,28 @@ export default {
display: flex;
padding: 10px;
border-radius: 5px;
.left {
display: flex;
flex-direction: column;
width: 0;
flex-grow: 4;
// border-right: 1px solid #ccc;
.filter-container {
display: flex;
align-items: center;
margin: 5px;
}
.data-table {
flex: 1;
padding: 5px 0px;
}
.pagination-container {
text-align: right;
}
}
.icon-i {
color: #f56c6c;
cursor: pointer;
}
.icon-success {
color: #67C23A
}
}
</style>
+559 -181
View File
@@ -9,28 +9,64 @@
</el-form-item>
<!-- 研究方案号 -->
<el-form-item :label="$t('trials:trials-list:table:researchNumber')">
<el-input v-model="searchData.ResearchProgramNo" style="width: 100px" clearable />
<el-input
v-model="searchData.ResearchProgramNo"
style="width: 100px"
clearable
/>
</el-form-item>
<!-- 试验名称 -->
<el-form-item :label="$t('trials:trials-list:table:experimentName')">
<el-input v-model="searchData.ExperimentName" style="width: 100px" clearable />
<el-input
v-model="searchData.ExperimentName"
style="width: 100px"
clearable
/>
</el-form-item>
<!-- Sponsor -->
<el-form-item :label="$t('trials:trials-list:table:sponsor')">
<el-select v-model="searchData.SponsorId" style="width: 150px" clearable>
<el-option v-for="item in sponsorList" :key="item.Id" :label="item.SponsorName" :value="item.Id" />
<el-select
v-model="searchData.SponsorId"
style="width: 150px"
clearable
>
<el-option
v-for="item in sponsorList"
:key="item.Id"
:label="item.SponsorName"
:value="item.Id"
/>
</el-select>
</el-form-item>
<!-- 阅片标准 -->
<el-form-item v-if="hasPermi(['role:ir'])" :label="$t('trials:trials-list:table:IR_ReadingCriterionList')">
<el-select v-model="searchData.CriterionType" style="width: 150px" clearable>
<el-option v-for="item in $d.CriterionType" :key="item.id" :label="item.label" :value="item.value" />
<el-form-item
v-if="hasPermi(['role:ir'])"
:label="$t('trials:trials-list:table:IR_ReadingCriterionList')"
>
<el-select
v-model="searchData.CriterionType"
style="width: 150px"
clearable
>
<el-option
v-for="item in $d.CriterionType"
:key="item.id"
:label="item.label"
:value="item.value"
/>
</el-select>
</el-form-item>
<!-- 联系人 -->
<el-form-item v-if="hasPermi(['role:ir'])" :label="$t('trials:trials-list:table:IR_PMEmailList')">
<el-input v-model="searchData.PM_EMail" style="width: 100px" clearable />
<el-form-item
v-if="hasPermi(['role:ir'])"
:label="$t('trials:trials-list:table:IR_PMEmailList')"
>
<el-input
v-model="searchData.PM_EMail"
style="width: 100px"
clearable
/>
</el-form-item>
<el-form-item>
<!-- <el-button type="text" @click="isShow = !isShow">More</el-button> -->
@@ -39,19 +75,33 @@
{{ $t('common:button:search') }}
</el-button>
<!-- Reset -->
<el-button type="primary" icon="el-icon-refresh-left" @click="handleReset">
<el-button
type="primary"
icon="el-icon-refresh-left"
@click="handleReset"
>
{{ $t('common:button:reset') }}
</el-button>
<!-- Export -->
<el-button v-hasPermi="['trials:trials-list:export']" type="primary" icon="el-icon-download"
:loading="exportLoading" @click="handleExportTrial">
<el-button
v-hasPermi="['trials:trials-list:export']"
type="primary"
icon="el-icon-download"
:loading="exportLoading"
@click="handleExportTrial"
>
{{ $t('common:button:export') }}
</el-button>
</el-form-item>
</el-form>
<span style="margin-left: auto">
<!-- New -->
<el-button v-hasPermi="['trials:trials-list:new']" icon="el-icon-plus" type="primary" @click="handleNew">
<el-button
v-hasPermi="['trials:trials-list:new']"
icon="el-icon-plus"
type="primary"
@click="handleNew"
>
{{ $t('common:button:new') }}
</el-button>
</span>
@@ -62,88 +112,190 @@
<div style="padding: 10px">
<el-form label-width="140px">
<el-form-item label="Trial ID">
<el-input v-model="searchData.Code" placeholder="Trial ID" style="width: 100%" clearable />
<el-input
v-model="searchData.Code"
placeholder="Trial ID"
style="width: 100%"
clearable
/>
</el-form-item>
<el-form-item label="Indication">
<el-input v-model="searchData.Indication" placeholder="Indication" style="width: 100%" clearable />
<el-input
v-model="searchData.Indication"
placeholder="Indication"
style="width: 100%"
clearable
/>
</el-form-item>
<el-form-item label="Assessment Criteria">
<el-select v-model="searchData.CriterionIds" placeholder="Assessment Criteria" style="width: 100%" clearable
multiple>
<el-select
v-model="searchData.CriterionIds"
placeholder="Assessment Criteria"
style="width: 100%"
clearable
multiple
>
<!-- <el-option
v-for="(key,value) of dictionaryList.ReadingStandard"
:key="key"
:label="key"
:value="value"
/> -->
<el-option v-for="item of dict.type.ReadingStandard" :key="item.value" :label="item.label"
:value="item.value" />
<el-option
v-for="item of dict.type.ReadingStandard"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</el-form-item>
<el-form-item label="Sponsor">
<el-select v-model="searchData.SponsorId" placeholder="Sponsor" style="width: 100%" clearable>
<el-option v-for="item in sponsorList" :key="item.Id" :label="item.SponsorName" :value="item.Id" />
<el-select
v-model="searchData.SponsorId"
placeholder="Sponsor"
style="width: 100%"
clearable
>
<el-option
v-for="item in sponsorList"
:key="item.Id"
:label="item.SponsorName"
:value="item.Id"
/>
</el-select>
</el-form-item>
<el-form-item label="CRO">
<el-select v-model="searchData.CROId" placeholder="CRO" style="width: 100%" clearable>
<el-option v-for="item of croList" :key="item.Id" :label="item.CROName" :value="item.Id" />
<el-select
v-model="searchData.CROId"
placeholder="CRO"
style="width: 100%"
clearable
>
<el-option
v-for="item of croList"
:key="item.Id"
:label="item.CROName"
:value="item.Id"
/>
</el-select>
</el-form-item>
<el-form-item label="Phase">
<el-select v-model="searchData.Phase" placeholder="Phase" style="width: 100%" clearable>
<el-option v-for="item in phaseOptions" :key="item.value" :label="item.value" :value="item.value" />
<el-select
v-model="searchData.Phase"
placeholder="Phase"
style="width: 100%"
clearable
>
<el-option
v-for="item in phaseOptions"
:key="item.value"
:label="item.value"
:value="item.value"
/>
</el-select>
</el-form-item>
<el-form-item label="ReviewType">
<el-select v-model="searchData.ReviewTypeIds" placeholder="ReviewType" style="width: 100%" clearable
multiple>
<el-select
v-model="searchData.ReviewTypeIds"
placeholder="ReviewType"
style="width: 100%"
clearable
multiple
>
<!-- <el-option
v-for="(key,value) of dictionaryList.ReviewType"
:key="key"
:label="key"
:value="value"
/> -->
<el-option v-for="item of dict.type.ReviewType" :key="item.value" :label="item.label"
:value="item.value" />
<el-option
v-for="item of dict.type.ReviewType"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</el-form-item>
<el-form-item label="Modality">
<el-select v-model="searchData.ModalityIds" multiple placeholder="Modality" style="width: 100%" clearable>
<el-select
v-model="searchData.ModalityIds"
multiple
placeholder="Modality"
style="width: 100%"
clearable
>
<!-- <el-option
v-for="(key,value) of dictionaryList.ReadingType"
:key="key"
:label="key"
:value="value"
/> -->
<el-option v-for="item of dict.type.ReadingType" :key="item.value" :label="item.label"
:value="item.value" />
<el-option
v-for="item of dict.type.ReadingType"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</el-form-item>
<el-form-item label="Expedited: ">
<el-select v-model="searchData.Expedited" value-key="value" clearable style="width: 100%">
<el-option v-for="item in expeditedOption" :key="item.value" :label="item.label" :value="item.value" />
<el-select
v-model="searchData.Expedited"
value-key="value"
clearable
style="width: 100%"
>
<el-option
v-for="item in expeditedOption"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</el-form-item>
<el-form-item label="BeginDate: ">
<el-date-picker v-model="searchData.BeginDate" value-format="yyyy-MM-dd" format="yyyy-MM-dd" type="date"
:picker-options="beginPickerOption" :clearable="false" style="width: 100%" />
<el-date-picker
v-model="searchData.BeginDate"
value-format="yyyy-MM-dd"
format="yyyy-MM-dd"
type="date"
:picker-options="beginPickerOption"
:clearable="false"
style="width: 100%"
/>
</el-form-item>
<el-form-item label="EndDate: ">
<el-date-picker v-model="searchData.EndDate" value-format="yyyy-MM-dd" format="yyyy-MM-dd" type="date"
:picker-options="endpickerOption" :clearable="false" style="width: 100%" />
<el-date-picker
v-model="searchData.EndDate"
value-format="yyyy-MM-dd"
format="yyyy-MM-dd"
type="date"
:picker-options="endpickerOption"
:clearable="false"
style="width: 100%"
/>
</el-form-item>
<el-form-item label="Attended Reviewer Type:">
<el-select v-model="searchData.AttendedReviewerType" placeholder="Attended Reviewer Type"
style="width: 100%" clearable>
<el-option v-for="item of $d.AttendedReviewerType" :key="item.value" :label="item.label"
:value="item.value" />
<el-select
v-model="searchData.AttendedReviewerType"
placeholder="Attended Reviewer Type"
style="width: 100%"
clearable
>
<el-option
v-for="item of $d.AttendedReviewerType"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="handleSelectSearch">Search</el-button>
<el-button type="primary" @click="handleSelectSearch"
>Search</el-button
>
<el-button type="primary" @click="handleReset">Reset</el-button>
<el-button type="primary" @click="isShow = false">Back</el-button>
</el-form-item>
@@ -153,89 +305,219 @@
<!-- 项目列表 -->
<template slot="main-container">
<el-table v-adaptive="{ bottomOffset: 60 }" v-loading="listLoading" :data="list" stripe height="100"
@selection-change="handleSelectChange" @sort-change="handleSortChange" @row-click="rowClick">
<el-table
v-adaptive="{ bottomOffset: 60 }"
v-loading="listLoading"
:data="list"
stripe
height="100"
@selection-change="handleSelectChange"
@sort-change="handleSortChange"
@row-click="rowClick"
>
<el-table-column type="selection" align="left" width="45" />
<el-table-column type="index" width="40" align="left" />
<el-table-column prop="TrialCode" :label="$t('trials:trials-list:table:trialId')" show-overflow-tooltip
sortable="custom" width="120" />
<el-table-column prop="ResearchProgramNo" :label="$t('trials:trials-list:table:researchNumber')"
show-overflow-tooltip sortable="custom" min-width="160" />
<el-table-column
prop="TrialCode"
:label="$t('trials:trials-list:table:trialId')"
show-overflow-tooltip
sortable="custom"
width="120"
/>
<el-table-column
prop="ResearchProgramNo"
:label="$t('trials:trials-list:table:researchNumber')"
show-overflow-tooltip
sortable="custom"
min-width="160"
/>
<el-table-column prop="ExperimentName" :label="$t('trials:trials-list:table:experimentName')"
show-overflow-tooltip sortable="custom" min-width="240" />
<el-table-column prop="Sponsor" :label="$t('trials:trials-list:table:sponsor')" show-overflow-tooltip
sortable="custom" min-width="120" />
<el-table-column prop="TrialStatusStr" :label="$t('trials:trials-list:table:status')" show-overflow-tooltip
sortable="custom" min-width="120">
<el-table-column
prop="ExperimentName"
:label="$t('trials:trials-list:table:experimentName')"
show-overflow-tooltip
sortable="custom"
min-width="240"
/>
<el-table-column
prop="Sponsor"
:label="$t('trials:trials-list:table:sponsor')"
show-overflow-tooltip
sortable="custom"
min-width="120"
/>
<el-table-column
prop="TrialStatusStr"
:label="$t('trials:trials-list:table:status')"
show-overflow-tooltip
sortable="custom"
min-width="120"
>
<template slot-scope="scope">
<el-tag v-if="scope.row.TrialStatusStr === 'Initializing'" type="info">{{ $fd('TrialStatusEnum',
scope.row.TrialStatusStr) }}</el-tag>
<el-tag v-if="scope.row.TrialStatusStr === 'Ongoing'" type="primary">{{ $fd('TrialStatusEnum',
scope.row.TrialStatusStr) }}</el-tag>
<el-tag v-if="scope.row.TrialStatusStr === 'Completed'" type="warning">{{ $fd('TrialStatusEnum',
scope.row.TrialStatusStr) }}</el-tag>
<el-tag v-if="scope.row.TrialStatusStr === 'Stopped'" type="danger">{{ $fd('TrialStatusEnum',
scope.row.TrialStatusStr) }}</el-tag>
<el-tag
v-if="scope.row.TrialStatusStr === 'Initializing'"
type="info"
>{{ $fd('TrialStatusEnum', scope.row.TrialStatusStr) }}</el-tag
>
<el-tag
v-if="scope.row.TrialStatusStr === 'Ongoing'"
type="primary"
>{{ $fd('TrialStatusEnum', scope.row.TrialStatusStr) }}</el-tag
>
<el-tag
v-if="scope.row.TrialStatusStr === 'Completed'"
type="warning"
>{{ $fd('TrialStatusEnum', scope.row.TrialStatusStr) }}</el-tag
>
<el-tag
v-if="scope.row.TrialStatusStr === 'Stopped'"
type="danger"
>{{ $fd('TrialStatusEnum', scope.row.TrialStatusStr) }}</el-tag
>
</template>
</el-table-column>
<el-table-column v-if="hasPermi(['role:pm', 'role:apm'])" prop="ExpetiedTaskCount"
:label="$t('trials:trials-list:table:ExpetiedTaskCount')" show-overflow-tooltip sortable="custom"
min-width="120" />
<el-table-column v-if="hasPermi(['role:pm', 'role:apm'])" prop="ReReadingApprovalCount"
:label="$t('trials:trials-list:table:ReReadingApprovalCount')" show-overflow-tooltip sortable="custom"
min-width="180" />
<el-table-column v-if="hasPermi(['role:pm', 'role:apm'])" prop="PendingReconciliationCount"
:label="$t('trials:trials-list:table:PendingReconciliationCount')" show-overflow-tooltip sortable="custom"
min-width="140" />
<el-table-column v-if="hasPermi(['role:pm', 'role:apm'])" prop="PendingResponseCount"
:label="$t('trials:trials-list:table:PendingResponseCount')" show-overflow-tooltip sortable="custom"
min-width="140" />
<el-table-column v-if="hasPermi(['role:crc', 'role:cra'])" prop="CRC_UrgentCount"
:label="$t('trials:trials-list:table:CRC_UrgentCount')" show-overflow-tooltip sortable="custom"
min-width="160" />
<el-table-column v-if="hasPermi(['role:crc', 'role:cra'])" prop="CRC_QCQuestionCount"
:label="$t('trials:trials-list:table:CRC_QCQuestionCount')" show-overflow-tooltip sortable="custom"
min-width="160" />
<el-table-column v-if="hasPermi(['role:crc', 'role:cra'])" prop="CRC_CheckQuestionCount"
:label="$t('trials:trials-list:table:CRC_CheckQuestionCount')" show-overflow-tooltip sortable="custom"
min-width="160" />
<el-table-column v-if="hasPermi(['role:ir'])" prop="IR_ReadingCriterionList"
:label="$t('trials:trials-list:table:IR_ReadingCriterionList')" show-overflow-tooltip min-width="160">
<el-table-column
v-if="hasPermi(['role:pm', 'role:apm'])"
prop="ExpetiedTaskCount"
:label="$t('trials:trials-list:table:ExpetiedTaskCount')"
show-overflow-tooltip
sortable="custom"
min-width="120"
/>
<el-table-column
v-if="hasPermi(['role:pm', 'role:apm'])"
prop="ReReadingApprovalCount"
:label="$t('trials:trials-list:table:ReReadingApprovalCount')"
show-overflow-tooltip
sortable="custom"
min-width="180"
/>
<el-table-column
v-if="hasPermi(['role:pm', 'role:apm'])"
prop="PendingReconciliationCount"
:label="$t('trials:trials-list:table:PendingReconciliationCount')"
show-overflow-tooltip
sortable="custom"
min-width="140"
/>
<el-table-column
v-if="hasPermi(['role:pm', 'role:apm'])"
prop="PendingResponseCount"
:label="$t('trials:trials-list:table:PendingResponseCount')"
show-overflow-tooltip
sortable="custom"
min-width="140"
/>
<el-table-column
v-if="hasPermi(['role:crc', 'role:cra'])"
prop="CRC_UrgentCount"
:label="$t('trials:trials-list:table:CRC_UrgentCount')"
show-overflow-tooltip
sortable="custom"
min-width="160"
/>
<el-table-column
v-if="hasPermi(['role:crc', 'role:cra'])"
prop="CRC_QCQuestionCount"
:label="$t('trials:trials-list:table:CRC_QCQuestionCount')"
show-overflow-tooltip
sortable="custom"
min-width="160"
/>
<el-table-column
v-if="hasPermi(['role:crc', 'role:cra'])"
prop="CRC_CheckQuestionCount"
:label="$t('trials:trials-list:table:CRC_CheckQuestionCount')"
show-overflow-tooltip
sortable="custom"
min-width="160"
/>
<el-table-column
v-if="hasPermi(['role:ir'])"
prop="IR_ReadingCriterionList"
:label="$t('trials:trials-list:table:IR_ReadingCriterionList')"
show-overflow-tooltip
min-width="160"
>
<template slot-scope="scope">
{{ scope.row.IR_ReadingCriterionList.join(', ') }}
</template>
</el-table-column>
<el-table-column v-if="hasPermi(['role:ir'])" prop="IR_UrgentCount"
:label="$t('trials:trials-list:table:IR_UrgentCount')" show-overflow-tooltip sortable="custom"
min-width="160" />
<el-table-column v-if="hasPermi(['role:ir'])" prop="IR_UnReadCount"
:label="$t('trials:trials-list:table:IR_UnReadCount')" show-overflow-tooltip sortable="custom"
min-width="160" />
<el-table-column v-if="hasPermi(['role:ir'])" prop="IR_TotalReadCount"
:label="$t('trials:trials-list:table:IR_TotalReadCount')" show-overflow-tooltip sortable="custom"
min-width="170" />
<el-table-column v-if="hasPermi(['role:ir'])" prop="IR_PMEmailList"
:label="$t('trials:trials-list:table:IR_PMEmailList')" show-overflow-tooltip min-width="170">
<el-table-column
v-if="hasPermi(['role:ir'])"
prop="IR_UrgentCount"
:label="$t('trials:trials-list:table:IR_UrgentCount')"
show-overflow-tooltip
sortable="custom"
min-width="160"
/>
<el-table-column
v-if="hasPermi(['role:ir'])"
prop="IR_UnReadCount"
:label="$t('trials:trials-list:table:IR_UnReadCount')"
show-overflow-tooltip
sortable="custom"
min-width="160"
/>
<el-table-column
v-if="hasPermi(['role:ir'])"
prop="IR_TotalReadCount"
:label="$t('trials:trials-list:table:IR_TotalReadCount')"
show-overflow-tooltip
sortable="custom"
min-width="170"
/>
<el-table-column
v-if="hasPermi(['role:ir'])"
prop="IR_PMEmailList"
:label="$t('trials:trials-list:table:IR_PMEmailList')"
show-overflow-tooltip
min-width="170"
>
<template slot-scope="scope">
{{ scope.row.IR_PMEmailList.join(', ') }}
</template>
</el-table-column>
<el-table-column v-if="hasPermi(['role:iqc'])" prop="IQC_UrgentCount"
:label="$t('trials:trials-list:table:IQC_UrgentCount')" show-overflow-tooltip sortable="custom"
min-width="140" />
<el-table-column v-if="hasPermi(['role:iqc'])" prop="IQC_ToBeClaimedCount"
:label="$t('trials:trials-list:table:IQC_ToBeClaimedCount')" show-overflow-tooltip sortable="custom"
min-width="140" />
<el-table-column v-if="hasPermi(['role:iqc'])" prop="IQC_AuditToBeDealedCount"
:label="$t('trials:trials-list:table:IQC_AuditToBeDealedCount')" show-overflow-tooltip sortable="custom"
min-width="140" />
<el-table-column v-if="hasPermi(['role:iqc'])" prop="IQC_QuestionToBeDealedCount"
:label="$t('trials:trials-list:table:IQC_QuestionToBeDealedCount')" show-overflow-tooltip sortable="custom"
min-width="160" />
<el-table-column v-if="hasPermi(['role:mim'])" prop="MIM_UrgentCount"
:label="$t('trials:trials-list:table:MIM_UrgentCount')" show-overflow-tooltip sortable="custom"
min-width="160" />
<el-table-column
v-if="hasPermi(['role:iqc'])"
prop="IQC_UrgentCount"
:label="$t('trials:trials-list:table:IQC_UrgentCount')"
show-overflow-tooltip
sortable="custom"
min-width="140"
/>
<el-table-column
v-if="hasPermi(['role:iqc'])"
prop="IQC_ToBeClaimedCount"
:label="$t('trials:trials-list:table:IQC_ToBeClaimedCount')"
show-overflow-tooltip
sortable="custom"
min-width="140"
/>
<el-table-column
v-if="hasPermi(['role:iqc'])"
prop="IQC_AuditToBeDealedCount"
:label="$t('trials:trials-list:table:IQC_AuditToBeDealedCount')"
show-overflow-tooltip
sortable="custom"
min-width="140"
/>
<el-table-column
v-if="hasPermi(['role:iqc'])"
prop="IQC_QuestionToBeDealedCount"
:label="$t('trials:trials-list:table:IQC_QuestionToBeDealedCount')"
show-overflow-tooltip
sortable="custom"
min-width="160"
/>
<el-table-column
v-if="hasPermi(['role:mim'])"
prop="MIM_UrgentCount"
:label="$t('trials:trials-list:table:MIM_UrgentCount')"
show-overflow-tooltip
sortable="custom"
min-width="160"
/>
<!-- <el-table-column
v-if="hasPermi(['role:mim'])"
prop="MIM_UrgentCount"
@@ -244,63 +526,127 @@
sortable="custom"
min-width="160"
/> -->
<el-table-column v-if="hasPermi(['role:mim'])" prop="MIM_PendingReviewCount"
:label="$t('trials:trials-list:table:MIM_PendingReviewCount')" show-overflow-tooltip sortable="custom"
min-width="160" />
<el-table-column v-if="hasPermi(['role:mim'])" prop="MIM_PendingResponseCount"
:label="$t('trials:trials-list:table:MIM_PendingResponseCount')" show-overflow-tooltip sortable="custom"
min-width="160" />
<el-table-column v-if="hasPermi(['role:spm', 'role:cpm'])" prop="SPM_ReReadingApprovalCount"
:label="$t('trials:trials-list:table:SPM_ReReadingApprovalCount')" show-overflow-tooltip sortable="custom"
min-width="160" />
<el-table-column v-if="hasPermi(['role:spm', 'role:cpm'])" prop="SPM_ReviewerSelectApprovalCount" :label="$t('trials:trials-list:table:SPM_ReviewerSelectApprovalCount')
" show-overflow-tooltip sortable="custom" min-width="160" />
<el-table-column prop="CreateTime" :label="$t('trials:trials-list:table:createDate')" show-overflow-tooltip
sortable="custom" width="180" />
<el-table-column :label="$t('common:action:action')" width="260" align="left" fixed="right">
<el-table-column
v-if="hasPermi(['role:mim'])"
prop="MIM_PendingReviewCount"
:label="$t('trials:trials-list:table:MIM_PendingReviewCount')"
show-overflow-tooltip
sortable="custom"
min-width="160"
/>
<el-table-column
v-if="hasPermi(['role:mim'])"
prop="MIM_PendingResponseCount"
:label="$t('trials:trials-list:table:MIM_PendingResponseCount')"
show-overflow-tooltip
sortable="custom"
min-width="160"
/>
<el-table-column
v-if="hasPermi(['role:spm', 'role:cpm'])"
prop="SPM_ReReadingApprovalCount"
:label="$t('trials:trials-list:table:SPM_ReReadingApprovalCount')"
show-overflow-tooltip
sortable="custom"
min-width="160"
/>
<el-table-column
v-if="hasPermi(['role:spm', 'role:cpm'])"
prop="SPM_ReviewerSelectApprovalCount"
:label="
$t('trials:trials-list:table:SPM_ReviewerSelectApprovalCount')
"
show-overflow-tooltip
sortable="custom"
min-width="160"
/>
<el-table-column
prop="CreateTime"
:label="$t('trials:trials-list:table:createDate')"
show-overflow-tooltip
sortable="custom"
width="180"
/>
<el-table-column
:label="$t('common:action:action')"
width="260"
align="left"
fixed="right"
>
<template slot-scope="scope">
<!-- 详情 -->
<el-button v-hasPermi="['trials:trials-list:panel']" circle icon="el-icon-info" :disabled="(scope.row.TrialStatusStr === 'Initializing' &&
!hasPermi(['role:pm'])) ||
scope.row.IsDeleted ||
((scope.row.TrialStatusStr === 'Completed' ||
scope.row.TrialStatusStr === 'Stopped') &&
!(
hasPermi(['role:qa']) ||
hasPermi(['role:ea']) ||
hasPermi(['role:pm']) ||
hasPermi(['role:op']) ||
hasPermi(['role:dev']) ||
hasPermi(['role:admin'])
))
" :title="$t('trials:trials-list:action:panel')" @click.stop="handleDetail(scope.row)" />
<el-button
v-hasPermi="['trials:trials-list:panel']"
circle
icon="el-icon-info"
:disabled="
(scope.row.TrialStatusStr === 'Initializing' &&
!hasPermi(['role:pm'])) ||
scope.row.IsDeleted ||
((scope.row.TrialStatusStr === 'Completed' ||
scope.row.TrialStatusStr === 'Stopped') &&
!(
hasPermi(['role:qa']) ||
hasPermi(['role:ea']) ||
hasPermi(['role:pm'])
))
"
:title="$t('trials:trials-list:action:panel')"
@click.stop="handleDetail(scope.row)"
/>
<!-- 编辑项目基本信息 -->
<el-button v-hasPermi="['trials:trials-list:edit']" circle icon="el-icon-edit-outline"
:disabled="scope.row.IsDeleted" :title="$t('trials:trials-list:action:edit')"
@click.stop="handleEdit(scope.row)" />
<el-button
v-hasPermi="['trials:trials-list:edit']"
circle
icon="el-icon-edit-outline"
:disabled="scope.row.IsDeleted"
:title="$t('trials:trials-list:action:edit')"
@click.stop="handleEdit(scope.row)"
/>
<!-- 修改项目状态 -->
<el-button v-hasPermi="['trials:trials-list:status']" circle icon="el-icon-edit"
:disabled="scope.row.IsDeleted" :title="$t('trials:trials-list:action:status')"
@click.stop="handleStatus(scope.row)" />
<el-button
v-hasPermi="['trials:trials-list:status']"
circle
icon="el-icon-edit"
:disabled="scope.row.IsDeleted"
:title="$t('trials:trials-list:action:status')"
@click.stop="handleStatus(scope.row)"
/>
<!--项目文档-->
<el-button v-hasPermi="[
'trials:trials-panel:trial-summary:trial-document:inspect',
'trials:trials-panel:trial-summary:trial-document:manage',
]" circle icon="el-icon-folder-opened" :disabled="(scope.row.TrialStatusStr === 'Initializing' &&
!hasPermi(['role:pm'])) ||
scope.row.IsDeleted ||
((scope.row.TrialStatusStr === 'Completed' ||
scope.row.TrialStatusStr === 'Stopped') &&
!(
hasPermi(['role:qa']) ||
hasPermi(['role:ea']) ||
hasPermi(['role:pm'])
))
" :title="$t('trials:trials-list:action:trialDocument')" @click.stop="toTrialDocument(scope.row)" />
<el-button
v-hasPermi="[
'trials:trials-panel:trial-summary:trial-document:inspect',
'trials:trials-panel:trial-summary:trial-document:manage',
]"
circle
icon="el-icon-folder-opened"
:disabled="
(scope.row.TrialStatusStr === 'Initializing' &&
!hasPermi(['role:pm'])) ||
scope.row.IsDeleted ||
((scope.row.TrialStatusStr === 'Completed' ||
scope.row.TrialStatusStr === 'Stopped') &&
!(
hasPermi(['role:qa']) ||
hasPermi(['role:ea']) ||
hasPermi(['role:pm'])
))
"
:title="$t('trials:trials-list:action:trialDocument')"
@click.stop="toTrialDocument(scope.row)"
/>
<!-- 废除项目 -->
<el-button v-hasPermi="['trials:trials-list:abolish']" circle icon="el-icon-delete" :disabled="scope.row.IsDeleted ||
scope.row.TrialStatusStr !== 'Initializing'
" :title="$t('trials:trials-list:action:abolition')" @click.stop="handleAbandon(scope.row)" />
<el-button
v-hasPermi="['trials:trials-list:abolish']"
circle
icon="el-icon-delete"
:disabled="
scope.row.IsDeleted ||
scope.row.TrialStatusStr !== 'Initializing'
"
:title="$t('trials:trials-list:action:abolition')"
@click.stop="handleAbandon(scope.row)"
/>
<!-- 代办详情-->
<!-- <el-button-->
<!-- v-hasPermi="['trials:trials-list:abolish']"-->
@@ -315,26 +661,61 @@
</el-table>
<!-- 分页组件 -->
<pagination class="page" :total="total" :page.sync="searchData.PageIndex" :limit.sync="searchData.PageSize"
@pagination="getList" />
<pagination
class="page"
:total="total"
:page.sync="searchData.PageIndex"
:limit.sync="searchData.PageSize"
@pagination="getList"
/>
</template>
<!-- 新增/编辑项目 -->
<el-dialog v-if="dialogVisible" :visible.sync="dialogVisible" :title="title" :fullscreen="true" append-to-body
custom-class="base-dialog-wrapper">
<TrialForm :trial-id="currentId" @getList="getList" @closeDialog="closeDialog" />
<el-dialog
v-if="dialogVisible"
:visible.sync="dialogVisible"
:title="title"
:fullscreen="true"
append-to-body
custom-class="base-dialog-wrapper"
>
<TrialForm
:trial-id="currentId"
@getList="getList"
@closeDialog="closeDialog"
/>
</el-dialog>
<!-- 修改项目状态 -->
<el-dialog v-if="statusVisible" :visible.sync="statusVisible" :close-on-click-modal="false"
:title="$t('trials:trials-list:dialogTitle:changeStatus')" width="700px" custom-class="base-dialog-wrapper"
append-to-body>
<TrialStatusForm :data="currentRow" @closeDialog="closeStatusDialog" @getList="getList" />
<el-dialog
v-if="statusVisible"
:visible.sync="statusVisible"
:close-on-click-modal="false"
:title="$t('trials:trials-list:dialogTitle:changeStatus')"
width="700px"
custom-class="base-dialog-wrapper"
append-to-body
>
<TrialStatusForm
:data="currentRow"
@closeDialog="closeStatusDialog"
@getList="getList"
/>
</el-dialog>
<el-dialog v-if="doneDialogVisible" :visible.sync="doneDialogVisible" :title="doneTitle" :fullscreen="true"
append-to-body custom-class="base-dialog-wrapper">
<DoneList :trial-id="currentId" @getList="getList" @closeDialog="doneDialogVisible = false" />
<el-dialog
v-if="doneDialogVisible"
:visible.sync="doneDialogVisible"
:title="doneTitle"
:fullscreen="true"
append-to-body
custom-class="base-dialog-wrapper"
>
<DoneList
:trial-id="currentId"
@getList="getList"
@closeDialog="doneDialogVisible = false"
/>
</el-dialog>
</BaseContainer>
</template>
@@ -516,7 +897,7 @@ export default {
this.$confirm(res.ErrorMessage, {
type: 'warning',
showCancelButton: false,
callback: (action) => { },
callback: (action) => {},
})
}
})
@@ -541,7 +922,7 @@ export default {
this.currentRow = { ...row }
this.abandonTrial()
})
.catch(() => { })
.catch(() => {})
},
// 废除项目
abandonTrial() {
@@ -573,10 +954,7 @@ export default {
!(
this.hasPermi(['role:qa']) ||
this.hasPermi(['role:ea']) ||
this.hasPermi(['role:pm']) ||
hasPermi(['role:op']) ||
hasPermi(['role:dev']) ||
hasPermi(['role:admin'])
this.hasPermi(['role:pm'])
)
) {
return
@@ -277,7 +277,7 @@ export default {
}
}
</script>
<style lang="scss" scoped>
<style lang="scss">
.preview-wrapper{
display: flex;
flex-direction: row !important;
@@ -1,10 +1,7 @@
<template>
<div ref="container" style="width:100%;height:100%" class="dicom-container">
<!-- 访视阅片 -->
<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">
<div v-if="(isReadingTaskViewInOrder === 1 || ((isReadingTaskViewInOrder !== 1) && isShow)) && readingCategory=== 1 && CriterionType !== 0" class="reading-wrapper">
<el-tabs v-model="activeName" v-loading="loading" :before-leave="beforeLeave">
<!-- 阅片 -->
<el-tab-pane :label="$t('trials:reading:tabTitle:review')" name="read">
@@ -32,7 +29,7 @@
</el-tab-pane>
</el-tabs>
</div>
<div v-else-if="(isReadingTaskViewInOrder === 1 || ((isReadingTaskViewInOrder !== 1) && isShow)) && readingCategory=== 1 && CriterionType === 0" class="reading-wrapper">
<div v-if="(isReadingTaskViewInOrder === 1 || ((isReadingTaskViewInOrder !== 1) && isShow)) && readingCategory=== 1 && CriterionType === 0" class="reading-wrapper">
<el-tabs v-model="activeName" v-loading="loading" :before-leave="beforeLeaveCustomize">
<!-- 阅片 -->
<el-tab-pane :label="$t('trials:reading:tabTitle:review')" name="read">
@@ -174,7 +171,6 @@
</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'
@@ -191,7 +187,6 @@ 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
@@ -1,318 +0,0 @@
<template>
<div>
<div
v-if="!!question.GroupName && question.Type==='group'"
>
<h4 style="color: #ddd;padding: 5px 0px;margin: 0;">
{{ language==='en'?question.GroupEnName:question.GroupName }}
</h4>
</div>
<template v-else>
<el-form-item
v-if="(question.ShowQuestion===1 && question.ParentTriggerValueList.includes(String(questionForm[question.ParentId]))) || question.ShowQuestion===0 "
:label="`${question.QuestionName}`"
:prop="question.Id"
:rules="[
{ required: (question.IsRequired === 0 || (question.IsRequired ===1 && question.RelevanceId && (questionForm[question.RelevanceId] === question.RelevanceValue))) && question.Type!=='group' && question.Type!=='summary',
message: ['radio', 'select', 'checkbox'].includes(question.Type) ? $t('common:ruleMessage:select') : $t('common:ruleMessage:specify'), trigger: ['blur', 'change']},
]"
:class="[question.Type==='group' ? 'mb' : (question.Type==='upload' || question.QuestionName.length > 15) ?'uploadWrapper' : '']"
>
<!-- 输入框 -->
<el-input
v-if="question.Type==='input'"
v-model="questionForm[question.Id]"
:disabled="readingTaskState >= 2"
@change="((val)=>{formItemChange(val, question)})"
/>
<!-- 多行文本输入框 -->
<el-input
v-else-if="question.Type==='textarea'"
v-model="questionForm[question.Id]"
type="textarea"
:autosize="{ minRows: 2, maxRows: 4}"
maxlength="500"
:disabled="readingTaskState >= 2"
@change="((val)=>{formItemChange(val, question)})"
/>
<!-- 下拉框 -->
<el-select
v-else-if="question.Type==='select'"
v-model="questionForm[question.Id]"
:disabled="readingTaskState >= 2 || ((question.TableQuestionType === 2 || question.QuestionGenre === 2) && !!question.DictionaryCode)"
clearable
@change="((val)=>{formItemChange(val, question)})"
>
<template v-if="question.TableQuestionType === 1">
<el-option
v-for="item in organList"
:key="item.Id"
:label="item[question.DataTableColumn]"
:value="item[question.DataTableColumn]"
/>
</template>
<template v-else-if="question.TableQuestionType === 3 || question.QuestionGenre === 3">
<el-option
v-for="item of $d[question.DictionaryCode]"
:key="item.id"
:value="String(item.value)"
:label="item.label"
/>
</template>
<template v-else-if="(question.TableQuestionType === 2 || question.QuestionGenre === 2) && question.DictionaryCode">
<el-option
v-for="item of $d[question.DictionaryCode]"
:key="item.id"
:value="String(item.value)"
:label="item.label"
/>
</template>
<template v-else>
<el-option
v-for="val in question.TypeValue.split('|')"
:key="val"
:label="val"
:value="val"
/>
</template>
</el-select>
<!-- 单选 -->
<el-radio-group
v-else-if="question.Type==='radio'"
v-model="questionForm[question.Id]"
:disabled="readingTaskState >= 2"
@change="((val)=>{formItemChange(val, question)})"
>
<template v-if="question.DictionaryCode">
<el-radio
v-for="item of $d[question.DictionaryCode]"
:key="item.id"
:label="String(item.value)"
>
{{ item.label }}
</el-radio>
</template>
<template v-else-if="question.TypeValue">
<el-radio
v-for="val in question.TypeValue.split('|')"
:key="val"
:label="val"
>
{{ val }}
</el-radio>
</template>
</el-radio-group>
<!-- 复选框 -->
<el-checkbox-group
v-else-if="question.Type==='checkbox'"
v-model="questionForm[question.Id]"
:disabled="readingTaskState >= 2"
>
<el-checkbox
v-for="val in question.TypeValue.split('|')"
:key="val"
:label="val"
>
{{ val }}
</el-checkbox>
</el-checkbox-group>
<!-- 数值 -->
<template v-else-if="question.Type==='number'">
<el-input-number
v-if="question.ValueType === 0"
v-model="questionForm[question.Id]"
:precision="0"
:disabled="readingTaskState >= 2"
/>
<el-input-number
v-else-if="question.ValueType === 3"
v-model="questionForm[question.Id]"
:disabled="readingTaskState >= 2"
/>
<el-input-number
v-else-if="question.ValueType === 1 || question.ValueType === 2"
v-model="questionForm[question.Id]"
:precision="digitPlaces"
:disabled="readingTaskState >= 2"
/>
</template>
<el-input
v-else-if="question.Type==='calculation'"
v-model="questionForm[question.Id]"
disabled
>
<template v-if="question.Unit" slot="append">
{{ $fd('ValueUnit', parseInt(question.Unit)) }}
</template>
</el-input>
<!-- 上传图像 -->
<el-upload
v-else-if="question.Type==='upload'"
action
:accept="accept"
:limit="question.ImageCount"
:on-preview="handlePictureCardPreview"
:before-upload="handleBeforeUpload"
:http-request="uploadScreenshot"
list-type="picture-card"
:on-remove="handleRemove"
:file-list="fileList"
:class="{disabled:fileList.length >= question.ImageCount}"
:disabled="readingTaskState >= 2"
>
<i slot="default" class="el-icon-plus" />
<div slot="file" slot-scope="{file}">
<img
class="el-upload-list__item-thumbnail"
:src="OSSclientConfig.basePath + file.url"
alt=""
>
<span class="el-upload-list__item-actions">
<span
class="el-upload-list__item-preview"
@click="handlePictureCardPreview(file)"
>
<i class="el-icon-zoom-in" />
</span>
<span
v-if="readingTaskState < 2"
class="el-upload-list__item-delete"
@click="handleRemove(file)"
>
<i class="el-icon-delete" />
</span>
</span>
</div>
</el-upload>
<el-dialog
v-if="question.Type==='upload'"
append-to-body
:visible.sync="imgVisible"
width="600px"
>
<el-image :src="imageUrl" width="100%">
<div slot="placeholder" class="image-slot">
加载中<span class="dot">...</span>
</div>
</el-image>
</el-dialog>
</el-form-item>
</template>
<question-form-item
v-for="(item) in question.Childrens"
:key="item.Id"
:question="item"
:question-form="questionForm"
:reading-task-state="readingTaskState"
:visitTaskId="visitTaskId"
/>
</div>
</template>
<script>
// import { uploadReadingAnswerImage } from '@/api/trials'
import { mapGetters } from 'vuex'
export default {
name: 'QuestionFormItem',
props: {
questionForm: {
type: Object,
default() {
return {}
}
},
question: {
type: Object,
default() {
return {}
}
},
readingTaskState: {
type: Number,
required: true
},
visitTaskId: {
type: String,
default: ''
}
},
data() {
return {
fileList: [],
accept: '.png,.jpg,.jpeg',
imgVisible: false,
imageUrl: '',
urls: [],
digitPlaces: 2
}
},
computed: {
...mapGetters(['language'])
},
watch: {
questionForm: {
deep: true,
immediate: true,
handler(v) {
// console.log(v)
}
}
},
mounted() {
let digitPlaces = Number(localStorage.getItem('digitPlaces'))
this.digitPlaces = digitPlaces === -1 ? this.digitPlaces : digitPlaces
},
methods: {
formItemChange(v, question) {
if (question.Childrens.length > 0) {
this.resetChild(question.Childrens)
} else {
this.$emit('setFormItemData', { key: question.Id, val: v })
}
},
resetChild(obj) {
obj.forEach(i => {
this.$emit('resetFormItemData', i.Id)
if (i.Childrens && i.Childrens.length > 0) {
this.resetChild(i.Childrens)
}
})
},
resetFormItemData(v) {
this.$emit('resetFormItemData', v)
},
setFormItemData(obj) {
this.$emit('setFormItemData', obj)
},
}
}
</script>
<style lang="scss" scoped>
.mb{
margin-bottom: 0px;
}
.disabled{
::v-deep .el-upload--picture-card {
display: none;
}
}
.uploadWrapper{
display: flex;
flex-direction: column !important;
align-items: flex-start;
}
::v-deep .el-input.is-disabled .el-input__inner{
background-color: #646464a1;
}
::v-deep .el-input-group__append, .el-input-group__prepend{
padding: 0 10px;
}
::v-deep .el-form-item__content {
width: 100%;
}
::v-deep .el-select.is-disabled .el-input__inner{
background-color: #646464a1;
}
</style>
@@ -1,352 +0,0 @@
<template>
<div class="table-question-form">
<div style="display: flex;justify-content: space-between;">
<h3 v-if="questionForm.LesionName" style="color: #ddd;padding: 5px 0px;margin: 0;">
{{ questionForm.LesionName }}
</h3>
<!-- 关闭 -->
<div>
<i class="el-icon-circle-close" style="font-size: 25px;cursor: pointer;" @click="close" />
</div>
</div>
<el-form-item
:label="$t('trials:reading:title:lesionType')"
prop="LesionType"
:rules="[
{ required:true,message: $t('common:ruleMessage:select'), trigger: ['blur']},
]"
>
<!-- 下拉框 -->
<el-select
v-model="questionForm.LesionType"
filterable
:disabled="!isCurrentTask || readingTaskState>=2 || !isBaseLineTask"
@change="((val)=>{lesionTypeChange(val)})"
>
<el-option
v-for="item of $d.LesionType"
v-show="!(isBaseLineTask && item.value === 2)"
:key="item.id"
:value="item.value"
:label="item.label"
/>
</el-select>
</el-form-item>
<el-form-item
v-for="qs in questions"
v-show="qs.ShowQuestion!==2"
:key="qs.Id"
:label="`${qs.QuestionName}`"
:prop="qs.Id"
:rules="[
{ required: (qs.IsRequired === 0 || (qs.IsRequired ===1 && qs.RelevanceId && (questionForm[qs.RelevanceId] === qs.RelevanceValue)) || (qs.QuestionMark === 6 && questionForm.IsCanEditPosition === true) || (questionForm.IsCanEditPosition && qs.QuestionMark === 10)) && qs.Type!=='group' && qs.Type!=='summary',
message:['radio', 'select', 'checkbox'].includes(qs.Type) ? $t('common:ruleMessage:select') : $t('common:ruleMessage:specify'), trigger: ['blur','change']},
]"
>
<!-- 输入框 -->
<template v-if="qs.Type==='input' || qs.Type==='number'">
<el-input
v-if="qs.Type==='input' || qs.Type==='number'"
v-model="questionForm[qs.Id]"
:disabled="!isCurrentTask || readingTaskState>=2 || qs.QuestionMark === 0 || qs.QuestionMark === 1 || qs.QuestionMark === 2 || qs.QuestionMark === 5 || (qs.QuestionMark === 6 && (isCurrentTaskAdd === 'False' || (isCurrentTaskAdd === 'True' && !questionForm.IsCanEditPosition) || !!answer.SplitOrMergeLesionName))|| (qs.QuestionMark === 8 && (isCurrentTaskAdd === 'False' || !!answer.SplitOrMergeLesionName) && lesionType !== 2) || (qs.QuestionMark === 10 && (isCurrentTaskAdd === 'False' || !!answer.SplitOrMergeLesionName))"
@change="((val)=>{formItemChange(val, qs)})"
>
<template v-if="(qs.QuestionMark===0 || qs.QuestionMark===1) && qs.Unit" slot="append">
{{ $fd('ValueUnit', parseInt(qs.Unit)) }}
</template>
</el-input>
</template>
<!-- 多行文本输入框 -->
<el-input
v-if="qs.Type==='textarea'"
v-model="questionForm[qs.Id]"
type="textarea"
:autosize="{ minRows: 2, maxRows: 4}"
:disabled="!isCurrentTask || readingTaskState>=2"
@change="((val)=>{formItemChange(val, qs)})"
/>
<!-- 下拉框 -->
<el-select
v-if="qs.Type==='select'"
v-model="questionForm[qs.Id]"
filterable
:placeholder="qs.QuestionMark === 8 ? $t('common:placeholder:selectorsearch') : qs.QuestionMark === 2 ? '' : $t('common:placeholder:select')"
:disabled="!isCurrentTask || readingTaskState>=2 || qs.QuestionMark === 0 || qs.QuestionMark === 1 || qs.QuestionMark === 2 || qs.QuestionMark === 5 || (qs.QuestionMark === 6 && (isCurrentTaskAdd === 'False' || (isCurrentTaskAdd === 'True' && !questionForm.IsCanEditPosition) || !!answer.SplitOrMergeLesionName))|| (qs.QuestionMark === 8 && (isCurrentTaskAdd === 'False'|| !!answer.SplitOrMergeLesionName)) || (qs.QuestionMark === 10 && (isCurrentTaskAdd === 'False' || (isCurrentTaskAdd === 'True' && !questionForm.IsCanEditPosition) || !!answer.SplitOrMergeLesionName))"
@change="((val)=>{formItemChange(val, qs)})"
>
<template v-if="qs.QuestionMark === 8" #prefix>
<span style="padding-left: 5px;">
<i class="el-icon-search" />
</span>
</template>
<template v-if="qs.TableQuestionType === 1">
<el-option
v-for="item in organList"
:key="item.Id"
:label="item[qs.DataTableColumn]"
:value="item[qs.DataTableColumn]"
/>
</template>
<template v-else-if="qs.DictionaryCode && qs.QuestionMark === 7 && isBaseLineTask">
<el-option
v-for="item of $d[qs.DictionaryCode]"
v-show="(lesionType === 0 && item.value ===0) || (lesionType === 1 && (item.value ===0))"
:key="item.id"
:value="item.value"
:label="item.label"
/>
</template>
<template v-else-if="qs.DictionaryCode && qs.QuestionMark === 7 && !isBaseLineTask">
<el-option-group
:label="!isNaN(parseFloat(answer.LastTaskState)) ? `${$t('trials:dicomReading:tip:lastVisitStatus')} ${$fd(qs.DictionaryCode,parseFloat(answer.LastTaskState))}` : ''"
>
<!-- 首次分裂的病灶只能选择存在 -->
<template v-if="answer.IsFristAdd=== 'True' && answer.SplitOrMergeType === '0'">
<el-option
v-for="item of $d[qs.DictionaryCode]"
v-show="item.value === 0"
:key="item.id"
:value="item.value"
:label="item.label"
/>
</template>
<!-- 首次添加的新病灶不能为无法评估和消失 -->
<template v-else-if="isCurrentTaskAdd=== 'True' && lesionType === 2">
<el-option
v-for="item of $d[qs.DictionaryCode]"
v-show="item.value === 0 || item.value === 1"
:key="item.id"
:value="item.value"
:label="item.label"
/>
</template>
<template v-else>
<el-option
v-for="item of filterState($d[qs.DictionaryCode])"
:key="item.id"
:value="item.value"
:label="item.label"
/>
</template>
</el-option-group>
</template>
<template v-else-if="qs.DictionaryCode && qs.QuestionMark !== 7">
<el-option
v-for="item of $d[qs.DictionaryCode]"
:key="item.id"
:value="item.value"
:label="item.label"
/>
</template>
<template v-else>
<el-option
v-for="val in qs.TypeValue.split('|')"
:key="val"
:label="val"
:value="val"
/>
</template>
</el-select>
<!-- 单选 -->
<el-radio-group
v-if="qs.Type==='radio'"
v-model="questionForm[qs.id]"
:disabled="!isCurrentTask || readingTaskState>=2"
>
<el-radio
v-for="val in qs.options.split('|')"
:key="val"
:label="val"
>
{{ val }}
</el-radio>
</el-radio-group>
</el-form-item>
</div>
</template>
<script>
export default {
name: 'TableQuestionFormItem',
props: {
tableInfo: {
type: Object,
default() {
return {}
}
},
answer: {
type: Object,
default() {
return {}
}
},
questionForm: {
type: Object,
default() {
return {}
}
},
organs: {
type: Array,
default() {
return []
}
},
readingTaskState: {
type: Number,
required: true
},
isBaseLineTask: {
type: Boolean,
required: true
},
isCurrentTask: {
type: Boolean,
required: true
}
},
watch: {
questionForm: {
deep: true,
immediate: true,
handler(v) {
if (v.MeasureData) {
const {markTool} = v.MeasureData
if (markTool === 'Bidirectional') {
this.getOrganList(1)
} else if (markTool === 'Length') {
this.getOrganList(0)
} else {
this.getOrganList()
}
} else {
this.getOrganList()
}
this.isCurrentTaskAdd = v.IsCurrentTaskAdd
}
},
tableInfo: {
deep: true,
immediate: true,
handler(v) {
if (v) {
this.lesionType = v.LesionType
this.questions = v.TableQuestions.Questions
}
}
},
},
data(){
return{
isCurrentTaskAdd: null,
lesionType: null,
questions: [],
organList: []
}
},
methods: {
lesionTypeChange(v) {
this.$emit('lesionTypeChange', {tableId: this.tableInfo.Id, rowIndex: this.answer.RowIndex, newLesionType: v})
},
formItemChange(v, qs) {
let updateArr = []
if (qs.QuestionMark === 8 && qs.RelationQuestions.length > 0) {
//
let index = this.organList.findIndex(item => item[qs.DataTableColumn] === v)
if (index > -1) {
let selected = this.organList[index]
qs.RelationQuestions.map(q => {
let val = selected[q.DataTableColumn]
updateArr.push({questionId: q.Id, val: val, questionMark: q.QuestionMark})
})
updateArr.push({questionId: 'OrganInfoId', val: selected.OrganInfoId})
updateArr.push({questionId: 'IsCanEditPosition', val: selected.IsCanEditPosition})
} else {
question.RelationQuestions.map(q => {
updateArr.push({questionId: q.Id, val: '', questionMark: q.QuestionMark})
})
}
}
this.$emit('update', {tableId: this.tableInfo.Id, rowIndex: this.answer.RowIndex, questionMark: qs.QuestionMark, questionId: qs.Id, val: v, updateArr})
},
getOrganList(isLymphNodes = null) {
let idx = this.organs.findIndex(i => i.LesionType === this.questionForm.LesionType)
if (idx > -1) {
let arr = this.organs[idx].OrganList
if (!isNaN(parseInt(isLymphNodes))) {
this.organList = arr.filter((item) => item.IsLymphNodes === parseInt(isLymphNodes))
} else {
this.organList = arr
}
}
},
filterState(arr) {
if (!this.isBaseLineTask) {
const isLymphLesion = this.questionForm.IsLymphNodes
const lesionLength = this.questionForm.LesionLength
const lesionShort = this.questionForm.LesionShort
const bLesionL = !isNaN(parseFloat(this.questionForm.BaseLineMajorAxis)) ? parseFloat(this.questionForm.BaseLineMajorAxis) : 0
const bLesionS = !isNaN(parseFloat(this.questionForm.BaseLineShortAxis)) ? parseFloat(this.questionForm.BaseLineShortAxis) : 0
if (this.lesionType === 1 && isLymphLesion === 1 && this.questionForm.MeasureData && this.questionForm.MeasureData.markTool === 'Bidirectional' && lesionShort < bLesionS) {
arr = arr.filter(i => i.value !== 1)
} else if (this.lesionType === 1 && isLymphLesion === 1 && this.questionForm.MeasureData && this.questionForm.MeasureData.markTool === 'Bidirectional' && lesionShort >= 10 && lesionShort > bLesionS) {
arr = arr.filter(i => i.value === 0 || i.value === 1)
} else if (this.lesionType === 1 && isLymphLesion === 0 && this.questionForm.MeasureData && (this.questionForm.MeasureData.markTool === 'Length' || this.questionForm.MeasureData.markTool === 'Bidirectional') && lesionLength < bLesionL) {
arr = arr.filter(i => i.value !== 1)
}
return arr
} else {
return arr
}
},
close() {
this.$emit('close', {tableId: this.tableInfo.Id, rowIndex: this.answer.RowIndex})
}
}
}
</script>
<style lang="scss" scoped>
.table-question-form{
::v-deep .el-form-item__label{
color: #c3c3c3;
}
::v-deep .el-input .el-input__inner{
background-color: transparent;
color: #ddd;
border: 1px solid #5e5e5e;
}
::v-deep .el-form-item{
display: flex;
flex-direction: row;
justify-content: flex-start;
}
::v-deep .el-form-item__content{
flex: 1;
}
::v-deep .el-input.is-disabled .el-input__inner{
background-color: #646464a1;
}
::v-deep .el-select.is-disabled .el-input__inner{
background-color: #646464a1;
}
::v-deep .el-button--mini, .el-button--mini.is-round {
padding: 7px 10px;
}
.el-form-item__content
.el-select{
width: 100%;
}
.input-width1{
width: calc(100% - 60px)!important;
}
.input-width2{
width: 100% !important;
}
}
</style>
@@ -1,915 +0,0 @@
<template>
<div class="report-wrapper">
<el-card v-loading="loading" shadow="never">
<div slot="header" class="clearfix report-header">
<!-- 电子影像病例报告表eICRF -->
<h3 style="margin:0;padding:0;">{{ $t('trials:readingReport:title:eicrf') }}</h3>
<div style="margin-left:auto">
<el-switch
v-model="isShowDetail"
:active-text="$t('trials:readingReport:title:expandDetails')"
:inactive-text="$t('trials:readingReport:title:collapseDetails')"
style="margin-right:5px;"
@change="handleShowDetail"
/>
<el-button
v-if="readingTaskState<2"
type="primary"
size="small"
@click="skipTask"
>
<!-- 跳过 -->
{{ $t('trials:readingReport:button:skip') }}
</el-button>
<el-button
v-if="readingTaskState<2"
type="primary"
size="small"
@click="getReportInfo(false)"
>
<!-- 刷新 -->
{{ $t('trials:readingReport:button:refresh') }}
</el-button>
<el-button
v-if="readingTaskState<2 && criterionType !== 10"
type="primary"
size="small"
@click="handleSave(true)"
>
<!-- 保存 -->
{{ $t('common:button:save') }}
</el-button>
<el-button
v-if="readingTaskState<2"
type="primary"
size="small"
@click="beforeLeave"
>
<!-- 提交 -->
{{ $t('common:button:submit') }}
</el-button>
</div>
</div>
<div ref="tableWrapper" style="height:100%;overflow-y: auto;">
<el-table
v-if="height"
ref="reportList"
:data="taskQuestions"
row-key="Id"
border
:expand-row-keys="expandedRows"
:height="height"
:tree-props="{children: 'Childrens', hasChildren: 'hasChildren'}"
size="mini"
>
<el-table-column
prop=""
label=""
show-overflow-tooltip
width="350px"
>
<template slot-scope="scope">
<span v-if="scope.row.QuestionName" :style="{color: ((scope.row.isLymphNodes === 1 && scope.row.QuestionMark === 1) || (scope.row.isLymphNodes === 0 && scope.row.QuestionMark === 0)) && (scope.row.LesionType === 0 || scope.row.LesionType === 5) ? '#f66' : '#fff'}">{{ scope.row.QuestionName }}</span>
<span
v-else
style="font-weight: bold;font-size: 16px;color: #f44336;"
>
{{ language==='en'?scope.row.GroupEnName:scope.row.GroupName }}
</span>
</template>
</el-table-column>
<el-table-column
v-for="task in visitTaskList"
:key="task.VisitTaskId"
prop="date"
show-overflow-tooltip
width="150px"
>
<template slot="header">
<div v-if="task.IsCurrentTask">
<div>
{{ task.BlindName }}
</div>
</div>
<div v-else>
<div>
{{ task.BlindName }}
<el-button type="text" size="small" @click="previewDicoms(task)">
<span class="el-icon-view" />
</el-button>
</div>
</div>
</template>
<template slot-scope="scope">
<span :style="{color: ((scope.row.isLymphNodes === 1 && scope.row.QuestionMark === 1) || (scope.row.isLymphNodes === 0 && scope.row.QuestionMark === 0)) && (scope.row.LesionType === 0 || scope.row.LesionType === 5) || (scope.row.QuestionMark === 12) || scope.row.HighlightAnswerList.includes(`${scope.row.Answers[task.VisitTaskId]}`) ? '#f66' : '#fff'}">
<template v-if="task.VisitTaskId === visitTaskId && readingTaskState < 2 && [13,14,15,42].includes(scope.row.QuestionType)">
<!-- 是否存在疾病基线时可修改 -->
<template v-if="task.IsBaseLine && scope.row.QuestionType=== 15">
<el-select
v-if="scope.row.Type==='select' && scope.row.DictionaryCode"
v-model="currentExistDisease"
size="mini"
@change="handleExistDiseaseChange"
>
<el-option
v-for="item of $d[ scope.row.DictionaryCode]"
:key="item.id"
:value="item.value"
:label="item.label"
/>
</el-select>
</template>
<!-- 整体肿瘤评估非基线可修改 -->
<template v-else-if="!task.IsBaseLine && (scope.row.QuestionType=== 13 || scope.row.QuestionType=== 42)">
<el-select
v-if="scope.row.Type==='select' && scope.row.DictionaryCode"
v-model="currentEvaluateResult"
size="mini"
@change="handleEvaluateResultChange"
>
<template v-if="criterionType === 1 && tLesionCount">
<el-option
v-for="item of $d[ scope.row.DictionaryCode]"
v-show="(!task.IsBaseLine && item.value > -1) && (task.CrterionDictionaryGroup.indexOf(item.raw.CrterionDictionaryGroup) > -1) && (item.value !== 1 && item.value !== 3)"
:key="item.id"
:value="item.value"
:label="item.label"
/>
</template>
<template v-else-if="criterionType === 1 && ntLesionCount">
<el-option
v-for="item of $d[ scope.row.DictionaryCode]"
v-show="(!task.IsBaseLine && item.value > -1) && (task.CrterionDictionaryGroup.indexOf(item.raw.CrterionDictionaryGroup) > -1) && (item.value !== 1)"
:key="item.id"
:value="item.value"
:label="item.label"
/>
</template>
<template v-else>
<el-option
v-for="item of $d[ scope.row.DictionaryCode]"
v-show="(!task.IsBaseLine && item.value > -1) && (task.CrterionDictionaryGroup.indexOf(item.raw.CrterionDictionaryGroup) > -1)"
:key="item.id"
:value="item.value"
:label="item.label"
/>
</template>
</el-select>
</template>
<!-- <template v-else-if="task.IsBaseLine && scope.row.QuestionType=== 13">
{{ $fd(scope.row.DictionaryCode, currentEvaluateResult) }}
</template> -->
<!-- 访视点备注是否存在疾病与系统不一致或者整体肿瘤评估与系统不一致时必填 -->
<!-- tumorEvaluate && task.VisitTaskId === visitTaskId && scope.row.QuestionType=== 14 && (currentEvaluateResult !== tumorEvaluate || currentExistDisease !== isExistDisease) -->
<template v-else-if="task.VisitTaskId === visitTaskId && scope.row.QuestionType=== 14 ">
<!-- v-if="tumorEvaluate && (currentEvaluateResult !== tumorEvaluate || currentExistDisease !== isExistDisease)" -->
<template>
<!-- 输入框 -->
<el-input
v-if="scope.row.Type==='input'"
v-model="currentTaskReason"
size="mini"
@change="evaluateReasonChange"
/>
<el-input
v-else-if="scope.row.Type==='textarea'"
v-model="currentTaskReason"
:autosize="{ minRows: 2, maxRows: 4}"
size="mini"
maxlength="500"
@change="evaluateReasonChange"
/>
<!-- 系统评估结果为xxx,与当前调整的结果不一致请填写调整原因 -->
<p v-if="currentEvaluateResult !== tumorEvaluate" style="width: 140px;padding:0 2px;white-space: normal;word-break: break-all;word-wrap: break-word;" v-html="getWarningText()" />
<p v-else-if="currentExistDisease !== isExistDisease" style="width: 140px;padding:0 2px;white-space: normal;word-break: break-all;word-wrap: break-word;">{{ $t('trials:readingReport:title:sysEvaluationRes') }}<span style="color:red">{{ $fd('ExistDisease',isExistDisease) }}</span>{{ $t('trials:readingReport:message:msg1') }}
</p>
</template>
<!-- <template v-else>
<span>{{ currentTaskReason }}</span>
</template> -->
</template>
<template v-else-if="scope.row.DictionaryCode">
{{ $fd(scope.row.DictionaryCode, scope.row.Answers[task.VisitTaskId]) }}
</template>
<template v-else>
{{ scope.row.Answers[task.VisitTaskId] }}
</template>
</template>
<template v-else-if="scope.row.QuestionType=== 15">
<el-tooltip v-if="getAnswerInfo(scope.row.Answer,task.VisitTaskId,'IsGlobalChange')" :content="`${$t('trials:reading:warnning:msg55')}${$fd(scope.row.DictionaryCode, getAnswerInfo(scope.row.Answer,task.VisitTaskId,'GlobalChangeAnswer'))}`" placement="top" effect="light">
<span style="color:red;"> {{ $fd(scope.row.DictionaryCode, scope.row.Answers[task.VisitTaskId]) }}</span>
</el-tooltip>
<span v-else>{{ $fd(scope.row.DictionaryCode, scope.row.Answers[task.VisitTaskId]) }}</span>
</template>
<template v-else-if="scope.row.QuestionType=== 13 || scope.row.QuestionType=== 42">
<el-tooltip v-if="getAnswerInfo(scope.row.Answer,task.VisitTaskId,'IsGlobalChange')" :content="`${$t('trials:reading:warnning:msg55')}${$fd(scope.row.DictionaryCode, getAnswerInfo(scope.row.Answer,task.VisitTaskId,'GlobalChangeAnswer'))}`" placement="top" effect="light">
<span style="color:red;"> {{ $fd(scope.row.DictionaryCode, scope.row.Answers[task.VisitTaskId]) }}</span>
</el-tooltip>
<span v-else>{{ $fd(scope.row.DictionaryCode, scope.row.Answers[task.VisitTaskId]) }}</span>
</template>
<template v-else-if="scope.row.QuestionType=== 22">
{{ scope.row.Answers[task.VisitTaskId] === '-1' ? $t('trials:readingReport:title:unknow') : scope.row.Answers[task.VisitTaskId] }}
</template>
<template v-else-if="scope.row.DictionaryCode">
{{ $fd(scope.row.DictionaryCode, scope.row.Answers[task.VisitTaskId]) }}
</template>
<template v-else-if="criterionType === 10">
{{ isNaN(parseInt(scope.row.Answers[task.VisitTaskId]))?scope.row.Answers[task.VisitTaskId]:`${scope.row.Answers[task.VisitTaskId]}` }}
</template>
<template v-else-if="(scope.row.ValueType === 0 || scope.row.ValueType === 1) && scope.row.Unit">
{{ `${scope.row.Answers[task.VisitTaskId]}` }}
<span v-if="scope.row.Answers[task.VisitTaskId] !== 'NA' && !isNaN(parseInt(scope.row.Answers[task.VisitTaskId]))">{{ `${$fd('ValueUnit',scope.row.Unit)}` }}</span>
</template>
<template v-else-if="scope.row.ValueType === 2">
{{ isNaN(parseInt(scope.row.Answers[task.VisitTaskId]))?scope.row.Answers[task.VisitTaskId]:`${scope.row.Answers[task.VisitTaskId]}%` }}
</template>
<template v-else-if="scope.row.Answers && scope.row.Answers.hasOwnProperty(task.VisitTaskId)">
{{ scope.row.Answers[task.VisitTaskId] }}
</template>
</span>
</template>
</el-table-column>
</el-table>
</div>
</el-card>
<!-- 附加评估 -->
<el-dialog
v-if="additionalAssessmentsDig.visible"
:visible.sync="additionalAssessmentsDig.visible"
:close-on-click-modal="false"
:title="additionalAssessmentsDig.title"
width="600px"
>
<AdditionalAssessment
:questions="assessmentQuestions"
:visit-task-id="visitTaskId"
@close="additionalAssessmentsDig.visible = false"
@sign="sign"
/>
</el-dialog>
<!-- 签名框 -->
<el-dialog
v-if="signVisible"
:visible.sync="signVisible"
:close-on-click-modal="false"
width="600px"
custom-class="base-dialog-wrapper"
>
<div slot="title">
<span style="font-size:18px;">{{ $t('common:dialogTitle:sign') }}</span>
<span style="font-size:12px;margin-left:5px">{{ `(${$t('common:label:sign')}${ currentUser })` }}</span>
</div>
<SignForm ref="signForm" :sign-code-enum="signCode" @closeDialog="closeSignDialog" />
</el-dialog>
</div>
</template>
<script>
import { getReadingReportEvaluation, changeDicomReadingQuestionAnswer, submitDicomVisitTask, verifyVisitTaskQuestions, getTaskAdditionalQuestion } from '@/api/trials'
import { setSkipReadingCache } from '@/api/reading'
import { getAutoCutNextTask } from '@/api/user'
import const_ from '@/const/sign-code'
import SignForm from '@/views/trials/components/newSignForm'
import { getToken } from '@/utils/auth'
import store from '@/store'
import { mapGetters } from 'vuex'
import { changeURLStatic } from '@/utils/history.js'
import AdditionalAssessment from '@/views/trials/trials-panel/reading/dicoms/components/AdditionalAssessment'
export default {
name: 'ReportPage',
components: { SignForm, AdditionalAssessment },
data() {
return {
currentUser: zzSessionStorage.getItem('userName'),
signVisible: false,
signCode: null,
visitTaskList: [],
taskQuestions: [],
loading: false,
answers: [],
readingTaskState: 2,
tumorEvaluate: null,
currentEvaluateResult: null,
isExistDisease: null,
currentExistDisease: null,
currentTaskReason: '',
answerArr: [],
questions: [],
isShowDetail: false,
criterionType: 0,
height: 0,
additionalAssessmentsDig: { visible: false, title: this.$t('trials:trials-panel:setting:reading-unit:TrialCriterionAdditionalAssessmentTypeList') },
assessmentQuestions: [],
tLesionCount: null,
ntLesionCount: null,
openWindow: null,
expandedRows: [],
taskInfo: {},
visitTaskId: '',
isBaselineTask: false
}
},
computed: {
...mapGetters(['language'])
},
watch: {
taskQuestions() {
this.$nextTick(() => {
this.getTableHeight()
this.$refs.reportList && this.$refs.reportList.doLayout()
this.setScrollTop()
})
}
},
created() { this.getTableHeight() },
mounted() {
this.taskInfo = JSON.parse(localStorage.getItem('taskInfo'))
this.criterionType = this.taskInfo.CriterionType
this.visitTaskId = this.taskInfo.VisitTaskId
this.isBaselineTask = this.taskInfo.IsBaseLine
window.addEventListener('resize', () => {
this.handleResize()
this.setScrollTop()
})
this.getReportInfo()
},
beforeDestroy() {
if (this.openWindow) {
this.openWindow.close()
}
},
methods: {
myConfirm(msg) {
return new Promise(resolve => {
this.$confirm(msg, {
type: 'warning',
showCancelButton: true
}).then(() => {
resolve(true)
}).catch(() => {
resolve(false)
})
})
},
async beforeLeave() {
this.handleConfirm()
},
getAnswerInfo(answerArr, visitTaskId, prop) {
var i = answerArr.findIndex(i => i.VisitTaskId === visitTaskId)
if (i === -1) return ''
var val = answerArr[i][prop]
return isNaN(parseInt(val)) ? val : parseInt(val)
},
getTableHeight() {
this.height = window.innerHeight - 170
},
async getReportInfo(IsCalculate) {
this.loading = true
try {
var params = {
visitTaskId: this.visitTaskId,
trialId: this.$router.currentRoute.query.trialId,
IsCalculate: IsCalculate !== false
}
const res = await getReadingReportEvaluation(params)
if (res.IsSuccess) {
this.readingTaskState = res.Result.ReadingTaskState
this.tumorEvaluate = res.Result.CalculateResult && res.Result.CalculateResult.TumorEvaluate ? parseInt(res.Result.CalculateResult.TumorEvaluate) : null
this.isExistDisease = res.Result.CalculateResult && res.Result.CalculateResult.IsExistDisease ? parseInt(res.Result.CalculateResult.IsExistDisease) : null
this.answerArr = []
this.questions = res.Result.TaskQuestions.concat()
this.visitTaskList = res.Result.VisitTaskList
var taskQuestions = this.getQuestions(res.Result.TaskQuestions, !this.isShowDetail, null, null)
this.taskQuestions = []
taskQuestions.forEach(item => {
this.$set(this.taskQuestions, this.taskQuestions.length, item)
})
const tLesion = res.Result.LesionCountList.find(i => i.LesionType === 0)
this.tLesionCount = tLesion ? tLesion.Count : 0
const ntLesion = res.Result.LesionCountList.find(i => i.LesionType === 1)
this.ntLesionCount = ntLesion ? ntLesion.Count : 0
this.setScrollTop()
}
this.loading = false
} catch (e) {
this.loading = false
console.log(e)
}
},
setScrollTop(a) {
setTimeout(() => {
this.$nextTick(() => {
if (this.$refs.reportList) {
this.getTableHeight()
this.$refs.reportList.bodyWrapper.scrollTop = this.$refs.reportList.bodyWrapper.scrollHeight
}
})
}, 50)
},
getQuestions(questions, isNTFilterLength, lesionType, isLymphNodes) {
const arr = []
if (questions.length !== 0) {
questions.forEach((item) => {
if (this.criterionType === 21) {
if (!this.isShowDetail) {
if (!item.RowId) {
this.expandedRows.push(item.Id)
}
} else {
this.expandedRows.push(item.Id)
}
} else {
this.expandedRows.push(item.Id)
}
//
//
//
lesionType = item.LesionType
var filterArr = [7]
// 0 5
// 12678irecisit
// 0123ID4567810
// 11051106
if ((item.LesionType === 1 || item.LesionType === 2 || item.LesionType === 6 || item.LesionType === 7 || item.LesionType === 8) && isNTFilterLength) {
filterArr = [0, 1, 3, 4, 5, 6, 2, 8, 10, 7, 1105]
} else {
filterArr = [3, 4, 5, 6, 2, 8, 10, 7, 1106, 1105]
}
if ((lesionType === 0 || lesionType === 5) && isLymphNodes === 0 && !this.isShowDetail && (this.criterionType === 1 || this.criterionType === 3 || this.criterionType === 17)) {
filterArr.push(1)
}
if (isLymphNodes === 0) {
filterArr.push(1)
}
if (!(filterArr.includes(item.QuestionMark))) {
const obj = item
obj.Answers = {}
if (item.RowIndex > 0) {
try {
var idx = item.Childrens.findIndex(i => i.QuestionMark === 8)
var idxLoc = item.Childrens.findIndex(i => i.QuestionMark === 10)
var state = item.Childrens.findIndex(i => i.QuestionMark === 7)
if (idx > -1) {
if (item.Childrens[idx].Answer.length > 0) {
var k = item.Childrens[idx].Answer.findIndex(v => v.Answer !== '')
var part = ''
if (obj.IsCanEditPosition) {
part = `${item.Childrens[idx].Answer[k].Answer}--${item.Childrens[idxLoc].Answer[k].Answer}`
} else {
part = `${item.Childrens[idx].Answer[k].Answer}`
}
if (item.SplitOrMergeLesionName && k > -1) {
// obj.QuestionName = `${obj.QuestionName} --${part} (Split from ${item.SplitOrMergeLesionName})`
obj.QuestionName = `${obj.QuestionName} --${part}`
var Answers = {}
if (state >= 0) {
this.visitTaskList.forEach(v => {
const o = item.Childrens[state].Answer.find(v1 => {
return v1.VisitTaskId === v.VisitTaskId
})
if (o) {
Answers[o.VisitTaskId] = this.$fd(item.Childrens[state].DictionaryCode, parseInt(o.Answer))
}
})
}
this.$set(obj, 'Answers', Answers)
// obj.QuestionName = `${obj.QuestionName} `
} else if (!item.SplitOrMergeLesionName && k > -1) {
obj.QuestionName = `${obj.QuestionName}--${part}`
const Answers = {}
if (state >= 0) {
this.visitTaskList.forEach(v => {
const o = item.Childrens[state].Answer.find(v1 => {
return v1.VisitTaskId === v.VisitTaskId
})
if (o) {
Answers[o.VisitTaskId] = this.$fd(item.Childrens[state].DictionaryCode, parseInt(o.Answer))
}
})
}
this.$set(obj, 'Answers', Answers)
// obj.QuestionName = `${obj.QuestionName} `
} else {
obj.QuestionName = `${obj.QuestionName} `
}
if (item.ReportMark) {
obj.QuestionName = `${obj.QuestionName} (${item.ReportMark})`
}
if (this.criterionType === 1 || this.criterionType === 3 || this.criterionType === 17) {
var idxLymphNode = item.Childrens.findIndex(i => i.QuestionMark === 2)
if (idxLymphNode > -1) {
isLymphNodes = item.Childrens[idxLymphNode].Answer[k].Answer ? parseInt(item.Childrens[idxLymphNode].Answer[k].Answer) : null
item.Childrens.forEach(v => {
this.$set(v, 'isLymphNodes', isLymphNodes)
})
}
}
}
}
if (this.criterionType === 21) {
var liverSegmentIdx = item.Childrens.findIndex(i => i.QuestionMark === 1106)
if (liverSegmentIdx > -1) {
if (item.Childrens[liverSegmentIdx].Answer.length > 0) {
let v = item.Childrens[liverSegmentIdx].Answer[0].Answer
obj.QuestionName = this.$fd(item.Childrens[liverSegmentIdx].DictionaryCode, parseInt(v))
let Answers = {}
let mean = item.Childrens.findIndex(i => i.QuestionMark === 1104)
if (mean > -1) {
this.visitTaskList.forEach(v => {
const o = item.Childrens[mean].Answer.find(v1 => {
return v1.VisitTaskId === v.VisitTaskId
})
if (o) {
Answers[o.VisitTaskId] = isNaN(parseFloat(o.Answer)) ? o.Answer : `${o.Answer}%`
}
})
}
this.$set(obj, 'Answers', Answers)
}
}
}
} catch (e) {
console.log(e)
}
}
item.Answer.forEach(i => {
if (item.DictionaryCode) {
obj.Answers[i.VisitTaskId] = i.Answer ? parseInt(i.Answer) : null
} else {
obj.Answers[i.VisitTaskId] = i.Answer
}
})
if (item.QuestionType === 15) {
this.currentExistDisease = obj.Answers[this.visitTaskId]
this.answerArr.push({ id: item.QuestionId, answer: obj.Answers[this.visitTaskId], questionType: 15 })
}
if (item.QuestionType === 13 || item.QuestionType === 42) {
this.currentEvaluateResult = obj.Answers[this.visitTaskId]
this.answerArr.push({ id: item.QuestionId, answer: obj.Answers[this.visitTaskId], questionType: item.QuestionType })
}
if (item.QuestionType === 14) {
this.currentTaskReason = obj.Answers[this.visitTaskId]
this.answerArr.push({ id: item.QuestionId, answer: obj.Answers[this.visitTaskId], questionType: 14 })
}
if (item.Childrens.length >= 1) {
obj.Childrens = this.getQuestions(item.Childrens, isNTFilterLength, lesionType, isLymphNodes)
}
arr.push(obj)
}
})
}
return arr
},
handleShowDetail(val) {
this.getReportInfo()
// this.taskQuestions = this.getQuestions(res.Result.TaskQuestions, !this.isShowDetail, null)
},
handleExistDiseaseChange(val) {
// this.currentExistDisease = parseInt(val)
if (val === this.isExistDisease && this.tumorEvaluate === this.currentEvaluateResult) {
this.currentTaskReason = ''
this.evaluateReasonChange('')
}
this.currentTaskReason = ''
this.evaluateReasonChange('')
var idx = this.answerArr.findIndex(i => i.questionType === 15)
if (idx > -1) {
this.answerArr[idx].answer = val
}
},
handleEvaluateResultChange(val) {
// this.currentEvaluateResult = parseInt(val)
if (val === this.tumorEvaluate && this.isExistDisease === this.currentExistDisease) {
this.currentTaskReason = ''
this.evaluateReasonChange('')
}
this.currentTaskReason = ''
this.evaluateReasonChange('')
var idx = this.answerArr.findIndex(i => i.questionType === 13 || i.questionType === 42)
if (idx > -1) {
this.answerArr[idx].answer = val
}
this.setScrollTop()
},
evaluateReasonChange(val) {
var idx = this.answerArr.findIndex(i => i.questionType === 14)
if (idx > -1) {
this.answerArr[idx].answer = val
}
},
async handleConfirm() {
this.loading = true
try {
await this.handleSave(false)
await verifyVisitTaskQuestions({ visitTaskId: this.visitTaskId })
var i = this.visitTaskList.findIndex(i => i.VisitTaskId === this.visitTaskId)
var isBaseline = this.visitTaskList[i].IsBaseLine
if (isBaseline) {
const res = await getTaskAdditionalQuestion({ visitTaskId: this.visitTaskId })
this.assessmentQuestions = res.Result
if (this.assessmentQuestions.length > 0) {
//
this.additionalAssessmentsDig.visible = true
} else {
const { ImageAssessmentReportConfirmation } = const_.processSignature
this.signCode = ImageAssessmentReportConfirmation
this.signVisible = true
}
} else {
const { ImageAssessmentReportConfirmation } = const_.processSignature
this.signCode = ImageAssessmentReportConfirmation
this.signVisible = true
}
this.loading = false
} catch (e) {
this.loading = false
}
},
sign() {
this.additionalAssessmentsDig.visible = false
this.$nextTick(() => {
const { ImageAssessmentReportConfirmation } = const_.processSignature
this.signCode = ImageAssessmentReportConfirmation
this.signVisible = true
})
},
handleResize() {
this.$nextTick(() => {
this.$refs.reportList && this.$refs.reportList.doLayout()
})
},
//
closeSignDialog(isSign, signInfo) {
if (isSign) {
this.signConfirm(signInfo)
} else {
this.signVisible = false
}
},
//
async signConfirm(signInfo) {
this.loading = true
try {
var params = {
data: {
visitTaskId: this.visitTaskId
},
signInfo: signInfo
}
const res = await submitDicomVisitTask(params)
if (res.IsSuccess) {
this.$message.success(this.$t('common:message:savedSuccessfully'))
if (this.$refs['signForm']) {
this.$refs['signForm'].btnLoading = false
}
this.signVisible = false
// window.location.reload()
// window.opener.postMessage('refreshTaskList', window.location)
//
this.readingTaskState = 2
this.$emit('setReadingTaskState', 2)
const res = await getAutoCutNextTask()
var isAutoTask = res.Result.AutoCutNextTask
if (isAutoTask) {
window.location.reload()
} else {
// ''
this.$confirm(this.$t('trials:readingReport:message:msg4'), {
type: 'warning',
distinguishCancelAndClose: true
})
.then(() => {
window.location.reload()
})
.catch(action => {
changeURLStatic('visitTaskId', this.visitTaskId)
})
}
window.opener.postMessage('refreshTaskList', window.location)
}
this.loading = false
} catch (e) {
this.loading = false
if (this.$refs['signForm'] && this.$refs['signForm'].btnLoading) {
this.$refs['signForm'].btnLoading = false
}
}
},
previewDicoms(task) {
if (this.openWindow) {
this.openWindow.close()
}
var token = getToken()
var trialReadingCriterionId = this.$router.currentRoute.query.TrialReadingCriterionId
// var subjectCode = this.$router.currentRoute.query.subjectCode
var subjectCode = localStorage.getItem('subjectCode')
var subjectId = this.$router.currentRoute.query.subjectId
var trialId = this.$router.currentRoute.query.trialId
var isReadingTaskViewInOrder = this.$router.currentRoute.query.isReadingTaskViewInOrder
var criterionType = this.$router.currentRoute.query.criterionType
var readingTool = this.$router.currentRoute.query.readingTool
var path = `/readingDicoms?TrialReadingCriterionId=${trialReadingCriterionId}&trialId=${trialId}&subjectCode=${subjectCode}&subjectId=${subjectId}&visitTaskId=${task.VisitTaskId}&isReadingTaskViewInOrder=${isReadingTaskViewInOrder}&criterionType=${criterionType}&readingTool=${readingTool}&TokenKey=${token}`
const routeData = this.$router.resolve({ path })
this.openWindow = window.open(routeData.href, '_blank')
},
handleSave(isPrompt) {
return new Promise(async(resolve, reject) => {
var isBeill
var evaluateResult = ''
var evaluateAjustReason = ''
this.answers = []
var isExistEvaluateResult = false
this.answerArr.map(item => {
if (item.questionType === 13 || item.questionType === 42) {
evaluateResult = item.answer
isExistEvaluateResult = true
}
if (item.questionType === 14) {
evaluateAjustReason = item.answer
}
if (item.questionType === 15) {
isBeill = item.answer
}
this.answers.push({ id: item.id, answer: item.answer })
})
console.log(this.currentExistDisease, this.isExistDisease, evaluateAjustReason, isBeill)
if (this.currentExistDisease !== this.isExistDisease && !evaluateAjustReason) {
this.$confirm(this.$t('trials:readingReport:message:msg2'), {
type: 'warning',
showCancelButton: false,
callback: action => {}
})
resolve()
return
}
if (isExistEvaluateResult && (evaluateResult === null && !this.isBaselineTask)) {
//
this.$confirm(this.$t('trials:readingReport:message:msg2'), {
type: 'warning',
showCancelButton: false,
callback: action => {}
})
resolve()
return
}
if (isExistEvaluateResult && (evaluateResult !== this.tumorEvaluate) && !evaluateAjustReason) {
//
this.$confirm(this.$t('trials:readingReport:message:msg3'), {
type: 'warning',
showCancelButton: false,
callback: action => {}
})
resolve()
return
}
this.loading = true
try {
var params = {
visitTaskId: this.visitTaskId,
answers: this.answers
}
const res = await changeDicomReadingQuestionAnswer(params)
if (res.IsSuccess && isPrompt) {
this.$message.success(this.$t('common:message:savedSuccessfully'))
}
this.loading = false
resolve()
} catch (e) {
this.loading = false
reject()
}
})
},
getWarningText() {
var sysRes = ''
var curRes = ''
if (this.CriterionType === 2) {
sysRes = this.$fd('ImagingOverallAssessment_Lugano', this.tumorEvaluate)
curRes = this.$fd('ImagingOverallAssessment_Lugano', this.currentEvaluateResult)
} else {
sysRes = this.$fd('OverallAssessment', this.tumorEvaluate)
curRes = this.$fd('OverallAssessment', this.currentEvaluateResult)
}
if (!curRes) {
return ''
}
const msg = this.$t('trials:readingReport:message:msg9').replace('xxx', '<font color="red">' + sysRes + '</font>').replace('yyy', '<font color="red">' + curRes + '</font>')
return msg
},
async skipTask() {
try {
//
const confirm = await this.$confirm(
this.$t('trials:readingReport:message:skipConfirm'),
{
type: 'warning',
distinguishCancelAndClose: true
}
)
if (confirm !== 'confirm') return
this.loading = true
const res = await setSkipReadingCache({ visitTaskId: this.visitTaskId })
this.loading = false
if (res.IsSuccess) {
window.location.reload()
}
} catch (e) {
this.loading = false
console.log(e)
}
}
}
}
</script>
<style lang="scss" scoped>
.report-wrapper{
height: 100%;
padding: 10px 0px;
// background-color: #fff;
background-color: #000;
::-webkit-scrollbar {
width: 7px;
height: 7px;
}
::-webkit-scrollbar-thumb {
border-radius: 10px;
background: #d0d0d0;
}
.report-header{
display: flex;
}
.el-card{
display:flex;flex-direction: column;height: 100%;
background-color: #000;
color: #ffffff;
border:none;
::v-deep .el-card__body{
flex: 1;
}
}
// ::v-deep .el-table__cell{
// background-color: #000;
// color: #ffffff;
// }
// ::v-deep .el-table{
// background-color: #000;
// color: #ffffff;
// }
// ::v-deep .el-table__cell{
// background-color: #000;
// color: #ffffff;
// }
::v-deep .el-table, .el-table__expanded-cell {
background-color: #000;
color: #fff;
border-color:#444444;
}
::v-deep .el-table th, .el-table tr {
background-color: #000;
color: #fff;
border-color:#444444;
}
::v-deep .el-table__body tr > td{
background-color:#000 !important;
color: #fff;
border-color:#444444;
}
::v-deep .el-table__body tr:hover > td{
background-color:#858282 !important;
color: #fff;
border-color:#444444;
}
::v-deep .el-table--border th.gutter:last-of-type{
border: none;
}
::v-deep .el-card__header{
border: none;
padding: 10px;
}
}
::v-deep .el-switch__label{
color:#fff;
}
::v-deep .el-switch__label.is-active{
color: #428bca;
}
.colorOfRed{
color: #f66;
}
</style>
@@ -1,275 +0,0 @@
<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 v-if="study.StudyName" style="text-overflow: ellipsis;overflow: hidden;">
<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 v-if="!study.IsCriticalSequence" class="text-desc" :title="series.SeriesNumber">
#{{ series.SeriesNumber }}
</div>
<div v-if="series.Description" class="text-desc" :title="series.Description">
{{ series.Description }}
</div>
<div v-if="series.SliceThickness && !study.IsCriticalSequence" class="text-desc">
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="annotations.findIndex(v=>v.seriesId === series.Id && v.MeasureData) > -1">
<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: [],
annotations: [],
digitPlaces: 2
}
},
mounted() {
this.taskInfo = JSON.parse(localStorage.getItem('taskInfo'))
const digitPlaces = Number(localStorage.getItem('digitPlaces'))
this.digitPlaces = digitPlaces === -1 ? this.digitPlaces : digitPlaces
this.studyList = this.visitTaskInfo.StudyList
this.annotations = this.visitTaskInfo.Annotations
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
const studyId = this.studyList[studyIndex].StudyId
if (!studyId) return
this.activeStudy(studyId)
},
getPreviousOrNextSeries(type, series) {
const seriseList = this.studyList.map(s => s.SeriesList).flat()
const 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
}
const studyIndex = seriseList[newIndex].StudyIndex
const 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>
@@ -1,554 +0,0 @@
<template>
<div
ref="viewport"
class="viewport-wrapper"
@mouseup="sliderMouseup"
@mousemove="sliderMousemove"
@mouseleave="sliderMouseleave"
>
<div v-if="series && taskInfo" class="left-top-text">
<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 v-if="series" class="right-top-text">
<div>{{ series.Description }}</div>
</div>
<div v-if="series" class="left-bottom-text">
<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 v-if="series" class="right-bottom-text">
<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 } from 'gl-matrix'
export default {
name: 'ImageViewport',
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'))
const digitPlaces = Number(localStorage.getItem('digitPlaces'))
this.digitPlaces = digitPlaces === -1 ? this.digitPlaces : digitPlaces
this.$nextTick(() => {
this.initViewport()
})
},
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(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)
const 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()
this.$emit('renderAnnotations', this.series)
},
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() {
const markers = [...this.orientationMarkers]
for (const key in this.markers) {
const 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
}
const 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, isLocate = false) {
if (this.series && obj.Id === this.series.Id && obj.Description === this.series.Description && !isLocate) {
obj.SliceIndex = this.series.SliceIndex
}
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>
@@ -1,88 +0,0 @@
<template>
<div class="visit-review-container">
<el-tabs
v-model="activeName"
>
<!-- 阅片 -->
<el-tab-pane
v-if="taskInfo"
ref="readPage"
: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'"
@setReadingTaskState="setReadingTaskState"
/>
</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'))
},
methods: {
setReadingTaskState(state) {
this.$refs['readPage'].setReadingTaskState(state)
}
}
}
</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>
@@ -1,318 +0,0 @@
<template>
<div>
<div
v-if="!!question.GroupName && question.Type==='group'"
>
<h4 style="color: #ddd;padding: 5px 0px;margin: 0;">
{{ language==='en'?question.GroupEnName:question.GroupName }}
</h4>
</div>
<template v-else>
<el-form-item
v-if="(question.ShowQuestion===1 && question.ParentTriggerValueList.includes(String(questionForm[question.ParentId]))) || question.ShowQuestion===0 "
:label="`${question.QuestionName}`"
:prop="question.Id"
:rules="[
{ required: (question.IsRequired === 0 || (question.IsRequired ===1 && question.RelevanceId && (questionForm[question.RelevanceId] === question.RelevanceValue))) && question.Type!=='group' && question.Type!=='summary',
message: ['radio', 'select', 'checkbox'].includes(question.Type) ? $t('common:ruleMessage:select') : $t('common:ruleMessage:specify'), trigger: ['blur', 'change']},
]"
:class="[question.Type==='group' ? 'mb' : (question.Type==='upload' || question.QuestionName.length > 15) ?'uploadWrapper' : '']"
>
<!-- 输入框 -->
<el-input
v-if="question.Type==='input'"
v-model="questionForm[question.Id]"
:disabled="readingTaskState >= 2"
@change="((val)=>{formItemChange(val, question)})"
/>
<!-- 多行文本输入框 -->
<el-input
v-else-if="question.Type==='textarea'"
v-model="questionForm[question.Id]"
type="textarea"
:autosize="{ minRows: 2, maxRows: 4}"
maxlength="500"
:disabled="readingTaskState >= 2"
@change="((val)=>{formItemChange(val, question)})"
/>
<!-- 下拉框 -->
<el-select
v-else-if="question.Type==='select'"
v-model="questionForm[question.Id]"
:disabled="readingTaskState >= 2 || ((question.TableQuestionType === 2 || question.QuestionGenre === 2) && !!question.DictionaryCode)"
clearable
@change="((val)=>{formItemChange(val, question)})"
>
<template v-if="question.TableQuestionType === 1">
<el-option
v-for="item in organList"
:key="item.Id"
:label="item[question.DataTableColumn]"
:value="item[question.DataTableColumn]"
/>
</template>
<template v-else-if="question.TableQuestionType === 3 || question.QuestionGenre === 3">
<el-option
v-for="item of $d[question.DictionaryCode]"
:key="item.id"
:value="String(item.value)"
:label="item.label"
/>
</template>
<template v-else-if="(question.TableQuestionType === 2 || question.QuestionGenre === 2) && question.DictionaryCode">
<el-option
v-for="item of $d[question.DictionaryCode]"
:key="item.id"
:value="String(item.value)"
:label="item.label"
/>
</template>
<template v-else>
<el-option
v-for="val in question.TypeValue.split('|')"
:key="val"
:label="val"
:value="val"
/>
</template>
</el-select>
<!-- 单选 -->
<el-radio-group
v-else-if="question.Type==='radio'"
v-model="questionForm[question.Id]"
:disabled="readingTaskState >= 2"
@change="((val)=>{formItemChange(val, question)})"
>
<template v-if="question.DictionaryCode">
<el-radio
v-for="item of $d[question.DictionaryCode]"
:key="item.id"
:label="String(item.value)"
>
{{ item.label }}
</el-radio>
</template>
<template v-else-if="question.TypeValue">
<el-radio
v-for="val in question.TypeValue.split('|')"
:key="val"
:label="val"
>
{{ val }}
</el-radio>
</template>
</el-radio-group>
<!-- 复选框 -->
<el-checkbox-group
v-else-if="question.Type==='checkbox'"
v-model="questionForm[question.Id]"
:disabled="readingTaskState >= 2"
>
<el-checkbox
v-for="val in question.TypeValue.split('|')"
:key="val"
:label="val"
>
{{ val }}
</el-checkbox>
</el-checkbox-group>
<!-- 数值 -->
<template v-else-if="question.Type==='number'">
<el-input-number
v-if="question.ValueType === 0"
v-model="questionForm[question.Id]"
:precision="0"
:disabled="readingTaskState >= 2"
/>
<el-input-number
v-else-if="question.ValueType === 3"
v-model="questionForm[question.Id]"
:disabled="readingTaskState >= 2"
/>
<el-input-number
v-else-if="question.ValueType === 1 || question.ValueType === 2"
v-model="questionForm[question.Id]"
:precision="digitPlaces"
:disabled="readingTaskState >= 2"
/>
</template>
<el-input
v-else-if="question.Type==='calculation'"
v-model="questionForm[question.Id]"
disabled
>
<template v-if="question.Unit" slot="append">
{{ $fd('ValueUnit', parseInt(question.Unit)) }}
</template>
</el-input>
<!-- 上传图像 -->
<el-upload
v-else-if="question.Type==='upload'"
action
:accept="accept"
:limit="question.ImageCount"
:on-preview="handlePictureCardPreview"
:before-upload="handleBeforeUpload"
:http-request="uploadScreenshot"
list-type="picture-card"
:on-remove="handleRemove"
:file-list="fileList"
:class="{disabled:fileList.length >= question.ImageCount}"
:disabled="readingTaskState >= 2"
>
<i slot="default" class="el-icon-plus" />
<div slot="file" slot-scope="{file}">
<img
class="el-upload-list__item-thumbnail"
:src="OSSclientConfig.basePath + file.url"
alt=""
>
<span class="el-upload-list__item-actions">
<span
class="el-upload-list__item-preview"
@click="handlePictureCardPreview(file)"
>
<i class="el-icon-zoom-in" />
</span>
<span
v-if="readingTaskState < 2"
class="el-upload-list__item-delete"
@click="handleRemove(file)"
>
<i class="el-icon-delete" />
</span>
</span>
</div>
</el-upload>
<el-dialog
v-if="question.Type==='upload'"
append-to-body
:visible.sync="imgVisible"
width="600px"
>
<el-image :src="imageUrl" width="100%">
<div slot="placeholder" class="image-slot">
加载中<span class="dot">...</span>
</div>
</el-image>
</el-dialog>
</el-form-item>
</template>
<question-form-item
v-for="(item) in question.Childrens"
:key="item.Id"
:question="item"
:question-form="questionForm"
:reading-task-state="readingTaskState"
:visitTaskId="visitTaskId"
/>
</div>
</template>
<script>
// import { uploadReadingAnswerImage } from '@/api/trials'
import { mapGetters } from 'vuex'
export default {
name: 'QuestionFormItem',
props: {
questionForm: {
type: Object,
default() {
return {}
}
},
question: {
type: Object,
default() {
return {}
}
},
readingTaskState: {
type: Number,
required: true
},
visitTaskId: {
type: String,
default: ''
}
},
data() {
return {
fileList: [],
accept: '.png,.jpg,.jpeg',
imgVisible: false,
imageUrl: '',
urls: [],
digitPlaces: 2
}
},
computed: {
...mapGetters(['language'])
},
watch: {
questionForm: {
deep: true,
immediate: true,
handler(v) {
// console.log(v)
}
}
},
mounted() {
let digitPlaces = Number(localStorage.getItem('digitPlaces'))
this.digitPlaces = digitPlaces === -1 ? this.digitPlaces : digitPlaces
},
methods: {
formItemChange(v, question) {
if (question.Childrens.length > 0) {
this.resetChild(question.Childrens)
} else {
this.$emit('setFormItemData', { key: question.Id, val: v })
}
},
resetChild(obj) {
obj.forEach(i => {
this.$emit('resetFormItemData', i.Id)
if (i.Childrens && i.Childrens.length > 0) {
this.resetChild(i.Childrens)
}
})
},
resetFormItemData(v) {
this.$emit('resetFormItemData', v)
},
setFormItemData(obj) {
this.$emit('setFormItemData', obj)
},
}
}
</script>
<style lang="scss" scoped>
.mb{
margin-bottom: 0px;
}
.disabled{
::v-deep .el-upload--picture-card {
display: none;
}
}
.uploadWrapper{
display: flex;
flex-direction: column !important;
align-items: flex-start;
}
::v-deep .el-input.is-disabled .el-input__inner{
background-color: #646464a1;
}
::v-deep .el-input-group__append, .el-input-group__prepend{
padding: 0 10px;
}
::v-deep .el-form-item__content {
width: 100%;
}
::v-deep .el-select.is-disabled .el-input__inner{
background-color: #646464a1;
}
</style>
@@ -1,360 +0,0 @@
<template>
<div class="table-question-form">
<div style="display: flex;justify-content: space-between;">
<h3 v-if="qsForm.LesionName" style="color: #ddd;padding: 5px 0px;margin: 0;">
{{ qsForm.LesionName }}
</h3>
<!-- 关闭 -->
<div>
<i class="el-icon-circle-close" style="font-size: 25px;cursor: pointer;" @click="close" />
</div>
</div>
<el-form-item
:label="$t('trials:reading:title:lesionType')"
prop="LesionType"
:rules="[
{ required:true,message: $t('common:ruleMessage:select'), trigger: ['blur']},
]"
>
<!-- 下拉框 -->
<el-select
v-model="qsForm.LesionType"
filterable
:disabled="!isCurrentTask || readingTaskState>=2 || !isBaseLineTask"
@change="((val)=>{lesionTypeChange(val)})"
>
<el-option
v-for="item of $d.LesionType"
v-show="!(isBaseLineTask && item.value === 2)"
:key="item.id"
:value="item.value"
:label="item.label"
/>
</el-select>
</el-form-item>
<!-- 靶病灶非靶病灶的器官为肝脏/Liver时,需要选择典型肝内病灶该值默认为否如果选择是对于靶病灶需要提示按照独立影像评估章程的相关规则对于典型肝内靶病灶请测量肿瘤活性部分最长径提示方式为在长径属性上显示浮框或者增加
-->
<el-form-item
v-for="qs in questions"
v-show="qs.ShowQuestion!==2"
:key="qs.Id"
:label="`${qs.QuestionName}`"
:prop="qs.Id"
:title="(qs.QuestionMark === 0 && (questionForm.LesionOrgan === '肝脏' || questionForm.LesionOrgan === 'Liver') && (lesionType === 0 || lesionType === 1) && questionForm.IntrahepaticLesion) ? $t('trials:mRecist:warnning:msg1') : ''"
:rules="[
{ required: (qs.IsRequired === 0 || (qs.IsRequired ===1 && qs.RelevanceId && (questionForm[qs.RelevanceId] === qs.RelevanceValue)) || (qs.QuestionMark === 6 && questionForm.IsCanEditPosition === true) || (questionForm.IsCanEditPosition && qs.QuestionMark === 10) || (qs.QuestionMark === 21 && (questionForm.LesionOrgan === '肝脏' || questionForm.LesionOrgan === 'Liver') && (lesionType === 0 || lesionType === 1 || lesionType === 2)) || (qs.QuestionMark === 0 && (questionForm.LesionOrgan === '肝脏' || questionForm.LesionOrgan === 'Liver') && (lesionType === 0 || lesionType === 1 || lesionType === 2))) && qs.Type!=='group' && qs.Type!=='summary',
message:['radio', 'select', 'checkbox'].includes(qs.Type) ? $t('common:ruleMessage:select') : $t('common:ruleMessage:specify'), trigger: ['blur','change']},
]"
>
<!-- 输入框 -->
<template v-if="qs.Type==='input' || qs.Type==='number'">
<el-input
v-if="qs.Type==='input' || qs.Type==='number'"
v-model="qsForm[qs.Id]"
:disabled="!isCurrentTask || readingTaskState>=2 || qs.QuestionMark === 0 || qs.QuestionMark === 1 || qs.QuestionMark === 2 || qs.QuestionMark === 5 || (qs.QuestionMark === 6 && (isCurrentTaskAdd === 'False' || (isCurrentTaskAdd === 'True' && !questionForm.IsCanEditPosition) || !!answer.SplitOrMergeLesionName))|| (qs.QuestionMark === 8 && (isCurrentTaskAdd === 'False' || !!answer.SplitOrMergeLesionName) && lesionType !== 2) || (qs.QuestionMark === 10 && (isCurrentTaskAdd === 'False' || !!answer.SplitOrMergeLesionName))"
@change="((val)=>{formItemChange(val, qs)})"
>
<template v-if="(qs.QuestionMark===0 || qs.QuestionMark===1) && qs.Unit" slot="append">
{{ $fd('ValueUnit', parseInt(qs.Unit)) }}
</template>
</el-input>
</template>
<!-- 多行文本输入框 -->
<el-input
v-if="qs.Type==='textarea'"
v-model="qsForm[qs.Id]"
type="textarea"
:autosize="{ minRows: 2, maxRows: 4}"
:disabled="!isCurrentTask || readingTaskState>=2"
@change="((val)=>{formItemChange(val, qs)})"
/>
<!-- 下拉框 -->
<el-select
v-if="qs.Type==='select'"
v-model="qsForm[qs.Id]"
filterable
:placeholder="qs.QuestionMark === 8 ? $t('common:placeholder:selectorsearch') : qs.QuestionMark === 2 ? '' : $t('common:placeholder:select')"
:disabled="!isCurrentTask || readingTaskState>=2 || qs.QuestionMark === 0 || qs.QuestionMark === 1 || qs.QuestionMark === 2 || qs.QuestionMark === 5 || (qs.QuestionMark === 6 && (isCurrentTaskAdd === 'False' || (isCurrentTaskAdd === 'True' && !questionForm.IsCanEditPosition) || !!answer.SplitOrMergeLesionName))|| (qs.QuestionMark === 8 && (isCurrentTaskAdd === 'False'|| !!answer.SplitOrMergeLesionName)) || (qs.QuestionMark === 10 && (isCurrentTaskAdd === 'False' || (isCurrentTaskAdd === 'True' && !questionForm.IsCanEditPosition) || !!answer.SplitOrMergeLesionName))"
@change="((val)=>{formItemChange(val, qs)})"
>
<template v-if="qs.QuestionMark === 8" #prefix>
<span style="padding-left: 5px;">
<i class="el-icon-search" />
</span>
</template>
<template v-if="qs.TableQuestionType === 1">
<el-option
v-for="item in organList"
:key="item.Id"
:label="item[qs.DataTableColumn]"
:value="item[qs.DataTableColumn]"
/>
</template>
<template v-else-if="qs.DictionaryCode && qs.QuestionMark === 7 && isBaseLineTask">
<el-option
v-for="item of $d[qs.DictionaryCode]"
v-show="(lesionType === 0 && item.value ===0) || (lesionType === 1 && (item.value ===0))"
:key="item.id"
:value="item.value"
:label="item.label"
/>
</template>
<template v-else-if="qs.DictionaryCode && qs.QuestionMark === 7 && !isBaseLineTask">
<el-option-group
:label="!isNaN(parseFloat(answer.LastTaskState)) ? `${$t('trials:dicomReading:tip:lastVisitStatus')} ${$fd(qs.DictionaryCode,parseFloat(answer.LastTaskState))}` : ''"
>
<!-- 首次分裂的病灶只能选择存在 -->
<template v-if="answer.IsFristAdd=== 'True' && answer.SplitOrMergeType === '0'">
<el-option
v-for="item of $d[qs.DictionaryCode]"
v-show="item.value === 0"
:key="item.id"
:value="item.value"
:label="item.label"
/>
</template>
<!-- 首次添加的新病灶不能为无法评估和消失 -->
<template v-else-if="isCurrentTaskAdd=== 'True' && lesionType === 2">
<el-option
v-for="item of $d[qs.DictionaryCode]"
v-show="item.value === 0 || item.value === 1"
:key="item.id"
:value="item.value"
:label="item.label"
/>
</template>
<template v-else>
<el-option
v-for="item of filterState($d[qs.DictionaryCode])"
:key="item.id"
:value="item.value"
:label="item.label"
/>
</template>
</el-option-group>
</template>
<template v-else-if="qs.DictionaryCode && qs.QuestionMark !== 7">
<el-option
v-for="item of $d[qs.DictionaryCode]"
:key="item.id"
:value="item.value"
:label="item.label"
/>
</template>
<template v-else>
<el-option
v-for="val in qs.TypeValue.split('|')"
:key="val"
:label="val"
:value="val"
/>
</template>
</el-select>
<!-- 单选 -->
<el-radio-group
v-if="qs.Type==='radio'"
v-model="qsForm[qs.id]"
:disabled="!isCurrentTask || readingTaskState>=2"
>
<el-radio
v-for="val in qs.options.split('|')"
:key="val"
:label="val"
>
{{ val }}
</el-radio>
</el-radio-group>
</el-form-item>
</div>
</template>
<script>
export default {
name: 'TableQuestionFormItem',
props: {
tableInfo: {
type: Object,
default() {
return {}
}
},
answer: {
type: Object,
default() {
return {}
}
},
questionForm: {
type: Object,
default() {
return {}
}
},
organs: {
type: Array,
default() {
return []
}
},
readingTaskState: {
type: Number,
required: true
},
isBaseLineTask: {
type: Boolean,
required: true
},
isCurrentTask: {
type: Boolean,
required: true
}
},
data() {
return {
isCurrentTaskAdd: null,
lesionType: null,
questions: [],
organList: [],
qsForm: {}
}
},
watch: {
questionForm: {
deep: true,
immediate: true,
handler(v) {
if (v.MeasureData) {
const { markTool } = v.MeasureData
if (markTool === 'Bidirectional') {
this.getOrganList(1)
} else if (markTool === 'Length') {
this.getOrganList(0)
} else {
this.getOrganList()
}
} else {
this.getOrganList()
}
for (const key in v) {
this.$set(this.qsForm, key, v[key])
}
this.isCurrentTaskAdd = v.IsCurrentTaskAdd
}
},
tableInfo: {
deep: true,
immediate: true,
handler(v) {
if (v) {
this.lesionType = v.LesionType
this.questions = v.TableQuestions.Questions
}
}
}
},
methods: {
lesionTypeChange(v) {
this.$emit('lesionTypeChange', { tableId: this.tableInfo.Id, rowIndex: this.answer.RowIndex, newLesionType: v })
},
formItemChange(v, qs) {
const updateArr = []
if (qs.QuestionMark === 8 && qs.RelationQuestions.length > 0) {
//
const index = this.organList.findIndex(item => item[qs.DataTableColumn] === v)
if (index > -1) {
const selected = this.organList[index]
qs.RelationQuestions.map(q => {
const val = selected[q.DataTableColumn]
updateArr.push({ questionId: q.Id, val: val, questionMark: q.QuestionMark })
})
updateArr.push({ questionId: 'OrganInfoId', val: selected.OrganInfoId })
updateArr.push({ questionId: 'IsCanEditPosition', val: selected.IsCanEditPosition })
} else {
qs.RelationQuestions.map(q => {
updateArr.push({ questionId: q.Id, val: '', questionMark: q.QuestionMark })
})
}
}
this.$emit('update', { tableId: this.tableInfo.Id, rowIndex: this.answer.RowIndex, questionMark: qs.QuestionMark, questionId: qs.Id, val: v, updateArr })
},
getOrganList(isLymphNodes = null) {
const idx = this.organs.findIndex(i => i.LesionType === this.questionForm.LesionType)
if (idx > -1) {
const arr = this.organs[idx].OrganList
if (!isNaN(parseInt(isLymphNodes))) {
this.organList = arr.filter((item) => item.IsLymphNodes === parseInt(isLymphNodes))
} else {
this.organList = arr
}
}
},
filterState(arr) {
if (!this.isBaseLineTask) {
const isLymphLesion = this.questionForm.IsLymphNodes
const lesionLength = this.questionForm.LesionLength
const lesionShort = this.questionForm.LesionShort
const bLesionL = !isNaN(parseFloat(this.questionForm.BaseLineMajorAxis)) ? parseFloat(this.questionForm.BaseLineMajorAxis) : 0
const bLesionS = !isNaN(parseFloat(this.questionForm.BaseLineShortAxis)) ? parseFloat(this.questionForm.BaseLineShortAxis) : 0
if (this.lesionType === 1 && isLymphLesion === 1 && this.questionForm.MeasureData && this.questionForm.MeasureData.markTool === 'Bidirectional' && lesionShort < bLesionS) {
arr = arr.filter(i => i.value !== 1)
} else if (this.lesionType === 1 && isLymphLesion === 1 && this.questionForm.MeasureData && this.questionForm.MeasureData.markTool === 'Bidirectional' && lesionShort >= 10 && lesionShort > bLesionS) {
arr = arr.filter(i => i.value === 0 || i.value === 1)
} else if (this.lesionType === 1 && isLymphLesion === 0 && this.questionForm.MeasureData && (this.questionForm.MeasureData.markTool === 'Length' || this.questionForm.MeasureData.markTool === 'Bidirectional') && lesionLength < bLesionL) {
arr = arr.filter(i => i.value !== 1)
}
return arr
} else {
return arr
}
},
close() {
this.$emit('close', { tableId: this.tableInfo.Id, rowIndex: this.answer.RowIndex })
}
}
}
</script>
<style lang="scss" scoped>
.table-question-form{
::v-deep .el-form-item__label{
color: #c3c3c3;
}
::v-deep .el-input .el-input__inner{
background-color: transparent;
color: #ddd;
border: 1px solid #5e5e5e;
}
::v-deep .el-form-item{
display: flex;
flex-direction: row;
justify-content: flex-start;
}
::v-deep .el-form-item__content{
flex: 1;
}
::v-deep .el-input.is-disabled .el-input__inner{
background-color: #646464a1;
}
::v-deep .el-select.is-disabled .el-input__inner{
background-color: #646464a1;
}
::v-deep .el-button--mini, .el-button--mini.is-round {
padding: 7px 10px;
}
.el-form-item__content
.el-select{
width: 100%;
}
.input-width1{
width: calc(100% - 60px)!important;
}
.input-width2{
width: 100% !important;
}
}
</style>
@@ -1,237 +0,0 @@
const config = {
"standards": [
{
"type": 1,
"name": "RECIST 1.1",
"tools": [
{
"name": "直径测量工具",
"icon": "length",
"toolName": "Length",
"i18nKey": "trials:reading:button:length",
"isDisabled": false,
"disabledReason": ''
},
{
"name": "长短径测量工具",
"icon": "bidirection",
"toolName": "Bidirectional",
"i18nKey": "trials:reading:button:bidirectional",
"isDisabled": false,
"disabledReason": ''
},
{
"name": "矩形工具",
"icon": "rectangle",
"toolName": "RectangleRoi",
"i18nKey": "trials:reading:button:rectangle",
"isDisabled": false,
"disabledReason": ''
},
{
"name": "箭头工具",
"icon": "arrow",
"toolName": "ArrowAnnotate",
"i18nKey": "trials:reading:button:arrowAnnotate",
"isDisabled": false,
"disabledReason": ''
}
]
},
{
"type": 2,
"name": "Lugano 2014",
"tools": [
{
"name": "直径测量工具",
"icon": "length",
"toolName": "Length",
"i18nKey": "trials:reading:button:length",
"isDisabled": false,
"disabledReason": ''
},
{
"name": "长短径测量工具",
"icon": "bidirection",
"toolName": "Bidirectional",
"i18nKey": "trials:reading:button:bidirectional",
"isDisabled": false,
"disabledReason": ''
},
{
"name": "矩形工具",
"icon": "rectangle",
"toolName": "RectangleRoi",
"i18nKey": "trials:reading:button:rectangle",
"isDisabled": false,
"disabledReason": ''
},
{
"name": "箭头工具",
"icon": "arrow",
"toolName": "ArrowAnnotate",
"i18nKey": "trials:reading:button:arrowAnnotate",
"isDisabled": false,
"disabledReason": ''
}
]
},
{
"type": 3,
"name": "iRECIST",
"tools": [
{
"name": "直径测量工具",
"icon": "length",
"toolName": "Length",
"i18nKey": "trials:reading:button:length",
"isDisabled": false,
"disabledReason": ''
},
{
"name": "长短径测量工具",
"icon": "bidirection",
"toolName": "Bidirectional",
"i18nKey": "trials:reading:button:bidirectional",
"isDisabled": false,
"disabledReason": ''
},
{
"name": "矩形工具",
"icon": "rectangle",
"toolName": "RectangleRoi",
"i18nKey": "trials:reading:button:rectangle",
"isDisabled": false,
"disabledReason": ''
},
{
"name": "箭头工具",
"icon": "arrow",
"toolName": "ArrowAnnotate",
"i18nKey": "trials:reading:button:arrowAnnotate",
"isDisabled": false,
"disabledReason": ''
}
]
},
{
"type": 7,
"name": "mRECIST HCC",
"tools": [
{
"name": "直径测量工具",
"icon": "length",
"toolName": "Length",
"i18nKey": "trials:reading:button:length",
"isDisabled": false,
"disabledReason": ''
},
{
"name": "长短径测量工具",
"icon": "bidirection",
"toolName": "Bidirectional",
"i18nKey": "trials:reading:button:bidirectional",
"isDisabled": false,
"disabledReason": ''
},
{
"name": "矩形工具",
"icon": "rectangle",
"toolName": "RectangleRoi",
"i18nKey": "trials:reading:button:rectangle",
"isDisabled": false,
"disabledReason": ''
},
{
"name": "箭头工具",
"icon": "arrow",
"toolName": "ArrowAnnotate",
"i18nKey": "trials:reading:button:arrowAnnotate",
"isDisabled": false,
"disabledReason": ''
}
]
},
{
"type": 10,
"name": "PCWG3",
"tools": [
{
"name": "矩形工具",
"icon": "rectangle",
"toolName": "RectangleRoi",
"i18nKey": "trials:reading:button:rectangle",
"isDisabled": false,
"disabledReason": ''
},
{
"name": "箭头工具",
"icon": "arrow",
"toolName": "ArrowAnnotate",
"i18nKey": "trials:reading:button:arrowAnnotate",
"isDisabled": false,
"disabledReason": ''
}
]
},
{
"type": 17,
"name": "PCWG3",
"tools": [
{
"name": "直径测量工具",
"icon": "length",
"toolName": "Length",
"i18nKey": "trials:reading:button:length",
"isDisabled": false,
"disabledReason": ''
},
{
"name": "矩形工具",
"icon": "rectangle",
"toolName": "RectangleRoi",
"i18nKey": "trials:reading:button:rectangle",
"isDisabled": false,
"disabledReason": ''
},
{
"name": "箭头工具",
"icon": "arrow",
"toolName": "ArrowAnnotate",
"i18nKey": "trials:reading:button:arrowAnnotate",
"isDisabled": false,
"disabledReason": ''
}
]
},
{
"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",
"isDisabled": false,
"disabledReason": ''
}
]
}
]
}
const getTools = (criterionType) => {
const standard = config.standards.find(s => s.type === criterionType);
return standard?.tools || [];
};
export {config, getTools}
@@ -1,113 +0,0 @@
<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.IsBaseLine && this.taskInfo.IsReadingTaskViewInOrder !== 0) {
if (this.taskInfo.VisitNum > 0 && this.taskInfo.IsReadingTaskViewInOrder !== 0) {
this.rows = 1
this.cols = 2
this.activeCanvasIndex = 1
@@ -200,8 +200,7 @@ export default {
this.$refs[res.Result[idx].VisitTaskId][0].setInitActiveFile()
})
}
if (this.taskInfo.IsReadingTaskViewInOrder === 1 && res.Result.length > 1) {
//
if (this.taskInfo.IsReadingTaskViewInOrder !== 0 && res.Result.length > 1) {
const i = this.visitTaskList.findIndex(i => i.IsBaseLineTask)
if (i > -1) {
await this.getReadingImageFile(res.Result[i].VisitTaskId, i)
@@ -216,14 +215,6 @@ 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)
@@ -295,8 +286,8 @@ export default {
async toggleTaskByViewer(visitTaskNum) {
const i = this.visitTaskList.findIndex(v => v.VisitTaskNum === visitTaskNum)
if (i === -1) return
const visitTaskId = this.visitTaskList[i].VisitTaskId
this.setActiveTaskVisitId(visitTaskId, true)
const visistTaskId = this.visitTaskList[i].VisitTaskId
this.setActiveTaskVisitId(visistTaskId, true)
},
// 访
async setActiveTaskVisitId(id, isInitActiveFile = false) {
@@ -2,14 +2,31 @@
<BaseContainer>
<template slot="search-container">
<el-form :inline="true">
<el-form-item :label="$t('trials:loginLog:table:optType')" prop="OptType">
<el-select v-model="searchData.OptTypeList" clearable multiple :collapse-tags="true" style="width: 200px">
<el-option v-for="item of $d.UserOptType" v-show="item.value !== 3 && item.value !== 10 && item.value !== 9"
:key="'UserOptType' + item.label" :value="item.value" :label="item.label" />
<el-form-item
:label="$t('trials:loginLog:table:optType')"
prop="OptType"
>
<el-select
v-model="searchData.OptType"
clearable
style="width: 120px"
>
<el-option
v-for="item of $d.UserOptType"
v-show="item.value !== 3 && item.value !== 10 && item.value !== 9"
:key="'UserOptType' + item.label"
:value="item.value"
:label="item.label"
/>
</el-select>
</el-form-item>
<el-form-item label="IP" prop="IP">
<el-input v-model="searchData.IP" size="small" clearable style="width: 120px" />
<el-input
v-model="searchData.IP"
size="small"
clearable
style="width: 120px"
/>
</el-form-item>
<!-- <el-form-item
:label="$t('trials:loginLog:table:incorrectUserName')"
@@ -23,52 +40,108 @@
style="width: 120px"
/>
</el-form-item> -->
<el-form-item :label="$t('trials:loginLog:table:userName')" prop="LoginUserName" v-if="!isMine">
<el-form-item
:label="$t('trials:loginLog:table:userName')"
prop="LoginUserName"
v-if="!isMine"
>
<el-select v-model="searchData.IdentityUserId" clearable style="width: 120px">
<el-option v-for="item of trialUserList" :key="item.IdentityUserId" :value="item.IdentityUserId"
:label="item.UserName" />
<el-option
v-for="item of trialUserList"
:key="item.IdentityUserId"
:value="item.IdentityUserId"
:label="item.UserName"
/>
</el-select>
</el-form-item>
<el-form-item :label="$t('trials:loginLog:table:optUserName')" prop="TargetIdentityUserId" v-if="!isMine">
<el-form-item
:label="$t('trials:loginLog:table:optUserName')"
prop="TargetIdentityUserId"
v-if="!isMine"
>
<el-select v-model="searchData.TargetIdentityUserId" clearable style="width: 120px">
<el-option v-for="item of trialUserList" :key="item.IdentityUserId" :value="item.IdentityUserId"
:label="item.UserName" />
<el-option
v-for="item of trialUserList"
:key="item.IdentityUserId"
:value="item.IdentityUserId"
:label="item.UserName"
/>
</el-select>
</el-form-item>
<el-form-item :label="$t('trials:loginLog:table:userType')" prop="OptType" v-if="!isMine">
<el-select v-model="searchData.LoginUserType" clearable style="width: 120px">
<el-option v-for="item of $d.UserType" v-show="item.value !== 7 && item.value !== 8"
:key="'UserType' + item.label" :value="item.label" :label="item.label" />
<el-form-item
:label="$t('trials:loginLog:table:userType')"
prop="OptType"
v-if="!isMine"
>
<el-select
v-model="searchData.LoginUserType"
clearable
style="width: 120px"
>
<el-option
v-for="item of $d.UserType"
v-show="item.value !== 7 && item.value !== 8"
:key="'UserType' + item.label"
:value="item.label"
:label="item.label"
/>
</el-select>
</el-form-item>
<el-form-item :label="$t('trials:loginLog:table:createTime')">
<el-date-picker v-model="datetimerange" type="datetimerange" :default-time="['00:00:00', '23:59:59']"
<el-date-picker
v-model="datetimerange"
type="datetimerange"
:default-time="['00:00:00', '23:59:59']"
:start-placeholder="$t('trials:loginLog:table:beginTime')"
:end-placeholder="$t('trials:loginLog:table:endTime')" value-format="yyyy-MM-dd HH:mm:ss"
@change="handleDatetimeChange" />
:end-placeholder="$t('trials:loginLog:table:endTime')"
value-format="yyyy-MM-dd HH:mm:ss"
@change="handleDatetimeChange"
/>
</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">
<el-button
type="primary"
icon="el-icon-refresh-left"
@click="handleReset"
>
{{ $t('common:button:reset') }}
</el-button>
</el-form-item>
</el-form>
</template>
<template slot="main-container">
<el-table v-loading="loading" v-adaptive="{ bottomOffset: isMine ? 80 : 60 }" height="100" :data="list"
class="table" @sort-change="handleSortByColumn" :default-sort="{ prop: 'CreateTime', order: 'descending' }">
<el-table
v-loading="loading"
v-adaptive="{ bottomOffset: isMine ? 80 : 60 }"
height="100"
:data="list"
class="table"
@sort-change="handleSortByColumn"
:default-sort="{ prop: 'CreateTime', order: 'descending' }"
>
<el-table-column type="index" width="50" />
<el-table-column :label="$t('trials:loginLog:table:optType')" prop="OptType" min-width="90"
show-overflow-tooltip sortable="custom">
<el-table-column
:label="$t('trials:loginLog:table:optType')"
prop="OptType"
min-width="90"
show-overflow-tooltip
sortable="custom"
>
<template slot-scope="scope">
{{ $fd('UserOptType', scope.row.OptType) }}
</template>
</el-table-column>
<el-table-column label="IP" prop="IP" min-width="90" show-overflow-tooltip sortable="custom" />
<el-table-column
label="IP"
prop="IP"
min-width="90"
show-overflow-tooltip
sortable="custom"
/>
<!-- <el-table-column
:label="$t('trials:loginLog:table:IPRegion')"
prop="IPRegion"
@@ -84,10 +157,20 @@
show-overflow-tooltip
sortable="custom"
/> -->
<el-table-column :label="$t('trials:loginLog:table:userName')" prop="ActionUserName" min-width="90"
show-overflow-tooltip sortable="custom" />
<el-table-column :label="$t('trials:loginLog:table:Aetionlserlype')" prop="ActionUserType" min-width="100"
show-overflow-tooltip sortable="custom" />
<el-table-column
:label="$t('trials:loginLog:table:userName')"
prop="ActionUserName"
min-width="90"
show-overflow-tooltip
sortable="custom"
/>
<el-table-column
:label="$t('trials:loginLog:table:Aetionlserlype')"
prop="ActionUserType"
min-width="100"
show-overflow-tooltip
sortable="custom"
/>
<!-- <el-table-column
:label="$t('trials:loginLog:table:userType')"
prop="LoginUserTypeEnum"
@@ -99,8 +182,14 @@
{{ $fd('UserType', scope.row.LoginUserTypeEnum) }}
</template>
</el-table-column> -->
<el-table-column v-if="!isMine" :label="$t('trials:loginLog:table:optUserName')" prop="TargetIdentityUserName"
min-width="120" show-overflow-tooltip sortable="custom" />
<el-table-column
v-if="!isMine"
:label="$t('trials:loginLog:table:optUserName')"
prop="TargetIdentityUserName"
min-width="120"
show-overflow-tooltip
sortable="custom"
/>
<!-- <el-table-column
v-if="!isMine"
:label="$t('trials:loginLog:table:optUserType')"
@@ -113,19 +202,37 @@
{{ $fd('UserType', scope.row.OptUserTypeEnum) }}
</template>
</el-table-column> -->
<el-table-column :label="$t('trials:loginLog:table:detail')" min-width="80" show-overflow-tooltip>
<el-table-column
:label="$t('trials:loginLog:table:detail')"
min-width="80"
show-overflow-tooltip
>
<template slot-scope="scope">
<el-button v-if="scope.row.JsonObj" type="text" @click="handleOpenDialog(scope.row)">
<el-button
v-if="scope.row.JsonObj"
type="text"
@click="handleOpenDialog(scope.row)"
>
<span>{{ $t('trials:loginLog:message:detail') }}</span>
</el-button>
</template>
</el-table-column>
<el-table-column :label="$t('trials:loginLog:table:createTime')" prop="CreateTime" min-width="90"
show-overflow-tooltip sortable="custom" />
<el-table-column
:label="$t('trials:loginLog:table:createTime')"
prop="CreateTime"
min-width="90"
show-overflow-tooltip
sortable="custom"
/>
</el-table>
<!-- 分页组件 -->
<pagination class="page" :total="total" :page.sync="searchData.PageIndex" :limit.sync="searchData.PageSize"
@pagination="getList" />
<pagination
class="page"
:total="total"
:page.sync="searchData.PageIndex"
:limit.sync="searchData.PageSize"
@pagination="getList"
/>
</template>
<detail :config="config" :JsonObj="JsonObj" />
</BaseContainer>
@@ -140,7 +247,6 @@ const searchDataDefault = () => {
return {
TrialId: '',
OptType: null,
OptTypeList: [],
Ip: '',
LoginFaildName: '',
LoginUserName: '',
@@ -10,20 +10,43 @@
)
}}</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>
@@ -31,45 +54,82 @@
</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
? `${(scope.row.size / 1024 / 1024).toFixed(3)}MB`
: '0MB'
: ''
}}</span>
</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.size && scope.row.size > 0 ? ((scope.row.uploadFileSize * 100) / scope.row.size).toFixed(2) *
1
: ((scope.row.uploadFileSize * 100) / 1).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>
@@ -79,8 +139,13 @@
<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>
@@ -200,11 +265,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)
@@ -235,7 +300,7 @@ export default {
)
}
})
.catch(() => { })
.catch(() => {})
},
//
async beginUpload() {
@@ -283,8 +348,7 @@ export default {
FileName: file.name,
FilePath: this.$getObjectName(res.url),
FileSize: file.size,
FileFormat: fileType.split('.')[1],
catalogue: file.webkitRelativePath
FileFormat: fileType,
})
let flag = arr.every((item) => item.status === 2)
if (flag) {
@@ -326,7 +390,7 @@ export default {
(percentage, checkpoint, lastPer) => {
item.uploadFileSize += checkpoint.size * (percentage - lastPer)
if (item.uploadFileSize > file.fileSize) {
item.uploadFileSize = file.fileSize > 0 ? file.fileSize : 1
item.uploadFileSize = file.fileSize
}
}
)
@@ -367,6 +431,7 @@ export default {
} else {
this.fileInput.accept = this.faccept.join(',')
}
console.log(this.fileInput)
this.fileInput.click()
},
},
@@ -416,7 +481,6 @@ export default {
background: #428bca;
border-color: #428bca;
color: #fff;
.select-file {
height: 30px;
width: 90px;
@@ -427,7 +491,6 @@ export default {
opacity: 0;
font-size: 0;
}
.btn-select {
//
width: 90px;
@@ -359,7 +359,6 @@ export default {
status: 'add',
upload: null,
},
DATA: {},
doctorList: [],
}
},
@@ -632,12 +631,6 @@ export default {
},
immediate: true,
},
rowData: {
handler() {
this.DATA = Object.assign({}, this.rowData)
},
immediate: true,
},
},
created() {
let typeArr = ['', 'Report', 'Doc', 'Record', 'Reviewer', 'Template']
@@ -253,11 +253,4 @@ 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>
@@ -2,40 +2,93 @@
<div v-loading="loading" class="non-dicom-wrapper">
<!-- <h4 class="box-title">既往放疗史</h4> -->
<div style="text-align: right">
<el-button v-if="allowAddOrEdit" v-hasPermi="['trials:trials-panel:visit:crc-upload:edit']" icon="el-icon-plus"
type="primary" size="small" @click.native.prevent="handleAdd">
<el-button
v-if="allowAddOrEdit"
v-hasPermi="['trials:trials-panel:visit:crc-upload:edit']"
icon="el-icon-plus"
type="primary"
size="small"
@click.native.prevent="handleAdd"
>
{{ $t('common:button:new') }}
</el-button>
<el-button icon="el-icon-view" type="primary" size="small" :disabled="nonDicomStudyList.length === 0"
@click="handlePreviewAllVisitFiles">
<el-button
icon="el-icon-view"
type="primary"
size="small"
:disabled="nonDicomStudyList.length === 0"
@click="handlePreviewAllVisitFiles"
>
{{ $t('trials:uploadNonDicoms:button:preview') }}
</el-button>
</div>
<el-table :data="nonDicomStudyList" style="width: 100%" :default-sort="{ prop: 'CreateTime', order: 'ascending' }"
:row-class-name="tableRowClassName">
<el-table
:data="nonDicomStudyList"
style="width: 100%"
:default-sort="{ prop: 'CreateTime', order: 'ascending' }"
:row-class-name="tableRowClassName"
>
<!-- 检查编号 -->
<el-table-column prop="CodeView" :label="$t('trials:uploadNonDicoms:table:studyId')" sortable />
<el-table-column
prop="CodeView"
:label="$t('trials:uploadNonDicoms:table:studyId')"
sortable
/>
<!-- 检查名称 -->
<el-table-column v-if="relationInfo.IsShowStudyName" prop="StudyName"
:label="$t('trials:uploadNonDicoms:table:StudyName')" sortable />
<el-table-column
v-if="relationInfo.IsShowStudyName"
prop="StudyName"
:label="$t('trials:uploadNonDicoms:table:StudyName')"
sortable
/>
<!-- 检查类型 -->
<el-table-column prop="Modality" :label="$t('trials:uploadNonDicoms:table:modality')" sortable />
<el-table-column
prop="Modality"
:label="$t('trials:uploadNonDicoms:table:modality')"
sortable
/>
<!-- 检查部位 -->
<el-table-column prop="BodyPart" :label="$t('trials:uploadNonDicoms:table:bodyPart')" sortable>
<el-table-column
prop="BodyPart"
:label="$t('trials:uploadNonDicoms:table:bodyPart')"
sortable
>
<template slot-scope="scope">
{{ getBodyPart(scope.row.BodyPart) }}
</template>
</el-table-column>
<!-- 文件 -->
<el-table-column prop="FileCount" :label="$t('trials:uploadNonDicoms:table:files')" sortable>
<el-table-column
prop="FileCount"
:label="$t('trials:uploadNonDicoms:table:files')"
sortable
>
<template slot-scope="scope">
<el-popover v-if="scope.row.FileCount" trigger="click" placement="bottom" popper-class="imgTable">
<el-table v-loading="filesLoading" :data="nonDicomfilesList" height="300" size="small"
:row-class-name="tableRowClassName">
<el-popover
v-if="scope.row.FileCount"
trigger="click"
placement="bottom"
popper-class="imgTable"
>
<el-table
v-loading="filesLoading"
:data="nonDicomfilesList"
height="300"
size="small"
:row-class-name="tableRowClassName"
>
<!-- 文件名称 -->
<el-table-column prop="FileName" :label="$t('trials:uploadNonDicoms:table:fileName')" width="200" />
<el-table-column prop="FileSize" :label="$t('trials:audit:table:nonDicomsFileSize')" width="100">
<el-table-column
prop="FileName"
:label="$t('trials:uploadNonDicoms:table:fileName')"
width="200"
/>
<el-table-column
prop="FileSize"
:label="$t('trials:audit:table:nonDicomsFileSize')"
width="100"
>
<template slot-scope="scope">
<span>{{
scope.row.FileSize && scope.row.FileSize > 0
@@ -48,38 +101,71 @@
<template slot-scope="files">
<div style="display: flex">
<!-- 预览 -->
<viewer v-if="files.row.type !== 'MP4'" :ref="files.row.FullFilePath" style="margin: 0 10px"
<viewer
v-if="files.row.type !== 'MP4'"
:ref="files.row.FullFilePath"
style="margin: 0 10px"
:images="[
`${OSSclientConfig.basePath}${files.row.FullFilePath}`,
]">
<el-button icon="el-icon-view" circle :title="$t('trials:uploadNonDicoms:action:preview')"
size="small" :disabled="files.row.FileType &&
]"
>
<el-button
icon="el-icon-view"
circle
:title="$t('trials:uploadNonDicoms:action:preview')"
size="small"
:disabled="
files.row.FileType &&
files.row.FileType.indexOf('zip') >= 0
" @click.native.prevent="handlePreviewImg(files.row)">
"
@click.native.prevent="handlePreviewImg(files.row)"
>
</el-button>
<img v-show="false" crossorigin="anonymous"
:src="`${OSSclientConfig.basePath}${files.row.FullFilePath}`" alt="Image" />
<img
v-show="false"
crossorigin="anonymous"
:src="`${OSSclientConfig.basePath}${files.row.FullFilePath}`"
alt="Image"
/>
</viewer>
<el-button v-if="files.row.type === 'MP4'" icon="el-icon-view" circle
:title="$t('trials:uploadNonDicoms:action:preview')" size="small" :disabled="files.row.FileType &&
<el-button
v-if="files.row.type === 'MP4'"
icon="el-icon-view"
circle
:title="$t('trials:uploadNonDicoms:action:preview')"
size="small"
:disabled="
files.row.FileType &&
files.row.FileType.indexOf('zip') >= 0
" @click.native.prevent="handleLookVideo(scope.row)" />
"
@click.native.prevent="handleLookVideo(scope.row)"
/>
<!-- 删除 -->
<el-button v-if="allowAddOrEdit" v-hasPermi="[
'trials:trials-panel:visit:crc-upload:delete',
]" icon="el-icon-delete" circle :title="$t('trials:uploadNonDicoms:action:delete')" size="small"
<el-button
v-if="allowAddOrEdit"
v-hasPermi="[
'trials:trials-panel:visit:crc-upload:delete',
]"
icon="el-icon-delete"
circle
:title="$t('trials:uploadNonDicoms:action:delete')"
size="small"
@click.native.prevent="
files.row.type === 'MP4'
? hadnleDeleteVideo(scope.row)
: handleDeleteFile(files.row.Id)
" />
"
/>
</div>
</template>
</el-table-column>
</el-table>
<div slot="reference" class="name-wrapper">
<el-button type="text" @click.native.prevent="handleGetFilesList(scope.row)">
<el-button
type="text"
@click.native.prevent="handleGetFilesList(scope.row)"
>
{{ scope.row.FileCount }}
</el-button>
</div>
@@ -88,23 +174,46 @@
</template>
</el-table-column>
<!-- 检查日期 -->
<el-table-column prop="ImageDate" :label="$t('trials:uploadNonDicoms:table:studyDate')" sortable>
<el-table-column
prop="ImageDate"
:label="$t('trials:uploadNonDicoms:table:studyDate')"
sortable
>
<template slot-scope="scope">
{{ moment(scope.row.ImageDate).format('YYYY-MM-DD') }}
</template>
</el-table-column>
<!-- 更新时间 -->
<el-table-column prop="UpdateTime" :label="$t('trials:uploadNonDicoms:table:updateTime')" sortable />
<el-table-column
prop="UpdateTime"
:label="$t('trials:uploadNonDicoms:table:updateTime')"
sortable
/>
<!-- 创建时间 -->
<el-table-column prop="CreateTime" :label="$t('trials:uploadNonDicoms:table:CreateTime')" sortable />
<el-table-column
prop="CreateTime"
:label="$t('trials:uploadNonDicoms:table:CreateTime')"
sortable
/>
<el-table-column :label="$t('common:action:action')" min-width="200">
<template slot-scope="scope">
<!-- 预览 -->
<el-button icon="el-icon-view" circle :title="$t('trials:uploadNonDicoms:action:preview')"
:disabled="scope.row.FileCount === 0" @click.native.prevent="handlePreviewAllFiles(scope.row)" />
<el-button
icon="el-icon-view"
circle
:title="$t('trials:uploadNonDicoms:action:preview')"
:disabled="scope.row.FileCount === 0"
@click.native.prevent="handlePreviewAllFiles(scope.row)"
/>
<!-- 上传 -->
<el-button v-if="allowAddOrEdit" icon="el-icon-upload2" circle :disabled="scope.row.IsDeleted"
:title="$t('trials:uploadNonDicoms:action:upload')" @click.native.prevent="handleUpload(scope.row)" />
<el-button
v-if="allowAddOrEdit"
icon="el-icon-upload2"
circle
:disabled="scope.row.IsDeleted"
:title="$t('trials:uploadNonDicoms:action:upload')"
@click.native.prevent="handleUpload(scope.row)"
/>
<!-- 上传视频 -->
<!-- <el-button
v-if="( allowAddOrEdit)"
@@ -114,86 +223,156 @@
@click.native.prevent="handleUploadVideo(scope.row)"
/> -->
<!-- 编辑 -->
<el-button v-if="allowAddOrEdit" v-hasPermi="['trials:trials-panel:visit:crc-upload:edit']"
icon="el-icon-edit-outline" circle :title="$t('trials:uploadNonDicoms:action:edit')"
@click.native.prevent="handleEdit(scope.row)" />
<el-button
v-if="allowAddOrEdit"
v-hasPermi="['trials:trials-panel:visit:crc-upload:edit']"
icon="el-icon-edit-outline"
circle
:title="$t('trials:uploadNonDicoms:action:edit')"
@click.native.prevent="handleEdit(scope.row)"
/>
<!-- 删除 -->
<el-button v-if="allowAddOrEdit" v-hasPermi="['trials:trials-panel:visit:crc-upload:delete']"
icon="el-icon-delete" circle :title="$t('trials:uploadNonDicoms:action:delete')"
@click.native.prevent="handleDelete(scope.row)" />
<el-button
v-if="allowAddOrEdit"
v-hasPermi="['trials:trials-panel:visit:crc-upload:delete']"
icon="el-icon-delete"
circle
:title="$t('trials:uploadNonDicoms:action:delete')"
@click.native.prevent="handleDelete(scope.row)"
/>
</template>
</el-table-column>
</el-table>
<!-- 编辑 -->
<el-dialog v-if="dialogVisible" :visible.sync="dialogVisible" :close-on-click-modal="false" :title="title"
width="600px" append-to-body custom-class="base-dialog-wrapper">
<el-dialog
v-if="dialogVisible"
:visible.sync="dialogVisible"
:close-on-click-modal="false"
:title="title"
width="600px"
append-to-body
custom-class="base-dialog-wrapper"
>
<el-form ref="editForm" :model="form" label-width="100px">
<div class="base-dialog-body">
<!-- 检查编号 -->
<el-form-item v-if="!!form.CodeView" :label="$t('trials:uploadNonDicoms:table:studyId')">
<el-form-item
v-if="!!form.CodeView"
:label="$t('trials:uploadNonDicoms:table:studyId')"
>
<el-input v-model="form.CodeView" disabled />
</el-form-item>
<!-- 检查名称 -->
<el-form-item v-if="relationInfo.IsShowStudyName" :label="$t('trials:uploadNonDicoms:table:StudyName')"
prop="StudyName" :rules="[
<el-form-item
v-if="relationInfo.IsShowStudyName"
:label="$t('trials:uploadNonDicoms:table:StudyName')"
prop="StudyName"
:rules="[
{
required: true,
message: $t('common:ruleMessage:specify'),
trigger: 'blur',
},
]">
]"
>
<el-radio-group v-model="form.StudyName">
<template v-for="m in relationInfo.StudyNameList">
<el-radio v-if="m.IsChoose" :key="m.Name" :label="isEN ? m.EnName : m.Name" style="line-height: 40px" />
<el-radio
v-if="m.IsChoose"
:key="m.Name"
:label="isEN ? m.EnName : m.Name"
style="line-height: 40px"
/>
</template>
</el-radio-group>
</el-form-item>
<!-- 检查类型 -->
<el-form-item :label="$t('trials:uploadNonDicoms:table:modality')" prop="Modality" :rules="[
{
required: true,
message: $t('common:ruleMessage:specify'),
trigger: 'blur',
},
]">
<el-form-item
:label="$t('trials:uploadNonDicoms:table:modality')"
prop="Modality"
:rules="[
{
required: true,
message: $t('common:ruleMessage:specify'),
trigger: 'blur',
},
]"
>
<el-radio-group v-model="form.Modality">
<template v-for="m in trialModalitys">
<el-radio v-if="m !== ''" :key="m" :label="m" style="line-height: 40px" />
<el-radio
v-if="m !== ''"
:key="m"
:label="m"
style="line-height: 40px"
/>
</template>
</el-radio-group>
</el-form-item>
<!-- 检查部位 -->
<el-form-item :label="$t('trials:uploadNonDicoms:table:bodyPart')" prop="BodyParts" :rules="[
{
required: true,
message: $t('common:ruleMessage:specify'),
trigger: 'blur',
},
]">
<el-form-item
:label="$t('trials:uploadNonDicoms:table:bodyPart')"
prop="BodyParts"
:rules="[
{
required: true,
message: $t('common:ruleMessage:specify'),
trigger: 'blur',
},
]"
>
<el-checkbox-group v-model="form.BodyParts">
<el-checkbox v-for="bodyPart in trialBodyPartTypes" :key="bodyPart" :label="bodyPart">{{
$fd('Bodypart', bodyPart, 'Code', BodyPart, 'Name')
}}</el-checkbox>
<el-checkbox
v-for="bodyPart in trialBodyPartTypes"
:key="bodyPart"
:label="bodyPart"
>{{
$fd('Bodypart', bodyPart, 'Code', BodyPart, 'Name')
}}</el-checkbox
>
</el-checkbox-group>
</el-form-item>
<!-- 检查日期 -->
<el-form-item :label="$t('trials:uploadNonDicoms:table:studyDate')" prop="ImageDate" :rules="[
{
required: true,
message: $t('common:ruleMessage:specify'),
trigger: 'blur',
},
]">
<el-date-picker v-model="form.ImageDate" type="date" :picker-options="pickerOption"
value-format="yyyy-MM-dd" format="yyyy-MM-dd" style="width: 100%" />
<el-form-item
:label="$t('trials:uploadNonDicoms:table:studyDate')"
prop="ImageDate"
:rules="[
{
required: true,
message: $t('common:ruleMessage:specify'),
trigger: 'blur',
},
]"
>
<el-date-picker
v-model="form.ImageDate"
type="date"
:picker-options="pickerOption"
value-format="yyyy-MM-dd"
format="yyyy-MM-dd"
style="width: 100%"
/>
</el-form-item>
</div>
<div class="base-dialog-footer" style="text-align: right; margin-top: 10px">
<div
class="base-dialog-footer"
style="text-align: right; margin-top: 10px"
>
<el-form-item>
<el-button size="small" type="primary" :disabled="btnLoading" @click="dialogVisible = false">
<el-button
size="small"
type="primary"
:disabled="btnLoading"
@click="dialogVisible = false"
>
{{ $t('common:button:cancel') }}
</el-button>
<el-button size="small" type="primary" :loading="btnLoading" @click="handleSave">
<el-button
size="small"
type="primary"
:loading="btnLoading"
@click="handleSave"
>
{{ $t('common:button:save') }}
</el-button>
</el-form-item>
@@ -202,9 +381,16 @@
</el-dialog>
<!-- 上传非dicom文件 -->
<el-dialog v-if="uploadVisible" :visible.sync="uploadVisible" :close-on-click-modal="false"
:title="$t('trials:uploadNonDicoms:dialogTitle:upload')" width="800px" append-to-body
custom-class="base-dialog-wrapper" @close="resetFileDiaolg">
<el-dialog
v-if="uploadVisible"
:visible.sync="uploadVisible"
:close-on-click-modal="false"
:title="$t('trials:uploadNonDicoms:dialogTitle:upload')"
width="800px"
append-to-body
custom-class="base-dialog-wrapper"
@close="resetFileDiaolg"
>
<!-- 多文件上传 -->
<form id="inputForm" ref="uploadForm">
<el-divider content-position="left">{{
@@ -215,15 +401,33 @@
}}</el-divider>
<div class="form-group">
<div class="upload" style="margin-right: 10px">
<input multiple="multiple" webkitdirectory="" directory accept="*/*" type="file" name="uploadFolder"
class="select-file" title="" @change="beginScanFiles($event)" v-if="!btnLoading" />
<input
multiple="multiple"
webkitdirectory=""
directory
accept="*/*"
type="file"
name="uploadFolder"
class="select-file"
title=""
@change="beginScanFiles($event)"
v-if="!btnLoading"
/>
<div class="btn-select">
{{ $t('trials:uploadNonDicoms:button:selectFolder') }}
</div>
</div>
<div class="upload">
<input class="select-file" multiple="" :accept="faccept.join(',')" type="file" name="uploadFile" title=""
@change="beginScanFiles($event)" v-if="!btnLoading" />
<input
class="select-file"
multiple=""
:accept="faccept.join(',')"
type="file"
name="uploadFile"
title=""
@change="beginScanFiles($event)"
v-if="!btnLoading"
/>
<div class="btn-select">
{{ $t('trials:uploadNonDicoms:button:select') }}
</div>
@@ -231,46 +435,82 @@
</div>
</form>
<!-- 文件列表 -->
<el-table ref="filesTable" :data="fileList" class="dicomFiles-table" height="300"
@selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" :selectable="(row, index) => row.status !== 2 && !btnLoading" />
<el-table
ref="filesTable"
:data="fileList"
class="dicomFiles-table"
height="300"
@selection-change="handleSelectionChange"
>
<el-table-column
type="selection"
width="55"
:selectable="(row, index) => row.status !== 2 && !btnLoading"
/>
<el-table-column type="index" width="50" />
<!-- 文件名称 -->
<el-table-column prop="name" :label="$t('trials:uploadNonDicoms:table:fileName')" min-width="100" />
<el-table-column
prop="name"
:label="$t('trials:uploadNonDicoms:table:fileName')"
min-width="100"
/>
<!-- 文件大小 -->
<el-table-column prop="size" :label="$t('trials:uploadNonDicoms:table:fileSize')">
<el-table-column
prop="size"
:label="$t('trials:uploadNonDicoms:table:fileSize')"
>
<template slot-scope="scope">
<span>{{
scope.row.size && scope.row.size > 0
? `${(scope.row.size / 1024 / 1024).toFixed(3)}MB`
: '0MB'
: ''
}}</span>
</template>
</el-table-column>
<!-- 文件类型 -->
<el-table-column prop="type" :label="$t('trials:uploadNonDicoms:table:fileType')" />
<el-table-column
prop="type"
:label="$t('trials:uploadNonDicoms:table:fileType')"
/>
<!-- 上传状态 -->
<el-table-column prop="status" :label="$t('trials:uploadNonDicoms:table:uploadStatus')" min-width="100">
<el-table-column
prop="status"
:label="$t('trials:uploadNonDicoms:table:uploadStatus')"
min-width="100"
>
<template slot-scope="scope">
<el-tag :type="['warning', 'info', 'success', 'danger'][scope.row.status]"
v-if="scope.row.status || scope.row.status === 0">{{ $fd('NoneDicomUploadStatus', scope.row.status) }}
<el-tag
:type="['warning', 'info', 'success', 'danger'][scope.row.status]"
v-if="scope.row.status || scope.row.status === 0"
>{{ $fd('NoneDicomUploadStatus', scope.row.status) }}
</el-tag>
</template>
</el-table-column>
<el-table-column :label="$t('trials:uploadNonDicoms:table:failedFileCount')" min-width="150"
show-overflow-tooltip>
<el-table-column
:label="$t('trials:uploadNonDicoms:table:failedFileCount')"
min-width="150"
show-overflow-tooltip
>
<template slot-scope="scope">
<el-progress color="#409eff" :percentage="scope.row.size && scope.row.size > 0 ? ((scope.row.uploadFileSize * 100) / scope.row.size).toFixed(2) *
<el-progress
color="#409eff"
:percentage="
((scope.row.uploadFileSize * 100) / scope.row.size).toFixed(2) *
1
: ((scope.row.uploadFileSize * 100) / 1).toFixed(2) *
1
" />
"
/>
</template>
</el-table-column>
<el-table-column :label="$t('common:action:action')">
<template slot-scope="scope">
<el-button size="mini" icon="el-icon-delete" circle :disabled="btnLoading"
:title="$t('trials:crcUpload:action:delete')" @click="handleRemoveFile(scope.row)" />
<el-button
size="mini"
icon="el-icon-delete"
circle
:disabled="btnLoading"
:title="$t('trials:crcUpload:action:delete')"
@click="handleRemoveFile(scope.row)"
/>
</template>
</el-table-column>
</el-table>
@@ -278,8 +518,13 @@
<span style="margin-right: 10px">{{
$store.state.trials.uploadTip
}}</span>
<el-button size="small" type="primary" :disabled="selectArr.length == 0" :loading="btnLoading"
@click="beginUpload">
<el-button
size="small"
type="primary"
:disabled="selectArr.length == 0"
:loading="btnLoading"
@click="beginUpload"
>
{{ $t('trials:uploadNonDicoms:action:upload') }}
</el-button>
</div>
@@ -299,11 +544,25 @@
<upload-videos @uploadOver="uploadOver" />
</el-dialog> -->
<!-- 预览非DICOM视频文件 -->
<el-dialog v-if="lookVideoVisible" :visible.sync="lookVideoVisible" upload-video-visible
:close-on-click-modal="false" :title="$t('trials:uploadNonDicoms:title:xflookvideo')" width="480px" append-to-body
custom-class="base-dialog-wrapper">
<el-dialog
v-if="lookVideoVisible"
:visible.sync="lookVideoVisible"
upload-video-visible
:close-on-click-modal="false"
:title="$t('trials:uploadNonDicoms:title:xflookvideo')"
width="480px"
append-to-body
custom-class="base-dialog-wrapper"
>
<div style="display: flex; justify-content: center">
<video v-if="lookVideoVisible" id="video" controls crossorigin="anonymous" width="400" height="270">
<video
v-if="lookVideoVisible"
id="video"
controls
crossorigin="anonymous"
width="400"
height="270"
>
<source :src="currentRow.VideoUrl" type="video/mp4" />
</video>
</div>
@@ -313,12 +572,27 @@
</el-button>
</div>
</el-dialog>
<el-dialog v-if="previewImgVisible" :visible.sync="previewImgVisible"
:title="$t('trials:uploadNonDicoms:dialogTitle:preview')" append-to-body width="565px">
<div v-loading="imageLoading" class="base-modal-body" style="border: 2px solid #ccc; padding: 10px">
<el-image :src="`${OSSclientConfig.basePath}${imgUrl}`" crossorigin="anonymous" fit="fit"
style="height: 500px; width: 500px" @error="imageLoading = false" @load="imageLoading = false"
:preview-src-list="[`${OSSclientConfig.basePath}${imgUrl}`]" />
<el-dialog
v-if="previewImgVisible"
:visible.sync="previewImgVisible"
:title="$t('trials:uploadNonDicoms:dialogTitle:preview')"
append-to-body
width="565px"
>
<div
v-loading="imageLoading"
class="base-modal-body"
style="border: 2px solid #ccc; padding: 10px"
>
<el-image
:src="`${OSSclientConfig.basePath}${imgUrl}`"
crossorigin="anonymous"
fit="fit"
style="height: 500px; width: 500px"
@error="imageLoading = false"
@load="imageLoading = false"
:preview-src-list="[`${OSSclientConfig.basePath}${imgUrl}`]"
/>
</div>
</el-dialog>
</div>
@@ -565,7 +839,7 @@ export default {
this.loading = false
})
})
.catch(() => { })
.catch(() => {})
},
//
handleUpload(row) {
@@ -688,8 +962,9 @@ 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,
}
@@ -749,7 +1024,7 @@ export default {
)
}
})
.catch(() => { })
.catch(() => {})
},
//
handleSelectionChange(selection) {
@@ -795,10 +1070,11 @@ export default {
if (!this.uploadVisible) return
let file = this.fileList.filter((item) => item.id === arr[index].id)[0]
file.status = 1
let path = `/${this.trialId}/Image/${this.data.SubjectId}/${this.data.Id
}/${this.$guid()}${file.name
.substring(file.name.lastIndexOf('.'))
.toLocaleLowerCase()}`
let path = `/${this.trialId}/Image/${this.data.SubjectId}/${
this.data.Id
}/${this.$guid()}${file.name
.substring(file.name.lastIndexOf('.'))
.toLocaleLowerCase()}`
file.curPath = path
const fileData = await this.fileToBlob(file.file)
let res = await this.fileToOss(path, fileData, file)
@@ -852,7 +1128,7 @@ export default {
(percentage, checkpoint, lastPer) => {
item.uploadFileSize += checkpoint.size * (percentage - lastPer)
if (item.uploadFileSize > file.fileSize) {
item.uploadFileSize = file.fileSize > 0 ? file.fileSize : 1
item.uploadFileSize = file.fileSize
}
}
)
@@ -995,7 +1271,7 @@ export default {
this.loading = false
})
})
.catch(() => { })
.catch(() => {})
},
//
handlePreview(row) {
@@ -1062,7 +1338,6 @@ export default {
background: #428bca;
border-color: #428bca;
color: #fff;
.select-file {
height: 30px;
width: 90px;
@@ -1073,7 +1348,6 @@ export default {
opacity: 0;
font-size: 0;
}
.btn-select {
//
width: 90px;
@@ -1089,7 +1363,6 @@ export default {
pointer-events: none; //pointer-events:none穿
}
}
.non-dicom-wrapper {
::v-deep .delete-row {
text-decoration-line: line-through;
File diff suppressed because it is too large Load Diff
@@ -375,7 +375,6 @@
<el-tab-pane
:label="$t('trials:audit:tab:nonDicoms')"
name="none-dicom"
v-if="noneDicomStudyList.length > 0"
>
<el-row>
<!-- 检查信息 -->
File diff suppressed because it is too large Load Diff
@@ -1,440 +0,0 @@
<template>
<BaseContainer class="reuploa-audit-wrapper">
<!-- 搜索框 -->
<template slot="search-container">
<el-form :inline="true">
<!-- 中心编号 -->
<el-form-item :label="$t('trials:reuploadAudit:table:siteId')">
<el-select v-model="searchData.TrialSiteId" clearable filterable style="width: 120px"
placeholder="">
<el-option v-for="(item, index) of siteOptions" :key="index" :label="item.TrialSiteCode"
:value="item.TrialSiteId" />
</el-select>
</el-form-item>
<!-- 受试者编号 -->
<el-form-item :label="$t('trials:reuploadAudit:table:subjectId')">
<el-input v-model="searchData.SubjectCode" style="width: 100px" clearable />
</el-form-item>
<!-- 访视名称 -->
<el-form-item :label="$t('trials:reuploadAudit:table:visitName')">
<el-select v-model="searchData.VisitPlanArray" style="width: 200px" clearable multiple
:collapse-tags="true" placeholder="">
<el-option v-for="(item, index) of visitPlanOptions" :key="index" :label="item.VisitName"
:value="item.VisitNum">
<span style="float: left">{{ item.VisitName }}</span>
</el-option>
<el-option key="Other" label="Out of Plan" value="1.11" />
</el-select>
</el-form-item>
<!-- 申请人 -->
<el-form-item class="my_multiple" :label="$t('trials:reuploadAudit:table:CreateUserId')">
<el-select v-model="searchData.CreateUserId" style="width: 140px" clearable placeholder="">
<el-option v-for="(item) of userOptions" :key="item.CreateUserId" :label="item.FullName"
:value="item.CreateUserId">
</el-option>
</el-select>
</el-form-item>
<!-- 申请人角色 -->
<el-form-item class="my_multiple" :label="$t('trials:reuploadAudit:table:ApplyUserRole')">
<el-select v-model="searchData.ApplyUserRole" style="width: 140px" clearable placeholder="">
<el-option v-for="(item) of $d.ImageBackApplyEnum" :key="item.id" :label="item.label"
:value="item.value">
</el-option>
</el-select>
</el-form-item>
<!-- 申请时间 -->
<el-form-item :label="$t('trials:reuploadAudit:table:createTime')">
<el-date-picker v-model="timeListC" value-format="yyyy-MM-dd HH:mm:ss" format="yyyy-MM-dd HH:mm:ss"
type="datetimerange" :default-time="['00:00:00', '23:59:59']" @change="changeTimeListC"
style="width: 360px" />
</el-form-item>
<!-- 审核状态 -->
<el-form-item :label="$t('trials:reuploadAudit:table:auditState')" class="my_multiple">
<el-select v-model="searchData.ImageBackState" clearable style="width: 140px" placeholder="">
<el-option v-for="item of $d.ImageBackstateEnum" :key="item.id" :value="item.value"
:label="item.label" />
</el-select>
</el-form-item>
<!-- 审核通过时间 -->
<el-form-item :label="$t('trials:reuploadAudit:table:auditTime')">
<el-date-picker v-model="timeList" value-format="yyyy-MM-dd HH:mm:ss" format="yyyy-MM-dd HH:mm:ss"
type="datetimerange" :default-time="['00:00:00', '23:59:59']" @change="changeTimeList"
style="width: 360px" />
</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>
</template>
<!-- 重传审批列表 -->
<template slot="main-container">
<el-table ref="reuploadAuditList" v-loading="loading" v-adaptive="{ bottomOffset: 60 }" :data="list" stripe
height="100" @sort-change="handleSortByColumn">
<!-- 是否加急 -->
<el-table-column prop="IsUrgent" :label="$t('trials:reuploadAudit:table:isUrgent')"
show-overflow-tooltip width="120" sortable="custom">
<template slot-scope="scope">
<el-button v-if="
scope.row.IsUrgent &&
hasPermi(['trials:trials-panel:visit:reuploa-audit:set-urgent'])
" type="danger" size="mini" :disabled="!(userTypeEnumInt === 1 || userTypeEnumInt === 3)"
@click="handleUrgentStatus(scope.row)">
{{ $fd('YesOrNo', scope.row.IsUrgent) }}
</el-button>
<el-button v-else-if="
!scope.row.IsUrgent &&
hasPermi(['trials:trials-panel:visit:reuploa-audit:set-urgent'])
" size="mini" type="primary" :disabled="!(userTypeEnumInt === 1 || userTypeEnumInt === 3)"
@click="handleUrgentStatus(scope.row)">
{{ $fd('YesOrNo', scope.row.IsUrgent) }}
</el-button>
<span v-else>
<el-tag v-if="scope.row.IsUrgent" type="danger">
{{ $fd('YesOrNo', scope.row.IsUrgent) }}
</el-tag>
<el-tag v-else type="primary">
{{ $fd('YesOrNo', scope.row.IsUrgent) }}
</el-tag>
</span>
</template>
</el-table-column>
<!-- 中心编号 -->
<el-table-column prop="TrialSiteCode" :label="$t('trials:reuploadAudit:table:siteId')"
show-overflow-tooltip sortable="custom" />
<!-- 受试者编号 -->
<el-table-column prop="SubjectCode" :label="$t('trials:reuploadAudit:table:subjectId')"
show-overflow-tooltip sortable="custom" width="120px" />
<!-- 访视名称 -->
<el-table-column prop="VisitName" :label="$t('trials:reuploadAudit:table:visitName')"
show-overflow-tooltip sortable="custom">
</el-table-column>
<!-- 最晚拍片日期 -->
<el-table-column prop="LatestScanDate" :label="$t('trials:reuploadAudit:table:lScanDate')"
show-overflow-tooltip width="170" sortable="custom">
<template slot-scope="scope">
<el-tooltip class="item" effect="dark" :content="`${scope.row.EarliestScanDate
? moment(scope.row.EarliestScanDate).format('YYYY-MM-DD')
: ''
} ~ ${scope.row.LatestScanDate
? moment(scope.row.LatestScanDate).format('YYYY-MM-DD')
: ''
}`" placement="top">
<span>
{{
scope.row.LatestScanDate
? moment(scope.row.LatestScanDate).format('YYYY-MM-DD')
: ''
}}
</span>
</el-tooltip>
</template>
</el-table-column>
<!-- 提交时间 -->
<el-table-column prop="SubmitTime" :label="$t('trials:reuploadAudit:table:SubmitTime')"
show-overflow-tooltip sortable="custom" width="150px" />
<!-- 申请人 -->
<el-table-column prop="CreateUserFullName" :label="$t('trials:reuploadAudit:table:createUserFullName')"
show-overflow-tooltip sortable="custom" />
<!-- 申请人角色 -->
<el-table-column prop="ApplyUserRole" :label="$t('trials:reuploadAudit:table:applyUserRole')"
show-overflow-tooltip sortable="custom" width="120px">
<template slot-scope="scope">
<span>{{ $fd('ImageBackApplyEnum',
scope.row.ApplyUserRole) }}</span>
</template>
</el-table-column>
<!-- 申请时间 -->
<el-table-column prop="CreateTime" :label="$t('trials:reuploadAudit:table:createTime')"
show-overflow-tooltip sortable="custom" width="150px" />
<!-- 审核状态 -->
<el-table-column prop="ImageBackState" :label="$t('trials:reuploadAudit:table:imageBackState')"
show-overflow-tooltip sortable="custom">
<template slot-scope="scope">
<el-tag :type="['warning', '', 'danger'][scope.row.ImageBackState]">{{ $fd('ImageBackstateEnum',
scope.row.ImageBackState) }}</el-tag>
</template>
</el-table-column>
<!-- 审核时间 -->
<el-table-column prop="AuditTime" :label="$t('trials:reuploadAudit:table:auditTime')"
show-overflow-tooltip sortable="custom" width="150px" />
<el-table-column :label="$t('common:action:action')" fixed="right">
<template slot-scope="scope">
<el-button :title="$t('trials:reuploadAudit:button:auditYes')" circle
:disabled="scope.row.ImageBackState > 0" icon="el-icon-check" size="mini"
@click="audit(scope.row, 1)" />
<el-button :title="$t('trials:reuploadAudit:button:auditNo')"
:disabled="scope.row.ImageBackState > 0" circle icon="el-icon-close" size="mini"
@click="audit(scope.row, 2)" />
</template>
</el-table-column>
</el-table>
<!-- 分页组件 -->
<pagination class="page" :total="total" :page.sync="searchData.PageIndex" :limit.sync="searchData.PageSize"
@pagination="getList" />
</template>
</BaseContainer>
</template>
<script>
import {
getImageBackList,
getTrialSiteSelect,
auditImageBack,
getImageBackApplyUserList,
getTrialVisitStageSelect
} from '@/api/trials'
import BaseContainer from '@/components/BaseContainer'
import Pagination from '@/components/Pagination'
import moment from 'moment'
const searchDataDefault = () => {
return {
TrialId: null,
TrialSiteId: null,
SubjectCode: null,
CreateUserId: null,
ApplyUserRole: null,
ApplyBeginTime: null,
ApplyEndTime: null,
ImageBackState: null,
AuditBeginTime: null,
AuditEndTime: null,
VisitName: null,
VisitPlanArray: [],
PageIndex: 1,
PageSize: 20,
Asc: true,
SortField: null
}
}
export default {
name: 'QcCheck',
components: {
BaseContainer,
Pagination
},
data() {
return {
searchData: searchDataDefault(),
total: 0,
list: [],
loading: false,
siteOptions: [],
userOptions: [],
visitPlanOptions: [],
timeListC: [],
timeList: [],
trialId: null,
moment
}
},
watch: {
list(val) {
this.doLayout()
},
},
mounted() {
this.trialId = this.$route.query.trialId
this.getList()
this.getSite()
this.getUser()
this.getVisitPlanOptions()
},
methods: {
async audit(row, state) {
try {
let message = this.$t("trials:reuploadAudit:confirmMessage:imageBack").replace("xxx", this.$fd("ImageBackstateEnum", state))
let confirm = await this.$confirm(message)
if (!confirm) return false
let params = {
IamgeBackRecordId: row.Id,
IsAgree: state === 1 ? true : false
}
this.loading = true
let res = await auditImageBack(params)
this.loading = false
if (res.IsSuccess) {
this.getList()
}
} catch (err) {
console.log(err)
this.loading = false
}
},
getList() {
this.loading = true
this.searchData.TrialId = this.trialId
getImageBackList(this.searchData)
.then((res) => {
this.loading = false
this.list = res.Result.CurrentPageData
this.total = res.Result.TotalCount
this.OtherInfo = res.OtherInfo
})
.catch(() => {
this.loading = false
})
},
// site
getSite() {
getTrialSiteSelect(this.trialId).then((res) => {
this.siteOptions = res.Result
})
},
// 访
getVisitPlanOptions() {
getTrialVisitStageSelect(this.trialId).then((res) => {
this.visitPlanOptions = res.Result
})
},
//
getUser() {
getImageBackApplyUserList({
TrialId: this.trialId
}).then((res) => {
this.userOptions = res.Result
})
},
doLayout() {
const scope = this
this.$nextTick(() => {
scope.$refs.reuploadAuditList.doLayout()
})
},
//
handleReset() {
this.searchData = searchDataDefault()
this.timeList = []
this.getList()
this.timeListC = []
this.$nextTick(() => {
this.$refs.reuploadAuditList.clearSort()
})
},
//
handleSearch() {
this.searchData.PageIndex = 1
this.getList()
},
//
handleSortByColumn(column) {
if (column.order === 'ascending') {
this.searchData.Asc = true
} else {
this.searchData.Asc = false
}
this.searchData.SortField = column.prop
this.searchData.PageIndex = 1
this.getList()
},
changeTimeList() {
if (this.timeList) {
this.searchData.AuditBeginTime = this.timeList[0]
this.searchData.AuditEndTime = this.timeList[1]
} else {
this.searchData.AuditBeginTime = null
this.searchData.AuditEndTime = null
}
},
changeTimeListC() {
if (this.timeListC) {
this.searchData.ApplyBeginTime = this.timeListC[0]
this.searchData.ApplyEndTime = this.timeListC[1]
} else {
this.searchData.ApplyBeginTime = null
this.searchData.ApplyEndTime = null
}
},
},
}
</script>
<style lang="scss">
.reuploa-audit-wrapper {
position: relative;
.remark {
position: absolute;
left: 5px;
bottom: 7px;
font-size: 12px;
}
height: 100%;
.qc-dialog {
.el-dialog__headerbtn {
top: 10px;
font-size: 30px;
}
.el-dialog__body {
height: calc(100% - 70px);
padding: 0 10px;
.qc-dialog-body {
padding: 10px 20px;
height: 100%;
overflow-y: auto;
}
}
.link-breadcrumb {
cursor: pointer;
color: #428bca;
}
}
.box-title {
padding: 12px;
margin-bottom: 10px;
background-color: #dcdfe6;
}
.status-primary-circle {
display: inline-block;
width: 20px;
height: 20px;
text-align: center;
line-height: 18px;
border-radius: 50%;
border: 1px solid #f56c6c;
color: #f56c6c;
font-size: 10px;
}
.manuals-dialog-container {
margin-top: 50px !important;
width: 75%;
height: 80%;
.el-dialog__body {
padding: 10px;
height: calc(100% - 50px) !important;
}
.el-dialog__header {
position: relative;
}
}
.manuals-full-dialog-container {
.el-dialog__body {
padding: 10px;
height: calc(100% - 50px) !important;
}
.el-dialog__header {
position: relative;
}
}
}
</style>
@@ -1,120 +0,0 @@
<template>
<div class="reuploadAudit-wrapper">
<el-row>
<el-col :span="12">
<!-- 重阅审批 -->
<h3>{{ $t('trials:trials-panel:attachments:reuploadAudit') }}</h3>
</el-col>
<el-col :span="12" style="text-align:right;">
<h3>
<Pagination class="page" :total="total" :page.sync="listQuery.pageIndex"
:limit.sync="listQuery.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-table ref="needSignDocList" v-loading="listLoading" :data="list" :show-header="true"
v-adaptive="{ bottomOffset: 45 }" height="100" @sort-change="handleSortByColumn">
<el-table-column type="index" width="40" />
<!-- 项目编号 -->
<el-table-column :label="$t('trials:workbench:table:trialId')" prop="TrialCode" show-overflow-tooltip
sortable="custom" />
<!-- 试验名称 -->
<el-table-column :label="$t('trials:workbench:table:experimentName')" prop="ExperimentName"
show-overflow-tooltip sortable="custom" />
<!-- 研究方案号 -->
<el-table-column :label="$t('trials:workbench:table:researchNo')" prop="ResearchProgramNo"
show-overflow-tooltip sortable="custom" />
<!-- 加急量 -->
<el-table-column :label="$t('trials:sysDocBeSigned:table:UrgentCount')" prop="UrgentCount"
show-overflow-tooltip sortable="custom" />
<!-- 待审批量 -->
<el-table-column :label="$t('trials:sysDocBeSigned:table:ToBeApprovalCount')" prop="ToBeApprovalCount"
show-overflow-tooltip sortable="custom" />
<el-table-column :label="$t('common:action:action')" width="100">
<template slot-scope="scope">
<el-button icon="el-icon-edit-outline" circle
:disabled="!!~trialIdList.indexOf(scope.row.TrialId) || isSignSystemDoc"
:title="$t('trials:researchRecord:action:view')" @click="handleAudit(scope.row)" />
</template>
</el-table-column>
</el-table>
</div>
</template>
<script>
import { getPMImageBackToBeDoneList } from '@/api/trials'
import Pagination from '@/components/Pagination'
const searchDataDefault = () => {
return {
pageIndex: 1,
pageSize: 20,
asc: true,
sortField: ''
}
}
export default {
name: 'ReuploadAudit',
components: { Pagination },
props: {
trialIdList: {
type: Array,
default() { return [] }
},
isSignSystemDoc: {
type: Boolean,
default() { return false }
}
},
data() {
return {
listLoading: false,
list: [],
listQuery: searchDataDefault(),
total: 0
}
},
mounted() {
this.getList()
},
methods: {
getList() {
this.listLoading = true
getPMImageBackToBeDoneList(this.listQuery).then(res => {
this.listLoading = false
this.total = res.Result.TotalCount
this.list = res.Result.CurrentPageData
}).catch(() => { this.listLoading = false })
},
handleAudit(row) {
this.$router.push({ path: `/trials/trials-panel/visit/reupload-audit?trialId=${row.TrialId}&trialCode=${row.TrialCode}&researchProgramNo=${row.ResearchProgramNo}` })
},
handleReset() {
this.listQuery = searchDataDefault()
this.getList()
this.$nextTick(() => {
this.$refs.needSignDocList.clearSort()
})
},
//
handleSortByColumn(column) {
if (column.order === 'ascending') {
this.listQuery.asc = true
} else {
this.listQuery.asc = false
}
this.listQuery.sortField = column.prop
this.getList()
}
}
}
</script>
<style lang="scss" scoped>
.reuploadAudit-wrapper {
height: 100%;
}
</style>
@@ -1,268 +0,0 @@
<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="['file', 'files', 'folder'].includes(type)">
<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('stickup')" v-if="checkList.length <= 1 && isCopy">
<i class="icon icon_stickup" />
<span>{{ $t('trials:trials-workbench:auditDocument:menu:stickup') }}</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('version')">
<i class="icon el-icon-warning-outline icon_Stats" />
<span>{{ $t('trials:trials-workbench:auditDocument:menu:version') }}</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')" v-if="type === 'version'">
<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 []
}
},
isCopy: {
type: Boolean,
default: false
}
},
data() {
return {
visible: false,
type: 'file',
zIndex: 9,
rowData: {}
};
},
methods: {
init(event, row, type, zIndex = 9) {
this.rowData = row
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", { key: item, row: this.rowData });
},
},
};
</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;
}
/*粘贴*/
.icon_stickup {
color: #1890ff;
display: inline-block;
background-image: url(@/assets/stickup.png);
background-position: 0 0;
background-size: 16px 16px;
background-repeat: no-repeat;
height: 16px;
margin-right: 8px;
}
</style>
@@ -1,444 +0,0 @@
<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_folder" v-if="!rowData.AuditDocumentTypeEnum"></i>
<img v-else-if="['png', 'jpg', 'jpeg'].includes(rowData.FileFormat.toLowerCase())"
:src="OSSclientConfig.basePath + rowData.FilePath" alt="" class="name_image">
<i :class="`name_${rowData.FileFormat}`" v-else></i>
</div>
<div class="file_name">
<div class="name">
<span class="name-text">{{ rowData.Name }}</span>
</div>
<div class="desc">
<span class="size">{{ formatFileSize(rowData) }}</span>
<span v-if="rowData.AuditDocumentTypeEnum">, </span>
<span class="time">{{ rowData.UpdateTime }}</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:versions')"
name="versions" v-if="rowData.AuditDocumentTypeEnum === 1">
<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"
@click.stop="getHistoricalVersion" />
<el-button icon="el-icon-upload2" plain size="small" @click.stop="openFile">{{
$t('trials:trials-workbench:auditDocument:detail:title:uploadNewVersion')
}}</el-button>
</div>
</div>
<div class="versions_content" v-loading="loading">
<div class="item" v-for="item of versionList" :key="item.Id">
<div class="item_line">
<div class="version current_version" v-if="item.IsCurrentVersion">
<span>{{
$t('trials:trials-workbench:auditDocument:detail:title:currentVersion')
}}</span>
</div>
<div class="version" v-else>
<span>v{{ item.Version }}</span>
</div>
<div class="mtime">{{ item.CreateTime }}</div>
<div class="size">{{ formatFileSize(item) }}</div>
<div class="add_desc" @click.stop="openMenu($event, item, 'c_version')"
v-if="item.IsCurrentVersion">
<i class="el-icon-more" />
</div>
<div class="add_desc" @click.stop="openMenu($event, item, 'version')" v-else>
<i class="el-icon-more" />
</div>
</div>
</div>
</div>
</el-tab-pane>
<el-tab-pane :label="$t('trials:trials-workbench:auditDocument:detail:tabs:Stats')" name="Stats"
v-if="false">
<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" v-if="!rowData.AuditDocumentTypeEnum">
<div class="title">{{ $t('trials:trials-workbench:auditDocument:detail:title:contain') }}
</div>
<div class="content">4 (2文件, 2文件夹)</div>
</div>
<div class="p" v-else>
<div class="title">{{ $t('trials:trials-workbench:auditDocument:detail:title:size') }}</div>
<div class="content">{{ formatFileSize(rowData) }}</div>
</div>
<div class="p">
<div class="title">{{ $t('trials:trials-workbench:auditDocument:detail:title:updateTime') }}
</div>
<div class="content">{{ rowData.UpdateTime }}</div>
</div>
</el-tab-pane>
</el-tabs>
</div>
</div>
</el-dialog>
</template>
<script>
import { getHistoricalVersion } from '@/api/trials'
export default {
name: "auditDocumentDetail",
props: {
visible: {
type: Boolean,
default: false
},
rowData: {
type: Object,
default: () => {
return {}
}
}
},
data() {
return {
activeName: 'versions',
versionList: [],
loading: false
}
},
// mounted() {
// this.getHistoricalVersion()
// },
watch: {
rowData: {
handler() {
this.getHistoricalVersion()
},
deep: true,
immediate: true
}
},
methods: {
handleClick() { },
openMenu(e, row, type) {
this.$emit('openContextmenu', { e, row, type, zIndex: 3000 })
},
handleClose() {
this.$emit("update:visible", false)
},
delAll() {
let ids = []
this.versionList.forEach(item => {
if (!item.IsCurrentVersion) {
ids.push(item.Id)
}
})
this.$emit('delData', ids)
},
//
async getHistoricalVersion() {
if (!this.rowData || !this.rowData.Id) return false
try {
let data = {
Id: this.rowData.Id
}
this.loading = true
let res = await getHistoricalVersion(data)
this.loading = false
if (res.IsSuccess) {
this.versionList = res.Result
}
} catch (err) {
this.loading = false
console.log(err)
}
},
openFile() {
let faccept = `.${this.rowData.FileFormat}`
this.$emit('openFileNewVersion', faccept)
},
//
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"
}
},
}
}
</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 10px 10px;
display: flex;
align-items: center;
border-bottom: 1px solid #f6f8ff;
.file_icon {
width: 50px;
height: 50px;
display: flex;
align-items: center;
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_image {
max-width: 90%;
max-height: 100%;
}
.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;
max-height: 60px;
line-height: 18px;
margin-top: 7px;
width: calc(100% - 170px);
display: flex;
align-items: center;
flex-wrap: wrap;
.name {
max-height: 35px;
width: 100%;
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>
File diff suppressed because it is too large Load Diff
@@ -238,7 +238,7 @@
:reading-id="selected.ReadingId"
:clinical-form-id="selected.ClinicalFormId"
:open-type="'look'"
@close="false"
@close=""
/>
</div>
</div>
@@ -1,3 +0,0 @@
<template>
<div>viewGeneralTraining</div>
</template>
+239 -420
View File
@@ -1,5 +1,5 @@
<style>
.user-status-item {
.user-status-item{
width: 100px;
height: 32px;
line-height: 1;
@@ -14,8 +14,7 @@
cursor: pointer;
padding: 0 8px;
}
.my_select_box {
.my_select_box{
margin-bottom: 12px;
margin-top: 12px;
padding: 0 12px 0 20px;
@@ -25,37 +24,31 @@
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;
@@ -63,237 +56,173 @@
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="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-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 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 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 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>
<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="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_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="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>
</div>
</div>
<!-- 重传审批 -->
<div class="my_select_box" :class="{ selected: selected === 'ReuploadAudit' }" tab-data="ReuploadAudit"
@click="selected = 'ReuploadAudit'" v-if="hasPermi(['trials:trials-workbench:ReuploadAudit'])">
<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:ReuploadAudit')
}}</span><span style="margin:0 0.25rem">·</span><span>{{ tabList.PM_ImageBackApprovalCount }}</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>
@@ -301,247 +230,168 @@
<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="handleClick('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="handleClick('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" />
<!-- 重c传审批 -->
<ReuploadAudit v-if="selected === 'ReuploadAudit'" :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>
@@ -569,21 +419,16 @@ 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 ReuploadAudit from "./components/ReuploadAudit"
import store from '@/store'
import './index.css'
import { getUserTobeDoneRecord, getNeedSignTrialDocTrialIdList } from '@/api/trials'
import {getUserTobeDoneRecord, getNeedSignTrialDocTrialIdList,getWaitSignSysDocList, getTrialSignDocumentList} 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,
@@ -606,8 +451,7 @@ export default {
MedicalFeedback,
MedicalAudit,
NeedSignedTrialDoc,
NeedSignedSysDoc,
ReuploadAudit
NeedSignedSysDoc
},
data() {
return {
@@ -633,14 +477,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) => {
@@ -648,12 +492,6 @@ export default {
});
},
methods: {
handleClick(key) {
this.selected = null;
this.$nextTick(() => {
this.selected = key
})
},
getUserInfo() {
getUser().then(async res => {
this.user = res.Result
@@ -683,7 +521,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)
@@ -701,26 +539,7 @@ export default {
}
</script>
<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;
}
}
<style lang="scss">
.workbench-container {
.el-tabs__nav {
transform: translateY(60px) !important;
-50
View File
@@ -1,50 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<style>
html,
body {
width: 99%;
height: 99%;
}
</style>
<title></title>
<!-- 引入外部JavaScript文件 -->
<script type="text/javascript"
src="https://onlyoffice.test.extimaging.com/web-apps/apps/api/documents/api.js"></script>
</head>
<body>
<div id="placeholder"></div>
<script language="javascript" type="text/javascript">
var obj = {}
var str = window.location.search.substr(1)
str = str.split('?')[1]
var url = window.location.search.substr(1).split('?')[0].split('=')[1]
var arrList = str.split('&')
arrList.forEach(function (item) {
var arr = item.split('=')
obj[arr[0]] = window.decodeURIComponent(arr[1])
})
var docEditor = new window.DocsAPI.DocEditor("placeholder", {
type: "embedded",
"document": {
"fileType": obj.type,
"key": "Khirz6zTPdfd7" + Date.now(),
"title": obj.title,
"url": url,
},
// editorConfig: {
// lang:'zh'
// },
"documentType": obj.documentType,
"height": "100%",
});
</script>
</body>
</html>
+5 -5
View File
@@ -24,10 +24,10 @@ module.exports = defineConfig({
productionSourceMap: false,
devServer: {
port: '8080',
// headers: {
// 'Cross-Origin-Opener-Policy': 'same-origin',
// 'Cross-Origin-Embedder-Policy': 'require-corp'
// },
headers: {
'Cross-Origin-Opener-Policy': 'same-origin',
'Cross-Origin-Embedder-Policy': 'require-corp'
},
// open: true,
client: {
overlay: {
@@ -97,7 +97,7 @@ module.exports = defineConfig({
]
}),
// new BundleAnalyzerPlugin(),
process.env.NODE_ENV === 'development' || process.env.NODE_ENV === 'prod' || process.env.NODE_ENV === 'production' || process.env.VUE_APP_OSS_CONFIG_BUCKET === 'zyypacs-usa' ? function () { }
process.env.NODE_ENV === 'development' || process.env.NODE_ENV === 'production' || process.env.VUE_APP_OSS_CONFIG_BUCKET === 'zyypacs-usa' ? function () { }
: new WebpackAliyunOss({
from: ['./dist/**'],
dist: process.env.VUE_APP_OSS_PATH + distDate,