irc_web/src/views/trials/trials-workbench/components/auditDocument/index.vue

731 lines
23 KiB
Vue

<template>
<div class="auditDocument">
<el-row>
<el-col :span="12">
<h3>{{ isManage ? $t('trials:tab:updateAuditDocument') : $t('trials:tab:viewAuditDocument') }}</h3>
</el-col>
<el-col :span="12" style="text-align:right;">
<h3>
<Pagination class="page" :total="total" :page.sync="searchData.pageIndex"
:limit.sync="searchData.pageSize" layout="total, sizes, prev, pager, next" :background="false"
style="display: inline-block;" @pagination="getList" />
<el-button icon="el-icon-refresh-left" size="small" circle :title="$t('common:button:reset')"
@click="handleReset" />
</h3>
</el-col>
</el-row>
<el-form :inline="true" class="base-search-form">
<el-form-item>
<el-input v-model="searchData.Name" clearable></el-input>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search" @click="handleSearch">
{{ $t('common:button:search') }}
</el-button>
<el-button type="primary" icon="el-icon-refresh-left" @click="handleReset">
{{ $t('common:button:reset') }}
</el-button>
</el-form-item>
<el-form-item>
<el-button type="primary">
{{ $t('trials:trials-workbench:auditDocument:button:addFolder') }}
</el-button>
<el-button type="primary" @click.stop="openFile(false)">
{{ $t('trials:trials-workbench:auditDocument:button:uploadFile') }}
</el-button>
<el-button type="primary" @click.stop="openFile(true)">
{{ $t('trials:trials-workbench:auditDocument:button:uploadFolder') }}
</el-button>
<el-button type="primary">
{{ $t('trials:trials-workbench:auditDocument:button:download') }}
</el-button>
<el-button type="primary">
{{ $t('trials:trials-workbench:auditDocument:button:del') }}
</el-button>
</el-form-item>
</el-form>
<div class="catalogue">
<span>{{ $t('trials:trials-workbench:auditDocument:catalogue:title') }}</span>
<el-button icon="el-icon-top" class="last_catalogue" :disabled="!Id"
@click.stop="toCatalogue(false)"></el-button>
<el-breadcrumb separator-class="el-icon-arrow-right" class="catalogue_name_box">
<el-breadcrumb-item v-for="item of catalogueData" :key="item.Id">
<span class="catalogue_name" @click.stop="toCatalogue(item)">{{ item.Name }}</span>
</el-breadcrumb-item>
</el-breadcrumb>
</div>
<el-table :data="tableData" style="width: 99%" row-key="Id" :loading="loading" :row-style="setRowStyle"
v-adaptive="{ bottomOffset: 75 }" height="100" :border="true" :expand-row-keys="expandedRows"
:tree-props="{ children: 'Children', hasChildren: 'hasChildren' }" @expand-change="handleExpandChange"
@row-click="handleRowClick" @cell-mouse-enter="handleCellMouseEnter"
@cell-mouse-leave="handleCellMouseLeave" @row-contextmenu="handleRowContextmenu"
@row-dblclick="handleRowDblclick">
<el-table-column prop="date" :label="$t('trials:trials-workbench:auditDocument:table:name')" sortable
min-width="300" class-name="catalogue_box">
<template slot-scope="scope">
<div class="name_layout_box">
<div class="name_layout" v-if="renameId !== scope.row.Id">
<span class="name_box">
<i class="icon icon_folder" v-if="!scope.row.AuditDocumentTypeEnum" />
<i v-else :class="`icon icon_file icon_${scope.row.FileFormat}`" />
<span class="name">{{ scope.row.Name }}</span>
<i class="el-icon-edit icon_edit" v-if="hoverId === scope.row.Id"
@click="addRenameId(scope.row)"
:title="$t('trials:trials-workbench:auditDocument:icon:rename')" />
</span>
<i :class="{ 'el-icon-circle-check': true, 'icon_check': true, isCheck: checkList.includes(scope.row.Id) }"
@click.stop="addCheck(scope.row)"
v-if="hoverId === scope.row.Id || checkList.includes(scope.row.Id)" />
</div>
<el-input v-model="scope.row.Name" :ref="`renameInp_${scope.row.Id}`" :autofocus="true"
class="renameInp" @blur="rename(scope.row)" v-else />
</div>
</template>
</el-table-column>
<el-table-column prop="FileFormat" :label="$t('trials:trials-workbench:auditDocument:table:fileType')">
<template slot-scope="scope">
<span>{{ formatFileType(scope.row) }}</span>
</template>
</el-table-column>
<el-table-column prop="FileSize" :label="$t('trials:trials-workbench:auditDocument:table:fileSize')">
<template slot-scope="scope">
<span>{{ formatFileSize(scope.row) }}</span>
</template>
</el-table-column>
<el-table-column prop="UpdateTime" :label="$t('trials:trials-workbench:auditDocument:table:updateTime')">
</el-table-column>
<el-table-column prop="CreateTime" :label="$t('trials:trials-workbench:auditDocument:table:createTime')">
</el-table-column>
</el-table>
<contextmenu ref="contextmenu" :checkList="checkList" @handleMenu="handleMenu" />
<upload-files :config="config" :faccept="faccept" :uploadPath="uploadPath" :limitLength="limitLength"
v-if="config.visible" @close="close" @uplaodFile="uplaodFile" />
<detail v-if="visible" :visible.sync="visible" :rowData="rowData" @openContextmenu="openContextmenu" />
</div>
</template>
<script>
import { getAuditDocumentData, addAuditDocument, getBreadcrumbData, updateAuditDocument } from '@/api/trials'
import Pagination from '@/components/Pagination'
import contextmenu from './contextmenu.vue'
import uploadFiles from '@/views/trials/trials-panel/trial-summary/trial-document/components/uploadFiles.vue'
import detail from './detail.vue'
const searchDataDefault = () => {
return {
Name: null,
pageIndex: 1,
pageSize: 20,
asc: false,
sortField: ''
}
}
export default {
name: "auditDocument",
components: { Pagination, contextmenu, uploadFiles, detail },
props: {
isManage: {
type: Boolean,
default: false
}
},
data() {
return {
searchData: searchDataDefault(),
total: 0,
Id: null,
loading: false,
expandedRows: [],
tableData: [],
catalogueData: [], // 目录层级
visible: false, // 属性详情弹框
rowData: {}, // 属性详情数据
config: {
visible: false,
showClose: true,
width: '800px',
title: '',
appendToBody: false,
isFolder: false,
},
uploadPath: '/System/AuditDocument',
faccept: ['.pdf'],
limitLength: 0,
checkList: [], // 选中的数据
hoverId: null, // hover中的数据
renameId: null, // 选中重命名的数据
copyList: [], // 选中复制的数据
shearList: [], // 选中剪切的数据
type: null, // 操作类型(右键菜单、键盘操作)
ctrlKey: false, // 键盘ctrl键是否按下
}
},
methods: {
// 获取当前目录层级
async getBreadcrumbData() {
if (!this.Id) return this.catalogueData = []
try {
let data = {
Id: this.Id
}
let res = await getBreadcrumbData(data)
if (res.IsSuccess) {
this.catalogueData = res.Result
}
} catch (err) { console.log(err) }
},
async getList() {
try {
this.searchData.Id = this.Id
this.loading = true
let res = await getAuditDocumentData(this.searchData)
this.loading = false
if (res.IsSuccess) {
this.tableData = res.Result.CurrentPageData
this.total = res.Result.TotalCount
}
} catch (err) {
this.loading = false
console.log(err)
}
},
handleSearch() {
this.getList()
},
handleReset() {
this.searchData = searchDataDefault()
this.getList()
},
addCheck(row) {
this.checkList.push(row.Id)
},
addRenameId(row) {
this.renameId = row.Id
this.$nextTick(() => {
if (this.$refs[`renameInp_${row.Id}`]) {
this.$refs[`renameInp_${row.Id}`].focus()
}
})
},
rename(row) {
this.renameId = null
this.updateData(row)
},
handleExpandChange(row, expanded) {
console.log(this.expandedRows)
if (expanded && !this.expandedRows.find(Id => Id === row.Id)) {
this.expandedRows.push(row.Id)
}
if (!expanded) {
let index = this.expandedRows.indexOf(row.Id)
if (!!~index) {
this.expandedRows.splice(index, 1)
}
}
},
// 重置所有操作
resetOpt() {
this.expandedRows = []
this.checkList = []
this.hoverId = null
this.renameId = null
this.copyList = []
this.shearList = []
},
// 跳转至目录
toCatalogue(row) {
if (!row) {
let data = this.catalogueData[this.catalogueData.length - 2]
if (data) {
return this.toCatalogue(data)
} else {
row = {}
}
}
this.Id = row.Id
this.resetOpt()
this.getList()
this.getBreadcrumbData()
},
// 修改数据
async updateData(row) {
try {
let data = {
AuditDocumentTypeEnum: row.AuditDocumentTypeEnum,
FileFormat: row.FileFormat,
FilePath: row.FilePath,
FileSize: row.FileSize,
Id: row.Id,
IsAuthorization: row.IsAuthorization,
Name: row.Name,
ParentId: row.ParentId
}
let res = await updateAuditDocument(data);
} catch (err) {
this.getList()
console.log(err)
}
},
// 新增列表数据
async uplaodFile(list) {
let data = this.formatData(list)
console.log(data, 'data')
try {
let res = await addAuditDocument(JSON.stringify(data))
if (res.IsSuccess) {
this.getList()
}
} catch (err) {
console.log(err)
}
},
// 格式化上传数据
formatData(arr) {
let list = [], strObj = {}
arr.forEach(item => {
if (item.catalogue) {
let catalogueStr = item.catalogue.split("/")
catalogueStr.pop()
let obj = {}, strKey = []
catalogueStr.forEach((str, index) => {
strKey.forEach((key, i) => {
if (i === 0) {
obj = strObj[key]
} else {
obj = obj[key]
}
})
if (index === 0) {
if (!strObj[str]) {
strObj[str] = {
children: []
}
}
} else {
if (!obj[str]) {
obj[str] = {
children: []
}
}
}
obj = obj[str]
strKey.push(str)
})
obj.children.push({
ParentId: null,
Name: item.FileName,
IsAuthorization: false,
FileSize: item.FileSize,
filePath: item.FilePath,
FileFormat: item.FileFormat,
AuditDocumentTypeEnum: 1
})
} else {
list.push({
ParentId: null,
Name: item.FileName,
IsAuthorization: false,
FileSize: item.FileSize,
filePath: item.FilePath,
FileFormat: item.FileFormat,
AuditDocumentTypeEnum: 1
})
}
})
let ARRAY = this.objToArr(strObj)
list = list.concat(ARRAY)
return list
},
objToArr(obj, list = []) {
Object.keys(obj).forEach(key => {
if (key !== 'children') {
let item = list.find(d => d.Name === key)
if (!item) {
let data = {
ParentId: null,
Name: key,
IsAuthorization: false,
AuditDocumentTypeEnum: 0,
children: obj[key].children
}
list.push(data)
}
this.objToArr(obj[key], obj[key].children)
}
})
return list;
},
// 格式化文件类型
formatFileType(row) {
if (!row.AuditDocumentTypeEnum) {
return this.$t('trials:trials-workbench:auditDocument:fileType:folder')
} else {
return `${row.FileFormat}${this.$t('trials:trials-workbench:auditDocument:fileType:file')}`
}
},
// 格式化文件大小
formatFileSize(row) {
if (!row.FileSize) return ''
if (row.FileSize < 1000) {
return row.FileSize + "B"
}
if (row.FileSize < 1000 * 1024) {
return (row.FileSize / 1024).toFixed(2) + "KB"
}
if (row.FileSize < 1000 * 1000 * 1024) {
return (row.FileSize / 1000 / 1024).toFixed(2) + "MB"
}
if (row.FileSize < 1000 * 1000 * 1000 * 1024) {
return (row.FileSize / 1000 / 1000 / 1024).toFixed(2) + "GB"
}
},
openFile(isFolder = false) {
this.faccept = [
'.jpg',
'.jpeg',
'.png',
'.pdf',
'.ppt',
'.pptx',
'.zip',
'.doc',
'.docx',
'.xls',
'.xlsx',
]
this.limitLength = 0
this.config.title = this.$t(
'trials:trials-workbench:auditDocument:form:title:uploadFile'
)
this.config.visible = true
this.config.isFolder = isFolder
},
close() {
this.config.visible = false
this.faccept = ['.pdf']
this.limitLength = 0
},
// 版本记录(右键菜单)
openContextmenu(data) {
let { e, row, type, zIndex } = data
this.$refs.contextmenu.init(e, row, type, zIndex)
},
// 单行右键单击(右键菜单)
handleRowContextmenu(row, column, e) {
e.preventDefault();
if (!this.checkList.includes(row.Id)) this.handleRowClick(row)
this.$refs.contextmenu.init(e, row, 'file')
},
// 单行左键双击(进入文件夹或者预览文件)
handleRowDblclick(row) {
if (!row.AuditDocumentTypeEnum) {
this.Id = row.Id
this.resetOpt()
this.getList()
this.getBreadcrumbData()
}
},
// 单行左键单击
handleRowClick(row) {
if (this.ctrlKey) {
this.checkList.push(row.Id)
} else {
this.checkList = [row.Id]
}
},
// 单行hover移入
handleCellMouseEnter(row) {
this.hoverId = row.Id
},
// 单行hover移出
handleCellMouseLeave() { this.hoverId = null },
// 右键菜单操作
handleMenu(key) {
this.type = key;
if (key === 'rename') {
this.renameId = this.checkList[0]
}
if (key === 'Stats') {
this.rowData = this.tableData.find(item => item.Id === this.checkList[0])
this.visible = true
}
},
setRowStyle({ row, rowIndex }) {
if (this.checkList.includes(row.Id)) {
return {
backgroundColor: '#cce8ff', // 错误行红色背景
}
}
},
// 复制
copy() { },
// 剪切
shear() { },
// 粘贴
stickup() { },
// 键盘事件(按下)
keydown(e) {
this.ctrlKey = e.ctrlKey
if (e.key === 'Control') {
e.preventDefault();
}
if (e.ctrlKey && e.key === 'c') {
e.preventDefault();
this.type = 'copy'
this.copy()
}
if (e.ctrlKey && e.key === 'v') {
e.preventDefault();
this.type = 'stickup'
this.stickup()
}
if (e.ctrlKey && e.key === 'x') {
e.preventDefault();
this.type = 'shear'
this.shear()
}
},
// 键盘事件(松开)
keyup(e) {
this.ctrlKey = e.ctrlKey
}
},
mounted() {
document.addEventListener('keydown', this.keydown);
document.addEventListener('keyup', this.keyup);
this.getList()
this.getBreadcrumbData()
},
destroyed() {
document.removeEventListener('keydown', this.keydown);
document.removeEventListener('keyup', this.keyup);
}
}
</script>
<style lang="scss" scoped>
.auditDocument {
// position: relative;
::v-deep .catalogue_box.el-table__cell {
.cell {
display: flex;
align-items: center;
}
}
}
.renameInp {
::v-deep .el-input__inner {
line-height: 23px;
height: 23px;
}
}
.name_layout_box {
display: inline-block;
flex: 1 1 0%;
min-width: 0;
}
.catalogue {
width: 99%;
display: flex;
align-items: center;
margin: 0 0 22px;
span {
font-size: 16px;
}
.last_catalogue {
width: 24px;
height: 24px;
line-height: 24px;
text-align: center;
border: 1px solid #ddd;
// cursor: pointer;
padding: 0;
border-radius: 4px 0 0 4px;
// &:hover {
// background-color: #e4f8ff;
// border-color: #aedaff;
// }
}
.catalogue_name_box {
flex: 1 0 0%;
box-sizing: border-box;
border: 1px solid #ddd;
border-left: none;
padding: 0 10px;
border-radius: 0 4px 4px 0;
height: 24px;
line-height: 24px;
}
.catalogue_name {
cursor: pointer;
font-size: 14px;
&:hover {
color: #3b8cff;
}
}
}
.name_layout {
width: 100%;
display: flex;
align-items: center;
justify-content: space-between;
.name_box {
display: flex;
align-items: center;
width: calc(100% - 20px);
.name {
max-width: calc(100% - 60px);
white-space: nowrap;
/* 文本不换行 */
overflow: hidden;
/* 超出部分隐藏 */
text-overflow: ellipsis;
}
}
}
.icon_edit {
cursor: pointer;
color: rgba(0, 0, 0, 0.3);
margin-left: 2px;
&:hover {
color: rgba(0, 0, 0, 0.5);
}
}
.icon_check {
font-size: 18px;
cursor: pointer;
color: rgba(0, 0, 0, 0.3);
&:hover {
color: rgba(0, 0, 0, 0.5);
}
}
.isCheck {
color: #3b8cff;
}
::v-deep .el-table--enable-row-hover .el-table__body tr:hover>td.el-table__cell {
background-color: #e5f3ff
}
.icon {
height: 20px;
width: 20px;
padding: 0px;
line-height: 20px;
// min-width: 20px;
margin-right: 6px;
margin-top: 6px;
}
/*文件*/
.icon_file {
width: 16px !important;
height: 16px !important;
margin-right: 6px;
background-size: inherit;
background-image: url(@/assets/0.file-16.png);
background-position: 0 0;
margin-top: -2px;
background-repeat: no-repeat;
font-style: normal;
display: inline-block;
pointer-events: none;
font-size: 85%;
}
/*文件夹*/
.icon_folder {
background-image: url(@/assets/folder_win11_small.png);
margin-top: -6px;
margin-left: 2px;
margin-right: 6px;
background-repeat: no-repeat;
}
/*docx*/
.icon_docx {
background-position: -81px -560px !important;
margin-top: 0;
margin-left: 2px;
}
/*doc*/
.icon_doc {
background-position: -81px -592px !important;
margin-top: 0;
margin-left: 2px;
}
/*xlsx*/
.icon_xlsx {
background-position: -81px -48px !important;
margin-top: 0;
margin-left: 2px;
}
/*pdf*/
.icon_pdf {
background-position: -81px -352px !important;
margin-top: 0;
margin-left: 2px;
}
/*pptx*/
.icon_pptx {
background-position: -81px -288px !important;
margin-top: 0;
margin-left: 2px;
}
/*zip*/
.icon_zip {
background-position: 0 0 !important;
margin-top: -2px;
margin-left: 2px;
}
/*ppt*/
.icon_ppt {
background-position: -81px -304px !important;
margin-top: 0;
margin-left: 2px;
}
/*xls*/
.icon_xls {
background-position: -81px -96px !important;
margin-top: 0;
margin-left: 2px;
}
</style>