Initial commit

This commit is contained in:
danshihao
2024-06-11 15:39:01 +08:00
commit 00acf31aa3
1589 changed files with 520803 additions and 0 deletions
@@ -0,0 +1,677 @@
<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>