Files
laws-sinotruk-client/src/views/documentTool/documentSplit/DocumentSplitDetail.vue
T
2024-01-26 17:54:56 +08:00

678 lines
23 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<template>
<internal-detail-page :title="pageTitle" :content-padding="0">
<div class="page-left-right-layout">
<!--树部分-->
<div class="page-left-box">
<a-input-search class="tree-search" v-model="searchValue" :placeholder="$t('nodeQuickLookup')" @search="onSearch" />
<div class="page-tree-box page-tree-box-has-search">
<a-spin :spinning="treeLoading">
<a-tree :show-line="true"
:show-icon="true"
:tree-data="treeData"
:selected-keys="selectedKeys"
:expanded-keys.sync="expandedKeys"
:replaceFields="{key: 'id'}">
<template #title="record">
<div class="tree-operate-node"
@mouseenter="handleTreeMouseover(record.id)"
@mouseleave="handleTreeMouseout(record.id)"
@click="handleSelectTreeNode(record)">
<a-icon class="parent-node-icon"
type="folder"
v-if="record.dataRef.children && record.dataRef.children.length > 0" />
<a-tooltip>
<template #title>
{{ record.name }}{{ record.itemName }}
</template>
<span class="tree-node-custom-title">{{ record.name }} {{ record.itemName }}</span>
</a-tooltip>
<div class="tree-operate-node-btn-box"
:class="{'tree-operate-node-btn-box-hide': record.id !== mouseInNodeKey}">
<!--新增-->
<a-button icon="plus"
class="tree-operate-node-btn"
@click.stop="orgAdd(record)"
v-has="'split:sarFileSplitMenu:add'"></a-button>
<!--编辑-->
<a-button class="tree-operate-node-btn"
@click.stop="orgEdit(record)"
v-if="record.pid"
v-has="'split:sarFileSplitMenu:update'">
<i class="iconfont icon-bianji" />
</a-button>
<!--删除根节点不能删除-->
<a-button class="tree-operate-node-btn"
v-if="record.pid"
v-has="'split:sarFileSplitMenu:delete'"
@click.stop="orgDelete(record)">
<i class="iconfont icon-shanchu_" />
</a-button>
<!--节点上移是否可以上移在树形数据中应该有字段标识-->
<a-button icon="up"
v-if="record.pid"
class="tree-operate-node-btn"
@click.stop="orgMoveUp(record)"
v-has="'split:sarFileSplitMenu:moveUp'">
</a-button>
<!--节点下移是否可以下移在树形数据中应该有字段标识-->
<a-button icon="down"
v-if="record.pid"
class="tree-operate-node-btn"
@click.stop="orgmoveDown(record)"
v-has="'split:sarFileSplitMenu:moveDown'">
</a-button>
</div>
</div>
</template>
</a-tree>
</a-spin>
</div>
</div>
<!--表格部分-->
<div class="page-right-box">
<div class="table-page-search-wrapper">
<search ref="searchRef"
:url="url"
:get-query-condition-func="getQueryConditionFunc"
search-has="split:sarFileSplitItems:search"
@search="searchQuery"
@reset="searchReset" />
</div>
<!--操作按钮-->
<div class="table-operator">
<!--新增-->
<!--<a-button icon="plus" type="primary" @click="handleAdd" v-has="'split:sarFileSplitItems:add'">{{ $t('newlyAdded') }}</a-button>-->
<!--导入-->
<span @click="handleImport">
<a-button type="primary" icon="download" ghost v-if="!menuId">{{ $t('import') }}</a-button>
<a-upload v-if="menuId"
name="file"
:showUploadList="false"
:multiple="false"
:headers="tokenHeader"
:action="importExcelUrl"
v-has="'split:sarFileSplitItems:import'"
:data="uploadData"
@change="handleImportExcel">
<a-button type="primary" icon="download" ghost>{{ $t('import') }}</a-button>
</a-upload>
</span>
<!--导出-->
<a-button icon="upload"
type="primary"
ghost
v-has="'split:sarFileSplitItems:export'"
@click="handleExportXls">
{{ $t('export') }}
</a-button>
<!--批量删除-->
<a-button type="primary" icon="delete" ghost @click="batchDel" v-has="'split:sarFileSplitItems:batchDelete'">
{{ $t('batchDelete') }}
</a-button>
<!--模板下载-->
<a-button type="primary"
icon="download"
ghost
v-has="'split:sarFileSplitItems:template'"
@click="downTemplate($t('docTool.split.documentSplitTemplate'), '.zip')">
{{ $t('templateDownload') }}
</a-button>
<!--批量复制-->
<a-button type="primary" ghost @click="handleBatchCopy" v-has="'split:sarFileSplitItems:batchCopy'">
{{ $t('docTool.split.batchCopy') }}
</a-button>
<!--批量编辑-->
<a-button type="primary" ghost @click="handleBatchEdit" v-has="'split:sarFileSplitItems:batchUpdate'">
{{ $t('docTool.split.batchEdit') }}
</a-button>
<!--合并条款-->
<a-button type="primary" ghost @click="handleMerge" v-has="'split:sarFileSplitItems:merge'">
{{ $t('docTool.split.mergerClause') }}
</a-button>
</div>
<div>
<j-table
v-if="columns && columns.length > 0"
:columns="columns"
:dataSource="dataSource"
:can-drag="true"
rowKey="id"
:row-selection="{ selectedRowKeys: selectedRowKeys, onChange: onSelectChange }"
:pagination="ipagination"
:scroll="{x: '100%', y: yScrollHeight}"
:operation-list="operationList"
:loading="loading"
@change="tableOnChange"
@operationClick="operationClick">
<!-- 详情-->
<template slot="detailClick" slot-scope="{text, record}">
<a-tooltip overlay-class-name="tooltip-style">
<template slot="title">{{ text || text === 0 ? text : global.emptyLine }}</template>
<a class="table-text textName" @click="detailClick(record)" v-if="text || text === 0">{{ text }}</a>
<div class="table-text" v-else>{{ global.emptyLine }}</div>
</a-tooltip>
</template>
<!--条文内容-->
<template slot="item_content" slot-scope="{text, record}">
<div class="table-text" v-if="text || text === 0" @click="showContent('item_content', text,record)">
{{ text && text !== 'null' ? text.replace(/<.*?>/ig, ' ') : '' }}
</div>
<div class="table-text" v-else>{{ global.emptyLine }}</div>
</template>
<!--条文解读-->
<template slot="interpretation_articles" slot-scope="{text, record}">
<div class="table-text" v-if="text || text === 0" @click="showContent('interpretation_articles', text,record)">
{{ text && text !== 'null' ? text.replace(/<.*?>/ig, ' ') : '' }}
</div>
<div class="table-text" v-else>{{ global.emptyLine }}</div>
</template>
</j-table>
</div>
</div>
</div>
<!--条文内容条文解读-->
<split-clause-detail ref="splitClauseDetail" />
<!--添加节点-->
<split-detail-node-add ref="splitDetailNodeAdd" @ok="nodeAddOk" />
<!--批量编辑-->
<split-detail-batch-edit-drawer ref="batchEditDrawer" @ok="modalFormOk" />
<!--条款添加-->
<split-add-form ref="modalForm" :flag="'4'" :infoId="infoId" :menuId="menuId" :itemId="itemId" @ok="modalFormOk" />
</internal-detail-page>
</template>
<script>
import InternalDetailPage from '../../../components/InternalDetailPage.vue'
import JTable from '../../../components/jero/JTable.vue'
// 条款添加
import SplitAddForm from './modules/SplitAddForm.vue'
// 条款内容弹框
import SplitClauseDetail from './modules/SplitClauseDetail.vue'
// 添加左侧树节点弹框
import SplitDetailNodeAdd from './modules/SplitDetailNodeAdd.vue'
import { mapGetters } from 'vuex'
import { ConfigurableTableMixin } from '../../../mixins/ConfigurableTableMixin.js'
import {
getDocSplitTableHeader,
getDocSplitSearch,
deleteClauseTreeNode,
moveUpOrDownClauseTreeNode,
batchCopyClause,
merageClause,
getClauseTreeData,
copyClause
} from '../../../api/documentToolApi.js'
import Search from '../../../components/customField/Search.vue'
import { isHasPermission } from '../../../utils/hasPermission.js'
import SplitDetailBatchEditDrawer from './modules/SplitDetailBatchEditDrawer.vue'
import { downFile, downloadFile, postAction } from '../../../api/manage'
export default {
name: 'DocumentSplitDetail',
components: {
InternalDetailPage,
JTable,
SplitAddForm,
SplitClauseDetail,
SplitDetailNodeAdd,
Search,
SplitDetailBatchEditDrawer
},
mixins: [ConfigurableTableMixin],
data () {
return {
data: [],
loading: false, // 提交的加载
treeLoading: false, // 树形区域的加载
confirmLoading: false,
nodeTreeItem: null, // 右键菜单
tmpStyle: '', // 右键菜单位置
infoId: '',
menuId: '',
itemId: '',
itemVal: {},
uploadMenuId: '',
deleteNode: false,
moveDownFlag: false,
moveUpFlag: false,
fullWidth: '',
parameter: {},
showAction: false,
flag: '4', // 查询要用到
operateSlotName: 'action',
getQueryConditionFunc: getDocSplitSearch,
getTableHeaderFunc: getDocSplitTableHeader,
treeData: [],
searchValue: '',
selectedKeys: [],
mouseInNodeKey: null, // 鼠标悬浮的节点key值
// 操作栏
operationList: [
// 编辑
{
text: this.$t('edit'),
clickEvent: 'handleEdit',
has: 'split:sarFileSplitItems:update'
},
// 复制
{
text: this.$t('copy'),
clickEvent: 'handleCopy',
has: 'split:sarFileSplitItems:copy'
},
// 删除
{
text: this.$t('delete'),
clickEvent: 'handleDelete',
has: 'split:sarFileSplitItems:delete'
}
],
url: {
list: '/laws/DocumentTool/documentSplit/queryDocumentSplitDetail',
importUrl: '/split/sarFileSplitItems/importSplitItems', // 导入
exportXlsUrl: '/split/sarFileSplitItems/exportSplitInfoZip', // 导出
delete: '/laws/DocumentTool/documentSplit/deleteDocumentSplitDetail', // 删除
deleteBatch: '/laws/DocumentTool/documentSplit/deleteBatchDocumentSplitDetail', // 批量删除
downTemplateUrl: '/laws/DocumentTool/documentSplit/downloadImportTemplate' // 模板下载
},
disabledMixinsCreate: true,
tableSlotField: ['item_content', 'interpretation_articles'],
uploadData: {},
isBackTitle: true,
expandedKeys: []
}
},
computed: {
// 页面标题是标准名称
pageTitle () {
return this.$route.query.infoNumber + ' ' + this.$route.query.standardName
},
yScrollHeight () {
/**
* 前几个使用变量是为了配合iframe嵌套,算出页面显示范围的高度
* 48px:分页器的高度
* 48pxa-card的padding(上24+下24
* 54px:表头行的高度
*/
return `calc(100vh - ${this.defaultHeight['user-info-height']} - ${this.defaultHeight['breadcrumb-height']} - ${this.defaultHeight.oneLineOperationHeight} - 48px - 48px - 54px - ${this.isBackTitle ? '56px' : '0px'})`
},
...mapGetters(['userInfo']),
administrators () {
const adminRoleList = window._CONFIG.adminRoleCode.split(',')
const userRoleList = this.userInfo.roleCode.split(',')
return userRoleList.some(tt => adminRoleList.includes(tt))
}
},
mounted () {
this.operateColumn.scopedSlots.customRender = 'action'
this.showAction = this.$route.query.createBy === this.userInfo.id || this.administrators
this.infoId = this.$route.query.infoId
this.filters = {
menu_id: this.menuId,
info_id: this.infoId
}
this.getTableHeader()
this.loadData()
// 过滤没有权限的按钮
if (this.needFilterTableBtn) {
this.operationList = this.operationList.filter(item => !item.has || isHasPermission(item.has))
}
this.infoId = this.$route.query.infoId
this.loadMenuData()
},
methods: {
/**
* 树节点鼠标移入
* @param key
*/
handleTreeMouseover (key) {
this.mouseInNodeKey = key
},
/**
* 树节点鼠标移出
* @param key
*/
handleTreeMouseout (key) {
if (this.mouseInNodeKey === key) {
this.mouseInNodeKey = null
}
},
/**
* 选中树节点
* @param dataRef
*/
handleSelectTreeNode ({ dataRef }) {
this.selectedKeys = [dataRef.id]
this.menuId = this.selectedKeys[0]
this.uploadData = {
menuId: this.menuId,
infoId: this.infoId
}
this.filters.info_id = this.infoId
this.filters.menu_id = this.menuId
this.loadData()
},
/**
* 显示条款内容、条文解读弹框
* @param fieldName
* @param val
*/
showContent (fieldName, val) {
const title = (this.columns.find(tt => tt.dbFieldName === fieldName) || {}).dbFieldTxt
if (title) {
this.$refs.splitClauseDetail.title = title
}
this.$refs.splitClauseDetail.open(val)
},
// 获取左侧目录数据
loadMenuData () {
const params = {
infoId: this.infoId,
name: this.searchValue
}
this.treeLoading = true
getClauseTreeData(params).then(res => {
if (res.success) {
this.treeData = res.result || []
this.expandedKeys = this.treeData.length > 0 ? [this.treeData[0].id] : []
}
}).finally(() => {
this.treeLoading = false
})
},
// 用于点击空白处隐藏增删改菜单
clearMenu () {
this.nodeTreeItem = null
},
// 树形新增
orgAdd (record) {
console.log(record)
this.$refs.splitDetailNodeAdd.add(record.dataRef, this.infoId)
},
// 树形修改
orgEdit (record) {
this.$refs.splitDetailNodeAdd.edit(record.dataRef, this.infoId)
},
// 添加节点完成后的回调
nodeAddOk (expandId) {
if (expandId && expandId.length > 0) {
this.onExpand(expandId)
}
this.loadMenuData()
this.loadData()
},
// 树形删除
orgDelete (record) {
this.$confirm({
content: this.$t('confirmDeleteNodes'),
onOk:
async () => {
deleteClauseTreeNode({ id: record.dataRef.id }).then(res => {
if (res.success) {
this.$message.success(this.$t('operationSuccessful'))
this.loadMenuData()
this.loadData()
} else {
this.$message.warning(this.$t('operationFailed'))
}
})
}
})
},
// 树上移
orgMoveUp (record) {
const query = {
moveFlag: 'up',
infoId: this.infoId,
sarFileSplitMenu: {
id: record.dataRef.id,
pId: record.dataRef.pid,
displaySeq: record.dataRef.displaySeq
}
}
moveUpOrDownClauseTreeNode(query).then(res => {
if (res.success) {
this.$message.success(this.$t('operationSuccessful'))
this.loadMenuData()
this.loadData()
} else {
this.$message.warning(this.$t('operationFailed'))
}
})
},
// 树下移
orgmoveDown (record) {
const query = {
moveFlag: 'down',
infoId: this.infoId,
sarFileSplitMenu: {
id: record.dataRef.id,
pId: record.dataRef.pid,
displaySeq: record.dataRef.displaySeq
}
}
moveUpOrDownClauseTreeNode(query).then(res => {
if (res.success) {
this.$message.success(this.$t('operationSuccessful'))
this.loadMenuData()
this.loadData()
} else {
this.$message.warning(this.$t('operationFailed'))
}
})
},
handleCopy ({ id }) {
this.$confirm({
title: this.$t('confirmReplication'),
content: '',
onOk: () => {
this.loading = true
copyClause({ id }).then(res => {
if (res.success) {
this.$message.success(res.message)
this.loadData()
} else {
this.$message.warning(res.message)
}
}).finally(() => {
this.loading = false
})
}
})
},
/**
* 批量复制
*/
handleBatchCopy () {
if (!this.selectedRowKeys || this.selectedRowKeys.length === 0) {
this.$message.warning(this.$t('selectLeastOne'))
return
}
this.$confirm({
title: this.$t('confirmReplication'),
content: '',
onOk: () => {
batchCopyClause({ ids: this.selectedRowKeys.join(',') }).then((res) => {
if (res.success) {
this.$message.success(this.$t('operationSuccessful'))
this.onClearSelected()
this.loadMenuData()
this.loadData()
} else {
this.$message.warning(this.$t('operationFailed'))
}
})
}
})
},
// 新增
handleAdd () {
if (!this.menuId) {
this.$message.warning(this.$t('docTool.split.selectDirectoryTerms'))
return
}
if (this.menuId) {
this.formTitle = this.$t('add')
this.itemId = ''
this.$refs.modalForm.add()
}
},
// 合并条款
handleMerge () {
if (this.selectedRowKeys && this.selectedRowKeys.length < 2) {
this.$message.warning(this.$t('leastTwo'))
return
}
const ids = this.selectedRowKeys.join(',')
this.$confirm({
title: this.$t('docTool.split.mergeTerms'),
content: '',
onOk: () => {
this.loading = true
merageClause({ ids: ids }).then(res => {
if (res.success) {
this.$message.success(res.message)
this.loading = false
this.onClearSelected()
this.loadMenuData()
this.loadData()
this.selectedRowKeys = []
} else {
this.$message.warning(res.message)
this.loading = false
}
})
}
})
},
/**
* 批量编辑
*/
handleBatchEdit () {
if (!this.selectedRowKeys || this.selectedRowKeys.length === 0) {
this.$message.warning(this.$t('selectLeastOne'))
return
}
this.$refs.batchEditDrawer.open(this.selectedRowKeys.join(','))
},
onSearch () {
this.loadMenuData()
},
/**
* 删除
* @param id
*/
handleDelete (id) {
if (!this.url.delete) {
this.$message.warning('请设置url.delete属性!')
return
}
const that = this
this.$confirm({
title: this.$t('confirmDeletion'),
content: this.$t('areYouSure'),
onOk: () => {
postAction(that.url.delete, { id: id }).then((res) => {
if (res.success) {
that.$message.success(res.message)
// 判断当前删除的数据是否是最后一页的最后一条数据,如果是的话页码减一
if (that.ipagination.current > 1 && ((that.ipagination.current - 1) * that.ipagination.pageSize) + 1 === that.ipagination.total) {
that.ipagination.current -= 1
}
that.loadData()
} else {
that.$message.warning(res.message)
}
})
}
})
},
/**
* 导出
*/
handleExportXls () {
const fileName = this.$route.query.infoNumber + ' ' + this.$route.query.standardName
const fileSuffix = '.zip'
const param = {}
if (this.selectedRowKeys && this.selectedRowKeys.length > 0) {
param.idList = this.selectedRowKeys.join(',')
}
param.parameter = this.getQueryParams()
param.exportName = fileName + fileSuffix
// 加一个大的提示
const modalLoading = this.$info({
title: this.$t('tips'),
content: <span>{this.$t('exportTip')}
<a-spin size="small" /></span>,
keyboard: false
})
// 把知道了这个按钮去掉
this.$nextTick(() => {
document.getElementsByClassName('ant-modal-confirm-btns')[0].style = 'display:none'
})
downFile(this.url.exportXlsUrl, param).then((data) => {
if (!data) {
this.$message.warning(this.$t('fileDownloadFail'))
return
}
if (typeof window.navigator.msSaveBlob !== 'undefined') {
window.navigator.msSaveBlob(new Blob([data], { type: 'application/vnd.ms-excel' }), fileName + fileSuffix)
} else {
const url = window.URL.createObjectURL(new Blob([data], { type: 'application/vnd.ms-excel' }))
const link = document.createElement('a')
link.style.display = 'none'
link.href = url
link.setAttribute('download', fileName + fileSuffix)
document.body.appendChild(link)
link.click()
document.body.removeChild(link) // 下载完成移除元素
window.URL.revokeObjectURL(url) // 释放掉blob对象
}
}).finally(() => {
// 销毁这个提示
modalLoading.destroy()
})
},
handleImport () {
if (!this.menuId) {
this.$message.warning(this.$t('docTool.split.selectDirectoryTerms'))
}
},
// 下载导入模板
downTemplate (fileName, fileSuffix = '.xls') {
if (!fileName || typeof fileName !== 'string') {
fileName = '模板文件'
}
downloadFile(this.url.downTemplateUrl, fileName + fileSuffix, { infoId: this.$route.query.infoId })
}
}
}
</script>
<style scoped lang="less">
@import '~@assets/less/common.less';
.page-left-right-layout {
height: 100%;
width: 100%;
display: flex;
}
/deep/ .ant-tree li span.ant-tree-switcher.ant-tree-switcher-noop {
color: #1D2129;
}
.parent-node-icon {
color: #1D2129;
font-size: 16px;
margin-right: 10px;
}
</style>