Merge branch 'main' of https://gitea.frp.extimaging.com/XCKJ/irc_web into main
continuous-integration/drone/push Build is running Details

uat
caiyiling 2025-04-16 15:55:44 +08:00
commit c2f3e02ef1
15 changed files with 1650 additions and 908 deletions

View File

@ -220,6 +220,29 @@ export function addOrUpdateSystemDocument(param) {
data: param data: param
}) })
} }
// 新增/修改通用培训附件
export function addOrUpdateSystemDocumentAttachment(param) {
return request({
url: `/SystemDocument/addOrUpdateSystemDocumentAttachment`,
method: 'post',
data: param
})
}
// 通用培训附件列表
export function getSystemDocumentAttachmentList(param) {
return request({
url: `/SystemDocument/getSystemDocumentAttachmentList`,
method: 'post',
data: param
})
}
// 删除通用培训附件
export function deleteSystemDocumentAttachment(systemDocumentAttachmentId) {
return request({
url: `/SystemDocument/deleteSystemDocumentAttachment/${systemDocumentAttachmentId}`,
method: 'delete',
})
}
export function deleteSystemDocument(id) { export function deleteSystemDocument(id) {
return request({ return request({

View File

@ -1,28 +1,28 @@
<template> <template>
<div class="preview-wrapper"> <div class="preview-wrapper">
<iframe <iframe v-if="fileType.indexOf('jpg') !== -1 || fileType.indexOf('png') !== -1" frameborder="0" :src="filePath"
v-if="fileType.indexOf('jpg') !== -1 || fileType.indexOf('png') !== -1" width="100%" height="100%" />
frameborder="0"
:src="filePath"
width="100%"
height="100%"
/>
<!-- <embed v-else-if="fileType.indexOf('pdf') !== -1" :src="filePath+'#toolbar=0'" style="width: 100%; height: 100%"> --> <!-- <embed v-else-if="fileType.indexOf('pdf') !== -1" :src="filePath+'#toolbar=0'" style="width: 100%; height: 100%"> -->
<!-- <iframe v-else-if="fileType.indexOf('pdf') !== -1" :src="filePath+'#toolbar=0'" width="100%" height="100%" frameborder="0" /> --> <!-- <iframe v-else-if="fileType.indexOf('pdf') !== -1" :src="filePath+'#toolbar=0'" width="100%" height="100%" frameborder="0" /> -->
<iframe v-else-if="fileType.indexOf('pdf') !== -1" :src="`/static/pdfjs/web/viewer.html?file=${OSSclientConfig.basePath}${filePath}?userName=${currentUser}&COMPANY=${COMPANY}`" width="100%" height="100%" frameborder="0" crossorigin="anonymous" /> <iframe v-else-if="fileType.indexOf('pdf') !== -1"
:src="`/static/pdfjs/web/viewer.html?file=${OSSclientConfig.basePath}${filePath}?userName=${currentUser}&COMPANY=${COMPANY}`"
width="100%" height="100%" frameborder="0" crossorigin="anonymous" />
<!-- <pdf--> <!-- <pdf-->
<!-- v-else-if="fileType.indexOf('pdf') !== -1"--> <!-- v-else-if="fileType.indexOf('pdf') !== -1"-->
<!-- :src="`/static/pdfjs/web/viewer.html?file=${filePath}`">--> <!-- :src="`/static/pdfjs/web/viewer.html?file=${filePath}`">-->
<!-- </pdf>--> <!-- </pdf>-->
<div v-else> <iframe v-else
:src="`/static/onlyOffice/viewer.html?url=${OSSclientConfig.basePath}${filePath}?type=${fileType}&title=${title}&documentType=${documentType}&userName=${currentUser}`"
width="100%" height="100%" frameborder="0" crossorigin="anonymous" />
<!-- <div v-else>
{{ $t('common:message:downloadFile') }} {{ $t('common:message:downloadFile') }}
<el-link type="primary" @click="downLoadFile">{{ $t('common:button:download') }}</el-link> <el-link type="primary" @click="downLoadFile">{{ $t('common:button:download') }}</el-link>
</div> </div> -->
</div> </div>
</template> </template>
<script> <script>
import { mapGetters } from 'vuex' import { mapGetters } from 'vuex'
import DOCUMENTTYPE from "@/utils/onlyOffice_type.js"
export default { export default {
name: 'PreviewFile', name: 'PreviewFile',
computed: { computed: {
@ -36,7 +36,11 @@ export default {
fileType: { fileType: {
type: String, type: String,
required: true required: true
} },
title: {
type: String,
default: ''
},
}, },
data() { data() {
return { return {
@ -44,6 +48,12 @@ export default {
COMPANY: process.env.VUE_APP_COMPANY_NAME COMPANY: process.env.VUE_APP_COMPANY_NAME
} }
}, },
computed: {
documentType() {
console.log(DOCUMENTTYPE[`.${this.fileType}`], 'documentType')
return DOCUMENTTYPE[`.${this.fileType}`]
}
},
mounted() { mounted() {
// document.querySelector('iframe').attachEvent('onload', () => { // document.querySelector('iframe').attachEvent('onload', () => {
// document.querySelector('iframe').contentDocument.oncontextmenu = function() { // document.querySelector('iframe').contentDocument.oncontextmenu = function() {
@ -66,10 +76,12 @@ export default {
height: 100%; height: 100%;
width: 100%; width: 100%;
padding: 10px; padding: 10px;
::-webkit-scrollbar { ::-webkit-scrollbar {
width: 7px; width: 7px;
height: 7px; height: 7px;
} }
::-webkit-scrollbar-thumb { ::-webkit-scrollbar-thumb {
border-radius: 10px; border-radius: 10px;
background: #d0d0d0; background: #d0d0d0;

View File

@ -1,100 +1,45 @@
<template> <template>
<el-form <el-form ref="sysAttachmentFrom" v-loading="loading" :model="form" label-width="190px" size="small" :rules="rules"
ref="sysAttachmentFrom" class="upload-temporary-file">
v-loading="loading"
:model="form"
label-width="190px"
size="small"
:rules="rules"
class="upload-temporary-file"
>
<div class="base-dialog-body"> <div class="base-dialog-body">
<el-form-item <el-form-item :label="$t('dictionary:signature:form:FileTypeId')" prop="FileTypeId">
:label="$t('dictionary:signature:form:FileTypeId')" <el-select v-model="form.FileTypeId" style="width: 100%" size="small" filterable>
prop="FileTypeId" <el-option v-for="item of dictionaryList.Sys_Document" :key="item.Id" :label="item.Value" :value="item.Id" />
>
<el-select
v-model="form.FileTypeId"
style="width: 100%"
size="small"
filterable
>
<el-option
v-for="item of dictionaryList.Sys_Document"
:key="item.Id"
:label="item.Value"
:value="item.Id"
/>
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item :label="$t('dictionary:signature:form:File')"> <el-form-item :label="$t('dictionary:signature:form:File')">
<div class="upload-container"> <div class="upload-container">
<el-upload <el-upload class="upload-demo" action accept=".pdf" :before-upload="beforeUpload"
class="upload-demo" :http-request="handleUploadFile" :on-preview="handlePreview" :on-remove="handleRemoveFile"
action :show-file-list="true" :file-list="fileList" :limit="1" :on-exceed="handleExceed"
accept=".pdf" :disabled="form.Type === ''">
:before-upload="beforeUpload" <el-button size="small" type="primary" :disabled="form.FileTypeId === ''" :loading="btnLoading">{{
:http-request="handleUploadFile" $t('common:button:check') }}</el-button>
:on-preview="handlePreview"
:on-remove="handleRemoveFile"
:show-file-list="true"
:file-list="fileList"
:limit="1"
:on-exceed="handleExceed"
:disabled="form.Type === ''"
>
<el-button
size="small"
type="primary"
:disabled="form.FileTypeId === ''"
:loading="btnLoading"
>{{ $t('common:button:check') }}</el-button
>
<span slot="tip" style="margin-left: 10px" class="el-upload__tip"> <span slot="tip" style="margin-left: 10px" class="el-upload__tip">
({{ $t('trials:signature:label:mustBepdf') }}) ({{ $t('trials:signature:label:mustBepdf') }})
</span> </span>
</el-upload> </el-upload>
</div> </div>
</el-form-item> </el-form-item>
<el-form-item <el-form-item :label="$t('dictionary:signature:form:NeedConfirmedUserTypeIdList')"
:label="$t('dictionary:signature:form:NeedConfirmedUserTypeIdList')" prop="NeedConfirmedUserTypeIdList">
prop="NeedConfirmedUserTypeIdList" <el-select v-model="form.NeedConfirmedUserTypeIdList" style="width: 100%" multiple>
> <el-option v-for="item of userTypeOptions" :key="item.Id" :label="item.UserTypeShortName" :value="item.Id" />
<el-select
v-model="form.NeedConfirmedUserTypeIdList"
style="width: 100%"
multiple
>
<el-option
v-for="item of userTypeOptions"
:key="item.Id"
:label="item.UserTypeShortName"
:value="item.Id"
/>
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item <el-form-item :label="$t('dictionary:signature:form:DocUserSignType')" prop="DocUserSignType">
:label="$t('dictionary:signature:form:DocUserSignType')" <el-switch v-model="form.DocUserSignType" :active-value="1" :inactive-value="0">
prop="DocUserSignType"
>
<el-switch
v-model="form.DocUserSignType"
:active-value="1"
:inactive-value="0"
>
</el-switch> </el-switch>
</el-form-item> </el-form-item>
<el-form-item <el-form-item :label="$t('dictionary:signature:form:SignViewMinimumMinutes')" prop="SignViewMinimumMinutes">
:label="$t('dictionary:signature:form:SignViewMinimumMinutes')" <el-input-number v-model="form.SignViewMinimumMinutes" controls-position="right" :min="1" :max="50" />
prop="SignViewMinimumMinutes" </el-form-item>
> <el-form-item :label="$t('dictionary:signature:form:CurrentStaffTrainDays')" prop="CurrentStaffTrainDays">
<el-input-number <el-input-number v-model="form.CurrentStaffTrainDays" controls-position="right" :min="1" :max="1000" />
v-model="form.SignViewMinimumMinutes" </el-form-item>
controls-position="right" <el-form-item :label="$t('dictionary:signature:form:NewStaffTrainDays')" prop="NewStaffTrainDays">
:min="1" <el-input-number v-model="form.NewStaffTrainDays" controls-position="right" :min="1" :max="1000" />
:max="50"
/>
</el-form-item> </el-form-item>
<!-- <el-form-item v-if="form.Id !== ''" label="是否废除: "> <!-- <el-form-item v-if="form.Id !== ''" label="是否废除: ">
<el-radio-group v-model="form.IsDeleted"> <el-radio-group v-model="form.IsDeleted">
@ -105,14 +50,8 @@
</div> </div>
<div class="base-dialog-footer" style="text-align: right; margin-top: 10px"> <div class="base-dialog-footer" style="text-align: right; margin-top: 10px">
<el-form-item style="text-align: right"> <el-form-item style="text-align: right">
<el-button <el-button size="small" type="primary" :disabled="form.FileTypeId === '' || form.Name === ''"
size="small" :loading="saveBtnLoading" @click="handleSave">{{ $t('common:button:save') }}</el-button>
type="primary"
:disabled="form.FileTypeId === '' || form.Name === ''"
:loading="saveBtnLoading"
@click="handleSave"
>{{ $t('common:button:save') }}</el-button
>
</el-form-item> </el-form-item>
</div> </div>
</el-form> </el-form>
@ -141,6 +80,8 @@ export default {
IsDeleted: false, IsDeleted: false,
SignViewMinimumMinutes: null, SignViewMinimumMinutes: null,
DocUserSignType: 0, DocUserSignType: 0,
CurrentStaffTrainDays: null,
NewStaffTrainDays: null,
}, },
rules: { rules: {
FileTypeId: [ FileTypeId: [
@ -198,6 +139,8 @@ export default {
this.form.IsDeleted = this.data.IsDeleted this.form.IsDeleted = this.data.IsDeleted
this.form.SignViewMinimumMinutes = this.data.SignViewMinimumMinutes this.form.SignViewMinimumMinutes = this.data.SignViewMinimumMinutes
this.form.DocUserSignType = this.data.DocUserSignType this.form.DocUserSignType = this.data.DocUserSignType
this.form.CurrentStaffTrainDays = this.data.CurrentStaffTrainDays
this.form.NewStaffTrainDays = this.data.NewStaffTrainDays
} }
this.loading = false this.loading = false
}, },
@ -305,13 +248,16 @@ export default {
width: 80px; width: 80px;
height: 40px; height: 40px;
} }
.upload-container .el-input--small { .upload-container .el-input--small {
margin-bottom: 5px; margin-bottom: 5px;
} }
.upload-container .el-icon-circle-check { .upload-container .el-icon-circle-check {
color: #428bca; color: #428bca;
font-size: 13px; font-size: 13px;
} }
.account_item_clear { .account_item_clear {
.el-tag__close { .el-tag__close {
display: none !important; display: none !important;

View File

@ -0,0 +1,223 @@
<template>
<el-form ref="attachmentFrom" v-loading="loading" :model="form" label-width="190px" size="small" :rules="rules"
class="upload-temporary-file">
<div class="base-dialog-body">
<el-form-item :label="$t('dictionary:signature:form:FileName')" prop="Name">
<el-input v-model="form.Name" clearable></el-input>
</el-form-item>
<el-form-item :label="$t('dictionary:signature:form:OffLine')" prop="OffLine">
<el-switch v-model="form.OffLine" :active-value="true" :inactive-value="false"
:active-text="$fd('YesOrNo', true)" :inactive-text="$fd('YesOrNo', false)">
</el-switch>
</el-form-item>
<el-form-item :label="$t('dictionary:signature:form:File')">
<div class="upload-container">
<el-upload class="upload-demo" action :accept="this.accept.join(',')" :before-upload="beforeUpload"
:http-request="handleUploadFile" :on-preview="handlePreview" :on-remove="handleRemoveFile"
:show-file-list="true" :file-list="fileList" :limit="1" :on-exceed="handleExceed">
<el-button size="small" type="primary" :loading="btnLoading">{{ $t('common:button:check')
}}</el-button>
<span slot="tip" style="margin-left: 10px" class="el-upload__tip">
({{ $t('trials:signature:label:type').replace("xxx", this.accept.join(", ")) }})
</span>
</el-upload>
</div>
</el-form-item>
</div>
<div class="base-dialog-footer" style="text-align: right; margin-top: 10px">
<el-form-item style="text-align: right">
<el-button size="small" type="primary" :disabled="form.FileTypeId === '' || form.Name === ''"
:loading="saveBtnLoading" @click="handleSave">{{ $t('common:button:save') }}</el-button>
</el-form-item>
</div>
</el-form>
</template>
<script>
import { addOrUpdateSystemDocumentAttachment } from '@/api/dictionary'
export default {
props: {
data: {
type: Object,
default() {
return {}
},
},
SystemDocumentId: {
type: String,
default: ''
}
},
data() {
return {
form: {
Id: '',
Name: null,
FileFormat: null,
FileName: null,
FilePath: null,
FileSize: null,
OffLine: false,
SystemDocumentId: null
},
rules: {
Name: [
{
required: true,
message: this.$t('common:ruleMessage:specify'),
trigger: ['change'],
},
],
},
fileList: [],
btnLoading: false,
saveBtnLoading: false,
loading: false,
accept: ['.jpg',
'.jpeg',
'.png',
'.pdf',
'.ppt',
'.pptx',
'.doc',
'.docx',
'.xls',
'.xlsx']
}
},
mounted() {
this.initForm()
},
methods: {
async initForm() {
this.loading = true
if (this.data && this.data.Id) {
Object.keys(this.form).forEach(key => {
this.form[key] = this.data[key]
})
this.fileList = [
{
name: this.data.FileName,
url: this.data.FilePath,
path: this.data.FilePath,
},
]
}
this.loading = false
},
beforeUpload(file) {
//
if (this.checkFileSuffix(file.name)) {
this.fileList = []
return true
} else {
this.$alert(this.$t('trials:signature:label:type').replace("xxx", this.accept.join(", ")))
return false
}
},
async handleUploadFile(param) {
this.loading = true
var file = await this.fileToBlob(param.file)
const res = await this.OSSclient.put(
`/System/DocumentToSign/${param.file.name}${new Date().getTime()}`,
file
)
this.fileList.push({
name: param.file.name,
path: this.$getObjectName(res.url),
url: this.$getObjectName(res.url),
})
this.form.Name = param.file.name
this.form.FileName = param.file.name
this.form.FilePath = this.$getObjectName(res.url)
this.form.FileSize = param.file.size
this.form.FileFormat = param.file.name
.substring(param.file.name.lastIndexOf('.'))
.toLocaleLowerCase().split('.')[1]
this.loading = false
},
handleSave() {
this.$refs.attachmentFrom.validate((valid) => {
if (!valid) return false
if (!this.form.FilePath)
return this.$alert(this.$t('trials:signature:message:selectFile'))
this.saveBtnLoading = true
if (this.SystemDocumentId) this.form.SystemDocumentId = this.SystemDocumentId
addOrUpdateSystemDocumentAttachment(this.form)
.then((res) => {
this.saveBtnLoading = false
this.$emit('closeDialog')
this.$emit('getList')
this.$message.success(this.$t('common:message:updatedSuccessfully'))
})
.catch(() => {
this.saveBtnLoading = false
})
})
},
handleRemoveFile() {
this.fileList = []
this.form.FilePath = ''
this.form.FileSize = ''
this.form.FileFormat = ''
this.form.FileName = ''
},
handlePreview(file) {
if (file.fullPath) {
window.open(file.fullPath, '_blank')
}
},
handleExceed(files, fileList) {
this.$message.warning(this.$t('upload:rule:maxFile1'))
},
checkFileSuffix(fileName) {
var typeArr = [
'jpg',
'jpeg',
'png',
'pdf',
'ppt',
'pptx',
'doc',
'docx',
'xls',
'xlsx',
]
var extendName = fileName
.substring(fileName.lastIndexOf('.') + 1)
.toLocaleLowerCase()
if (typeArr.indexOf(extendName) !== -1) {
return true
} else {
return false
}
},
},
}
</script>
<style lang="scss">
.upload-temporary-file {
.upload-container .el-upload--text {
border: none;
width: 80px;
height: 40px;
}
.upload-container .el-input--small {
margin-bottom: 5px;
}
.upload-container .el-icon-circle-check {
color: #428bca;
font-size: 13px;
}
.account_item_clear {
.el-tag__close {
display: none !important;
}
}
}
</style>

View File

@ -0,0 +1,229 @@
<template>
<div v-if="config.visible">
<base-model :config="config">
<template slot="dialog-body">
<el-button size="mini" type="primary" style="float:right" @click.stop="edit({})">
{{ $t('common:button:add') }}</el-button>
<el-table :data="list" style="width: 100%" max-height="300px" v-loading="loading"
@sort-change="handleSortByColumn">
<el-table-column type="index" width="60" />
<el-table-column prop="Name" :label="$t('dictionary:signature:attachmentList:FileName')"
sortable="custom" />
<el-table-column prop="OffLine" :label="$t('dictionary:signature:attachmentList:OffLine')"
sortable="custom">
<template slot-scope="scope">
<el-switch v-model="scope.row.OffLine" @change="(val) => OffLine(scope.row, val)"
:active-value="true" :inactive-value="false" :active-text="$fd('YesOrNo', true)"
:inactive-text="$fd('YesOrNo', false)">
</el-switch>
</template>
</el-table-column>
<el-table-column prop="CreateTime" :label="$t('dictionary:signature:attachmentList:CreateTime')"
sortable="custom" />
<el-table-column :label="$t('common:action:action')" min-width="120px">
<template slot-scope="scope">
<el-button size="mini" type="text" @click.stop="preview(scope.row)">
{{ $t('common:button:preview') }}
</el-button>
<el-button size="mini" type="text" @click.stop="edit(scope.row)">
{{ $t('common:button:edit') }}
</el-button>
<el-button size="mini" type="text" @click.stop="OffLine(scope.row, true)"
:disabled="scope.row.OffLine">
{{ $t('dictionary:signature:attachmentList:OffLine') }}
</el-button>
<el-button size="mini" type="text" @click.stop="del(scope.row)">
{{ $t('common:button:delete') }}
</el-button>
</template>
</el-table-column>
</el-table>
<!-- 新增/编辑附件 -->
<el-dialog :visible.sync="visible" :close-on-click-modal="false" :append-to-body="true" :title="title"
width="800px" custom-class="base-dialog-wrapper">
<attachmentForm v-if="visible" :data="rowData" :SystemDocumentId="SystemDocumentId"
@closeDialog="closeDialog" @getList="getAllList" />
</el-dialog>
</template>
</base-model>
<viewer ref="picture_perview2" style="margin: 0 10px"
v-if="rowData.FileFormat && ['png', 'jpg', 'jpeg'].includes(rowData.FileFormat.toLowerCase())"
:images="[`${OSSclientConfig.basePath}${rowData.FilePath}`]" :options="viewerOptions">
<img v-show="false" :src="`${OSSclientConfig.basePath}${rowData.FilePath}`" alt="Image" />
</viewer>
<!-- <attachmentPreview :SystemDocumentId="SystemDocumentId" :visible.sync="perview_visible"
v-if="perview_visible" /> -->
</div>
</template>
<script>
import BaseModel from '@/components/BaseModel'
import attachmentForm from './attachmentForm'
// import attachmentPreview from './attachmentPreview'
import { addOrUpdateSystemDocumentAttachment, getSystemDocumentAttachmentList, deleteSystemDocumentAttachment } from '@/api/dictionary'
const defaultSearchData = () => {
return {
PageIndex: 1,
PageSize: 1000,
Asc: false,
SortField: null
}
}
export default {
components: {
BaseModel,
attachmentForm,
// attachmentPreview
},
props: {
config: {
type: Object,
default: () => {
return {
visible: false,
title: this.$t('dictionary:signature:attachmentList:title'),
width: '800px',
}
}
},
SystemDocumentId: {
type: String,
default: ''
}
},
data() {
return {
searchData: defaultSearchData(),
visible: false,
title: null,
list: [],
rowData: {},
loading: false,
viewerOptions: {
toolbar: {
zoomIn: true,
zoomOut: true,
reset: true,
prev: false,
next: false,
rotateLeft: true,
rotateRight: true,
flipHorizontal: true,
flipVertical: true,
}
},
// perview_visible: false
}
},
watch: {
SystemDocumentId: {
handler() {
this.getList()
},
immediate: true,
}
},
methods: {
closeDialog() {
this.visible = false
},
getAllList() {
this.getList()
this.$emit("getList")
},
async del(row) {
try {
let confirm = await this.$confirm(this.$t("dictionary:signature:attachmentList:message:del"))
if (!confirm) return false
this.loading = true
let res = await deleteSystemDocumentAttachment(row.Id)
this.loading = false
if (res.IsSuccess) {
this.getAllList()
}
} catch (err) {
console.log(err)
this.loading = false
}
},
edit(row) {
this.rowData = Object.assign({}, row)
this.visible = true
},
async getList() {
try {
if (!this.SystemDocumentId) return false
this.loading = true
this.searchData.SystemDocumentId = this.SystemDocumentId
let res = await getSystemDocumentAttachmentList(this.searchData)
this.loading = false
if (res.IsSuccess) {
this.list = res.Result.CurrentPageData
}
} catch (err) {
this.loading = false
console.log(err)
}
},
async OffLine(row, val) {
try {
let data = Object.assign({}, row)
data.OffLine = val
this.loading = true
let res = await addOrUpdateSystemDocumentAttachment(data)
this.loading = false
if (res.IsSuccess) {
this.$t('dictionary:signature:attachmentList:updateSuccessfully')
this.getList()
}
} catch (err) {
this.loading = false
row.OffLine = !row.OffLine
console.log(err)
}
},
preview(data) {
// return this.perview_visible = true
this.rowData = Object.assign({}, data)
if (['.ppt',
'.pptx',
'.doc',
'.docx',
'.xls',
'.xlsx'].includes(`.${data.FileFormat.toLowerCase()}`)) {
this.$onlyOffice({
path: data.FilePath,
type: data.FileFormat,
title: data.Name
})
}
if (['.jpg',
'.jpeg',
'.png'].includes(`.${data.FileFormat.toLowerCase()}`)) {
this.$nextTick(() => {
this.$refs['picture_perview2'].$viewer.show()
})
}
if (['.pdf'].includes(`.${data.FileFormat.toLowerCase()}`)) {
this.$preview({
path: data.Path || data.FilePath,
type: 'pdf',
title: data.Name,
})
}
},
//
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()
},
}
}
</script>

View File

@ -0,0 +1,305 @@
<template>
<el-dialog :visible.sync="visible" :title="title" :fullscreen="true" append-to-body
custom-class="base-dialog-wrapper" :before-close="handleClose">
<div v-loading="loading" class="img-container" v-if="visible">
<el-card class="box-card left">
<div class="title">
{{ $t('dictionary:signature:fileList') }}
</div>
<div class="left-content">
<!-- 检查层级 -->
<div id="imgList" style="height: 100%; overflow: hidden">
<template v-for="(item, index) in list">
<div :id="`img${item.Id}`" :key="item.Id" :class="{
'is-boxActive': item.Id === rowData.Id,
}" class="img-box" @click="selected(item)">
<div class="file-image">
<el-image v-if="
[
'jpeg',
'jpg',
'png',
].includes(item.FileFormat)
" style="width: 100%; height: 100%"
:src="`${OSSclientConfig.basePath}${item.FilePath}?x-oss-process=image/resize,w_50,h_50/format,png`"
fit="contain" crossorigin="anonymous" />
<el-image v-else style="width: 100%; height: 100%" :src="getsrc(item.FileFormat)"
fit="contain" crossorigin="anonymous" />
</div>
<div v-if="item.Name.length < 15" class="img-text">
{{ `${index + 1}. ${item.Name}` }}
</div>
<el-tooltip v-else :content="item.Name" placement="bottom">
<div class="img-text">
{{ `${index + 1}. ${item.Name}` }}
</div>
</el-tooltip>
</div>
</template>
</div>
</div>
</el-card>
<!-- 预览图像 -->
<el-card class="box-card right">
<div style="width: 100%; height: 100%" v-if="[
'jpeg',
'jpg',
'png',
].includes(rowData.FileFormat)">
<imageViewer :rowData="rowData" />
</div>
<div style="width: 100%; height: 100%" v-else>
<PreviewFile v-if='rowData.FilePath' :file-path="rowData.FilePath" :file-type="rowData.FileFormat"
:title="rowData.Name" />
</div>
</el-card>
<!-- <el-card class="box-card" style="width:300px;height:100%;padding: 10px;margin-left:10px;">
<CheckForm />
</el-card> -->
</div>
</el-dialog>
</template>
<script>
import pdf from '@/assets/file_icon/pdf.png'
import zip from '@/assets/file_icon/zip.png'
import doc from '@/assets/file_icon/doc.png'
import docx from '@/assets/file_icon/docx.png'
import ppt from '@/assets/file_icon/ppt.png'
import pptx from '@/assets/file_icon/pptx.png'
import xls from '@/assets/file_icon/xls.png'
import xlsx from '@/assets/file_icon/xlsx.png'
import PreviewFile from '@/components/PreviewFile'
import imageViewer from './image-viewer'
import { getSystemDocumentAttachmentList } from '@/api/dictionary'
const defaultSearchData = () => {
return {
PageIndex: 1,
PageSize: 1000,
Asc: false,
OffLine: false,
SortField: null
}
}
export default {
name: 'Notice',
components: {
PreviewFile,
imageViewer
},
props: {
SystemDocumentId: {
type: String,
default: ''
},
visible: {
type: Boolean,
default: false
}
},
data() {
return {
pdf,
zip,
doc,
docx,
ppt,
pptx,
xls,
xlsx,
rowData: {},
list: [],
searchData: defaultSearchData(),
title: this.$t('dictionary:signature:fileList')
}
},
watch: {
SystemDocumentId: {
handler() {
this.getList()
},
immediate: true,
}
},
methods: {
getsrc(type) {
return this[type.toLowerCase()]
},
selected(row) {
this.rowData = row
},
handleClose() {
this.$emit("update:visible", false)
},
async getList() {
try {
if (!this.SystemDocumentId) return false
this.loading = true
this.searchData.SystemDocumentId = this.SystemDocumentId
let res = await getSystemDocumentAttachmentList(this.searchData)
this.loading = false
if (res.IsSuccess) {
this.list = res.Result.CurrentPageData
this.rowData = this.list[0] || {}
}
} catch (err) {
this.loading = false
console.log(err)
}
},
},
}
</script>
<style lang="scss" scoped>
.img-container {
position: relative;
width: 100%;
height: 100%;
padding: 10px;
display: flex;
::-webkit-scrollbar {
width: 7px;
height: 7px;
}
::-webkit-scrollbar-thumb {
border-radius: 10px;
background: #d0d0d0;
}
::v-deep .el-card__body {
padding: 0px;
}
}
.study-desc {
padding: 10px 5px;
line-height: 20px;
background-color: #d5d5d5;
font-weight: 500;
}
.left {
width: 220px;
height: 100%;
::v-deep .el-card__body {
height: 100%;
width: 100%;
display: flex;
flex-direction: column;
}
.title {
height: 40px;
line-height: 40px;
border: 1ppx solid;
border: 1px solid #ebe7e7;
padding-left: 10px;
background-color: #4e4e4e;
color: #ffffff;
}
.left-content {
flex: 1;
overflow-y: auto;
}
// ::v-deep .el-tabs{
// height: 100%;
// }
// ::v-deep .el-tabs__header{
// height: 40px;
// }
// ::v-deep .el-tabs__content{
// flex: 1;
// overflow-y: auto;
// padding: 0;
// }
.img-box {
// position: relative;
display: inline-block;
box-sizing: border-box;
border-bottom: 2px solid #f3f3f3;
display: flex;
align-items: center;
flex-wrap: wrap;
justify-content: flex-start;
padding: 5px 10px;
cursor: pointer;
// margin-bottom: 5px;
padding-left: 5px;
}
.img-text {
display: inline-block;
width: calc(100% - 60px);
margin-left: 5px;
height: 50px;
line-height: 50px;
overflow: hidden;
text-overflow: ellipsis;
/* 用省略号表示溢出的文本 */
white-space: nowrap;
}
.img-box:nth-last-child(1) {
margin-bottom: 0px;
}
.is-boxActive {
// border-color: #409eff;
color: #409eff;
}
.is-boxActiv:after {
opacity: 0;
}
}
.right {
flex: 1;
height: 100%;
margin-left: 10px;
::v-deep .el-card__body {
height: 100%;
width: 100%;
}
}
.switchBox {
width: 100%;
margin: 5px 0;
color: #4e4e4e;
.item {
display: flex;
align-items: center;
justify-content: space-between;
margin-bottom: 5px;
}
}
.file-image {
width: 50px;
height: 50px;
}
::v-deep .el-collapse-item__header {
background-color: #d5d5d5;
}
::v-deep .el-collapse-item__header {
min-height: 48px;
height: auto;
}
::v-deep .el-collapse-item__content {
padding-bottom: 0;
}
</style>

View File

@ -0,0 +1,381 @@
/* eslint-disable no-unused-vars */
<template>
<div style="width: 100%; height: 100%">
<transition name="viewer-fade">
<div ref="image-viewer__wrapper" tabindex="-1" class="image-viewer__wrapper" :style="{ 'z-index': 5 }">
<!-- Arrow -->
<!-- 工具栏 -->
<div class="image-viewer__btn image-viewer__actions">
<div class="image-viewer__actions__inner">
<i class="el-icon-zoom-out" @click="handleActions('zoomOut')" />
<i class="el-icon-zoom-in" @click="handleActions('zoomIn')" />
<i class="el-image-viewer__actions__divider" />
<i class="el-icon-c-scale-to-original" @click="toggleMode" />
<i class="el-image-viewer__actions__divider" />
<i class="el-icon-refresh-left" @click="handleActions('anticlocelise')" />
<i class="el-icon-refresh-right" @click="handleActions('clocelise')" />
</div>
</div>
<!-- 图片 -->
<div id="image-viewer__canvas" class="image-viewer__canvas">
<img crossorigin="anonymous" :src="`${OSSclientConfig.basePath}${rowData.FilePath}`
" :style="imgStyle" style="max-width: 100%; max-height: 100%" @load="handleImgLoad" @error="handleImgError"
@mousedown="handleMouseDown" />
</div>
</div>
</transition>
</div>
</template>
<script>
import { on, off } from 'element-ui/src/utils/dom'
import { rafThrottle, isFirefox } from 'element-ui/src/utils/util'
const mousewheelEventName = isFirefox() ? 'DOMMouseScroll' : 'mousewheel'
export default {
name: 'ImageViewer',
props: {
onSwitch: {
type: Function,
default: () => { },
},
onClose: {
type: Function,
default: () => { },
},
rowData:{
type: Object,
default: () => {
return {}
},
}
},
data() {
return {
loading: false,
transform: {
scale: 1,
deg: 0,
offsetX: 0,
offsetY: 0,
enableTransition: false,
},
}
},
computed: {
imgStyle() {
const { scale, deg, offsetX, offsetY, enableTransition } = this.transform
const style = {
transform: `scale(${scale}) rotate(${deg}deg)`,
transition: enableTransition ? 'transform .3s' : '',
'margin-left': `${offsetX}px`,
'margin-top': `${offsetY}px`,
}
return style
},
},
mounted() {
document.getElementById('image-viewer__canvas').onmousewheel = (event) => {
if (event.deltaY > 0) {
//
this.handleActions('zoomOut', {
zoomRate: 0.015,
enableTransition: false,
})
} else {
//
this.handleActions('zoomIn', {
zoomRate: 0.015,
enableTransition: false,
})
}
return false
}
this.deviceSupportInstall()
},
methods: {
hide() {
this.deviceSupportUninstall()
this.onClose()
},
deviceSupportInstall() {
this._keyDownHandler = (e) => {
e.stopPropagation()
const keyCode = e.keyCode
switch (keyCode) {
// ESC
case 27:
this.hide()
break
// SPACE
case 32:
this.toggleMode()
break
// LEFT_ARROW
case 37:
this.prev()
break
// UP_ARROW
case 38:
this.handleActions('zoomIn')
break
// RIGHT_ARROW
case 39:
this.next()
break
// DOWN_ARROW
case 40:
this.handleActions('zoomOut')
break
}
}
this._mouseWheelHandler = rafThrottle((e) => {
const delta = e.wheelDelta ? e.wheelDelta : -e.detail
if (delta > 0) {
this.handleActions('zoomIn', {
zoomRate: 0.015,
enableTransition: false,
})
} else {
this.handleActions('zoomOut', {
zoomRate: 0.015,
enableTransition: false,
})
}
})
on(document, 'keydown', this._keyDownHandler)
on(document, mousewheelEventName, null)
// on(document, mousewheelEventName, this._mouseWheelHandler)
},
deviceSupportUninstall() {
off(document, 'keydown', this._keyDownHandler)
off(document, mousewheelEventName, this._mouseWheelHandler)
this._keyDownHandler = null
this._mouseWheelHandler = null
},
handleImgLoad(e) {
this.loading = false
},
handleImgError(e) {
this.loading = false
e.target.alt = '加载失败'
},
handleMouseDown(e) {
if (this.loading || e.button !== 0) return
const { offsetX, offsetY } = this.transform
const startX = e.pageX
const startY = e.pageY
this._dragHandler = rafThrottle((ev) => {
this.transform.offsetX = offsetX + ev.pageX - startX
this.transform.offsetY = offsetY + ev.pageY - startY
})
on(document, 'mousemove', this._dragHandler)
on(document, 'mouseup', (ev) => {
off(document, 'mousemove', this._dragHandler)
})
e.preventDefault()
},
reset() {
this.transform = {
scale: 1,
deg: 0,
offsetX: 0,
offsetY: 0,
enableTransition: false,
}
},
toggleMode() {
if (this.loading) return
this.reset()
},
handleActions(action, options = {}) {
if (this.loading) return
const { zoomRate, rotateDeg, enableTransition } = {
zoomRate: 0.2,
rotateDeg: 90,
enableTransition: true,
...options,
}
const { transform } = this
switch (action) {
case 'zoomOut':
if (transform.scale > 0.2) {
transform.scale = parseFloat(
(transform.scale - zoomRate).toFixed(3)
)
}
break
case 'zoomIn':
if (transform.scale < 5) {
transform.scale = parseFloat(
(transform.scale + zoomRate).toFixed(3)
)
}
break
case 'clocelise':
transform.deg += rotateDeg
break
case 'anticlocelise':
transform.deg -= rotateDeg
break
}
transform.enableTransition = enableTransition
},
},
}
</script>
<style lang="scss" scoped>
.image-viewer__wrapper {
position: relative;
top: 0;
right: 0;
bottom: 0;
left: 0;
width: 100%;
height: 100%;
}
.image-viewer__btn {
position: absolute;
z-index: 1;
display: flex;
align-items: center;
justify-content: center;
border-radius: 50%;
opacity: 0.8;
cursor: pointer;
box-sizing: border-box;
user-select: none;
}
.image-viewer__close {
display: none;
top: 40px;
right: 40px;
width: 40px;
height: 40px;
font-size: 40px;
}
.image-viewer_desc {
position: absolute;
top: 40px;
left: 40px;
font-size: 15px;
padding: 5px;
height: 30px;
width: 70px;
line-height: 20px;
text-align: center;
color: #fff;
background-color: #606266;
border-color: #fff;
z-index: 1;
border-radius: 17px;
// border-radius: 2%;
}
.image-viewer__canvas {
position: absolute;
top: 50%;
transform: translateY(-50%);
width: 100%;
height: 100%;
display: flex;
justify-content: center;
align-items: center;
}
.image-viewer__actions {
left: 50%;
bottom: 30px;
transform: translateX(-50%);
width: 282px;
height: 44px;
padding: 0 23px;
background-color: #606266;
border-color: #fff;
border-radius: 22px;
}
.image-viewer__actions__inner {
width: 100%;
height: 100%;
text-align: justify;
cursor: default;
font-size: 23px;
color: #fff;
display: flex;
align-items: center;
justify-content: space-around;
}
.image-viewer__next,
.image-viewer__prev {
top: 50%;
width: 44px;
height: 44px;
font-size: 24px;
color: #fff;
background-color: #606266;
border-color: #fff;
}
.image-viewer__prev {
transform: translateY(-50%);
left: 40px;
}
.image-viewer__next {
transform: translateY(-50%);
right: 40px;
text-indent: 2px;
}
.image-viewer__mask {
position: absolute;
width: 100%;
height: 100%;
top: 0;
left: 0;
opacity: 0.5;
// background:#000
}
.viewer-fade-enter-active {
animation: viewer-fade-in 0.3s;
}
.viewer-fade-leave-active {
animation: viewer-fade-out 0.3s;
}
@keyframes viewer-fade-in {
0% {
transform: translate3d(0, -20px, 0);
opacity: 0;
}
100% {
transform: translate3d(0, 0, 0);
opacity: 1;
}
}
@keyframes viewer-fade-out {
0% {
transform: translate3d(0, 0, 0);
opacity: 1;
}
100% {
transform: translate3d(0, -20px, 0);
opacity: 0;
}
}
</style>

View File

@ -69,12 +69,16 @@
@sort-change="handleSortByColumn"> @sort-change="handleSortByColumn">
<el-table-column type="index" width="40" /> <el-table-column type="index" width="40" />
<el-table-column prop="FileType" :label="$t('dictionary:signature:table:FileType')" show-overflow-tooltip <el-table-column prop="FileType" :label="$t('dictionary:signature:table:FileType')" show-overflow-tooltip
sortable="custom" /> sortable="custom" min-width="120px" />
<el-table-column prop="Name" :label="$t('dictionary:signature:table:Name')" show-overflow-tooltip <el-table-column prop="Name" :label="$t('dictionary:signature:table:Name')" show-overflow-tooltip
sortable="custom" /> sortable="custom" min-width="120px" />
<el-table-column prop="SignViewMinimumMinutes" :label="$t('dictionary:signature:table:SignViewMinimumMinutes')" <el-table-column prop="SignViewMinimumMinutes" :label="$t('dictionary:signature:table:SignViewMinimumMinutes')"
show-overflow-tooltip sortable="custom" min-width="110" /> show-overflow-tooltip sortable="custom" min-width="200px" />
<el-table-column prop="CurrentStaffTrainDays" :label="$t('dictionary:signature:table:CurrentStaffTrainDays')"
show-overflow-tooltip sortable="custom" min-width="200px" />
<el-table-column prop="NewStaffTrainDays" :label="$t('dictionary:signature:table:NewStaffTrainDays')"
show-overflow-tooltip sortable="custom" min-width="200px" />
<el-table-column prop="NeedConfirmedUserTypes" :label="$t('dictionary:signature:table:NeedConfirmedUserTypes')" <el-table-column prop="NeedConfirmedUserTypes" :label="$t('dictionary:signature:table:NeedConfirmedUserTypes')"
show-overflow-tooltip> show-overflow-tooltip>
<template slot-scope="scope"> <template slot-scope="scope">
@ -86,7 +90,7 @@
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="IsDeleted" :label="$t('dictionary:signature:table:IsDeleted')" show-overflow-tooltip <el-table-column prop="IsDeleted" :label="$t('dictionary:signature:table:IsDeleted')" show-overflow-tooltip
sortable="custom"> sortable="custom" min-width="120px">
<template slot-scope="scope"> <template slot-scope="scope">
<el-tag v-if="scope.row.IsDeleted" type="danger">{{ <el-tag v-if="scope.row.IsDeleted" type="danger">{{
$fd('TrainingStatus', scope.row.IsDeleted) $fd('TrainingStatus', scope.row.IsDeleted)
@ -97,15 +101,21 @@
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="DocUserSignType" :label="$t('dictionary:signature:table:DocUserSignType')" <el-table-column prop="DocUserSignType" :label="$t('dictionary:signature:table:DocUserSignType')"
show-overflow-tooltip sortable="custom" min-width="90"> show-overflow-tooltip sortable="custom" min-width="150px">
<template slot-scope="scope"> <template slot-scope="scope">
{{ $fd('ReadingYesOrNo', Number(scope.row.DocUserSignType)) }} {{ $fd('ReadingYesOrNo', Number(scope.row.DocUserSignType)) }}
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="AttachmentCount" :label="$t('dictionary:signature:table:AttachmentCount')"
show-overflow-tooltip sortable="custom" min-width="150px">
<template slot-scope="scope">
<el-button type="text" @click.stop="openAttachment(scope.row)">{{ scope.row.AttachmentCount }}</el-button>
</template>
</el-table-column>
<el-table-column prop="CreateTime" :label="$t('dictionary:signature:table:CreateTime')" show-overflow-tooltip <el-table-column prop="CreateTime" :label="$t('dictionary:signature:table:CreateTime')" show-overflow-tooltip
sortable="custom" /> sortable="custom" min-width="180px" />
<el-table-column :label="$t('common:action:action')" min-width="120"> <el-table-column :label="$t('common:action:action')" min-width="180px" fixed="right">
<template slot-scope="scope"> <template slot-scope="scope">
<el-button type="text" @click="handlePreview(scope.row)"> <el-button type="text" @click="handlePreview(scope.row)">
{{ $t('common:button:preview') }} {{ $t('common:button:preview') }}
@ -131,7 +141,8 @@
width="600px" custom-class="base-dialog-wrapper"> width="600px" custom-class="base-dialog-wrapper">
<TemplateForm :data="currentRow" @closeDialog="closeDialog" @getList="getList" /> <TemplateForm :data="currentRow" @closeDialog="closeDialog" @getList="getList" />
</el-dialog> </el-dialog>
<!--附件列表-->
<attachmentList v-if="config.visible" :config="config" :SystemDocumentId="SystemDocumentId" @getLit="getList" />
<!-- 预览文件 --> <!-- 预览文件 -->
<el-dialog v-if="previewVisible" :visible.sync="previewVisible" :title="$t('common:button:preview')" <el-dialog v-if="previewVisible" :visible.sync="previewVisible" :title="$t('common:button:preview')"
:fullscreen="true" append-to-body custom-class="base-dialog-wrapper"> :fullscreen="true" append-to-body custom-class="base-dialog-wrapper">
@ -148,6 +159,8 @@ import { userAbandonDoc, getTrialUserTypeList } from '@/api/trials'
import BaseContainer from '@/components/BaseContainer' import BaseContainer from '@/components/BaseContainer'
import Pagination from '@/components/Pagination' import Pagination from '@/components/Pagination'
import TemplateForm from './TemplateForm' import TemplateForm from './TemplateForm'
import attachmentList from './attachmentList'
import PreviewFile from '@/components/PreviewFile/index' import PreviewFile from '@/components/PreviewFile/index'
const searchDataDefault = () => { const searchDataDefault = () => {
return { return {
@ -164,7 +177,7 @@ const searchDataDefault = () => {
} }
export default { export default {
name: 'SignatureTemplate', name: 'SignatureTemplate',
components: { BaseContainer, Pagination, TemplateForm, PreviewFile }, components: { BaseContainer, Pagination, TemplateForm, PreviewFile, attachmentList },
dicts: ['Sys_Document'], dicts: ['Sys_Document'],
props: { props: {
isSystem: { isSystem: {
@ -189,7 +202,14 @@ export default {
title: '', title: '',
loading: false, loading: false,
userTypeOptions: [], userTypeOptions: [],
timeList: [] timeList: [],
attachment_Visible: false,
SystemDocumentId: null,
config: {
visible: false,
title: this.$t('dictionary:signature:attachmentList:title'),
width: '800px',
}
} }
}, },
mounted() { mounted() {
@ -197,6 +217,10 @@ export default {
this.getUserType() this.getUserType()
}, },
methods: { methods: {
openAttachment(row) {
this.SystemDocumentId = row.Id
this.config.visible = true
},
changeTimeList() { changeTimeList() {
if (this.timeList) { if (this.timeList) {
this.searchData.BeginCreateTime = this.timeList[0] this.searchData.BeginCreateTime = this.timeList[0]
@ -311,6 +335,7 @@ export default {
// //
closeDialog() { closeDialog() {
this.editVisible = false this.editVisible = false
this.attachment_Visible = false
}, },
// //
handleReset() { handleReset() {

View File

@ -122,6 +122,12 @@
<!-- 文件名称 --> <!-- 文件名称 -->
<el-table-column prop="Name" :label="$t('trials:signRecords:table:fileName')" show-overflow-tooltip <el-table-column prop="Name" :label="$t('trials:signRecords:table:fileName')" show-overflow-tooltip
sortable="custom" /> sortable="custom" />
<el-table-column :label="$t('trials:signRecords:table:AttachmentCount')" prop="AttachmentCount"
show-overflow-tooltip sortable="custom">
<template slot-scope="scope">
<el-button type="text" @click.stop="openAttachment(scope.row)">{{ scope.row.AttachmentCount }}</el-button>
</template>
</el-table-column>
<!-- 文件级别 --> <!-- 文件级别 -->
<el-table-column prop="IsSystemDoc" :label="$t('trials:signRecords:table:fileLevel')" show-overflow-tooltip <el-table-column prop="IsSystemDoc" :label="$t('trials:signRecords:table:fileLevel')" show-overflow-tooltip
width="160" sortable="custom" v-if="!isSystem"> width="160" sortable="custom" v-if="!isSystem">
@ -201,10 +207,15 @@
<!-- 预览文件 --> <!-- 预览文件 -->
<el-dialog v-if="previewVisible" :visible.sync="previewVisible" :title="$t('trials:signRecords:action:preview')" <el-dialog v-if="previewVisible" :visible.sync="previewVisible" :title="$t('trials:signRecords:action:preview')"
:fullscreen="true" append-to-body custom-class="base-dialog-wrapper"> :fullscreen="true" append-to-body custom-class="base-dialog-wrapper">
<span style="position: fixed; left: 16px; top: 45px;cursor: pointer;" @click.stop="openAttachment(currentRow)"
v-if="currentRow.AttachmentCount">{{
$t('trials:signRecords:table:AttachmentCount') }} ({{
currentRow.AttachmentCount }})</span>
<div class="base-modal-body" style="border: 2px solid #ccc; padding: 10px"> <div class="base-modal-body" style="border: 2px solid #ccc; padding: 10px">
<PreviewFile v-if="previewVisible" :file-path="currentPath" :file-type="currentType" @getList="getList" /> <PreviewFile v-if="previewVisible" :file-path="currentPath" :file-type="currentType" @getList="getList" />
</div> </div>
</el-dialog> </el-dialog>
<attachmentPreview :SystemDocumentId="SystemDocumentId" :visible.sync="perview_visible" v-if="perview_visible" />
</BaseContainer> </BaseContainer>
</template> </template>
<script> <script>
@ -220,6 +231,7 @@ import { pMTrainingRecordList_Export } from '@/api/export'
import BaseContainer from '@/components/BaseContainer' import BaseContainer from '@/components/BaseContainer'
import Pagination from '@/components/Pagination' import Pagination from '@/components/Pagination'
import PreviewFile from '@/components/PreviewFile/index' import PreviewFile from '@/components/PreviewFile/index'
import attachmentPreview from '@/views/dictionary/attachment/components/SignatureTemplate/attachmentPreview'
const searchDataDefault = () => { const searchDataDefault = () => {
return { return {
UserName: null, UserName: null,
@ -240,7 +252,7 @@ const searchDataDefault = () => {
} }
export default { export default {
name: 'AttachmentsManagement', name: 'AttachmentsManagement',
components: { BaseContainer, Pagination, PreviewFile }, components: { BaseContainer, Pagination, PreviewFile, attachmentPreview },
props: { props: {
isDoc: { isDoc: {
type: Boolean, type: Boolean,
@ -276,7 +288,9 @@ export default {
trialId: this.$route.query.trialId, trialId: this.$route.query.trialId,
exportLoading: false, exportLoading: false,
timeList: [], timeList: [],
timeListC: [] timeListC: [],
SystemDocumentId: null,
perview_visible: null,
} }
}, },
mounted() { mounted() {
@ -285,6 +299,11 @@ export default {
this.getUserType() this.getUserType()
}, },
methods: { methods: {
openAttachment(row) {
if (!row.AttachmentCount) return false
this.SystemDocumentId = row.Id
this.perview_visible = true
},
changeTimeList() { changeTimeList() {
if (this.timeList) { if (this.timeList) {
this.searchData.StartConfirmTime = this.timeList[0] this.searchData.StartConfirmTime = this.timeList[0]

View File

@ -5,17 +5,9 @@
<el-form :inline="true"> <el-form :inline="true">
<!-- 文件类型 --> <!-- 文件类型 -->
<el-form-item :label="$t('trials:self-attachment:table:fileType')"> <el-form-item :label="$t('trials:self-attachment:table:fileType')">
<el-select <el-select v-model="searchData.FileTypeId" clearable style="width:150px;">
v-model="searchData.FileTypeId" <el-option v-for="item of typeOptions" :key="item.FileTypeId" :label="item.FileType"
clearable :value="item.FileTypeId" />
style="width:150px;"
>
<el-option
v-for="item of typeOptions"
:key="item.FileTypeId"
:label="item.FileType"
:value="item.FileTypeId"
/>
</el-select> </el-select>
</el-form-item> </el-form-item>
<!-- 文件名称 --> <!-- 文件名称 -->
@ -44,104 +36,70 @@
</template> </template>
<template slot="main-container"> <template slot="main-container">
<!-- 系统文件列表 --> <!-- 系统文件列表 -->
<el-table <el-table ref="TrialAttachments" v-loading="loading" v-adaptive="{ bottomOffset: 60 }" :data="list" stripe
ref="TrialAttachments" height="100" @sort-change="handleSortByColumn">
v-loading="loading"
v-adaptive="{bottomOffset:60}"
:data="list"
stripe
height="100"
@sort-change="handleSortByColumn"
>
<el-table-column type="selection" width="50" /> <el-table-column type="selection" width="50" />
<el-table-column type="index" width="40" /> <el-table-column type="index" width="40" />
<!-- 文件类型 --> <!-- 文件类型 -->
<el-table-column <el-table-column prop="FileType" :label="$t('trials:self-attachment:table:fileType')" show-overflow-tooltip
prop="FileType" sortable="custom" />
:label="$t('trials:self-attachment:table:fileType')"
show-overflow-tooltip
sortable="custom"
/>
<!-- 文件名称 --> <!-- 文件名称 -->
<el-table-column <el-table-column prop="Name" :label="$t('trials:self-attachment:table:fileName')" show-overflow-tooltip
prop="Name" sortable="custom" />
:label="$t('trials:self-attachment:table:fileName')" <el-table-column :label="$t('trials:self-attachment:table:AttachmentCount')" prop="AttachmentCount"
show-overflow-tooltip show-overflow-tooltip sortable="custom">
sortable="custom" <template slot-scope="scope">
/> <el-button type="text" @click.stop="openAttachment(scope.row)">{{ scope.row.AttachmentCount }}</el-button>
</template>
</el-table-column>
<!-- 是否废除 --> <!-- 是否废除 -->
<el-table-column <el-table-column prop="IsDeleted" :label="$t('trials:self-attachment:table:isDeleted')" show-overflow-tooltip
prop="IsDeleted" sortable="custom">
:label="$t('trials:self-attachment:table:isDeleted')"
show-overflow-tooltip
sortable="custom"
>
<template slot-scope="scope"> <template slot-scope="scope">
<el-tag v-if="scope.row.IsDeleted" type="danger">{{ $fd('TrainingStatus', scope.row.IsDeleted) }}</el-tag> <el-tag v-if="scope.row.IsDeleted" type="danger">{{ $fd('TrainingStatus', scope.row.IsDeleted) }}</el-tag>
<el-tag v-else type="primary">{{ $fd('TrainingStatus', scope.row.IsDeleted) }}</el-tag> <el-tag v-else type="primary">{{ $fd('TrainingStatus', scope.row.IsDeleted) }}</el-tag>
</template> </template>
</el-table-column> </el-table-column>
<!-- 上传时间 --> <!-- 上传时间 -->
<el-table-column <el-table-column prop="CreateTime" :label="$t('trials:self-attachment:table:uploadTime')" show-overflow-tooltip
prop="CreateTime" sortable="custom" />
:label="$t('trials:self-attachment:table:uploadTime')"
show-overflow-tooltip
sortable="custom"
/>
<!-- 是否签署 --> <!-- 是否签署 -->
<el-table-column <el-table-column prop="ConfirmTime" :label="$t('trials:self-attachment:table:isSign')" show-overflow-tooltip
prop="ConfirmTime" sortable="custom">
:label="$t('trials:self-attachment:table:isSign')"
show-overflow-tooltip
sortable="custom"
>
<template slot-scope="scope"> <template slot-scope="scope">
<el-tag v-if="scope.row.IsConfirmed" type="primary">{{ $fd('TrainingStatusEnum', scope.row.IsConfirmed) }}</el-tag> <el-tag v-if="scope.row.IsConfirmed" type="primary">{{ $fd('TrainingStatusEnum', scope.row.IsConfirmed)
}}</el-tag>
<el-tag v-else type="danger">{{ $fd('TrainingStatusEnum', scope.row.IsConfirmed) }}</el-tag> <el-tag v-else type="danger">{{ $fd('TrainingStatusEnum', scope.row.IsConfirmed) }}</el-tag>
</template> </template>
</el-table-column> </el-table-column>
<!-- 签署时间 --> <!-- 签署时间 -->
<el-table-column <el-table-column prop="ConfirmTime" :label="$t('trials:self-attachment:table:signTime')" show-overflow-tooltip
prop="ConfirmTime" sortable="custom" />
:label="$t('trials:self-attachment:table:signTime')"
show-overflow-tooltip
sortable="custom"
/>
<el-table-column :label="$t('common:action:action')"> <el-table-column :label="$t('common:action:action')">
<template slot-scope="scope"> <template slot-scope="scope">
<!-- 预览 --> <!-- 预览 -->
<el-button <el-button icon="el-icon-view" circle :title="$t('trials:self-attachment:action:preview')"
icon="el-icon-view" @click="handlePreview(scope.row)" />
circle
:title="$t('trials:self-attachment:action:preview')"
@click="handlePreview(scope.row)"
/>
<!-- 签署 --> <!-- 签署 -->
<el-button <el-button icon="el-icon-edit-outline" circle :disabled="!!scope.row.ConfirmTime"
icon="el-icon-edit-outline" :title="$t('trials:self-attachment:action:sign')" @click="handleSign(scope.row)" />
circle
:disabled="!!scope.row.ConfirmTime"
:title="$t('trials:self-attachment:action:sign')"
@click="handleSign(scope.row)"
/>
</template> </template>
</el-table-column> </el-table-column>
</el-table> </el-table>
<!-- 分页组件 --> <!-- 分页组件 -->
<pagination class="page" :total="total" :page.sync="searchData.PageIndex" :limit.sync="searchData.PageSize" @pagination="getList" /> <pagination class="page" :total="total" :page.sync="searchData.PageIndex" :limit.sync="searchData.PageSize"
@pagination="getList" />
</template> </template>
<!-- 预览文件 --> <!-- 预览文件 -->
<el-dialog <el-dialog v-if="previewVisible" :visible.sync="previewVisible" :title="title" :fullscreen="true" append-to-body
v-if="previewVisible" custom-class="base-dialog-wrapper">
:visible.sync="previewVisible" <span style="position: fixed; left: 16px; top: 45px;cursor: pointer;" @click.stop="openAttachment(currentRow)"
:title="title" v-if="currentRow.AttachmentCount">{{
:fullscreen="true" $t('trials:self-attachment:table:AttachmentCount') }} ({{
append-to-body currentRow.AttachmentCount }})</span>
custom-class="base-dialog-wrapper"
>
<span v-if="!currentIsConfirm" style="position: fixed;right: 75px;top: 14px;"> <span v-if="!currentIsConfirm" style="position: fixed;right: 75px;top: 14px;">
<span style="color:red;margin-right:10px;"> <span style="color:red;margin-right:10px;">
<!-- 请仔细阅读文件并签名确认 --> <!-- 请仔细阅读文件并签名确认 -->
@ -149,13 +107,8 @@
<span v-show="duration < currentMinMinutes * 60">{{ `(${currentMinMinutes * 60 - duration}s)` }}</span> <span v-show="duration < currentMinMinutes * 60">{{ `(${currentMinMinutes * 60 - duration}s)` }}</span>
</span> </span>
<!-- 签署 --> <!-- 签署 -->
<el-button <el-button size="small" type="primary" :disabled="timer !== null || duration === 0" :loading="btnLoading"
size="small" @click="handleConfirm">
type="primary"
:disabled="timer !== null || duration === 0"
:loading="btnLoading"
@click="handleConfirm"
>
{{ $t('common:button:sign') }} {{ $t('common:button:sign') }}
<!-- {{ duration >= currentMinMinutes * 60?'确认':`确认(${currentMinMinutes * 60 - duration}s)` }} --> <!-- {{ duration >= currentMinMinutes * 60?'确认':`确认(${currentMinMinutes * 60 - duration}s)` }} -->
</el-button> </el-button>
@ -167,19 +120,16 @@
</el-dialog> </el-dialog>
<!-- 签名弹框 --> <!-- 签名弹框 -->
<el-dialog <el-dialog v-if="signVisible" :visible.sync="signVisible" :close-on-click-modal="false" width="600px"
v-if="signVisible" append-to-body>
:visible.sync="signVisible"
:close-on-click-modal="false"
width="600px"
append-to-body
>
<div slot="title"> <div slot="title">
<span style="font-size:18px;">{{ $t('common:dialogTitle:sign') }}</span> <span style="font-size:18px;">{{ $t('common:dialogTitle:sign') }}</span>
<span style="font-size:12px;margin-left:5px">{{ `(${$t('common:label:sign')}${currentUser})` }}</span> <span style="font-size:12px;margin-left:5px">{{ `(${$t('common:label:sign')}${currentUser})` }}</span>
</div> </div>
<SignForm :is-system-doc="currentRow.IsSystemDoc" :document-id="currentRow.Id" :file-name="fileName" :trial-id="trialId" @closeDialog="closeSignDialog" /> <SignForm :is-system-doc="currentRow.IsSystemDoc" :document-id="currentRow.Id" :file-name="fileName"
:trial-id="trialId" @closeDialog="closeSignDialog" />
</el-dialog> </el-dialog>
<attachmentPreview :SystemDocumentId="SystemDocumentId" :visible.sync="perview_visible" v-if="perview_visible" />
</BaseContainer> </BaseContainer>
</template> </template>
<script> <script>
@ -189,6 +139,7 @@ import Pagination from '@/components/Pagination'
import PreviewFile from '@/components/PreviewFile/index' import PreviewFile from '@/components/PreviewFile/index'
import SignForm from './components/SignForm' import SignForm from './components/SignForm'
import store from '@/store' import store from '@/store'
import attachmentPreview from '@/views/dictionary/attachment/components/SignatureTemplate/attachmentPreview'
const searchDataDefault = () => { const searchDataDefault = () => {
return { return {
FileTypeId: '', FileTypeId: '',
@ -202,7 +153,7 @@ const searchDataDefault = () => {
} }
export default { export default {
name: 'TrialAttachments', name: 'TrialAttachments',
components: { BaseContainer, Pagination, PreviewFile, SignForm }, components: { BaseContainer, Pagination, PreviewFile, SignForm, attachmentPreview },
data() { data() {
return { return {
searchData: searchDataDefault(), searchData: searchDataDefault(),
@ -223,7 +174,9 @@ export default {
fileName: '', fileName: '',
currentUser: zzSessionStorage.getItem('userName'), currentUser: zzSessionStorage.getItem('userName'),
typeOptions: [], typeOptions: [],
trialId: this.$route.query.trialId trialId: this.$route.query.trialId,
SystemDocumentId: null,
perview_visible: null
} }
}, },
mounted() { mounted() {
@ -240,6 +193,11 @@ export default {
} }
}, },
methods: { methods: {
openAttachment(row) {
if (!row.AttachmentCount) return false
this.SystemDocumentId = row.Id
this.perview_visible = true
},
// //
getList() { getList() {
this.loading = true this.loading = true

View File

@ -9,48 +9,25 @@
</div> </div>
<div class="functions" style="text-align: right"> <div class="functions" style="text-align: right">
<!-- // --> <!-- // -->
<el-button <el-button :disabled="deleteArr.length === 0" type="primary" size="small" icon="el-icon-delete"
:disabled="deleteArr.length === 0" @click="handleBatchDelete">
type="primary"
size="small"
icon="el-icon-delete"
@click="handleBatchDelete"
>
{{ $t('trials:uploadedDicoms:action:delete') }} {{ $t('trials:uploadedDicoms:action:delete') }}
</el-button> </el-button>
<!-- 预览 --> <!-- 预览 -->
<el-button <el-button type="primary" icon="el-icon-view" size="small" :disabled="studyList.length === 0"
type="primary" @click="handlePreviewAllFiles">
icon="el-icon-view"
size="small"
:disabled="studyList.length === 0"
@click="handlePreviewAllFiles"
>
{{ $t('trials:uploadedDicoms:action:preview') }} {{ $t('trials:uploadedDicoms:action:preview') }}
</el-button> </el-button>
</div> </div>
<el-table <el-table v-loading="studyLoading" :data="studyList" style="width: 100%" :row-class-name="tableRowClassName"
v-loading="studyLoading" max-height="250" @selection-change="handleUploadedSelectionChange"
:data="studyList" :default-sort="{ prop: 'UploadedTime', order: 'ascending' }">
style="width: 100%"
:row-class-name="tableRowClassName"
max-height="250"
@selection-change="handleUploadedSelectionChange"
:default-sort="{ prop: 'UploadedTime', order: 'ascending' }"
>
<el-table-column type="selection" width="55" /> <el-table-column type="selection" width="55" />
<!-- 检查编号 --> <!-- 检查编号 -->
<el-table-column <el-table-column prop="StudyCode" :label="$t('trials:uploadedDicoms:table:studyId')" min-width="80"
prop="StudyCode" show-overflow-tooltip sortable>
:label="$t('trials:uploadedDicoms:table:studyId')"
min-width="80"
show-overflow-tooltip
sortable
>
<template slot-scope="scope"> <template slot-scope="scope">
<el-tooltip <el-tooltip placement="top" v-if="
placement="top"
v-if="
(() => { (() => {
var r = false var r = false
if (scope.row.IsHaveUploadFailed) { if (scope.row.IsHaveUploadFailed) {
@ -66,84 +43,45 @@
} }
return r return r
})() })()
" ">
>
<div slot="content"> <div slot="content">
{{ $t('trials:uploadDicomList:table:status4') }} {{ $t('trials:uploadDicomList:table:status4') }}
</div> </div>
<span <span class="el-icon-warning" style="color: #cbb024; cursor: pointer"
class="el-icon-warning" v-if="scope.row.IsHaveUploadFailed"></span>
style="color: #cbb024; cursor: pointer"
v-if="scope.row.IsHaveUploadFailed"
></span>
</el-tooltip> </el-tooltip>
<el-tooltip placement="top" v-if="!scope.row.IsCompleteClinicalData"> <el-tooltip placement="top" v-if="!scope.row.IsCompleteClinicalData">
<div slot="content"> <div slot="content">
{{ $t('trials:crc-upload:confirm:message') }} {{ $t('trials:crc-upload:confirm:message') }}
</div> </div>
<span <span class="el-icon-warning" style="color: red; cursor: pointer"></span>
class="el-icon-warning"
style="color: red; cursor: pointer"
></span>
</el-tooltip> </el-tooltip>
{{ scope.row.StudyCode }} {{ scope.row.StudyCode }}
</template> </template>
</el-table-column> </el-table-column>
<!-- 检查名称 --> <!-- 检查名称 -->
<el-table-column <el-table-column v-if="relationInfo.IsShowStudyName" prop="StudyName" :label="$t('trials:audit:table:StudyName')"
v-if="relationInfo.IsShowStudyName" sortable />
prop="StudyName"
:label="$t('trials:audit:table:StudyName')"
sortable
/>
<!-- 检查类型 --> <!-- 检查类型 -->
<el-table-column <el-table-column prop="ModalityForEdit" :label="$t('trials:audit:table:modality')" sortable />
prop="ModalityForEdit"
:label="$t('trials:audit:table:modality')"
sortable
/>
<!-- 检查设备 --> <!-- 检查设备 -->
<el-table-column <el-table-column prop="Modalities" :label="$t('trials:audit:table:modality1')" sortable />
prop="Modalities"
:label="$t('trials:audit:table:modality1')"
sortable
/>
<!-- 检查部位 --> <!-- 检查部位 -->
<el-table-column <el-table-column prop="BodyPartForEdit" :label="$t('trials:uploadedDicoms:table:bodyPart')" min-width="100"
prop="BodyPartForEdit" show-overflow-tooltip sortable>
:label="$t('trials:uploadedDicoms:table:bodyPart')"
min-width="100"
show-overflow-tooltip
sortable
>
<template slot-scope="scope"> <template slot-scope="scope">
{{ getBodyPart(scope.row.BodyPartForEdit) }} {{ getBodyPart(scope.row.BodyPartForEdit) }}
</template> </template>
</el-table-column> </el-table-column>
<!-- 序列数量 --> <!-- 序列数量 -->
<el-table-column <el-table-column prop="SeriesCount" :label="$t('trials:uploadedDicoms:table:seriesCount')" min-width="100"
prop="SeriesCount" show-overflow-tooltip sortable />
:label="$t('trials:uploadedDicoms:table:seriesCount')"
min-width="100"
show-overflow-tooltip
sortable
/>
<!-- 图像数量 --> <!-- 图像数量 -->
<el-table-column <el-table-column prop="InstanceCount" :label="$t('trials:uploadedDicoms:table:instanceCount')" min-width="100"
prop="InstanceCount" show-overflow-tooltip sortable />
:label="$t('trials:uploadedDicoms:table:instanceCount')"
min-width="100"
show-overflow-tooltip
sortable
/>
<!-- 检查日期 --> <!-- 检查日期 -->
<el-table-column <el-table-column prop="StudyTime" :label="$t('trials:uploadedDicoms:table:studyDate')" min-width="120"
prop="StudyTime" show-overflow-tooltip sortable>
:label="$t('trials:uploadedDicoms:table:studyDate')"
min-width="120"
show-overflow-tooltip
sortable
>
<template slot-scope="scope"> <template slot-scope="scope">
{{ {{
scope.row.StudyTime scope.row.StudyTime
@ -153,63 +91,27 @@
</template> </template>
</el-table-column> </el-table-column>
<!-- 更新时间 --> <!-- 更新时间 -->
<el-table-column <el-table-column prop="UpdateTime" :label="$t('trials:uploadedDicoms:table:UpdateTime')" min-width="120"
prop="UpdateTime" show-overflow-tooltip sortable />
:label="$t('trials:uploadedDicoms:table:UpdateTime')"
min-width="120"
show-overflow-tooltip
sortable
/>
<!-- 上传时间 --> <!-- 上传时间 -->
<el-table-column <el-table-column prop="UploadedTime" :label="$t('trials:uploadedDicoms:table:uploadedTime')" min-width="120"
prop="UploadedTime" show-overflow-tooltip sortable />
:label="$t('trials:uploadedDicoms:table:uploadedTime')" <el-table-column :label="$t('common:action:action')" min-width="260" fixed="right">
min-width="120"
show-overflow-tooltip
sortable
/>
<el-table-column
:label="$t('common:action:action')"
min-width="260"
fixed="right"
>
<template slot-scope="scope"> <template slot-scope="scope">
<!-- 预览 --> <!-- 预览 -->
<el-button <el-button icon="el-icon-view" :disabled="scope.row.SeriesCount === 0"
icon="el-icon-view" :title="$t('trials:uploadedDicoms:action:preview')" circle @click="handleViewStudy(scope.row)" />
:disabled="scope.row.SeriesCount === 0 || scope.row.IsDeleted"
:title="$t('trials:uploadedDicoms:action:preview')"
circle
@click="handleViewStudy(scope.row)"
/>
<!-- 上传临床数据 --> <!-- 上传临床数据 -->
<el-button <el-button icon="el-icon-upload2" v-if="
icon="el-icon-upload2"
v-if="
['PT、CT', 'CT、PT', 'PET-CT'].includes(scope.row.Modalities) && ['PT、CT', 'CT、PT', 'PET-CT'].includes(scope.row.Modalities) &&
relationInfo.IsHaveStudyClinicalData relationInfo.IsHaveStudyClinicalData
" " :title="$t('trials:workbench:title:UploadClinicalData')" circle @click="handleUploadPetData(scope.row)" />
:title="$t('trials:workbench:title:UploadClinicalData')"
circle
@click="handleUploadPetData(scope.row)"
/>
<!-- 编辑 --> <!-- 编辑 -->
<el-button <el-button icon="el-icon-edit-outline" v-hasPermi="['trials:trials-panel:visit:crc-upload:edit']"
icon="el-icon-edit-outline" :title="$t('common:button:edit')" circle @click="handleEditStudy(scope.row)" />
v-hasPermi="['trials:trials-panel:visit:crc-upload:edit']" <!-- 删除 :disabled="scope.row.IsDeleted"-->
:title="$t('common:button:edit')" <el-button icon="el-icon-delete" :title="$t('trials:uploadedDicoms:action:delete')" circle
circle @click="handleDeleteStudy(scope.row)" />
:disabled="scope.row.IsDeleted"
@click="handleEditStudy(scope.row)"
/>
<!-- 删除 -->
<el-button
icon="el-icon-delete"
:disabled="scope.row.IsDeleted"
:title="$t('trials:uploadedDicoms:action:delete')"
circle
@click="handleDeleteStudy(scope.row)"
/>
<!-- <el-button--> <!-- <el-button-->
<!-- icon="el-icon-toilet-paper"--> <!-- icon="el-icon-toilet-paper"-->
<!-- circle--> <!-- circle-->
@ -228,49 +130,23 @@
</div> </div>
<el-tabs v-model="uploadActiveName"> <el-tabs v-model="uploadActiveName">
<!-- 本地上传 --> <!-- 本地上传 -->
<el-tab-pane <el-tab-pane :label="$t('trials:uploadedDicoms:tab:uploadFile')" name="file">
:label="$t('trials:uploadedDicoms:tab:uploadFile')"
name="file"
>
<form id="inputForm" ref="uploadForm" enctype="multipart/form-data"> <form id="inputForm" ref="uploadForm" enctype="multipart/form-data">
<div class="form-group"> <div class="form-group">
<div id="directoryInputWrapper" class="btn btn-link file-input"> <div id="directoryInputWrapper" class="btn btn-link file-input">
<el-button <el-button type="primary" :disabled="btnLoading" :loading="btnLoading" size="small">{{
type="primary"
:disabled="btnLoading"
:loading="btnLoading"
size="small"
>{{
$t('trials:uploadedDicomsicom:button:selectFolder') $t('trials:uploadedDicomsicom:button:selectFolder')
}}</el-button }}</el-button>
> <input type="file" name="file" ref="pathClear" :disabled="btnLoading" webkitdirectory multiple title=""
<input @change="beginScanFiles($event)" />
type="file"
name="file"
ref="pathClear"
:disabled="btnLoading"
webkitdirectory
multiple
title=""
@change="beginScanFiles($event)"
/>
</div> </div>
</div> </div>
</form> </form>
<!-- 文件列表 --> <!-- 文件列表 -->
<el-table <el-table ref="dicomFilesTable" :data="uploadQueues" :row-key="(row) => row.studyIndex" class="dicomFiles-table"
ref="dicomFilesTable" @selection-change="handleSelectionChange">
:data="uploadQueues" <el-table-column type="selection" width="55" :selectable="handleSelectable" />
:row-key="(row) => row.studyIndex"
class="dicomFiles-table"
@selection-change="handleSelectionChange"
>
<el-table-column
type="selection"
width="55"
:selectable="handleSelectable"
/>
<el-table-column type="index" width="40" /> <el-table-column type="index" width="40" />
<el-table-column min-width="200" show-overflow-tooltip> <el-table-column min-width="200" show-overflow-tooltip>
<template slot="header"> <template slot="header">
@ -287,28 +163,21 @@
<div style="line-height: 15px"> <div style="line-height: 15px">
<div> <div>
<div> <div>
<span v-if="scope.row.dicomInfo.accNumber" <span v-if="scope.row.dicomInfo.accNumber"><span style="font-weight: 500">Acc:</span>
><span style="font-weight: 500">Acc:</span> {{ scope.row.dicomInfo.accNumber }}</span>
{{ scope.row.dicomInfo.accNumber }}</span
>
<span v-else style="color: #f44336">N/A</span> <span v-else style="color: #f44336">N/A</span>
</div> </div>
<div style="display: inline-block; margin-right: 2px"> <div style="display: inline-block; margin-right: 2px">
<span v-if="scope.row.dicomInfo.modality.length > 0"> <span v-if="scope.row.dicomInfo.modality.length > 0">
{{ scope.row.dicomInfo.modality.join('、') }},</span {{ scope.row.dicomInfo.modality.join('、') }},</span>
>
<span v-else style="color: #f44336">N/A,</span> <span v-else style="color: #f44336">N/A,</span>
</div> </div>
<div style="display: inline-block; margin-right: 2px"> <div style="display: inline-block; margin-right: 2px">
<span v-if="scope.row.seriesList.length" <span v-if="scope.row.seriesList.length">{{ scope.row.seriesList.length }} Series,</span>
>{{ scope.row.seriesList.length }} Series,</span
>
<span v-else style="color: #f44336">N/A,</span> <span v-else style="color: #f44336">N/A,</span>
</div> </div>
<div style="display: inline-block"> <div style="display: inline-block">
<span v-if="scope.row.fileList.length" <span v-if="scope.row.fileList.length">{{ scope.row.fileList.length }} Instances</span>
>{{ scope.row.fileList.length }} Instances</span
>
<span v-else style="color: #f44336">N/A</span> <span v-else style="color: #f44336">N/A</span>
</div> </div>
</div> </div>
@ -322,8 +191,7 @@
</div> </div>
<div style="display: inline-block"> <div style="display: inline-block">
<span v-if="scope.row.dicomInfo.description"> <span v-if="scope.row.dicomInfo.description">
{{ scope.row.dicomInfo.description }}</span {{ scope.row.dicomInfo.description }}</span>
>
<span v-else style="color: #f44336">N/A</span> <span v-else style="color: #f44336">N/A</span>
</div> </div>
</div> </div>
@ -349,18 +217,14 @@
<template slot-scope="scope"> <template slot-scope="scope">
<div style="line-height: 15px"> <div style="line-height: 15px">
<div> <div>
<span v-if="scope.row.dicomInfo.patientId" <span v-if="scope.row.dicomInfo.patientId"><span style="font-weight: 500">PID: </span>{{
><span style="font-weight: 500">PID: </span scope.row.dicomInfo.patientId }}</span>
>{{ scope.row.dicomInfo.patientId }}</span
>
<span v-else style="color: #f44336">N/A</span> <span v-else style="color: #f44336">N/A</span>
</div> </div>
<div> <div>
<span <span :class="[
:class="[
scope.row.dicomInfo.patientName ? '' : 'colorOfRed', scope.row.dicomInfo.patientName ? '' : 'colorOfRed',
]" ]">
>
{{ {{
scope.row.dicomInfo.patientName scope.row.dicomInfo.patientName
? scope.row.dicomInfo.patientName ? scope.row.dicomInfo.patientName
@ -369,11 +233,9 @@
</span> </span>
</div> </div>
<div> <div>
<span <span :class="[
:class="[
scope.row.dicomInfo.patientSex ? '' : 'colorOfRed', scope.row.dicomInfo.patientSex ? '' : 'colorOfRed',
]" ]">
>
{{ {{
scope.row.dicomInfo.patientSex scope.row.dicomInfo.patientSex
? scope.row.dicomInfo.patientSex ? scope.row.dicomInfo.patientSex
@ -381,11 +243,9 @@
}}, }},
</span> </span>
<span <span :class="[
:class="[
scope.row.dicomInfo.patientAge ? '' : 'colorOfRed', scope.row.dicomInfo.patientAge ? '' : 'colorOfRed',
]" ]">
>
{{ {{
scope.row.dicomInfo.patientAge scope.row.dicomInfo.patientAge
? scope.row.dicomInfo.patientAge ? scope.row.dicomInfo.patientAge
@ -393,11 +253,9 @@
}}, }},
</span> </span>
<span <span :class="[
:class="[
scope.row.dicomInfo.patientBirthDate ? '' : 'colorOfRed', scope.row.dicomInfo.patientBirthDate ? '' : 'colorOfRed',
]" ]">
>
{{ {{
scope.row.dicomInfo.patientBirthDate scope.row.dicomInfo.patientBirthDate
? scope.row.dicomInfo.patientBirthDate ? scope.row.dicomInfo.patientBirthDate
@ -408,26 +266,19 @@
</div> </div>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column <el-table-column :label="$t('trials:uploadDicomList:table:failedFileCount')" min-width="150"
:label="$t('trials:uploadDicomList:table:failedFileCount')" show-overflow-tooltip>
min-width="150"
show-overflow-tooltip
>
<!--:percentage=" <!--:percentage="
(scope.row.dicomInfo.failedFileCount * 100) / (scope.row.dicomInfo.failedFileCount * 100) /
scope.row.dicomInfo.fileCount scope.row.dicomInfo.fileCount
" "
:show-text="false"---> :show-text="false"--->
<template slot-scope="scope"> <template slot-scope="scope">
<el-progress <el-progress color="#409eff" :percentage="(
color="#409eff"
:percentage="
(
(scope.row.dicomInfo.uploadFileSize * 100) / (scope.row.dicomInfo.uploadFileSize * 100) /
scope.row.dicomInfo.fileSize scope.row.dicomInfo.fileSize
).toFixed(2) * 1 ).toFixed(2) * 1
" " />
/>
<span> <span>
{{ $t('trials:uploadDicomList:table:uploadNow') {{ $t('trials:uploadDicomList:table:uploadNow')
}}{{ scope.row.dicomInfo.failedFileCount }}/{{ }}{{ scope.row.dicomInfo.failedFileCount }}/{{
@ -442,86 +293,53 @@
</template> </template>
</el-table-column> </el-table-column>
<el-table-column <el-table-column :label="$t('trials:uploadDicomList:table:status')" min-width="140" show-overflow-tooltip>
:label="$t('trials:uploadDicomList:table:status')"
min-width="140"
show-overflow-tooltip
>
<template slot-scope="scope"> <template slot-scope="scope">
<span <span v-if="
v-if="
!scope.row.dicomInfo.failedFileCount && !scope.row.dicomInfo.failedFileCount &&
!scope.row.dicomInfo.isInit !scope.row.dicomInfo.isInit
" ">
> {{ $t('trials:uploadDicomList:table:status1') }}</span>
{{ $t('trials:uploadDicomList:table:status1') }}</span <span style="color: #409eff" v-else-if="
>
<span
style="color: #409eff"
v-else-if="
!scope.row.dicomInfo.failedFileCount && !scope.row.dicomInfo.failedFileCount &&
scope.row.dicomInfo.isInit && scope.row.dicomInfo.isInit &&
btnLoading btnLoading
" ">{{ $t('trials:uploadDicomList:table:status2') }}</span>
>{{ $t('trials:uploadDicomList:table:status2') }}</span <span style="color: #409eff" v-else-if="
>
<span
style="color: #409eff"
v-else-if="
scope.row.dicomInfo.failedFileCount < scope.row.dicomInfo.failedFileCount <
scope.row.dicomInfo.fileCount && scope.row.dicomInfo.fileCount &&
!scope.row.uploadState.record !scope.row.uploadState.record
" ">{{ $t('trials:uploadDicomList:table:status2') }}</span>
>{{ $t('trials:uploadDicomList:table:status2') }}</span <span style="color: #2cc368" v-else-if="
>
<span
style="color: #2cc368"
v-else-if="
scope.row.dicomInfo.failedFileCount === scope.row.dicomInfo.failedFileCount ===
scope.row.dicomInfo.fileCount scope.row.dicomInfo.fileCount
" ">{{ $t('trials:uploadDicomList:table:status3') }}</span>
>{{ $t('trials:uploadDicomList:table:status3') }}</span <span style="color: #f66" v-else-if="
>
<span
style="color: #f66"
v-else-if="
scope.row.uploadState.record && scope.row.uploadState.record &&
scope.row.uploadState.record.fileCount === 0 scope.row.uploadState.record.fileCount === 0
" ">{{ $t('trials:uploadDicomList:table:status5') }}</span>
>{{ $t('trials:uploadDicomList:table:status5') }}</span
>
<span style="color: #f66" v-else>{{ <span style="color: #f66" v-else>{{
$t('trials:uploadDicomList:table:Failed') $t('trials:uploadDicomList:table:Failed')
}}</span> }}</span>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column <el-table-column :label="$t('trials:uploadDicomList:table:record')" min-width="140" show-overflow-tooltip>
:label="$t('trials:uploadDicomList:table:record')"
min-width="140"
show-overflow-tooltip
>
<template slot-scope="scope"> <template slot-scope="scope">
<el-tooltip placement="top" v-if="scope.row.uploadState.record"> <el-tooltip placement="top" v-if="scope.row.uploadState.record">
<div slot="content"> <div slot="content">
<div style="max-height: 500px; overflow-y: auto"> <div style="max-height: 500px; overflow-y: auto">
{{ $t('trials:uploadDicomList:table:Existed') }}: {{ $t('trials:uploadDicomList:table:Existed') }}:
<div v-if="scope.row.uploadState.record.Existed.length"> <div v-if="scope.row.uploadState.record.Existed.length">
<div <div v-for="item of scope.row.uploadState.record.Existed" :key="item"
v-for="item of scope.row.uploadState.record.Existed" style="font-size: 12px; color: #baa72a">
:key="item"
style="font-size: 12px; color: #baa72a"
>
{{ item }} {{ item }}
</div> </div>
</div> </div>
<div v-else>&nbsp;</div> <div v-else>&nbsp;</div>
{{ $t('trials:uploadDicomList:table:Uploaded') }}: {{ $t('trials:uploadDicomList:table:Uploaded') }}:
<div v-if="scope.row.uploadState.record.Uploaded.length"> <div v-if="scope.row.uploadState.record.Uploaded.length">
<div <div v-for="item of scope.row.uploadState.record.Uploaded" :key="item"
v-for="item of scope.row.uploadState.record.Uploaded" style="font-size: 12px; color: #24b837">
:key="item"
style="font-size: 12px; color: #24b837"
>
{{ item }} {{ item }}
</div> </div>
</div> </div>
@ -529,11 +347,8 @@
<br /> <br />
{{ $t('trials:uploadDicomList:table:Failed') }}: {{ $t('trials:uploadDicomList:table:Failed') }}:
<div v-if="scope.row.uploadState.record.Failed.length"> <div v-if="scope.row.uploadState.record.Failed.length">
<div <div v-for="item of scope.row.uploadState.record.Failed" :key="item"
v-for="item of scope.row.uploadState.record.Failed" style="font-size: 12px; color: #f66">
:key="item"
style="font-size: 12px; color: #f66"
>
{{ item }} {{ item }}
</div> </div>
</div> </div>
@ -556,43 +371,25 @@
</el-tooltip> </el-tooltip>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column <el-table-column v-show="isScan" :label="$t('common:action:action')" width="200">
v-show="isScan"
:label="$t('common:action:action')"
width="200"
>
<template slot-scope="scope"> <template slot-scope="scope">
<!-- 预览 --> <!-- 预览 -->
<!-- :disabled="scope.row.dicomInfo.failedFileCount < scope.row.dicomInfo.fileCount && scope.row.dicomInfo.failedFileCount !== 0"--> <!-- :disabled="scope.row.dicomInfo.failedFileCount < scope.row.dicomInfo.fileCount && scope.row.dicomInfo.failedFileCount !== 0"-->
<el-button <el-button icon="el-icon-view" circle :disabled="(scope.row.uploadState.stateCode !== '' &&
icon="el-icon-view"
circle
:disabled="
(scope.row.uploadState.stateCode !== '' &&
scope.row.dicomInfo.failedFileCount < scope.row.dicomInfo.failedFileCount <
scope.row.dicomInfo.fileCount && scope.row.dicomInfo.fileCount &&
!scope.row.uploadState.record) || !scope.row.uploadState.record) ||
btnLoading btnLoading
" " :title="$t('trials:uploadedDicoms:action:preview')" size="small"
:title="$t('trials:uploadedDicoms:action:preview')" @click="handlePreview(scope.row.dicomInfo.studyUid)" />
size="small"
@click="handlePreview(scope.row.dicomInfo.studyUid)"
/>
<!-- 移除 --> <!-- 移除 -->
<el-button <el-button icon="el-icon-delete" circle :title="$t('trials:uploadedDicoms:action:delete')" size="small"
icon="el-icon-delete" :disabled="(scope.row.uploadState.stateCode !== '' &&
circle
:title="$t('trials:uploadedDicoms:action:delete')"
size="small"
:disabled="
(scope.row.uploadState.stateCode !== '' &&
scope.row.dicomInfo.failedFileCount < scope.row.dicomInfo.failedFileCount <
scope.row.dicomInfo.fileCount && scope.row.dicomInfo.fileCount &&
!scope.row.uploadState.record) || !scope.row.uploadState.record) ||
btnLoading btnLoading
" " @click="handleDelete(scope.$index, scope.row)" />
@click="handleDelete(scope.$index, scope.row)"
/>
</template> </template>
</el-table-column> </el-table-column>
</el-table> </el-table>
@ -605,70 +402,32 @@
$store.state.trials.uploadTip $store.state.trials.uploadTip
}}</span> }}</span>
<!-- 上传 --> <!-- 上传 -->
<el-button <el-button size="small" type="primary" :disabled="selectArr.length == 0 || !isScan" :loading="btnLoading"
size="small" @click="beginUploadQueues">
type="primary"
:disabled="selectArr.length == 0 || !isScan"
:loading="btnLoading"
@click="beginUploadQueues"
>
{{ $t('trials:uploadDicomList:button:upload') }} {{ $t('trials:uploadDicomList:button:upload') }}
</el-button> </el-button>
</div> </div>
</el-tab-pane> </el-tab-pane>
<!-- pacs上传 --> <!-- pacs上传 -->
<el-tab-pane <el-tab-pane :label="$t('trials:uploadNonDicoms:tab:uploadPacs')" name="pacs" :disabled="btnLoading"
:label="$t('trials:uploadNonDicoms:tab:uploadPacs')" v-if="relationInfo.IsPacsConnectConfiged">
name="pacs" <uploadDicomPacs v-if="uploadActiveName === 'pacs'" ref="dicomPacs" :subjectVisitId="subjectVisitId"
:disabled="btnLoading" :relationInfo="relationInfo" :subjectId="subjectId" @getList="getParentList" @petDataTip="petDataTip" />
v-if="relationInfo.IsPacsConnectConfiged"
>
<uploadDicomPacs
v-if="uploadActiveName === 'pacs'"
ref="dicomPacs"
:subjectVisitId="subjectVisitId"
:relationInfo="relationInfo"
:subjectId="subjectId"
@getList="getParentList"
@petDataTip="petDataTip"
/>
</el-tab-pane> </el-tab-pane>
</el-tabs> </el-tabs>
<!-- 预览影像模态框 --> <!-- 预览影像模态框 -->
<el-dialog <el-dialog v-if="previewVisible" :fullscreen="true" :show-close="true" :visible.sync="previewVisible"
v-if="previewVisible" append-to-body>
:fullscreen="true"
:show-close="true"
:visible.sync="previewVisible"
append-to-body
>
<DicomPreview :uid="uid" :studyList="uploadQueues" /> <DicomPreview :uid="uid" :studyList="uploadQueues" />
</el-dialog> </el-dialog>
<!--pet-ct临床数据上传--> <!--pet-ct临床数据上传-->
<el-dialog <el-dialog v-if="petVisible" :show-close="true" :visible.sync="petVisible" append-to-body>
v-if="petVisible" <uploadPetClinicalData :subject-visit-id="data.Id" :data="data" :studyData="studyData" :allow-add-or-edit="true"
:show-close="true" @getStudyInfo="getStudyInfo" />
:visible.sync="petVisible"
append-to-body
>
<uploadPetClinicalData
:subject-visit-id="data.Id"
:data="data"
:studyData="studyData"
:allow-add-or-edit="true"
@getStudyInfo="getStudyInfo"
/>
</el-dialog> </el-dialog>
<!-- 校验警告信息模态框 --> <!-- 校验警告信息模态框 -->
<el-dialog <el-dialog v-if="warning_cfg.visible" :visible.sync="warning_cfg.visible" width="500px"
v-if="warning_cfg.visible" :close-on-click-modal="false" append-to-body title="Warning" custom-class="warning-dialog">
:visible.sync="warning_cfg.visible"
width="500px"
:close-on-click-modal="false"
append-to-body
title="Warning"
custom-class="warning-dialog"
>
<div style="border: 1px solid #e0e0e0; padding: 10px"> <div style="border: 1px solid #e0e0e0; padding: 10px">
<!-- Information from DICOM headers not consistent with that of this subject --> <!-- Information from DICOM headers not consistent with that of this subject -->
<div style="color: red; font-size: 14px; margin-bottom: 10px"> <div style="color: red; font-size: 14px; margin-bottom: 10px">
@ -676,11 +435,7 @@
</div> </div>
<div v-for="(item, i) in warningArr" :key="item.index"> <div v-for="(item, i) in warningArr" :key="item.index">
<div>{{ `(${i + 1}). ACC: ${item.accNumber}` }}</div> <div>{{ `(${i + 1}). ACC: ${item.accNumber}` }}</div>
<div <div v-for="(warning, index) in item.warnings" :key="index" style="margin: 10px 0px; font-size: 13px">
v-for="(warning, index) in item.warnings"
:key="index"
style="margin: 10px 0px; font-size: 13px"
>
<ul> <ul>
<li>{{ warning }}</li> <li>{{ warning }}</li>
</ul> </ul>
@ -696,103 +451,63 @@
</el-button> </el-button>
</div> </div>
</el-dialog> </el-dialog>
<el-dialog <el-dialog v-if="editStudyInfoVisible" :title="$t('trials:audit:action:edit')" :visible.sync="editStudyInfoVisible"
v-if="editStudyInfoVisible" :close-on-click-modal="false" append-to-body custom-class="base-dialog-wrapper" width="600px">
:title="$t('trials:audit:action:edit')" <div style="
:visible.sync="editStudyInfoVisible"
:close-on-click-modal="false"
append-to-body
custom-class="base-dialog-wrapper"
width="600px"
>
<div
style="
padding: 10px; padding: 10px;
border: 1px solid #e0e0e0; border: 1px solid #e0e0e0;
max-height: 650px; max-height: 650px;
overflow-y: auto; overflow-y: auto;
" ">
>
<el-form ref="studyForm" :model="studyForm" label-width="100px"> <el-form ref="studyForm" :model="studyForm" label-width="100px">
<!-- 检查编号 --> <!-- 检查编号 -->
<el-form-item :label="$t('trials:audit:table:studyId')"> <el-form-item :label="$t('trials:audit:table:studyId')">
<el-input v-model="studyForm.StudyCode" disabled /> <el-input v-model="studyForm.StudyCode" disabled />
</el-form-item> </el-form-item>
<!-- 检查名称 --> <!-- 检查名称 -->
<el-form-item <el-form-item v-if="relationInfo.IsShowStudyName" :label="$t('trials:audit:table:StudyName')" prop="StudyName"
v-if="relationInfo.IsShowStudyName"
:label="$t('trials:audit:table:StudyName')"
prop="StudyName"
:rules="[ :rules="[
{ {
required: true, required: true,
message: $t('common:ruleMessage:specify'), message: $t('common:ruleMessage:specify'),
trigger: 'blur', trigger: 'blur',
}, },
]" ]">
>
<el-radio-group v-model="studyForm.StudyName"> <el-radio-group v-model="studyForm.StudyName">
<template v-for="m in relationInfo.StudyNameList"> <template v-for="m in relationInfo.StudyNameList">
<el-radio <el-radio v-if="m.IsChoose" :key="m.Name" :label="isEN ? m.EnName : m.Name"
v-if="m.IsChoose" style="margin-bottom: 15px" />
:key="m.Name"
:label="isEN ? m.EnName : m.Name"
style="margin-bottom: 15px"
/>
</template> </template>
</el-radio-group> </el-radio-group>
</el-form-item> </el-form-item>
<!-- 检查类型 --> <!-- 检查类型 -->
<el-form-item <el-form-item v-if="studyForm.IsDicomData" :label="$t('trials:audit:table:modality')">
v-if="studyForm.IsDicomData"
:label="$t('trials:audit:table:modality')"
>
<el-input v-model="studyForm.Modalities" disabled /> <el-input v-model="studyForm.Modalities" disabled />
</el-form-item> </el-form-item>
<!-- 检查类型 --> <!-- 检查类型 -->
<el-form-item <el-form-item v-else :label="$t('trials:audit:table:modality')" prop="Modalities" :rules="[
v-else
:label="$t('trials:audit:table:modality')"
prop="Modalities"
:rules="[
{ {
required: true, required: true,
message: $t('common:ruleMessage:specify'), message: $t('common:ruleMessage:specify'),
trigger: 'blur', trigger: 'blur',
}, },
]" ]">
>
<el-radio-group v-model="studyForm.Modality"> <el-radio-group v-model="studyForm.Modality">
<el-radio <el-radio v-for="m in trialModalitys" v-show="m !== ''" :key="m" :label="m" style="margin-bottom: 15px" />
v-for="m in trialModalitys"
v-show="m !== ''"
:key="m"
:label="m"
style="margin-bottom: 15px"
/>
</el-radio-group> </el-radio-group>
</el-form-item> </el-form-item>
<!-- 检查部位 --> <!-- 检查部位 -->
<el-form-item <el-form-item :label="$t('trials:audit:table:bodyPart')" prop="BodyPartForEdit" :rules="[
:label="$t('trials:audit:table:bodyPart')"
prop="BodyPartForEdit"
:rules="[
{ {
required: true, required: true,
message: $t('common:ruleMessage:specify'), message: $t('common:ruleMessage:specify'),
trigger: 'blur', trigger: 'blur',
}, },
]" ]">
>
<el-checkbox-group v-model="studyForm.BodyPartForEdit"> <el-checkbox-group v-model="studyForm.BodyPartForEdit">
<el-checkbox <el-checkbox v-for="bodyPart in trialBodyPartTypes" :key="bodyPart" :label="bodyPart">{{
v-for="bodyPart in trialBodyPartTypes"
:key="bodyPart"
:label="bodyPart"
>{{
$fd('Bodypart', bodyPart, 'Code', BodyPart, 'Name') $fd('Bodypart', bodyPart, 'Code', BodyPart, 'Name')
}}</el-checkbox }}</el-checkbox>
>
</el-checkbox-group> </el-checkbox-group>
</el-form-item> </el-form-item>
<!-- 序列数量 --> <!-- 序列数量 -->
@ -800,40 +515,21 @@
<el-input v-model="studyForm.SeriesCount" disabled /> <el-input v-model="studyForm.SeriesCount" disabled />
</el-form-item> </el-form-item>
<!-- 图像数量 --> <!-- 图像数量 -->
<el-form-item <el-form-item v-if="studyForm.InstanceCount" :label="$t('trials:audit:table:instanceCount')">
v-if="studyForm.InstanceCount"
:label="$t('trials:audit:table:instanceCount')"
>
<el-input v-model="studyForm.InstanceCount" disabled /> <el-input v-model="studyForm.InstanceCount" disabled />
</el-form-item> </el-form-item>
<!-- 检查日期 --> <!-- 检查日期 -->
<el-form-item :label="$t('trials:audit:table:studyDate')"> <el-form-item :label="$t('trials:audit:table:studyDate')">
<el-date-picker <el-date-picker v-model="studyForm.StudyTime" disabled type="date" value-format="yyyy-MM-dd"
v-model="studyForm.StudyTime" format="yyyy-MM-dd" style="width: 100%" />
disabled
type="date"
value-format="yyyy-MM-dd"
format="yyyy-MM-dd"
style="width: 100%"
/>
</el-form-item> </el-form-item>
</el-form> </el-form>
</div> </div>
<div slot="footer" class="dialog-footer"> <div slot="footer" class="dialog-footer">
<el-button <el-button :disabled="btnLoading" size="small" type="primary" @click="editStudyInfoVisible = false">
:disabled="btnLoading"
size="small"
type="primary"
@click="editStudyInfoVisible = false"
>
{{ $t('common:button:cancel') }} {{ $t('common:button:cancel') }}
</el-button> </el-button>
<el-button <el-button :loading="btnLoading" size="small" type="primary" @click="handleUpdateStudyInfo">
:loading="btnLoading"
size="small"
type="primary"
@click="handleUpdateStudyInfo"
>
{{ $t('common:button:save') }} {{ $t('common:button:save') }}
</el-button> </el-button>
</div> </div>
@ -1739,10 +1435,8 @@ export default {
dicomInfo.failedFileCount++ dicomInfo.failedFileCount++
Record.FileCount++ Record.FileCount++
} else { } else {
let path = `/${params.trialId}/Image/${ let path = `/${params.trialId}/Image/${params.subjectId
params.subjectId }/${params.subjectVisitId}/${dicomInfo.studyUid
}/${params.subjectVisitId}/${
dicomInfo.studyUid
}/${scope.getGuid( }/${scope.getGuid(
dicomInfo.studyUid + dicomInfo.studyUid +
v.seriesUid + v.seriesUid +
@ -2161,22 +1855,27 @@ export default {
overflow-y: auto; overflow-y: auto;
} }
} }
.delete-row { .delete-row {
text-decoration-line: line-through; text-decoration-line: line-through;
color: #c0c4cc; color: #c0c4cc;
} }
.previewActive:hover { .previewActive:hover {
cursor: pointer; cursor: pointer;
color: #428bca; color: #428bca;
} }
#inputForm label { #inputForm label {
font-weight: normal; font-weight: normal;
} }
#inputForm .file-input { #inputForm .file-input {
position: relative; position: relative;
overflow: hidden; overflow: hidden;
display: inline-block; display: inline-block;
} }
#inputForm .file-input input[type='file'] { #inputForm .file-input input[type='file'] {
position: absolute; position: absolute;
top: 0; top: 0;
@ -2195,9 +1894,11 @@ export default {
#inputForm #listWrapper a { #inputForm #listWrapper a {
text-decoration: none; text-decoration: none;
} }
#inputForm .text-left { #inputForm .text-left {
text-align: left; text-align: left;
} }
.colorOfRed { .colorOfRed {
color: #f44336; color: #f44336;
} }

View File

@ -102,8 +102,8 @@
<!-- 预览 --> <!-- 预览 -->
<el-button icon="el-icon-view" circle :title="$t('trials:uploadNonDicoms:action:preview')" <el-button icon="el-icon-view" circle :title="$t('trials:uploadNonDicoms:action:preview')"
:disabled="scope.row.FileCount === 0" @click.native.prevent="handlePreviewAllFiles(scope.row)" /> :disabled="scope.row.FileCount === 0" @click.native.prevent="handlePreviewAllFiles(scope.row)" />
<!-- 上传 --> <!-- 上传 :disabled="scope.row.IsDeleted" -->
<el-button v-if="allowAddOrEdit" icon="el-icon-upload2" circle :disabled="scope.row.IsDeleted" <el-button v-if="allowAddOrEdit" icon="el-icon-upload2" circle
:title="$t('trials:uploadNonDicoms:action:upload')" @click.native.prevent="handleUpload(scope.row)" /> :title="$t('trials:uploadNonDicoms:action:upload')" @click.native.prevent="handleUpload(scope.row)" />
<!-- 上传视频 --> <!-- 上传视频 -->
<!-- <el-button <!-- <el-button

View File

@ -13,91 +13,53 @@
</el-col> </el-col>
<el-col :span="12" style="text-align: right"> <el-col :span="12" style="text-align: right">
<h3> <h3>
<Pagination <Pagination class="page" :total="total" :page.sync="listQuery.pageIndex" :limit.sync="listQuery.pageSize"
class="page" layout="total, sizes, prev, pager, next" :background="false" style="display: inline-block"
:total="total" @pagination="getList" />
:page.sync="listQuery.pageIndex" <el-button icon="el-icon-refresh-left" size="small" circle :title="$t('common:button:reset')"
:limit.sync="listQuery.pageSize" @click="handleReset" />
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> </h3>
</el-col> </el-col>
</el-row> </el-row>
<!-- --> <!-- -->
<el-table <el-table ref="needSignSysList" v-loading="listLoading" :data="list" :show-header="true"
ref="needSignSysList" v-adaptive="{ bottomOffset: 45 }" height="100" @sort-change="handleSortByColumn"
v-loading="listLoading" :default-sort="{ prop: 'UpdateTime', order: 'descending' }">
:data="list"
:show-header="true"
v-adaptive="{ bottomOffset: 45 }"
height="100"
@sort-change="handleSortByColumn"
:default-sort="{ prop: 'UpdateTime', order: 'descending' }"
>
<el-table-column type="index" width="40" /> <el-table-column type="index" width="40" />
<el-table-column <el-table-column :label="$t('trials:sysDocBeSigned:table:fileType')" prop="FileType" show-overflow-tooltip
:label="$t('trials:sysDocBeSigned:table:fileType')" sortable="custom" />
prop="FileType" <el-table-column :label="$t('trials:sysDocBeSigned:table:fileName')" prop="Name" show-overflow-tooltip
show-overflow-tooltip sortable="custom" />
sortable="custom" <el-table-column :label="$t('trials:sysDocBeSigned:table:AttachmentCount')" prop="AttachmentCount"
/> show-overflow-tooltip sortable="custom">
<el-table-column <template slot-scope="scope">
:label="$t('trials:sysDocBeSigned:table:fileName')" <el-button type="text" @click.stop="openAttachment(scope.row)">{{ scope.row.AttachmentCount }}</el-button>
prop="Name" </template>
show-overflow-tooltip </el-table-column>
sortable="custom" <el-table-column :label="$t('trials:sysDocBeSigned:table:uploadTime')" prop="CreateTime" show-overflow-tooltip
/> sortable="custom" />
<el-table-column <el-table-column :label="$t('trials:sysDocBeSigned:table:SuggestFinishTime')" prop="SuggestFinishTime"
:label="$t('trials:sysDocBeSigned:table:uploadTime')" show-overflow-tooltip sortable="custom" />
prop="CreateTime"
show-overflow-tooltip
sortable="custom"
/>
<el-table-column :label="$t('common:action:action')" width="140"> <el-table-column :label="$t('common:action:action')" width="140">
<template slot-scope="scope"> <template slot-scope="scope">
<!-- 预览 --> <!-- 预览 -->
<el-button <el-button icon="el-icon-view" circle v-if="isSigned" :title="$t('trials:self-attachment:action:preview')"
icon="el-icon-view" @click="handlePreview(scope.row)" />
circle <el-button icon="el-icon-edit-outline" circle v-if="!isSigned"
v-if="isSigned"
:title="$t('trials:self-attachment:action:preview')"
@click="handlePreview(scope.row)"
/>
<el-button
icon="el-icon-edit-outline"
circle
v-if="!isSigned"
:disabled="IsFirstSysDocNeedSign && !!~scope.row.DocTypeCode" :disabled="IsFirstSysDocNeedSign && !!~scope.row.DocTypeCode"
:title="$t('trials:needSignSysDoc:action:sign')" :title="$t('trials:needSignSysDoc:action:sign')" @click="handleSign(scope.row)" />
@click="handleSign(scope.row)"
/>
</template> </template>
</el-table-column> </el-table-column>
</el-table> </el-table>
<!-- 预览/签署文件 --> <!-- 预览/签署文件 -->
<el-dialog <el-dialog v-if="previewVisible" :visible.sync="previewVisible" :title="title" :fullscreen="true" append-to-body
v-if="previewVisible" custom-class="base-dialog-wrapper">
:visible.sync="previewVisible" <span style="position: fixed; left: 16px; top: 45px;cursor: pointer;" @click.stop="openAttachment(currentRow)"
:title="title" v-if="currentRow.AttachmentCount">{{
:fullscreen="true" $t('trials:sysDocBeSigned:table:AttachmentCount') }} ({{
append-to-body currentRow.AttachmentCount }})</span>
custom-class="base-dialog-wrapper" <span v-if="!currentIsConfirm" style="position: fixed; right: 75px; top: 14px">
>
<span
v-if="!currentIsConfirm"
style="position: fixed; right: 75px; top: 14px"
>
<span style="color: red; margin-right: 10px"> <span style="color: red; margin-right: 10px">
<!-- 请仔细阅读文件并签名确认 --> <!-- 请仔细阅读文件并签名确认 -->
{{ $t('common:message:signTip') }} {{ $t('common:message:signTip') }}
@ -106,51 +68,30 @@
}}</span> }}</span>
</span> </span>
<el-button <el-button size="small" type="primary" :disabled="timer !== null || duration === 0" :loading="btnLoading"
size="small" @click="handleConfirm">
type="primary"
:disabled="timer !== null || duration === 0"
:loading="btnLoading"
@click="handleConfirm"
>
{{ $t('common:button:sign') }} {{ $t('common:button:sign') }}
</el-button> </el-button>
</span> </span>
<div <div class="base-modal-body" style="border: 2px solid #ccc; padding: 10px">
class="base-modal-body" <PreviewFile v-if="previewVisible" :file-path="currentPath" :file-type="currentType" @getList="getList" />
style="border: 2px solid #ccc; padding: 10px"
>
<PreviewFile
v-if="previewVisible"
:file-path="currentPath"
:file-type="currentType"
@getList="getList"
/>
</div> </div>
</el-dialog> </el-dialog>
<!-- 签名弹框 --> <!-- 签名弹框 -->
<el-dialog <el-dialog v-if="signVisible" :visible.sync="signVisible" :close-on-click-modal="false" width="600px"
v-if="signVisible" append-to-body>
:visible.sync="signVisible"
:close-on-click-modal="false"
width="600px"
append-to-body
>
<div slot="title"> <div slot="title">
<span style="font-size: 18px">{{ $t('common:dialogTitle:sign') }}</span> <span style="font-size: 18px">{{ $t('common:dialogTitle:sign') }}</span>
<span style="font-size: 12px; margin-left: 5px">{{ <span style="font-size: 12px; margin-left: 5px">{{
`(${$t('common:label:sign')}${currentUser})` `(${$t('common:label:sign')}${currentUser})`
}}</span> }}</span>
</div> </div>
<SignForm <SignForm :is-system-doc="currentRow.IsSystemDoc" :document-id="currentRow.Id" :file-name="fileName"
:is-system-doc="currentRow.IsSystemDoc" @closeDialog="closeSignDialog" />
:document-id="currentRow.Id"
:file-name="fileName"
@closeDialog="closeSignDialog"
/>
</el-dialog> </el-dialog>
<attachmentPreview :SystemDocumentId="SystemDocumentId" :visible.sync="perview_visible" v-if="perview_visible" />
</div> </div>
</template> </template>
<script> <script>
@ -162,6 +103,7 @@ import {
import Pagination from '@/components/Pagination' import Pagination from '@/components/Pagination'
import PreviewFile from '@/components/PreviewFile/index' import PreviewFile from '@/components/PreviewFile/index'
import SignForm from '@/views/trials/trials-panel/attachments/self-attachment/components/SignForm' import SignForm from '@/views/trials/trials-panel/attachments/self-attachment/components/SignForm'
import attachmentPreview from '@/views/dictionary/attachment/components/SignatureTemplate/attachmentPreview'
import { mapGetters } from 'vuex' import { mapGetters } from 'vuex'
const searchDataDefault = () => { const searchDataDefault = () => {
return { return {
@ -173,7 +115,7 @@ const searchDataDefault = () => {
} }
export default { export default {
name: 'NeedSignSysDoc', name: 'NeedSignSysDoc',
components: { Pagination, PreviewFile, SignForm }, components: { Pagination, PreviewFile, SignForm, attachmentPreview },
props: { props: {
isSigned: { isSigned: {
type: Boolean, type: Boolean,
@ -200,6 +142,8 @@ export default {
currentIsConfirm: false, currentIsConfirm: false,
currentUser: zzSessionStorage.getItem('userName'), currentUser: zzSessionStorage.getItem('userName'),
currentRow: {}, currentRow: {},
SystemDocumentId: null,
perview_visible: false
} }
}, },
mounted() { mounted() {
@ -214,6 +158,11 @@ export default {
...mapGetters(['IsFirstSysDocNeedSign']), ...mapGetters(['IsFirstSysDocNeedSign']),
}, },
methods: { methods: {
openAttachment(row) {
if (!row.AttachmentCount) return false
this.SystemDocumentId = row.Id
this.perview_visible = true
},
// //
handlePreview(row) { handlePreview(row) {
this.currentRow = { ...row } this.currentRow = { ...row }

View File

@ -3,84 +3,56 @@
<el-row> <el-row>
<el-col :span="12"> <el-col :span="12">
<!-- 待签署的系统文件 --> <!-- 待签署的系统文件 -->
<h3>{{ !isSigned ? $t('trials:workbench:title:sysDocBeSigned') : $t('trials:workbench:title:sysDocSigned') }}</h3> <h3>{{ !isSigned ? $t('trials:workbench:title:sysDocBeSigned') : $t('trials:workbench:title:sysDocSigned') }}
</h3>
</el-col> </el-col>
<el-col :span="12" style="text-align:right;"> <el-col :span="12" style="text-align:right;">
<h3> <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" /> <Pagination class="page" :total="total" :page.sync="listQuery.pageIndex" :limit.sync="listQuery.pageSize"
<el-button icon="el-icon-refresh-left" size="small" circle :title="$t('common:button:reset')" @click="handleReset" /> 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> </h3>
</el-col> </el-col>
</el-row> </el-row>
<!-- --> <!-- -->
<el-table <el-table ref="needSignSysList" v-loading="listLoading" :data="list" :show-header="true"
ref="needSignSysList" v-adaptive="{ bottomOffset: 45 }" height="100" @sort-change="handleSortByColumn"
v-loading="listLoading" :default-sort="{ prop: 'UpdateTime', order: 'descending' }">
:data="list"
:show-header="true"
v-adaptive="{bottomOffset:45}"
height="100"
@sort-change="handleSortByColumn"
:default-sort ="{prop: 'UpdateTime', order: 'descending'}"
>
<el-table-column type="index" width="40" /> <el-table-column type="index" width="40" />
<el-table-column <el-table-column :label="$t('trials:sysDocBeSigned:table:fileType')" prop="FileType" show-overflow-tooltip
:label="$t('trials:sysDocBeSigned:table:fileType')" sortable="custom" />
prop="FileType" <el-table-column :label="$t('trials:sysDocBeSigned:table:fileName')" prop="Name" show-overflow-tooltip
show-overflow-tooltip sortable="custom" />
sortable="custom" <el-table-column :label="$t('trials:sysDocBeSigned:table:AttachmentCount')" prop="AttachmentCount"
/> show-overflow-tooltip sortable="custom">
<el-table-column <template slot-scope="scope">
:label="$t('trials:sysDocBeSigned:table:fileName')" <el-button type="text" @click.stop="openAttachment(scope.row)">{{ scope.row.AttachmentCount }}</el-button>
prop="Name" </template>
show-overflow-tooltip </el-table-column>
sortable="custom" <el-table-column :label="$t('trials:sysDocBeSigned:table:uploadTime')" prop="CreateTime" show-overflow-tooltip
/> sortable="custom" />
<el-table-column <el-table-column :label="$t('trials:sysDocBeSigned:table:ConfirmTime')" prop="ConfirmTime" show-overflow-tooltip
:label="$t('trials:sysDocBeSigned:table:uploadTime')" sortable="custom" />
prop="CreateTime" <el-table-column :label="$t('common:action:action')" width="140">
show-overflow-tooltip
sortable="custom"
/>
<el-table-column
:label="$t('trials:sysDocBeSigned:table:ConfirmTime')"
prop="ConfirmTime"
show-overflow-tooltip
sortable="custom"
/>
<el-table-column
:label="$t('common:action:action')"
width="140"
>
<template slot-scope="scope"> <template slot-scope="scope">
<!-- 预览 --> <!-- 预览 -->
<el-button <el-button icon="el-icon-view" circle v-if="isSigned" :title="$t('trials:self-attachment:action:preview')"
icon="el-icon-view" @click="handlePreview(scope.row)" />
circle <el-button icon="el-icon-edit-outline" circle v-if="!isSigned"
v-if="isSigned" :title="$t('trials:needSignedSysDoc:action:sign')" @click="handleSign(scope.row)" />
:title="$t('trials:self-attachment:action:preview')"
@click="handlePreview(scope.row)"
/>
<el-button
icon="el-icon-edit-outline"
circle
v-if="!isSigned"
:title="$t('trials:needSignedSysDoc:action:sign')"
@click="handleSign(scope.row)"
/>
</template> </template>
</el-table-column> </el-table-column>
</el-table> </el-table>
<!-- 预览/签署文件 --> <!-- 预览/签署文件 -->
<el-dialog <el-dialog v-if="previewVisible" :visible.sync="previewVisible" :title="title" :fullscreen="true" append-to-body
v-if="previewVisible" custom-class="base-dialog-wrapper">
:visible.sync="previewVisible" <span style="position: fixed; left: 16px; top: 45px;cursor: pointer;" @click.stop="openAttachment(currentRow)"
:title="title" v-if="currentRow.AttachmentCount">{{
:fullscreen="true" $t('trials:sysDocBeSigned:table:AttachmentCount') }} ({{
append-to-body currentRow.AttachmentCount }})</span>
custom-class="base-dialog-wrapper"
>
<span v-if="!currentIsConfirm" style="position: fixed;right: 75px;top: 14px;"> <span v-if="!currentIsConfirm" style="position: fixed;right: 75px;top: 14px;">
<span style="color:red;margin-right:10px;"> <span style="color:red;margin-right:10px;">
<!-- 请仔细阅读文件并签名确认 --> <!-- 请仔细阅读文件并签名确认 -->
@ -88,13 +60,8 @@
<span v-show="duration < currentMinMinutes * 60">{{ `(${currentMinMinutes * 60 - duration}s)` }}</span> <span v-show="duration < currentMinMinutes * 60">{{ `(${currentMinMinutes * 60 - duration}s)` }}</span>
</span> </span>
<el-button <el-button size="small" type="primary" :disabled="timer !== null || duration === 0" :loading="btnLoading"
size="small" @click="handleConfirm">
type="primary"
:disabled="timer !== null || duration === 0"
:loading="btnLoading"
@click="handleConfirm"
>
{{ $t('common:button:sign') }} {{ $t('common:button:sign') }}
</el-button> </el-button>
</span> </span>
@ -105,19 +72,16 @@
</el-dialog> </el-dialog>
<!-- 签名弹框 --> <!-- 签名弹框 -->
<el-dialog <el-dialog v-if="signVisible" :visible.sync="signVisible" :close-on-click-modal="false" width="600px"
v-if="signVisible" append-to-body>
:visible.sync="signVisible"
:close-on-click-modal="false"
width="600px"
append-to-body
>
<div slot="title"> <div slot="title">
<span style="font-size:18px;">{{ $t('common:dialogTitle:sign') }}</span> <span style="font-size:18px;">{{ $t('common:dialogTitle:sign') }}</span>
<span style="font-size:12px;margin-left:5px">{{ `(${$t('common:label:sign')}${currentUser})` }}</span> <span style="font-size:12px;margin-left:5px">{{ `(${$t('common:label:sign')}${currentUser})` }}</span>
</div> </div>
<SignForm :is-system-doc="currentRow.IsSystemDoc" :document-id="currentRow.Id" :file-name="fileName" @closeDialog="closeSignDialog" /> <SignForm :is-system-doc="currentRow.IsSystemDoc" :document-id="currentRow.Id" :file-name="fileName"
@closeDialog="closeSignDialog" />
</el-dialog> </el-dialog>
<attachmentPreview :SystemDocumentId="SystemDocumentId" :visible.sync="perview_visible" v-if="perview_visible" />
</div> </div>
</template> </template>
<script> <script>
@ -125,6 +89,7 @@ import { getWaitSignSysDocList, setSystemDocFirstViewTime } from '@/api/trials'
import Pagination from '@/components/Pagination' import Pagination from '@/components/Pagination'
import PreviewFile from '@/components/PreviewFile/index' import PreviewFile from '@/components/PreviewFile/index'
import SignForm from '@/views/trials/trials-panel/attachments/self-attachment/components/SignForm' import SignForm from '@/views/trials/trials-panel/attachments/self-attachment/components/SignForm'
import attachmentPreview from '@/views/dictionary/attachment/components/SignatureTemplate/attachmentPreview'
const searchDataDefault = () => { const searchDataDefault = () => {
return { return {
pageIndex: 1, pageIndex: 1,
@ -135,7 +100,7 @@ const searchDataDefault = () => {
} }
export default { export default {
name: 'NeedSignSysDoc', name: 'NeedSignSysDoc',
components: { Pagination, PreviewFile, SignForm }, components: { Pagination, PreviewFile, SignForm, attachmentPreview },
props: { props: {
isSigned: { isSigned: {
type: Boolean, type: Boolean,
@ -159,7 +124,9 @@ export default {
currentType: '', currentType: '',
currentIsConfirm: false, currentIsConfirm: false,
currentUser: zzSessionStorage.getItem('userName'), currentUser: zzSessionStorage.getItem('userName'),
currentRow: {} currentRow: {},
perview_visible: false,
SystemDocumentId: null
} }
}, },
mounted() { mounted() {
@ -171,6 +138,11 @@ export default {
} }
}, },
methods: { methods: {
openAttachment(row) {
if (!row.AttachmentCount) return false
this.SystemDocumentId = row.Id
this.perview_visible = true
},
// //
handlePreview(row) { handlePreview(row) {
this.currentRow = { ...row } this.currentRow = { ...row }
@ -273,5 +245,4 @@ export default {
.needSignSys-wrapper { .needSignSys-wrapper {
height: 100%; height: 100%;
} }
</style> </style>

View File

@ -370,7 +370,7 @@
</div> </div>
</div> </div>
</div> </div>
<div style="width: auto;flex:1;padding: 0 20px"> <div style="width: auto;flex:1;padding: 0 20px;max-width: calc(100% - 250px);">
<!-- 加急影像提交 --> <!-- 加急影像提交 -->
<ImageSubmission v-if="selected === 'ImageSubmission'" :trial-id-list="trialIdList" <ImageSubmission v-if="selected === 'ImageSubmission'" :trial-id-list="trialIdList"
:is-sign-system-doc="tabList.SysWaitSignDocCount > 0 && !isTestUser" /> :is-sign-system-doc="tabList.SysWaitSignDocCount > 0 && !isTestUser" />