|
@@ -1,157 +1,204 @@
|
|
|
<template>
|
|
|
- <div class="shadow rounded-[6px] shadow-blue-500"
|
|
|
- :style="{ height: typeof props.height === 'string' ? props.height : props.height + 'px' }">
|
|
|
- <el-input class="pb-[10px]" v-model="filterText" placeholder="输入关键字过滤" @input="funfilterChange" />
|
|
|
- <el-tree ref="treeRef" :data="props.data" :show-checkbox="props.showCheckbox" default-expand-all node-key="id"
|
|
|
- highlight-current :props="defaultProps" :current-node-key="''" @check="funCheckChange"
|
|
|
- :expand-on-click-node="false" @node-click="funCurrentChange" :filter-node-method="funTreeFilter">
|
|
|
- <template #default="{ node, data }">
|
|
|
- <span v-if="node.level == 1" class="text-[14px]">{{ node.label }}</span>
|
|
|
- <el-dropdown ref="dropdown1" v-else size="small" trigger="contextmenu" @command="funCommand"
|
|
|
- style="margin-right: 30px">
|
|
|
- <span class="el-dropdown-link">{{ node.label }} </span>
|
|
|
- <template #dropdown>
|
|
|
- <el-dropdown-menu>
|
|
|
- <el-dropdown-item v-if="data.childs && data.childs.length" :command="{ type: 'export', data, node }">导出
|
|
|
- </el-dropdown-item>
|
|
|
- <el-dropdown-item :command="{ type: 'delete', data, node }">删除</el-dropdown-item>
|
|
|
- </el-dropdown-menu>
|
|
|
- </template>
|
|
|
- </el-dropdown>
|
|
|
- </template>
|
|
|
- </el-tree>
|
|
|
-
|
|
|
-
|
|
|
- <!--
|
|
|
- <div class="buttons">
|
|
|
- <el-button @click="getCheckedNodes">get by node</el-button>
|
|
|
- <el-button @click="getCheckedKeys">get by key</el-button>
|
|
|
- <el-button @click="setCheckedNodes">set by node</el-button>
|
|
|
- <el-button @click="setCheckedKeys">set by key</el-button>
|
|
|
- <el-button @click="resetChecked">reset</el-button>
|
|
|
- </div>
|
|
|
- -->
|
|
|
- </div>
|
|
|
-</template>
|
|
|
-<script lang="ts" setup name="search">
|
|
|
-import { ref } from 'vue'
|
|
|
-import type Node from 'element-plus/es/components/tree/src/model/node'
|
|
|
-import { emit } from 'process';
|
|
|
-import { ElMessage, ElMessageBox } from 'element-plus';
|
|
|
-import config from '../../../../api/config';
|
|
|
-import request from '../../../../api/axios.js';
|
|
|
-const emits = defineEmits(['currentChange', 'checkChange', 'refresh'])
|
|
|
-interface Tree {
|
|
|
- id: string
|
|
|
- label: string
|
|
|
- children?: Tree[]
|
|
|
-}
|
|
|
-const props = withDefaults(defineProps<{
|
|
|
- data: Tree[],
|
|
|
- height?: number | string,
|
|
|
- showCheckbox?: boolean,
|
|
|
-}>(), {
|
|
|
- data: () => [],
|
|
|
- height: 400,
|
|
|
- showCheckbox: false,
|
|
|
-})
|
|
|
-
|
|
|
-const treeRef = ref()
|
|
|
-const filterText = ref('')
|
|
|
-/**输入框过滤 */
|
|
|
-const funfilterChange = () => {
|
|
|
- treeRef.value!.filter(filterText.value)
|
|
|
-}
|
|
|
-const funTreeFilter = (value: string, data: Tree) => {
|
|
|
- if (!value) return true
|
|
|
- return data.label.includes(value)
|
|
|
-}
|
|
|
-/**选中节点变化 */
|
|
|
-const funCurrentChange = (current: Tree, currentNode: Node) => {
|
|
|
- emits('currentChange', { current, currentNode })
|
|
|
-}
|
|
|
-/**复选框选中变化 */
|
|
|
-const funCheckChange = (current: Tree, { checkedNodes, checkedKeys, halfCheckedNodes, halfCheckedKeys }) => {
|
|
|
- emits('checkChange', { current, checkedNodes, checkedKeys, halfCheckedNodes, halfCheckedKeys })
|
|
|
-}
|
|
|
-//右键时, command菜单
|
|
|
-const funCommand = async ({ type, data, node }) => {
|
|
|
- console.log(type, data, node)
|
|
|
+ <div
|
|
|
+ class="shadow rounded-[6px] shadow-blue-500"
|
|
|
+ :style="{
|
|
|
+ height:
|
|
|
+ typeof props.height === 'string' ? props.height : props.height + 'px',
|
|
|
+ }"
|
|
|
+ >
|
|
|
+ <el-input
|
|
|
+ class="pb-[10px]"
|
|
|
+ v-model="filterText"
|
|
|
+ placeholder="输入关键字过滤"
|
|
|
+ @input="funfilterChange"
|
|
|
+ />
|
|
|
+ <el-tree
|
|
|
+ ref="treeRef"
|
|
|
+ :data="props.data"
|
|
|
+ :show-checkbox="props.showCheckbox"
|
|
|
+ default-expand-all
|
|
|
+ node-key="id"
|
|
|
+ highlight-current
|
|
|
+ :props="defaultProps"
|
|
|
+ :current-node-key="''"
|
|
|
+ @check="funCheckChange"
|
|
|
+ :expand-on-click-node="false"
|
|
|
+ @node-click="funCurrentChange"
|
|
|
+ :filter-node-method="funTreeFilter"
|
|
|
+ >
|
|
|
+ <template #default="{ node, data }">
|
|
|
+ <span v-if="node.level == 1" class="text-[14px]">{{ node.label }}</span>
|
|
|
+ <el-dropdown
|
|
|
+ ref="dropdown1"
|
|
|
+ v-else
|
|
|
+ size="small"
|
|
|
+ trigger="contextmenu"
|
|
|
+ @command="funCommand"
|
|
|
+ style="margin-right: 30px"
|
|
|
+ >
|
|
|
+ <span class="el-dropdown-link">{{ node.label }} </span>
|
|
|
+ <template #dropdown>
|
|
|
+ <el-dropdown-menu>
|
|
|
+ <el-dropdown-item
|
|
|
+ v-if="data.childs && data.childs.length"
|
|
|
+ :command="{ type: 'export', data, node }"
|
|
|
+ >导出
|
|
|
+ </el-dropdown-item>
|
|
|
+ <el-dropdown-item :command="{ type: 'delete', data, node }"
|
|
|
+ >删除</el-dropdown-item
|
|
|
+ >
|
|
|
+ </el-dropdown-menu>
|
|
|
+ </template>
|
|
|
+ </el-dropdown>
|
|
|
+ </template>
|
|
|
+ </el-tree>
|
|
|
+
|
|
|
+ <!--
|
|
|
+ <div class="buttons">
|
|
|
+ <el-button @click="getCheckedNodes">get by node</el-button>
|
|
|
+ <el-button @click="getCheckedKeys">get by key</el-button>
|
|
|
+ <el-button @click="setCheckedNodes">set by node</el-button>
|
|
|
+ <el-button @click="setCheckedKeys">set by key</el-button>
|
|
|
+ <el-button @click="resetChecked">reset</el-button>
|
|
|
+ </div>
|
|
|
+ --></div>
|
|
|
+ </template>
|
|
|
+ <script lang="ts" setup name="search">
|
|
|
+ import { ref } from "vue";
|
|
|
+ import type Node from "element-plus/es/components/tree/src/model/node";
|
|
|
+ import { emit } from "process";
|
|
|
+ import { ElMessage, ElMessageBox } from "element-plus";
|
|
|
+ import config from "../../../../api/config";
|
|
|
+ import request from "../../../../api/axios.js";
|
|
|
+ const emits = defineEmits(["currentChange", "checkChange", "refresh"]);
|
|
|
+ interface Tree {
|
|
|
+ id: string;
|
|
|
+ label: string;
|
|
|
+ children?: Tree[];
|
|
|
+ }
|
|
|
+ const props = withDefaults(
|
|
|
+ defineProps<{
|
|
|
+ data: Tree[];
|
|
|
+ height?: number | string;
|
|
|
+ showCheckbox?: boolean;
|
|
|
+ }>(),
|
|
|
+ {
|
|
|
+ data: () => [],
|
|
|
+ height: 400,
|
|
|
+ showCheckbox: false,
|
|
|
+ }
|
|
|
+ );
|
|
|
+
|
|
|
+ const treeRef = ref();
|
|
|
+ const filterText = ref("");
|
|
|
+ /**输入框过滤 */
|
|
|
+ const funfilterChange = () => {
|
|
|
+ treeRef.value!.filter(filterText.value);
|
|
|
+ };
|
|
|
+ const funTreeFilter = (value: string, data: Tree) => {
|
|
|
+ if (!value) return true;
|
|
|
+ return data.label.includes(value);
|
|
|
+ };
|
|
|
+ /**选中节点变化 */
|
|
|
+ const funCurrentChange = (current: Tree, currentNode: Node) => {
|
|
|
+ emits("currentChange", { current, currentNode });
|
|
|
+ };
|
|
|
+ /**复选框选中变化 */
|
|
|
+ const funCheckChange = (
|
|
|
+ current: Tree,
|
|
|
+ { checkedNodes, checkedKeys, halfCheckedNodes, halfCheckedKeys }
|
|
|
+ ) => {
|
|
|
+ emits("checkChange", {
|
|
|
+ current,
|
|
|
+ checkedNodes,
|
|
|
+ checkedKeys,
|
|
|
+ halfCheckedNodes,
|
|
|
+ halfCheckedKeys,
|
|
|
+ });
|
|
|
+ };
|
|
|
+ //右键时, command菜单
|
|
|
+ const funCommand = async ({ type, data, node }) => {
|
|
|
+ console.log(type, data, node);
|
|
|
switch (type) {
|
|
|
- case 'export':
|
|
|
- ElMessageBox.confirm(
|
|
|
- '确认导出当前节点的所有数据?',
|
|
|
- '导出',
|
|
|
- {
|
|
|
- confirmButtonText: '确认',
|
|
|
- cancelButtonText: '取消',
|
|
|
- type: 'warning',
|
|
|
- }
|
|
|
- )
|
|
|
- .then(() => {
|
|
|
- const a = document.createElement('a')
|
|
|
- const childs = data.childs.map(o => o.id)
|
|
|
- a.href = config.baseURL + '/data/option/download?ids=' + childs.join(',')
|
|
|
- a.download = ''
|
|
|
- a.click()
|
|
|
- })
|
|
|
- break;
|
|
|
- case 'delete':
|
|
|
- let deleteArr = []
|
|
|
- const repeatArr = (arr, deleteArr) => {
|
|
|
- for (const unit of arr) {
|
|
|
- if (unit.childs?.length) {
|
|
|
- deleteArr.push(...unit.childs.map(o => o.id))
|
|
|
- } else if (unit.children?.length) {
|
|
|
- repeatArr(unit.children, deleteArr)
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- if (data.childs?.length) {
|
|
|
- deleteArr = data.childs.map(o => o.id)
|
|
|
- } else if (data.children?.length) {
|
|
|
- repeatArr(data.children, deleteArr)
|
|
|
- }
|
|
|
- console.log(deleteArr)
|
|
|
- const res = await request.get('/data/option/delete', { params: { ids: deleteArr.join(',') } }) //删除当前节点
|
|
|
- if (res.code === 200) {
|
|
|
- ElMessage.success(res.msg)
|
|
|
- emits('refresh')
|
|
|
+ case "export":
|
|
|
+ ElMessageBox.confirm("确认导出当前节点的所有数据?", "导出", {
|
|
|
+ confirmButtonText: "确认",
|
|
|
+ cancelButtonText: "取消",
|
|
|
+ type: "warning",
|
|
|
+ }).then(() => {
|
|
|
+ const a = document.createElement("a");
|
|
|
+ const childs = data.childs.map((o) => o.id);
|
|
|
+ a.href =
|
|
|
+ config.baseURL + "/data/option/download?ids=" + childs.join(",");
|
|
|
+ a.download = "";
|
|
|
+ a.click();
|
|
|
+ });
|
|
|
+ break;
|
|
|
+ case "delete":
|
|
|
+ ElMessageBox.confirm("确认删除当前节点的所有数据?", "删除", {
|
|
|
+ confirmButtonText: "确认",
|
|
|
+ cancelButtonText: "取消",
|
|
|
+ type: "warning",
|
|
|
+ }).then(async () => {
|
|
|
+ let deleteArr = [];
|
|
|
+ const repeatArr = (arr, deleteArr) => {
|
|
|
+ for (const unit of arr) {
|
|
|
+ if (unit.childs?.length) {
|
|
|
+ deleteArr.push(...unit.childs.map((o) => o.id));
|
|
|
+ } else if (unit.children?.length) {
|
|
|
+ repeatArr(unit.children, deleteArr);
|
|
|
}
|
|
|
- break;
|
|
|
+ }
|
|
|
+ };
|
|
|
+ if (data.childs?.length) {
|
|
|
+ deleteArr = data.childs.map((o) => o.id);
|
|
|
+ } else if (data.children?.length) {
|
|
|
+ repeatArr(data.children, deleteArr);
|
|
|
+ }
|
|
|
+ console.log(deleteArr);
|
|
|
+ const res = await request.get("/data/option/delete", {
|
|
|
+ params: { ids: deleteArr.join(",") },
|
|
|
+ }); //删除当前节点
|
|
|
+ if (res.code === 200) {
|
|
|
+ ElMessage.success(res.msg);
|
|
|
+ emits("refresh");
|
|
|
+ }
|
|
|
+ });
|
|
|
+
|
|
|
+ break;
|
|
|
}
|
|
|
-}
|
|
|
-
|
|
|
-const getCheckedNodes = () => {
|
|
|
- console.log(treeRef.value!.getCheckedNodes(false, false))
|
|
|
-}
|
|
|
-const getCheckedKeys = () => {
|
|
|
- console.log(treeRef.value!.getCheckedKeys(false))
|
|
|
-}
|
|
|
-const setCheckedNodes = () => {
|
|
|
+ };
|
|
|
+
|
|
|
+ const getCheckedNodes = () => {
|
|
|
+ console.log(treeRef.value!.getCheckedNodes(false, false));
|
|
|
+ };
|
|
|
+ const getCheckedKeys = () => {
|
|
|
+ console.log(treeRef.value!.getCheckedKeys(false));
|
|
|
+ };
|
|
|
+ const setCheckedNodes = () => {
|
|
|
treeRef.value!.setCheckedNodes(
|
|
|
- [
|
|
|
- {
|
|
|
- id: 5,
|
|
|
- label: 'Level two 2-1',
|
|
|
- },
|
|
|
- {
|
|
|
- id: 9,
|
|
|
- label: 'Level three 1-1-1',
|
|
|
- },
|
|
|
- ],
|
|
|
- false
|
|
|
- )
|
|
|
-}
|
|
|
-const setCheckedKeys = () => {
|
|
|
- treeRef.value!.setCheckedKeys([3], false)
|
|
|
-}
|
|
|
-const resetChecked = () => {
|
|
|
- treeRef.value!.setCheckedKeys([], false)
|
|
|
-}
|
|
|
-
|
|
|
-const defaultProps = {
|
|
|
- children: 'children',
|
|
|
- label: 'label',
|
|
|
-}
|
|
|
-</script>
|
|
|
+ [
|
|
|
+ {
|
|
|
+ id: 5,
|
|
|
+ label: "Level two 2-1",
|
|
|
+ },
|
|
|
+ {
|
|
|
+ id: 9,
|
|
|
+ label: "Level three 1-1-1",
|
|
|
+ },
|
|
|
+ ],
|
|
|
+ false
|
|
|
+ );
|
|
|
+ };
|
|
|
+ const setCheckedKeys = () => {
|
|
|
+ treeRef.value!.setCheckedKeys([3], false);
|
|
|
+ };
|
|
|
+ const resetChecked = () => {
|
|
|
+ treeRef.value!.setCheckedKeys([], false);
|
|
|
+ };
|
|
|
+
|
|
|
+ const defaultProps = {
|
|
|
+ children: "children",
|
|
|
+ label: "label",
|
|
|
+ };
|
|
|
+ </script>
|