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

<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>