You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
593 lines
18 KiB
593 lines
18 KiB
6 months ago
|
<template>
|
||
|
<div class="app-container">
|
||
|
<el-row :gutter="16">
|
||
|
<el-col :span="5">
|
||
|
<el-card shadow="never">
|
||
|
<el-input
|
||
|
v-model="filterText"
|
||
|
style="width: 100%"
|
||
|
placeholder="搜索目录名称"
|
||
|
>
|
||
|
<template #prefix>
|
||
|
<el-icon><Search /></el-icon>
|
||
|
</template>
|
||
|
</el-input>
|
||
|
<div class="tree-box">
|
||
|
<el-tree
|
||
|
class="tree"
|
||
|
ref="treeRef"
|
||
|
node-key="tempId"
|
||
|
:default-expand-all="true"
|
||
|
:highlight-current="true"
|
||
|
:expand-on-click-node="false"
|
||
|
:data="directoryTree"
|
||
|
:props="defaultProps"
|
||
|
:filter-node-method="filterNode"
|
||
|
:current-node-key="currentNode.tempId"
|
||
|
@node-click="handleNodeClick"
|
||
|
>
|
||
|
<template #default="{ data }">
|
||
|
<div class="custom-tree-node">
|
||
|
<el-space :size="2">
|
||
|
<el-icon v-if="data.contentOnum && !data.astOnum"
|
||
|
><Folder
|
||
|
/></el-icon>
|
||
|
<el-icon v-else><Document /></el-icon>
|
||
|
<span>{{ data.contentName || data.dataAstCnName }}</span>
|
||
|
</el-space>
|
||
|
<div
|
||
|
v-if="!isCollectionDirectory(data)"
|
||
|
class="tree-node__action"
|
||
|
>
|
||
|
<template v-if="isAsset(data)">
|
||
|
<el-button
|
||
|
v-if="!isCollected(data)"
|
||
|
link
|
||
|
type="warning"
|
||
|
icon="Star"
|
||
|
@click="(e) => handleCollect(data, e)"
|
||
|
></el-button>
|
||
|
<el-button
|
||
|
v-else
|
||
|
link
|
||
|
type="warning"
|
||
|
style="margin-right: -2px"
|
||
|
@click="(e) => handleCollectionCancel(data, e)"
|
||
|
>
|
||
|
<el-icon slot="icon" size="18" color="#E6A23C">
|
||
|
<StarFilled />
|
||
|
</el-icon>
|
||
|
</el-button>
|
||
|
</template>
|
||
|
<el-dropdown
|
||
|
v-if="
|
||
|
!isCollection(data) &&
|
||
|
(isDirectory(data) || isRoot(data)) &&
|
||
|
hasPermiOr([
|
||
|
'dataAsset:directory:add',
|
||
|
'dataAsset:directory:edit',
|
||
|
'dataAsset:directory:remove',
|
||
|
'dataAsset:directory:move',
|
||
|
'dataAsset:directory:merge',
|
||
|
])
|
||
|
"
|
||
|
placement="right-start"
|
||
|
@command="(command) => handleCommand(command, data)"
|
||
|
>
|
||
|
<el-button
|
||
|
style="margin-left: 4px"
|
||
|
link
|
||
|
type="primary"
|
||
|
icon="Menu"
|
||
|
></el-button>
|
||
|
<template #dropdown>
|
||
|
<el-dropdown-menu>
|
||
|
<el-dropdown-item
|
||
|
v-if="
|
||
|
isRoot(data) &&
|
||
|
hasPermiOr(['dataAsset:directory:add'])
|
||
|
"
|
||
|
command="handleAddDialogOpen"
|
||
|
>
|
||
|
新增目录
|
||
|
</el-dropdown-item>
|
||
|
<template v-if="isDirectory(data)">
|
||
|
<el-dropdown-item
|
||
|
v-if="hasPermiOr(['dataAsset:directory:add'])"
|
||
|
command="handleAddDialogOpen"
|
||
|
>
|
||
|
新增目录
|
||
|
</el-dropdown-item>
|
||
|
<el-dropdown-item
|
||
|
v-if="hasPermiOr(['dataAsset:directory:edit'])"
|
||
|
command="handleEditDialogOpen"
|
||
|
>
|
||
|
修改目录
|
||
|
</el-dropdown-item>
|
||
|
<el-dropdown-item
|
||
|
v-if="hasPermiOr(['dataAsset:directory:remove'])"
|
||
|
command="handleDelete"
|
||
|
>
|
||
|
删除目录
|
||
|
</el-dropdown-item>
|
||
|
<el-dropdown-item
|
||
|
v-if="hasPermiOr(['dataAsset:directory:move'])"
|
||
|
command="handleMoveDialogOpen"
|
||
|
>
|
||
|
移动目录
|
||
|
</el-dropdown-item>
|
||
|
<el-dropdown-item
|
||
|
v-if="hasPermiOr(['dataAsset:directory:merge'])"
|
||
|
command="handleMergerDialogOpen"
|
||
|
>
|
||
|
合并目录
|
||
|
</el-dropdown-item>
|
||
|
</template>
|
||
|
</el-dropdown-menu>
|
||
|
</template>
|
||
|
</el-dropdown>
|
||
|
<el-dropdown
|
||
|
v-if="
|
||
|
!isCollection(data) &&
|
||
|
isAsset(data) &&
|
||
|
hasPermiOr([
|
||
|
'dataAsset:asset:remove',
|
||
|
'dataAsset:asst:move',
|
||
|
])
|
||
|
"
|
||
|
placement="right-start"
|
||
|
@command="(command) => handleCommand(command, data)"
|
||
|
>
|
||
|
<el-button
|
||
|
style="margin-left: 4px"
|
||
|
link
|
||
|
type="primary"
|
||
|
icon="Menu"
|
||
|
></el-button>
|
||
|
<template #dropdown>
|
||
|
<el-dropdown-menu>
|
||
|
<el-dropdown-item
|
||
|
v-if="hasPermiOr(['dataAsset:asset:remove'])"
|
||
|
command="handleAssetDelete"
|
||
|
>
|
||
|
删除资产
|
||
|
</el-dropdown-item>
|
||
|
<el-dropdown-item
|
||
|
v-if="hasPermiOr(['dataAsset:asst:move'])"
|
||
|
command="handleAssetMoveDialogOpen"
|
||
|
>
|
||
|
移动资产
|
||
|
</el-dropdown-item>
|
||
|
</el-dropdown-menu>
|
||
|
</template>
|
||
|
</el-dropdown>
|
||
|
</div>
|
||
|
</div>
|
||
|
</template>
|
||
|
</el-tree>
|
||
|
</div>
|
||
|
</el-card>
|
||
|
</el-col>
|
||
|
<el-col :span="19">
|
||
|
<el-card shadow="never">
|
||
|
<template v-if="currentNode.contentOnum && !currentNode.astOnum">
|
||
|
<el-descriptions
|
||
|
:title="currentNode.contentName"
|
||
|
:column="3"
|
||
|
border
|
||
|
>
|
||
|
<el-descriptions-item label="简介">
|
||
|
{{ currentNode.contentIntr }}
|
||
|
</el-descriptions-item>
|
||
|
</el-descriptions>
|
||
|
<el-row style="margin-top: 20px" :gutter="20">
|
||
|
<el-col :span="12">
|
||
|
<el-table :data="directoryTableData" border style="width: 100%">
|
||
|
<el-table-column
|
||
|
prop="contentName"
|
||
|
width="160"
|
||
|
:label="`${tableHeaderLabel}名称`"
|
||
|
>
|
||
|
<template #default="{ row }">
|
||
|
{{ row.contentName || row.dataAstCnName }}
|
||
|
</template>
|
||
|
</el-table-column>
|
||
|
<el-table-column
|
||
|
prop="contentIntr"
|
||
|
:label="`${tableHeaderLabel}简介`"
|
||
|
>
|
||
|
<template #default="{ row }">
|
||
|
{{ row.contentIntr || row.dataAstDesc }}
|
||
|
</template>
|
||
|
</el-table-column>
|
||
|
</el-table>
|
||
|
</el-col>
|
||
|
<el-col :span="12">
|
||
|
<el-card class="html-box" shadow="never">
|
||
|
<iframe
|
||
|
ref="iframe"
|
||
|
:srcdoc="htmlContent"
|
||
|
:style="iframeStyle"
|
||
|
></iframe>
|
||
|
</el-card>
|
||
|
</el-col>
|
||
|
</el-row>
|
||
|
</template>
|
||
|
<template v-if="currentNode.astOnum">
|
||
|
<el-descriptions
|
||
|
:title="currentNode.dataAstCnName"
|
||
|
:column="3"
|
||
|
border
|
||
|
>
|
||
|
<el-descriptions-item label="简介">
|
||
|
{{ currentNode.dataAstDesc }}
|
||
|
</el-descriptions-item>
|
||
|
</el-descriptions>
|
||
|
<el-tabs style="margin-top: 8px" v-model="activeName">
|
||
|
<el-tab-pane label="资产字段" name="1">
|
||
|
<el-table :data="[]" border>
|
||
|
<el-table-column type="index" label="序号" width="60" />
|
||
|
<el-table-column prop="" label="字段中文名" />
|
||
|
<el-table-column prop="" label="字段英文名" />
|
||
|
<el-table-column prop="" label="字段类型" />
|
||
|
<el-table-column prop="" label="枚举" />
|
||
|
<el-table-column prop="" label="有值率" />
|
||
|
<el-table-column prop="" label="说明" />
|
||
|
</el-table>
|
||
|
</el-tab-pane>
|
||
|
<el-tab-pane label="样例数据" name="2">
|
||
|
<el-table :data="[]" border>
|
||
|
<el-table-column type="index" label="序号" width="60" />
|
||
|
<el-table-column prop="" label="股票代码" />
|
||
|
<el-table-column prop="" label="股票名称" />
|
||
|
<el-table-column prop="" label="股票价格" />
|
||
|
</el-table>
|
||
|
</el-tab-pane>
|
||
|
<el-tab-pane label="常见问题" name="3">
|
||
|
<div class="faq">
|
||
|
<el-text>{{ faq }}</el-text>
|
||
|
</div>
|
||
|
</el-tab-pane>
|
||
|
</el-tabs>
|
||
|
</template>
|
||
|
</el-card>
|
||
|
</el-col>
|
||
|
</el-row>
|
||
|
<FormDialog
|
||
|
ref="formDialogRef"
|
||
|
:directoryTree="directoryTree"
|
||
|
@onSuccess="setDirectoryTree"
|
||
|
/>
|
||
|
<MoveDialog
|
||
|
ref="moveDialogRef"
|
||
|
:directoryTree="directoryTree"
|
||
|
@onSuccess="setDirectoryTree"
|
||
|
/>
|
||
|
<MergerDialog
|
||
|
ref="mergerDialogRef"
|
||
|
:directoryTree="directoryTree"
|
||
|
@onSuccess="setDirectoryTree"
|
||
|
/>
|
||
|
<AssetMoveDialog
|
||
|
ref="assetMoveDialogRef"
|
||
|
:directoryTree="directoryTree"
|
||
|
@onSuccess="setDirectoryTree"
|
||
|
/>
|
||
|
</div>
|
||
|
</template>
|
||
|
|
||
|
<script setup name="Directory">
|
||
|
import { ElMessage, ElMessageBox } from 'element-plus'
|
||
|
import {
|
||
|
getDirectoryTree,
|
||
|
delDirectory,
|
||
|
getDirectory,
|
||
|
getHtmlString,
|
||
|
delDirectoryAsset,
|
||
|
addDirectoryCollection,
|
||
|
cancelDirectoryCollection,
|
||
|
} from '@/api/dataAsset/directory'
|
||
|
import auth from '@/plugins/auth'
|
||
|
import FormDialog from './components/FormDialog.vue'
|
||
|
import MoveDialog from './components/MoveDialog.vue'
|
||
|
import MergerDialog from './components/MergerDialog.vue'
|
||
|
import AssetMoveDialog from './components/AssetMoveDialog.vue'
|
||
|
import useUserStore from '@/store/modules/user'
|
||
|
import { nextTick } from 'vue'
|
||
|
const { proxy } = getCurrentInstance()
|
||
|
const { hasPermiOr } = auth
|
||
|
const userStore = useUserStore()
|
||
|
|
||
|
const defaultProps = {
|
||
|
children: 'children',
|
||
|
label: 'contentName',
|
||
|
}
|
||
|
const directoryTree = ref([])
|
||
|
const currentNode = ref({})
|
||
|
|
||
|
const directoryTableData = ref([])
|
||
|
const tableHeaderLabel = computed(() => {
|
||
|
if (currentNode.value.leafNodeFlag === 1) {
|
||
|
return '资产'
|
||
|
}
|
||
|
return '目录'
|
||
|
})
|
||
|
|
||
|
/** 增加临时ID作为树节点的唯一键值 */
|
||
|
const addTreeNodeId = (tree) => {
|
||
|
return tree.map((node) => {
|
||
|
return {
|
||
|
...node,
|
||
|
tempId: node.astOnum || node.contentOnum,
|
||
|
children:
|
||
|
node.children && node.children.length
|
||
|
? addTreeNodeId(node.children)
|
||
|
: [],
|
||
|
}
|
||
|
})
|
||
|
}
|
||
|
const htmlContent = ref('')
|
||
|
const setHtmlContent = async (data) => {
|
||
|
return getHtmlString(data).then((res) => {
|
||
|
htmlContent.value = res
|
||
|
})
|
||
|
}
|
||
|
|
||
|
const setDirectoryTree = () => {
|
||
|
return getDirectoryTree({
|
||
|
pageSize: 999,
|
||
|
}).then(({ rows }) => {
|
||
|
directoryTree.value = addTreeNodeId(rows)
|
||
|
})
|
||
|
}
|
||
|
setDirectoryTree().then(async () => {
|
||
|
if (directoryTree.value.length) {
|
||
|
currentNode.value = directoryTree.value[0]
|
||
|
directoryTableData.value = directoryTree.value[0].children || []
|
||
|
await setHtmlContent(currentNode.value)
|
||
|
setTimeout(() => {
|
||
|
setIframeSize()
|
||
|
}, 300)
|
||
|
}
|
||
|
})
|
||
|
|
||
|
const filterText = ref(undefined)
|
||
|
const treeRef = ref(null)
|
||
|
watch(filterText, (val) => {
|
||
|
treeRef.value.filter(val)
|
||
|
})
|
||
|
|
||
|
const filterNode = (value, data) => {
|
||
|
if (!value) {
|
||
|
return true
|
||
|
}
|
||
|
if (data.contentName) {
|
||
|
return data.contentName.includes(value)
|
||
|
}
|
||
|
if (data.dataAstCnName) {
|
||
|
return data.dataAstCnName.includes(value)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// 是否根目录
|
||
|
const isRoot = (data) => {
|
||
|
return data.contentOnum === 1
|
||
|
}
|
||
|
|
||
|
// 是否我的收藏目录
|
||
|
const isCollectionDirectory = (data) => {
|
||
|
return data.contentName === '我的收藏'
|
||
|
}
|
||
|
|
||
|
// 是否收藏的目录
|
||
|
const isCollection = (data) => {
|
||
|
return false
|
||
|
}
|
||
|
|
||
|
// 是否已收藏的
|
||
|
const isCollected = (data) => {
|
||
|
return data.bookmarkFlag === 1
|
||
|
}
|
||
|
|
||
|
// 是否子目录
|
||
|
const isDirectory = (data) => {
|
||
|
return data.contentOnum && !isRoot(data) && !data.astOnum
|
||
|
}
|
||
|
|
||
|
// 是否资产
|
||
|
const isAsset = (data) => {
|
||
|
return data.astOnum
|
||
|
}
|
||
|
|
||
|
const activeName = ref('1')
|
||
|
const handleNodeClick = async (data) => {
|
||
|
if (isCollectionDirectory(data)) {
|
||
|
return
|
||
|
}
|
||
|
activeName.value = '1'
|
||
|
currentNode.value = {
|
||
|
...data,
|
||
|
}
|
||
|
directoryTableData.value = data.children
|
||
|
if (!data.astOnum) {
|
||
|
await setHtmlContent(data)
|
||
|
setTimeout(() => {
|
||
|
setIframeSize()
|
||
|
}, 300)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
const handleCollect = (data, e) => {
|
||
|
e.stopPropagation()
|
||
|
addDirectoryCollection({
|
||
|
dataAstNo: String(data.dataAstNo),
|
||
|
userId: String(userStore.id),
|
||
|
}).then(() => {
|
||
|
proxy.$modal.msgSuccess('收藏成功')
|
||
|
setDirectoryTree()
|
||
|
})
|
||
|
}
|
||
|
|
||
|
const handleCollectionCancel = (data, e) => {
|
||
|
e.stopPropagation()
|
||
|
cancelDirectoryCollection(data.relaOnum).then(() => {
|
||
|
proxy.$modal.msgSuccess('取消成功')
|
||
|
setDirectoryTree()
|
||
|
})
|
||
|
}
|
||
|
|
||
|
const formDialogRef = ref(null)
|
||
|
const handleAddDialogOpen = (data) => {
|
||
|
formDialogRef.value.title = '新增目录'
|
||
|
formDialogRef.value.openDialog({
|
||
|
suprContentOnum: data.contentOnum,
|
||
|
})
|
||
|
}
|
||
|
|
||
|
const handleEditDialogOpen = (data) => {
|
||
|
formDialogRef.value.title = '修改目录'
|
||
|
formDialogRef.value.openDialog(data)
|
||
|
}
|
||
|
|
||
|
const handleDelete = (data) => {
|
||
|
ElMessageBox.confirm(
|
||
|
`确定删除 ${data.contentName} 目录及其资产关系吗?`,
|
||
|
'目录删除',
|
||
|
{
|
||
|
confirmButtonText: '确定',
|
||
|
cancelButtonText: '取消',
|
||
|
type: 'warning',
|
||
|
}
|
||
|
).then(() => {
|
||
|
delDirectory(data.contentOnum).then(() => {
|
||
|
proxy.$modal.msgSuccess('删除成功')
|
||
|
setDirectoryTree()
|
||
|
})
|
||
|
})
|
||
|
}
|
||
|
|
||
|
const moveDialogRef = ref(null)
|
||
|
const handleMoveDialogOpen = (data) => {
|
||
|
moveDialogRef.value.title = '移动目录'
|
||
|
moveDialogRef.value.openDialog(data)
|
||
|
}
|
||
|
|
||
|
const mergerDialogRef = ref(null)
|
||
|
const handleMergerDialogOpen = (data) => {
|
||
|
mergerDialogRef.value.title = '合并目录'
|
||
|
mergerDialogRef.value.openDialog(data)
|
||
|
}
|
||
|
|
||
|
const handleAssetDelete = (data) => {
|
||
|
ElMessageBox.confirm(`确定删除 ${data.dataAstCnName} 资产吗?`, '资产删除', {
|
||
|
confirmButtonText: '确定',
|
||
|
cancelButtonText: '取消',
|
||
|
type: 'warning',
|
||
|
}).then(() => {
|
||
|
delDirectoryAsset({
|
||
|
...data,
|
||
|
relaStatus: '0', // 0-删除,1-正常
|
||
|
}).then(() => {
|
||
|
proxy.$modal.msgSuccess('删除成功')
|
||
|
setDirectoryTree()
|
||
|
})
|
||
|
})
|
||
|
}
|
||
|
|
||
|
const assetMoveDialogRef = ref(null)
|
||
|
const handleAssetMoveDialogOpen = (data) => {
|
||
|
assetMoveDialogRef.value.title = '移动资产'
|
||
|
assetMoveDialogRef.value.openDialog(data)
|
||
|
}
|
||
|
|
||
|
const handleCommand = (command, data) => {
|
||
|
const strategy = {
|
||
|
handleAddDialogOpen: handleAddDialogOpen,
|
||
|
handleEditDialogOpen: handleEditDialogOpen,
|
||
|
handleDelete: handleDelete,
|
||
|
handleMoveDialogOpen: handleMoveDialogOpen,
|
||
|
handleMergerDialogOpen: handleMergerDialogOpen,
|
||
|
handleAssetDelete: handleAssetDelete,
|
||
|
handleAssetMoveDialogOpen: handleAssetMoveDialogOpen,
|
||
|
}
|
||
|
strategy[command](data)
|
||
|
}
|
||
|
|
||
|
const faq = `1、常见问题1\n2、常见问题2\n3、常见问题3`
|
||
|
|
||
|
const iframeStyle = ref({
|
||
|
width: '100%',
|
||
|
height: '100%',
|
||
|
})
|
||
|
const iframe = ref(null)
|
||
|
const setIframeSize = () => {
|
||
|
const content =
|
||
|
iframe.value.contentDocument || iframe.value.contentWindow.document
|
||
|
const width = Math.max(
|
||
|
content.body.scrollWidth,
|
||
|
content.documentElement.scrollWidth,
|
||
|
content.body.offsetWidth,
|
||
|
content.documentElement.offsetWidth,
|
||
|
content.body.clientWidth,
|
||
|
content.documentElement.clientWidth
|
||
|
)
|
||
|
const height = Math.max(
|
||
|
content.body.scrollHeight,
|
||
|
content.documentElement.scrollHeight,
|
||
|
content.body.offsetHeight,
|
||
|
content.documentElement.offsetHeight,
|
||
|
content.body.clientHeight,
|
||
|
content.documentElement.clientHeight
|
||
|
)
|
||
|
console.log('width', width)
|
||
|
console.log('height', height)
|
||
|
iframeStyle.value = {
|
||
|
width: `${width}px`,
|
||
|
height: `${height}px`,
|
||
|
}
|
||
|
}
|
||
|
</script>
|
||
|
|
||
|
<style lang="scss" scoped>
|
||
|
.tree-box {
|
||
|
overflow: auto;
|
||
|
}
|
||
|
.tree {
|
||
|
margin-top: 10px;
|
||
|
min-width: 260px;
|
||
|
}
|
||
|
.custom-tree-node {
|
||
|
flex: 1;
|
||
|
display: flex;
|
||
|
align-items: center;
|
||
|
justify-content: space-between;
|
||
|
.tree-node__action {
|
||
|
padding: 0 8px;
|
||
|
display: flex;
|
||
|
justify-content: flex-end;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
:deep(
|
||
|
.el-descriptions__body
|
||
|
.el-descriptions__table.is-bordered
|
||
|
.el-descriptions__cell
|
||
|
) {
|
||
|
width: 80px !important;
|
||
|
}
|
||
|
|
||
|
.faq {
|
||
|
white-space: pre-wrap;
|
||
|
}
|
||
|
|
||
|
.html-box {
|
||
|
:deep(.el-card__body) {
|
||
|
overflow: auto;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
iframe {
|
||
|
border: none;
|
||
|
}
|
||
|
</style>
|