7 changed files with 1784 additions and 0 deletions
@ -0,0 +1,110 @@ |
|||||
|
import request from '@/utils/request' |
||||
|
|
||||
|
export function getDirectoryTree(params) { |
||||
|
return request({ |
||||
|
url: '/default-api/system/data_catalog/list', |
||||
|
method: 'get', |
||||
|
params, |
||||
|
}) |
||||
|
} |
||||
|
|
||||
|
export function getDirectory(id) { |
||||
|
return request({ |
||||
|
url: `/default-api/system/data_catalog/${id}`, |
||||
|
method: 'get', |
||||
|
}) |
||||
|
} |
||||
|
|
||||
|
export function addDirectory(data) { |
||||
|
return request({ |
||||
|
url: '/default-api/system/data_catalog', |
||||
|
method: 'post', |
||||
|
data, |
||||
|
}) |
||||
|
} |
||||
|
|
||||
|
export function updateDirectory(data) { |
||||
|
return request({ |
||||
|
url: `/default-api/system/data_catalog/edit`, |
||||
|
method: 'put', |
||||
|
data, |
||||
|
}) |
||||
|
} |
||||
|
|
||||
|
export function delDirectory(id) { |
||||
|
return request({ |
||||
|
url: `/default-api/system/data_catalog/${id}`, |
||||
|
method: 'delete', |
||||
|
}) |
||||
|
} |
||||
|
|
||||
|
export function addDirectoryCollection(data) { |
||||
|
return request({ |
||||
|
url: '/default-api/system/data_catalog/bookmark ', |
||||
|
method: 'post', |
||||
|
data, |
||||
|
}) |
||||
|
} |
||||
|
|
||||
|
export function cancelDirectoryCollection(id) { |
||||
|
return request({ |
||||
|
url: `/default-api/system/data_catalog/bookmark/${id}`, |
||||
|
method: 'delete', |
||||
|
}) |
||||
|
} |
||||
|
|
||||
|
export function delDirectoryCollection(data) { |
||||
|
return request({ |
||||
|
url: '/default-api/system/delete_data_asset_collection', |
||||
|
method: 'delete', |
||||
|
data, |
||||
|
}) |
||||
|
} |
||||
|
|
||||
|
export function moveDirectory(data) { |
||||
|
return request({ |
||||
|
url: '/default-api/system/data_catalog/moved', |
||||
|
method: 'put', |
||||
|
data, |
||||
|
}) |
||||
|
} |
||||
|
|
||||
|
export function mergeDirectory(data) { |
||||
|
return request({ |
||||
|
url: '/default-api/system/data_catalog/merge', |
||||
|
method: 'put', |
||||
|
data, |
||||
|
}) |
||||
|
} |
||||
|
|
||||
|
export function delDirectoryAsset(data) { |
||||
|
return request({ |
||||
|
url: '/default-api/system/data_catalog/removerel', |
||||
|
method: 'put', |
||||
|
data, |
||||
|
}) |
||||
|
} |
||||
|
|
||||
|
export function moveDirectoryAsset(data) { |
||||
|
return request({ |
||||
|
url: '/default-api/system/data_catalog/moverel', |
||||
|
method: 'put', |
||||
|
data, |
||||
|
}) |
||||
|
} |
||||
|
|
||||
|
export function getDirectoryAsset(params) { |
||||
|
return request({ |
||||
|
url: '/default-api/system/data_catalog/atree', |
||||
|
method: 'get', |
||||
|
params, |
||||
|
}) |
||||
|
} |
||||
|
|
||||
|
export function getHtmlString(params) { |
||||
|
return request({ |
||||
|
url: '/default-api/system/data_catalog/indx/list', |
||||
|
method: 'get', |
||||
|
params, |
||||
|
}) |
||||
|
} |
@ -0,0 +1,336 @@ |
|||||
|
<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> |
||||
|
<el-tree |
||||
|
style="margin-top: 10px" |
||||
|
ref="treeRef" |
||||
|
node-key="id" |
||||
|
:default-expand-all="true" |
||||
|
:highlight-current="true" |
||||
|
:expand-on-click-node="false" |
||||
|
:data="treeData" |
||||
|
:props="defaultProps" |
||||
|
:filter-node-method="filterNode" |
||||
|
:current-node-key="currentNode.id" |
||||
|
@node-click="handleNodeClick" |
||||
|
> |
||||
|
<template #default="{ node, data }"> |
||||
|
<el-space :size="2"> |
||||
|
<el-icon v-if="!data.isLeaf"><Folder /></el-icon> |
||||
|
<el-icon v-else><Document /></el-icon> |
||||
|
<span>{{ node.label }}</span> |
||||
|
</el-space> |
||||
|
</template> |
||||
|
</el-tree> |
||||
|
</el-card> |
||||
|
</el-col> |
||||
|
<el-col :span="19"> |
||||
|
<el-form |
||||
|
:model="queryParams" |
||||
|
ref="queryRef" |
||||
|
:inline="true" |
||||
|
v-show="showSearch" |
||||
|
label-width="68px" |
||||
|
> |
||||
|
<el-form-item label="名称"> |
||||
|
<el-input |
||||
|
v-model="queryParams.name" |
||||
|
placeholder="请输入名称" |
||||
|
clearable |
||||
|
style="width: 240px" |
||||
|
@keyup.enter="handleQuery" |
||||
|
/> |
||||
|
</el-form-item> |
||||
|
<el-form-item label="类型"> |
||||
|
<el-input |
||||
|
v-model="queryParams.name" |
||||
|
placeholder="请输入类型" |
||||
|
clearable |
||||
|
style="width: 240px" |
||||
|
@keyup.enter="handleQuery" |
||||
|
/> |
||||
|
</el-form-item> |
||||
|
<el-form-item label="标签"> |
||||
|
<el-input |
||||
|
v-model="queryParams.name" |
||||
|
placeholder="请输入标签" |
||||
|
clearable |
||||
|
style="width: 240px" |
||||
|
@keyup.enter="handleQuery" |
||||
|
/> |
||||
|
</el-form-item> |
||||
|
<el-form-item> |
||||
|
<el-button type="primary" icon="Search" @click="handleQuery" |
||||
|
>搜索</el-button |
||||
|
> |
||||
|
<el-button icon="Refresh" @click="resetQuery">重置</el-button> |
||||
|
</el-form-item> |
||||
|
</el-form> |
||||
|
<el-row :gutter="10" class="mb8"> |
||||
|
<el-col :span="1.5"> |
||||
|
<el-button |
||||
|
type="primary" |
||||
|
plain |
||||
|
icon="Plus" |
||||
|
@click="handleAdd" |
||||
|
v-hasPermi="['dataAsset:assetDetail:add']" |
||||
|
>新增</el-button |
||||
|
> |
||||
|
</el-col> |
||||
|
<el-col :span="1.5"> |
||||
|
<el-button |
||||
|
type="success" |
||||
|
plain |
||||
|
icon="Edit" |
||||
|
:disabled="single" |
||||
|
@click="handleUpdate" |
||||
|
v-hasPermi="['dataAsset:assetDetail:edit']" |
||||
|
>修改</el-button |
||||
|
> |
||||
|
</el-col> |
||||
|
<el-col :span="1.5"> |
||||
|
<el-button |
||||
|
type="danger" |
||||
|
plain |
||||
|
icon="Delete" |
||||
|
:disabled="multiple" |
||||
|
@click="handleDelete" |
||||
|
v-hasPermi="['dataAsset:assetDetail:remove']" |
||||
|
>删除</el-button |
||||
|
> |
||||
|
</el-col> |
||||
|
<el-col :span="1.5"> |
||||
|
<el-button |
||||
|
type="warning" |
||||
|
plain |
||||
|
icon="Download" |
||||
|
@click="handleExport" |
||||
|
v-hasPermi="['dataAsset:assetDetail:export']" |
||||
|
>导出</el-button |
||||
|
> |
||||
|
</el-col> |
||||
|
<right-toolbar |
||||
|
v-model:showSearch="showSearch" |
||||
|
@queryTable="getList" |
||||
|
:columns="columns" |
||||
|
></right-toolbar> |
||||
|
</el-row> |
||||
|
|
||||
|
<el-table |
||||
|
v-loading="loading" |
||||
|
:data="list" |
||||
|
@selection-change="handleSelectionChange" |
||||
|
> |
||||
|
<el-table-column type="selection" width="50" align="center" /> |
||||
|
<el-table-column |
||||
|
label="编号" |
||||
|
align="center" |
||||
|
key="" |
||||
|
prop="" |
||||
|
v-if="columns[0].visible" |
||||
|
/> |
||||
|
<el-table-column |
||||
|
label="来源系统" |
||||
|
align="center" |
||||
|
key="" |
||||
|
prop="" |
||||
|
v-if="columns[1].visible" |
||||
|
/> |
||||
|
<el-table-column |
||||
|
label="英文名称" |
||||
|
align="center" |
||||
|
key="" |
||||
|
prop="" |
||||
|
v-if="columns[2].visible" |
||||
|
/> |
||||
|
<el-table-column |
||||
|
label="中文名称" |
||||
|
align="center" |
||||
|
key="" |
||||
|
prop="" |
||||
|
v-if="columns[3].visible" |
||||
|
/> |
||||
|
<el-table-column |
||||
|
label="类型" |
||||
|
align="center" |
||||
|
key="" |
||||
|
prop="" |
||||
|
v-if="columns[4].visible" |
||||
|
/> |
||||
|
<el-table-column |
||||
|
label="描述" |
||||
|
align="center" |
||||
|
key="" |
||||
|
prop="" |
||||
|
v-if="columns[5].visible" |
||||
|
/> |
||||
|
<el-table-column |
||||
|
label="标签" |
||||
|
align="center" |
||||
|
key="" |
||||
|
prop="" |
||||
|
v-if="columns[6].visible" |
||||
|
/> |
||||
|
<el-table-column |
||||
|
label="负责人" |
||||
|
align="center" |
||||
|
key="" |
||||
|
prop="" |
||||
|
v-if="columns[7].visible" |
||||
|
/> |
||||
|
<el-table-column |
||||
|
label="建立时间" |
||||
|
align="center" |
||||
|
key="" |
||||
|
prop="" |
||||
|
v-if="columns[8].visible" |
||||
|
/> |
||||
|
<el-table-column |
||||
|
label="更新时间" |
||||
|
align="center" |
||||
|
key="" |
||||
|
prop="" |
||||
|
v-if="columns[9].visible" |
||||
|
/> |
||||
|
<el-table-column |
||||
|
label="操作" |
||||
|
align="center" |
||||
|
width="100" |
||||
|
class-name="small-padding fixed-width" |
||||
|
> |
||||
|
<template #default="scope"> |
||||
|
<el-tooltip content="修改" placement="top"> |
||||
|
<el-button |
||||
|
link |
||||
|
type="primary" |
||||
|
icon="Edit" |
||||
|
@click="handleUpdate(scope.row)" |
||||
|
v-hasPermi="['dataAsset:assetDetail:edit']" |
||||
|
></el-button> |
||||
|
</el-tooltip> |
||||
|
<el-tooltip content="删除" placement="top"> |
||||
|
<el-button |
||||
|
link |
||||
|
type="primary" |
||||
|
icon="Delete" |
||||
|
@click="handleDelete(scope.row)" |
||||
|
v-hasPermi="['dataAsset:assetDetail:remove']" |
||||
|
></el-button> |
||||
|
</el-tooltip> |
||||
|
</template> |
||||
|
</el-table-column> |
||||
|
</el-table> |
||||
|
<pagination |
||||
|
v-show="total > 0" |
||||
|
:total="total" |
||||
|
v-model:page="queryParams.pageNum" |
||||
|
v-model:limit="queryParams.pageSize" |
||||
|
@pagination="getList" |
||||
|
/> |
||||
|
</el-col> |
||||
|
</el-row> |
||||
|
</div> |
||||
|
</template> |
||||
|
|
||||
|
<script setup name="AssetDetail"> |
||||
|
const { proxy } = getCurrentInstance() |
||||
|
const defaultProps = { |
||||
|
children: 'children', |
||||
|
label: 'name', |
||||
|
} |
||||
|
const currentNode = ref({}) |
||||
|
const treeData = ref([ |
||||
|
{ |
||||
|
catalogId: '-1', |
||||
|
name: '系统', |
||||
|
isLeaf: 0, |
||||
|
children: [ |
||||
|
{ |
||||
|
parentId: '-1', |
||||
|
id: '1', |
||||
|
name: 'wind', |
||||
|
isLeaf: 1, |
||||
|
}, |
||||
|
{ |
||||
|
parentId: '-1', |
||||
|
id: '2', |
||||
|
name: 'O32', |
||||
|
isLeaf: 1, |
||||
|
}, |
||||
|
], |
||||
|
}, |
||||
|
]) |
||||
|
|
||||
|
const handleNodeClick = (data) => { |
||||
|
currentNode.value = data |
||||
|
} |
||||
|
|
||||
|
const filterText = ref(undefined) |
||||
|
const treeRef = ref(null) |
||||
|
watch(filterText, (val) => { |
||||
|
treeRef.value.filter(val) |
||||
|
}) |
||||
|
|
||||
|
const filterNode = (value, data) => { |
||||
|
if (!value) { |
||||
|
return true |
||||
|
} |
||||
|
return data.catalogName.includes(value) |
||||
|
} |
||||
|
|
||||
|
const columns = ref([ |
||||
|
{ key: 0, label: `编号`, visible: true }, |
||||
|
{ key: 1, label: `来源系统`, visible: true }, |
||||
|
{ key: 2, label: `英文名称`, visible: true }, |
||||
|
{ key: 3, label: `中文名称`, visible: true }, |
||||
|
{ key: 4, label: `类型`, visible: true }, |
||||
|
{ key: 5, label: `描述`, visible: true }, |
||||
|
{ key: 6, label: `标签`, visible: true }, |
||||
|
{ key: 7, label: `负责人`, visible: true }, |
||||
|
{ key: 8, label: `建立时间`, visible: true }, |
||||
|
{ key: 9, label: `更新时间`, visible: true }, |
||||
|
]) |
||||
|
const loading = ref(false) |
||||
|
const list = ref([]) |
||||
|
const total = ref(0) |
||||
|
const showSearch = ref(true) |
||||
|
const queryParams = ref({ |
||||
|
pageNum: 1, |
||||
|
pageSize: 10, |
||||
|
name: undefined, |
||||
|
}) |
||||
|
const getList = () => {} |
||||
|
const handleQuery = () => { |
||||
|
queryParams.value.pageNum = 1 |
||||
|
getList() |
||||
|
} |
||||
|
const resetQuery = () => { |
||||
|
proxy.resetForm('queryRef') |
||||
|
handleQuery() |
||||
|
} |
||||
|
|
||||
|
const handleAdd = () => {} |
||||
|
const handleUpdate = (row) => {} |
||||
|
const handleDelete = (row) => {} |
||||
|
const handleExport = () => {} |
||||
|
|
||||
|
const ids = ref([]) |
||||
|
const single = ref(true) |
||||
|
const multiple = ref(true) |
||||
|
const handleSelectionChange = (selection) => { |
||||
|
ids.value = selection.map((item) => item.userId) |
||||
|
single.value = selection.length != 1 |
||||
|
multiple.value = !selection.length |
||||
|
} |
||||
|
</script> |
@ -0,0 +1,171 @@ |
|||||
|
<template> |
||||
|
<el-dialog width="800px" append-to-body :title="title" v-model="open"> |
||||
|
<el-form label-width="100px" ref="formRef" :model="form" :rules="rules"> |
||||
|
<el-row :gutter="16"> |
||||
|
<el-col :span="11"> |
||||
|
<el-form-item label="当前资产" prop="dataAstCnName"> |
||||
|
<el-input :disabled="true" v-model="form.dataAstCnName" /> |
||||
|
</el-form-item> |
||||
|
<el-form-item label="当前资产简介" prop="dataAstDesc"> |
||||
|
<el-input |
||||
|
placeholder="自动带入" |
||||
|
type="textarea" |
||||
|
:disabled="true" |
||||
|
:rows="8" |
||||
|
v-model="form.dataAstDesc" |
||||
|
/> |
||||
|
</el-form-item> |
||||
|
</el-col> |
||||
|
<el-col :span="2"> |
||||
|
<div class="arrow"> |
||||
|
<span>········</span> |
||||
|
<el-icon><Right /></el-icon> |
||||
|
</div> |
||||
|
</el-col> |
||||
|
<el-col :span="11"> |
||||
|
<el-form-item label="目标目录" prop="contentOnumAfter"> |
||||
|
<el-tree-select |
||||
|
check-strictly |
||||
|
value-key="contentOnum" |
||||
|
placeholder="选择目标目录" |
||||
|
:default-expand-all="true" |
||||
|
:disabled="disabled" |
||||
|
:clearable="true" |
||||
|
:data="localDirectoryTree" |
||||
|
:props="{ |
||||
|
value: 'contentOnum', |
||||
|
label: 'contentName', |
||||
|
children: 'children', |
||||
|
}" |
||||
|
v-model="form.contentOnumAfter" |
||||
|
@node-click="handleTargetCatalogNodeClick" |
||||
|
/> |
||||
|
</el-form-item> |
||||
|
<el-form-item label="目标目录简介" prop="contentIntrAfter"> |
||||
|
<el-input |
||||
|
placeholder="自动带入" |
||||
|
type="textarea" |
||||
|
:disabled="true" |
||||
|
:rows="8" |
||||
|
v-model="form.contentIntrAfter" |
||||
|
/> |
||||
|
</el-form-item> |
||||
|
</el-col> |
||||
|
</el-row> |
||||
|
</el-form> |
||||
|
<template #footer> |
||||
|
<div class="dialog-footer"> |
||||
|
<el-button @click="cancel">取消</el-button> |
||||
|
<el-button type="primary" :disabled="disabled" @click="submitForm" |
||||
|
>确定</el-button |
||||
|
> |
||||
|
</div> |
||||
|
</template> |
||||
|
</el-dialog> |
||||
|
</template> |
||||
|
|
||||
|
<script setup> |
||||
|
import { nextTick } from 'vue' |
||||
|
import { moveDirectoryAsset } from '@/api/dataAsset/directory' |
||||
|
|
||||
|
const props = defineProps({ |
||||
|
directoryTree: { |
||||
|
type: Array, |
||||
|
required: true, |
||||
|
}, |
||||
|
}) |
||||
|
|
||||
|
const filterTree = (tree, conditionFn) => { |
||||
|
return tree |
||||
|
.map((node) => { |
||||
|
// 递归处理每个节点的子节点 |
||||
|
const filteredChildren = node.children |
||||
|
? filterTree(node.children, conditionFn) |
||||
|
: [] |
||||
|
// 根据条件判断是否保留当前节点 |
||||
|
if (conditionFn(node)) { |
||||
|
// 返回新的节点结构,保留符合条件的子节点 |
||||
|
return { |
||||
|
...node, |
||||
|
children: filteredChildren, |
||||
|
} |
||||
|
} |
||||
|
// 如果不符合条件,返回 null,不加入到最终结果中 |
||||
|
return null |
||||
|
}) |
||||
|
.filter(Boolean) // 移除值为 null 的项 |
||||
|
} |
||||
|
|
||||
|
const localDirectoryTree = computed(() => { |
||||
|
const tree = props.directoryTree |
||||
|
return filterTree(tree, (node) => node.contentOnum && !node.astOnum) // 过滤资产子节点 |
||||
|
}) |
||||
|
|
||||
|
const title = ref('') |
||||
|
const open = ref(false) |
||||
|
const disabled = ref(false) |
||||
|
const { proxy } = getCurrentInstance() |
||||
|
const form = ref({}) |
||||
|
const rules = ref({ |
||||
|
targetContentOnum: [ |
||||
|
{ required: true, message: '目标目录不能为空', trigger: 'blur' }, |
||||
|
], |
||||
|
}) |
||||
|
|
||||
|
const formRef = ref(null) |
||||
|
const openDialog = (row) => { |
||||
|
open.value = true |
||||
|
form.value = { |
||||
|
relaOnum: undefined, |
||||
|
contentOnum: undefined, |
||||
|
contentOnumAfter: undefined, |
||||
|
} |
||||
|
if (row.relaOnum) { |
||||
|
form.value = { |
||||
|
...form.value, |
||||
|
...row, |
||||
|
} |
||||
|
} |
||||
|
nextTick(() => { |
||||
|
formRef.value.clearValidate() |
||||
|
}) |
||||
|
} |
||||
|
|
||||
|
const handleTargetCatalogNodeClick = (data) => { |
||||
|
form.value = { |
||||
|
...form.value, |
||||
|
contentIntrAfter: data.contentIntr, |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
const emit = defineEmits(['onSuccess']) |
||||
|
const submitForm = () => { |
||||
|
formRef.value.validate((valid) => { |
||||
|
if (valid) { |
||||
|
moveDirectoryAsset(form.value).then((response) => { |
||||
|
proxy.$modal.msgSuccess('移动成功') |
||||
|
open.value = false |
||||
|
emit('onSuccess') |
||||
|
}) |
||||
|
} |
||||
|
}) |
||||
|
} |
||||
|
|
||||
|
const cancel = () => { |
||||
|
open.value = false |
||||
|
} |
||||
|
|
||||
|
defineExpose({ title, disabled, openDialog }) |
||||
|
</script> |
||||
|
|
||||
|
<style lang="scss" scoped> |
||||
|
.arrow { |
||||
|
display: flex; |
||||
|
font-size: 18px; |
||||
|
text-align: center; |
||||
|
margin: 8px auto; |
||||
|
span { |
||||
|
line-height: 18px; |
||||
|
} |
||||
|
} |
||||
|
</style> |
@ -0,0 +1,227 @@ |
|||||
|
<template> |
||||
|
<el-dialog width="600px" append-to-body :title="title" v-model="open"> |
||||
|
<el-form label-width="100px" ref="formRef" :model="form" :rules="rules"> |
||||
|
<el-form-item label="目录名称" prop="contentName"> |
||||
|
<el-input |
||||
|
placeholder="请输入目录名称" |
||||
|
:disabled="disabled" |
||||
|
v-model="form.contentName" |
||||
|
/> |
||||
|
</el-form-item> |
||||
|
<el-form-item label="上级目录" prop="suprContentOnum"> |
||||
|
<el-tree-select |
||||
|
check-strictly |
||||
|
value-key="contentOnum" |
||||
|
placeholder="请选择上级目录" |
||||
|
:default-expand-all="true" |
||||
|
:disabled="disabled" |
||||
|
:clearable="true" |
||||
|
:data="localDirectoryTree" |
||||
|
:props="{ |
||||
|
value: 'contentOnum', |
||||
|
label: 'contentName', |
||||
|
children: 'children', |
||||
|
}" |
||||
|
v-model="form.suprContentOnum" |
||||
|
> |
||||
|
</el-tree-select> |
||||
|
</el-form-item> |
||||
|
<el-form-item label="负责人" prop="contentPic"> |
||||
|
<el-input |
||||
|
placeholder="请输入负责人" |
||||
|
:disabled="disabled" |
||||
|
v-model="form.contentPic" |
||||
|
/> |
||||
|
</el-form-item> |
||||
|
<el-form-item label="关联资产" prop="assets"> |
||||
|
<el-tree-select |
||||
|
filterable |
||||
|
multiple |
||||
|
show-checkbox |
||||
|
value-key="id" |
||||
|
placeholder="请选择关联资产" |
||||
|
:default-expand-all="true" |
||||
|
:render-after-expand="false" |
||||
|
:disabled="disabled" |
||||
|
:clearable="true" |
||||
|
:data="assetTree" |
||||
|
:props="{ |
||||
|
value: 'id', |
||||
|
label: 'dataAssetCatalogName', |
||||
|
children: 'children', |
||||
|
}" |
||||
|
v-model="form.assets" |
||||
|
> |
||||
|
<template #default="{ data }"> |
||||
|
<div class="custom-tree-node"> |
||||
|
<span>{{ |
||||
|
data.dataAssetCatalogName || data.dataAssetSysName |
||||
|
}}</span> |
||||
|
</div> |
||||
|
</template> |
||||
|
</el-tree-select> |
||||
|
</el-form-item> |
||||
|
<el-form-item label="目录简介" prop="contentIntr"> |
||||
|
<el-input |
||||
|
placeholder="请输入目录简介" |
||||
|
type="textarea" |
||||
|
:disabled="disabled" |
||||
|
:rows="8" |
||||
|
v-model="form.contentIntr" |
||||
|
/> |
||||
|
</el-form-item> |
||||
|
</el-form> |
||||
|
<template #footer> |
||||
|
<div class="dialog-footer"> |
||||
|
<el-button @click="cancel">取消</el-button> |
||||
|
<el-button type="primary" :disabled="disabled" @click="submitForm" |
||||
|
>确定</el-button |
||||
|
> |
||||
|
</div> |
||||
|
</template> |
||||
|
</el-dialog> |
||||
|
</template> |
||||
|
|
||||
|
<script setup> |
||||
|
import { computed, nextTick } from 'vue' |
||||
|
import { |
||||
|
getDirectory, |
||||
|
addDirectory, |
||||
|
updateDirectory, |
||||
|
getDirectoryAsset, |
||||
|
} from '@/api/dataAsset/directory' |
||||
|
|
||||
|
const props = defineProps({ |
||||
|
directoryTree: { |
||||
|
type: Array, |
||||
|
required: true, |
||||
|
}, |
||||
|
}) |
||||
|
|
||||
|
const filterTree = (tree, conditionFn) => { |
||||
|
return tree |
||||
|
.map((node) => { |
||||
|
// 递归处理每个节点的子节点 |
||||
|
const filteredChildren = node.children |
||||
|
? filterTree(node.children, conditionFn) |
||||
|
: [] |
||||
|
// 根据条件判断是否保留当前节点 |
||||
|
if (conditionFn(node)) { |
||||
|
// 返回新的节点结构,保留符合条件的子节点 |
||||
|
return { |
||||
|
...node, |
||||
|
children: filteredChildren, |
||||
|
} |
||||
|
} |
||||
|
// 如果不符合条件,返回 null,不加入到最终结果中 |
||||
|
return null |
||||
|
}) |
||||
|
.filter(Boolean) // 移除值为 null 的项 |
||||
|
} |
||||
|
|
||||
|
const localDirectoryTree = computed(() => { |
||||
|
const tree = props.directoryTree |
||||
|
return filterTree(tree, (node) => node.contentOnum && !node.astOnum) // 过滤资产子节点 |
||||
|
}) |
||||
|
|
||||
|
const title = ref('') |
||||
|
const open = ref(false) |
||||
|
const disabled = ref(false) |
||||
|
const { proxy } = getCurrentInstance() |
||||
|
const form = ref({}) |
||||
|
const rules = ref({ |
||||
|
contentName: [ |
||||
|
{ required: true, message: '目录名称不能为空', trigger: 'blur' }, |
||||
|
], |
||||
|
suprContentOnum: [ |
||||
|
{ required: true, message: '上级目录不能为空', trigger: 'blur' }, |
||||
|
], |
||||
|
}) |
||||
|
|
||||
|
const formRef = ref(null) |
||||
|
const openDialog = (row) => { |
||||
|
open.value = true |
||||
|
setAssetTree() |
||||
|
form.value = { |
||||
|
contentName: undefined, |
||||
|
suprContentOnum: undefined, |
||||
|
contentPic: undefined, |
||||
|
contentStat: '1', // 0-废弃,1-有效,2-停用 |
||||
|
contentIntr: undefined, |
||||
|
children: [], |
||||
|
} |
||||
|
if (row.contentOnum || row.suprContentOnum) { |
||||
|
form.value = { |
||||
|
...form.value, |
||||
|
...row, |
||||
|
assets: |
||||
|
row.children && |
||||
|
row.children.length && |
||||
|
row.children.find((i) => i.astOnum) |
||||
|
? [...row.children].map((i) => i.astOnum) |
||||
|
: [], // 新增冗余字段来暂存资产编号 |
||||
|
} |
||||
|
} |
||||
|
nextTick(() => { |
||||
|
formRef.value.clearValidate() |
||||
|
}) |
||||
|
} |
||||
|
|
||||
|
const addTreeNodeId = (tree) => { |
||||
|
return tree.map((node, index) => { |
||||
|
return { |
||||
|
...node, |
||||
|
id: node.dataAssetCatalogAstno || index, |
||||
|
children: |
||||
|
node.children && node.children.length |
||||
|
? addTreeNodeId(node.children) |
||||
|
: [], |
||||
|
} |
||||
|
}) |
||||
|
} |
||||
|
|
||||
|
const assetTree = ref([]) |
||||
|
const setAssetTree = () => { |
||||
|
getDirectoryAsset().then(({ data }) => { |
||||
|
assetTree.value = addTreeNodeId(data) |
||||
|
}) |
||||
|
} |
||||
|
|
||||
|
const emit = defineEmits(['onSuccess']) |
||||
|
const submitForm = () => { |
||||
|
formRef.value.validate((valid) => { |
||||
|
if (valid) { |
||||
|
const children = form.value.assets.reduce((arr, cur) => { |
||||
|
const item = form.value.children.find((i) => i.astOnum === cur) |
||||
|
if (!item) { |
||||
|
arr.push({ |
||||
|
contentOnum: form.value.contentOnum, |
||||
|
astOnum: cur, |
||||
|
}) |
||||
|
} else { |
||||
|
arr.push(item) |
||||
|
} |
||||
|
return arr |
||||
|
}, []) |
||||
|
form.value = { |
||||
|
...form.value, |
||||
|
children, |
||||
|
} |
||||
|
const request = form.value.contentOnum ? updateDirectory : addDirectory |
||||
|
request(form.value).then((response) => { |
||||
|
proxy.$modal.msgSuccess( |
||||
|
form.value.contentOnum ? '修改成功' : '新增成功' |
||||
|
) |
||||
|
open.value = false |
||||
|
emit('onSuccess') |
||||
|
}) |
||||
|
} |
||||
|
}) |
||||
|
} |
||||
|
|
||||
|
const cancel = () => { |
||||
|
open.value = false |
||||
|
} |
||||
|
|
||||
|
defineExpose({ title, disabled, openDialog }) |
||||
|
</script> |
@ -0,0 +1,175 @@ |
|||||
|
<template> |
||||
|
<el-dialog width="800px" append-to-body :title="title" v-model="open"> |
||||
|
<el-form label-width="100px" ref="formRef" :model="form" :rules="rules"> |
||||
|
<el-row :gutter="16"> |
||||
|
<el-col :span="11"> |
||||
|
<el-form-item label="当前目录" prop="contentName"> |
||||
|
<el-input :disabled="true" v-model="form.contentName" /> |
||||
|
</el-form-item> |
||||
|
<el-form-item label="当前目录简介" prop="contentIntr"> |
||||
|
<el-input |
||||
|
placeholder="自动带入" |
||||
|
type="textarea" |
||||
|
:disabled="true" |
||||
|
:rows="8" |
||||
|
v-model="form.contentIntr" |
||||
|
/> |
||||
|
</el-form-item> |
||||
|
</el-col> |
||||
|
<el-col :span="2"> |
||||
|
<div class="arrow"> |
||||
|
<span>········</span> |
||||
|
<el-icon><Right /></el-icon> |
||||
|
</div> |
||||
|
</el-col> |
||||
|
<el-col :span="11"> |
||||
|
<el-form-item label="目标目录" prop="contentOnumAfter"> |
||||
|
<el-tree-select |
||||
|
check-strictly |
||||
|
value-key="contentOnum" |
||||
|
placeholder="选择目标目录" |
||||
|
:default-expand-all="true" |
||||
|
:disabled="disabled" |
||||
|
:clearable="true" |
||||
|
:data="localDirectoryTree" |
||||
|
:props="{ |
||||
|
value: 'contentOnum', |
||||
|
label: 'contentName', |
||||
|
children: 'children', |
||||
|
}" |
||||
|
v-model="form.contentOnumAfter" |
||||
|
@node-click="handleTargetCatalogNodeClick" |
||||
|
/> |
||||
|
</el-form-item> |
||||
|
<el-form-item label="目标目录简介" prop="contentIntrAfter"> |
||||
|
<el-input |
||||
|
placeholder="自动带入" |
||||
|
type="textarea" |
||||
|
:disabled="true" |
||||
|
:rows="8" |
||||
|
v-model="form.contentIntrAfter" |
||||
|
/> |
||||
|
</el-form-item> |
||||
|
</el-col> |
||||
|
</el-row> |
||||
|
</el-form> |
||||
|
<template #footer> |
||||
|
<div class="dialog-footer"> |
||||
|
<el-button @click="cancel">取消</el-button> |
||||
|
<el-button type="primary" :disabled="disabled" @click="submitForm" |
||||
|
>确定</el-button |
||||
|
> |
||||
|
</div> |
||||
|
</template> |
||||
|
</el-dialog> |
||||
|
</template> |
||||
|
|
||||
|
<script setup> |
||||
|
import { nextTick } from 'vue' |
||||
|
import { mergeDirectory } from '@/api/dataAsset/directory' |
||||
|
|
||||
|
const props = defineProps({ |
||||
|
directoryTree: { |
||||
|
type: Array, |
||||
|
required: true, |
||||
|
}, |
||||
|
}) |
||||
|
|
||||
|
const filterTree = (tree, conditionFn) => { |
||||
|
return tree |
||||
|
.map((node) => { |
||||
|
// 递归处理每个节点的子节点 |
||||
|
const filteredChildren = node.children |
||||
|
? filterTree(node.children, conditionFn) |
||||
|
: [] |
||||
|
// 根据条件判断是否保留当前节点 |
||||
|
if (conditionFn(node)) { |
||||
|
// 返回新的节点结构,保留符合条件的子节点 |
||||
|
return { |
||||
|
...node, |
||||
|
children: filteredChildren, |
||||
|
} |
||||
|
} |
||||
|
// 如果不符合条件,返回 null,不加入到最终结果中 |
||||
|
return null |
||||
|
}) |
||||
|
.filter(Boolean) // 移除值为 null 的项 |
||||
|
} |
||||
|
|
||||
|
const localDirectoryTree = computed(() => { |
||||
|
const tree = props.directoryTree |
||||
|
return filterTree(tree, (node) => node.contentOnum && !node.astOnum) // 过滤资产子节点 |
||||
|
}) |
||||
|
|
||||
|
const title = ref('') |
||||
|
const open = ref(false) |
||||
|
const disabled = ref(false) |
||||
|
const { proxy } = getCurrentInstance() |
||||
|
const form = ref({}) |
||||
|
const rules = ref({ |
||||
|
contentOnumAfter: [ |
||||
|
{ required: true, message: '目标目录不能为空', trigger: 'blur' }, |
||||
|
], |
||||
|
}) |
||||
|
|
||||
|
const formRef = ref(null) |
||||
|
const openDialog = (row) => { |
||||
|
open.value = true |
||||
|
form.value = { |
||||
|
contentOnum: undefined, |
||||
|
suprContentOnum: undefined, |
||||
|
contentIntr: undefined, |
||||
|
contentOnumAfter: undefined, |
||||
|
suprContentOnumAfter: undefined, |
||||
|
contentIntrAfter: undefined, |
||||
|
} |
||||
|
if (row.contentOnum) { |
||||
|
form.value = { |
||||
|
...form.value, |
||||
|
...row, |
||||
|
} |
||||
|
} |
||||
|
nextTick(() => { |
||||
|
formRef.value.clearValidate() |
||||
|
}) |
||||
|
} |
||||
|
|
||||
|
const handleTargetCatalogNodeClick = (data) => { |
||||
|
form.value = { |
||||
|
...form.value, |
||||
|
suprContentOnumAfter: data.suprContentOnum, |
||||
|
contentIntrAfter: data.contentIntr, |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
const emit = defineEmits(['onSuccess']) |
||||
|
const submitForm = () => { |
||||
|
formRef.value.validate((valid) => { |
||||
|
if (valid) { |
||||
|
mergeDirectory(form.value).then((response) => { |
||||
|
proxy.$modal.msgSuccess('合并成功') |
||||
|
open.value = false |
||||
|
emit('onSuccess') |
||||
|
}) |
||||
|
} |
||||
|
}) |
||||
|
} |
||||
|
|
||||
|
const cancel = () => { |
||||
|
open.value = false |
||||
|
} |
||||
|
|
||||
|
defineExpose({ title, disabled, openDialog }) |
||||
|
</script> |
||||
|
|
||||
|
<style lang="scss" scoped> |
||||
|
.arrow { |
||||
|
display: flex; |
||||
|
font-size: 18px; |
||||
|
text-align: center; |
||||
|
margin: 8px auto; |
||||
|
span { |
||||
|
line-height: 18px; |
||||
|
} |
||||
|
} |
||||
|
</style> |
@ -0,0 +1,173 @@ |
|||||
|
<template> |
||||
|
<el-dialog width="800px" append-to-body :title="title" v-model="open"> |
||||
|
<el-form label-width="100px" ref="formRef" :model="form" :rules="rules"> |
||||
|
<el-row :gutter="16"> |
||||
|
<el-col :span="11"> |
||||
|
<el-form-item label="当前目录" prop="contentName"> |
||||
|
<el-input :disabled="true" v-model="form.contentName" /> |
||||
|
</el-form-item> |
||||
|
<el-form-item label="当前目录简介" prop="contentIntr"> |
||||
|
<el-input |
||||
|
placeholder="自动带入" |
||||
|
type="textarea" |
||||
|
:disabled="true" |
||||
|
:rows="8" |
||||
|
v-model="form.contentIntr" |
||||
|
/> |
||||
|
</el-form-item> |
||||
|
</el-col> |
||||
|
<el-col :span="2"> |
||||
|
<div class="arrow"> |
||||
|
<span>········</span> |
||||
|
<el-icon><Right /></el-icon> |
||||
|
</div> |
||||
|
</el-col> |
||||
|
<el-col :span="11"> |
||||
|
<el-form-item label="目标目录" prop="suprContentOnumAfter"> |
||||
|
<el-tree-select |
||||
|
check-strictly |
||||
|
value-key="contentOnum" |
||||
|
placeholder="选择目标目录" |
||||
|
:default-expand-all="true" |
||||
|
:disabled="disabled" |
||||
|
:clearable="true" |
||||
|
:data="localDirectoryTree" |
||||
|
:props="{ |
||||
|
value: 'contentOnum', |
||||
|
label: 'contentName', |
||||
|
children: 'children', |
||||
|
}" |
||||
|
v-model="form.suprContentOnumAfter" |
||||
|
@node-click="handleTargetCatalogNodeClick" |
||||
|
/> |
||||
|
</el-form-item> |
||||
|
<el-form-item label="目标目录简介" prop="contentIntrAfter"> |
||||
|
<el-input |
||||
|
placeholder="自动带入" |
||||
|
type="textarea" |
||||
|
:disabled="true" |
||||
|
:rows="8" |
||||
|
v-model="form.contentIntrAfter" |
||||
|
/> |
||||
|
</el-form-item> |
||||
|
</el-col> |
||||
|
</el-row> |
||||
|
</el-form> |
||||
|
<template #footer> |
||||
|
<div class="dialog-footer"> |
||||
|
<el-button @click="cancel">取消</el-button> |
||||
|
<el-button type="primary" :disabled="disabled" @click="submitForm" |
||||
|
>确定</el-button |
||||
|
> |
||||
|
</div> |
||||
|
</template> |
||||
|
</el-dialog> |
||||
|
</template> |
||||
|
|
||||
|
<script setup> |
||||
|
import { nextTick } from 'vue' |
||||
|
import { moveDirectory } from '@/api/dataAsset/directory' |
||||
|
|
||||
|
const props = defineProps({ |
||||
|
directoryTree: { |
||||
|
type: Array, |
||||
|
required: true, |
||||
|
}, |
||||
|
}) |
||||
|
|
||||
|
const filterTree = (tree, conditionFn) => { |
||||
|
return tree |
||||
|
.map((node) => { |
||||
|
// 递归处理每个节点的子节点 |
||||
|
const filteredChildren = node.children |
||||
|
? filterTree(node.children, conditionFn) |
||||
|
: [] |
||||
|
// 根据条件判断是否保留当前节点 |
||||
|
if (conditionFn(node)) { |
||||
|
// 返回新的节点结构,保留符合条件的子节点 |
||||
|
return { |
||||
|
...node, |
||||
|
children: filteredChildren, |
||||
|
} |
||||
|
} |
||||
|
// 如果不符合条件,返回 null,不加入到最终结果中 |
||||
|
return null |
||||
|
}) |
||||
|
.filter(Boolean) // 移除值为 null 的项 |
||||
|
} |
||||
|
|
||||
|
const localDirectoryTree = computed(() => { |
||||
|
const tree = props.directoryTree |
||||
|
return filterTree(tree, (node) => node.contentOnum && !node.astOnum) // 过滤资产子节点 |
||||
|
}) |
||||
|
|
||||
|
const title = ref('') |
||||
|
const open = ref(false) |
||||
|
const disabled = ref(false) |
||||
|
const { proxy } = getCurrentInstance() |
||||
|
const form = ref({}) |
||||
|
const rules = ref({ |
||||
|
suprContentOnumAfter: [ |
||||
|
{ required: true, message: '目标目录不能为空', trigger: 'blur' }, |
||||
|
], |
||||
|
}) |
||||
|
|
||||
|
const formRef = ref(null) |
||||
|
const openDialog = (row) => { |
||||
|
open.value = true |
||||
|
form.value = { |
||||
|
contentOnum: undefined, |
||||
|
contentIntr: undefined, |
||||
|
suprContentOnum: undefined, |
||||
|
suprContentOnumAfter: undefined, |
||||
|
contentIntrAfter: undefined, |
||||
|
} |
||||
|
if (row.contentOnum) { |
||||
|
form.value = { |
||||
|
...form.value, |
||||
|
...row, |
||||
|
} |
||||
|
} |
||||
|
nextTick(() => { |
||||
|
formRef.value.clearValidate() |
||||
|
}) |
||||
|
} |
||||
|
|
||||
|
const handleTargetCatalogNodeClick = (data) => { |
||||
|
form.value = { |
||||
|
...form.value, |
||||
|
contentIntrAfter: data.contentIntr, |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
const emit = defineEmits(['onSuccess']) |
||||
|
const submitForm = () => { |
||||
|
formRef.value.validate((valid) => { |
||||
|
if (valid) { |
||||
|
moveDirectory(form.value).then((response) => { |
||||
|
proxy.$modal.msgSuccess('移动成功') |
||||
|
open.value = false |
||||
|
emit('onSuccess') |
||||
|
}) |
||||
|
} |
||||
|
}) |
||||
|
} |
||||
|
|
||||
|
const cancel = () => { |
||||
|
open.value = false |
||||
|
} |
||||
|
|
||||
|
defineExpose({ title, disabled, openDialog }) |
||||
|
</script> |
||||
|
|
||||
|
<style lang="scss" scoped> |
||||
|
.arrow { |
||||
|
display: flex; |
||||
|
font-size: 18px; |
||||
|
text-align: center; |
||||
|
margin: 8px auto; |
||||
|
span { |
||||
|
line-height: 18px; |
||||
|
} |
||||
|
} |
||||
|
</style> |
@ -0,0 +1,592 @@ |
|||||
|
<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> |
Loading…
Reference in new issue