|
@@ -0,0 +1,186 @@
|
|
|
+<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" icon="" :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 }">
|
|
|
+ <p v-if="node.level == 1" class="flex justify-between items-center text-[12px]"
|
|
|
+ :class="[props.showCheckbox ? 'w-[84%]' : 'w-[90%]']">
|
|
|
+ <span>{{ node.label }}</span>
|
|
|
+ <el-icon @click.stop="emits('refresh')">
|
|
|
+ <RefreshRight />
|
|
|
+ </el-icon>
|
|
|
+ </p>
|
|
|
+ <el-dropdown ref="dropdown1" v-else size="small" trigger="contextmenu" @command="funCommand"
|
|
|
+ style="margin-right: 30px">
|
|
|
+ <span class="el-dropdown-link text-[12px] flex items-center">
|
|
|
+ <el-icon class="mr-[4px]">
|
|
|
+ <Folder v-if="!node.expanded" />
|
|
|
+ <FolderOpened v-else />
|
|
|
+ </el-icon>
|
|
|
+ {{ 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 { 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":
|
|
|
+ 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);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ };
|
|
|
+ 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 = () => {
|
|
|
+ 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>
|