172 lines
6.2 KiB
Plaintext
172 lines
6.2 KiB
Plaintext
<template>
|
|
<el-card class="box-card" shadow="hover" body-style="height:100%; overflow:auto; padding:5px; width:100%;">
|
|
<template #header>
|
|
<div class="card-header">
|
|
<div class="tree-h-flex">
|
|
<div class="tree-h-left">
|
|
<el-input :prefix-icon="Search" v-model.lazy="filterText" clearable placeholder="@(Model.TreeConfig.TreeTitle)" />
|
|
</div>
|
|
<div class="tree-h-right">
|
|
<el-dropdown @@command="handleCommand">
|
|
<el-button style="margin-left: 8px; width: 34px">
|
|
<el-icon class="el-icon--center">
|
|
<more-filled />
|
|
</el-icon>
|
|
</el-button>
|
|
<template #dropdown>
|
|
<el-dropdown-menu>
|
|
<el-dropdown-item command="expandAll">全部展开</el-dropdown-item>
|
|
<el-dropdown-item command="collapseAll">全部折叠</el-dropdown-item>
|
|
<el-dropdown-item command="rootNode">根节点</el-dropdown-item>
|
|
<el-dropdown-item command="refresh">刷新</el-dropdown-item>
|
|
</el-dropdown-menu>
|
|
</template>
|
|
</el-dropdown>
|
|
</div>
|
|
<el-checkbox v-if="!props.checkStrictly && state.isShowCheckbox" v-model="state.strictly" label="联动" style="margin-left: 8px" border />
|
|
</div>
|
|
</div>
|
|
</template>
|
|
<div style="margin-bottom: 45px" v-loading="state.loading">
|
|
<el-scrollbar>
|
|
<el-tree
|
|
ref="treeRef"
|
|
class="filter-tree"
|
|
:data="state.@(Model.TreeConfig.LowerEntityName)Data"
|
|
node-key="@(Model.TreeConfig.LowerLinkPropertyName)"
|
|
:props="{ children: 'children', label: '@(Model.TreeConfig.LowerFirstDisplayName)' }"
|
|
:filter-node-method="filterNode"
|
|
@@node-click="nodeClick"
|
|
:show-checkbox="state.isShowCheckbox"
|
|
:default-expanded-keys="state.@(Model.TreeConfig.LowerEntityName)Data[0] && [state.@(Model.TreeConfig.LowerEntityName)Data[0].@(Model.TreeConfig.LowerLinkPropertyName)]"
|
|
:default-checked-keys="state.own@(Model.TreeConfig.EntityName)Data"
|
|
highlight-current
|
|
:check-strictly="!state.strictly"
|
|
>
|
|
<template #default="{ node }">
|
|
<el-icon v-if="node.level == 1" size="16" style="margin-right: 3px; display: inline; vertical-align: middle"><ele-School /></el-icon>
|
|
<el-icon v-else-if="node.level == 2" size="16" style="margin-right: 3px; display: inline; vertical-align: middle"><ele-Refrigerator /></el-icon>
|
|
<el-icon v-else size="16" style="margin-right: 3px; display: inline; vertical-align: middle"><ele-CollectionTag /></el-icon>
|
|
{{ node.label }}
|
|
</template>
|
|
</el-tree>
|
|
</el-scrollbar>
|
|
</div>
|
|
</el-card>
|
|
</template>
|
|
|
|
<script lang="ts" setup>
|
|
import { onMounted, reactive, ref, watch } from 'vue';
|
|
import type { ElTree } from 'element-plus';
|
|
import { Search, MoreFilled } from '@@element-plus/icons-vue';
|
|
|
|
import { getAPI } from '/@@/utils/axios-utils';
|
|
import { @(Model.TreeConfig.EntityName)Api } from '/@@/api-services/@(Model.PagePath)/api';
|
|
import { @(Model.TreeConfig.EntityName) } from '/@@/api-services/@(Model.PagePath)/models';
|
|
import { TreeKey } from 'element-plus/es/components/tree/src/tree.type';
|
|
|
|
const props = defineProps({
|
|
checkStrictly: { type: Boolean, default: true },
|
|
});
|
|
|
|
const filterText = ref('');
|
|
const treeRef = ref<InstanceType<typeof ElTree>>();
|
|
const state = reactive({
|
|
loading: false,
|
|
@(Model.TreeConfig.LowerEntityName)Data: [] as Array<@(Model.TreeConfig.EntityName)>,
|
|
isShowCheckbox: false,
|
|
own@(Model.TreeConfig.EntityName)Data: [],
|
|
strictly: false,
|
|
});
|
|
|
|
// 页面初始化
|
|
onMounted(async () => {
|
|
await fetchTreeData();
|
|
});
|
|
|
|
// 查询监听
|
|
watch(filterText, (val) => {
|
|
treeRef.value!.filter(val);
|
|
});
|
|
|
|
// 获取树数据
|
|
const fetchTreeData = async (showLoading: boolean = true) => {
|
|
if (showLoading) state.loading = true;
|
|
var res = await getAPI(@(Model.TreeConfig.EntityName)Api).api@(Model.TreeConfig.EntityName)ListGet(0);
|
|
state.@(Model.TreeConfig.LowerEntityName)Data = res.data.result ?? [];
|
|
if (showLoading) state.loading = false;
|
|
return res.data.result ?? [];
|
|
};
|
|
|
|
// 设置默认选择
|
|
const setCheckedKeys = (@(Model.TreeConfig.LowerEntityName)Data: any) => {
|
|
state.isShowCheckbox = true;
|
|
treeRef.value!.setCheckedKeys([]);
|
|
state.own@(Model.TreeConfig.EntityName)Data = @(Model.TreeConfig.LowerEntityName)Data;
|
|
};
|
|
|
|
// 获取已经选择
|
|
const getCheckedKeys = () => {
|
|
return treeRef.value!.getCheckedKeys();
|
|
};
|
|
|
|
// 节点过滤
|
|
const filterNode = (value: string, data: any) => {
|
|
if (!value) return true;
|
|
return data.@(Model.TreeConfig.LowerSearchPropertyName).includes(value);
|
|
};
|
|
|
|
// 节点操作
|
|
const handleCommand = async (command: string | number | object) => {
|
|
if ('expandAll' == command) {
|
|
for (let i = 0; i < treeRef.value!.store._getAllNodes().length; i++) {
|
|
treeRef.value!.store._getAllNodes()[i].expanded = true;
|
|
}
|
|
} else if ('collapseAll' == command) {
|
|
for (let i = 0; i < treeRef.value!.store._getAllNodes().length; i++) {
|
|
treeRef.value!.store._getAllNodes()[i].expanded = false;
|
|
}
|
|
} else if ('refresh' == command) {
|
|
fetchTreeData();
|
|
} else if ('rootNode' == command) {
|
|
treeRef.value?.setCurrentKey();
|
|
emits('node-click', { @(Model.TreeConfig.LowerLinkPropertyName): 0, @(Model.TreeConfig.LowerFirstDisplayName): '' });
|
|
}
|
|
};
|
|
|
|
// 与父组件的交互逻辑
|
|
const emits = defineEmits(['node-click']);
|
|
const nodeClick = (node: any) => {
|
|
emits('node-click', { @(Model.TreeConfig.LowerLinkPropertyName): node.@(Model.TreeConfig.LowerLinkPropertyName), @(Model.TreeConfig.LowerFirstDisplayName): node.@(Model.TreeConfig.LowerFirstDisplayName) });
|
|
};
|
|
|
|
//设置当前选中节点
|
|
const setCurrentKey = (key?: TreeKey | undefined, shouldAutoExpandParent?: boolean | undefined) => {
|
|
treeRef.value?.setCurrentKey(key, shouldAutoExpandParent);
|
|
};
|
|
|
|
// 导出对象
|
|
defineExpose({ fetchTreeData, setCheckedKeys, getCheckedKeys, setCurrentKey });
|
|
</script>
|
|
|
|
<style lang="scss" scoped>
|
|
.box-card {
|
|
flex: 1;
|
|
> :deep(.el-card__header) {
|
|
padding: 5px;
|
|
}
|
|
}
|
|
.tree-h-flex {
|
|
display: flex;
|
|
}
|
|
|
|
.tree-h-left {
|
|
flex: 1;
|
|
width: 100%;
|
|
}
|
|
|
|
.tree-h-right {
|
|
width: 42px;
|
|
min-width: 42px;
|
|
}
|
|
</style> |