<template>
  <div>
    <div class="titleBox">
      <div class="title">菜单管理</div>
    </div>
    <!-- <div class="menu" :style="{ height: menuHeight }" v-if="showTree" > -->
    <div class="menu" style="height: 85vh;"  v-if="showTree">
      <el-tree :data="treeData" :props="defaultProps" :load="loadNode" :lazy="true" ref="tree">
        <template #default="scoped">
          <div class="menuItem" @contextmenu.prevent="onContextmenu(scoped.data, $event)">
            <el-icon class="left_icon">
              <Document />
            </el-icon>
            <span class="center_text"> {{ scoped.data.menuName }}</span>
            <el-icon v-if="!scoped.data.hasChildren">
              <CaretRight />
            </el-icon>
          </div>
        </template>
      </el-tree>
    </div>
    <Contextmenu ref="contextmenuRef" :items="contextmenuItems.list" @contextmenuItemClick="onContextmenuItem" />
    <Dialog ref="dialog" :formData="formData" @saveSuccess="saveSuccess" />
  </div>
</template>

<script setup>
import { ref, onMounted, reactive } from "vue";
import Contextmenu from "@/components/contextmenu/index.vue";
import Dialog from "@/components/dialog/index.vue";
import { selectMenuList, deleteSysMenu, changeOrderno } from "@/api/menu";
import { ElMessage, ElMessageBox } from "element-plus";
const defaultProps = {
  label: "menuName",
  isLeaf: "hasChildren"
};
const formData = ref({});
const showTree = ref(true);
const treeData = ref([]);
const tree = ref();
const contextmenuRef = ref();
const dialog = ref(null);
/** 记录最后一次点击的元素 */
const lastClick= ref({})
/** 需要重新加载的父级元素 */
const needRefreshParentId = ref()
// 菜单的高度
const menuHeight = ref("");
// 自定义右键菜单的功能列表
const contextmenuItems = reactive({
  list: [
    { name: "addGroup", label: "新增菜单分组", icon: "Plus" },
    { name: "addItem", label: "添加下级", icon: "CirclePlus" },
    { name: "edit", label: "修改", icon: "Edit" },
    { name: "delete", label: "删除", icon: "Delete" },
    { name: "up", label: "上移", icon: "CaretTop" },
    { name: "down", label: "下移", icon: "CaretBottom" }
  ]
});
onMounted(() => {
  menuHeightFn();
  window.onresize = function () {
    menuHeightFn();
  };
});
// 新增成功
const saveSuccess = () => {
  // 如果最后一次点击的元素存在，则重新加载该元素
  let nodeObj = lastClick.value[needRefreshParentId.value]
  if (nodeObj) {
    loadNode(nodeObj.node, nodeObj.resolve)
  } else {
    showTree.value = false;
    setTimeout(function () {
      showTree.value = true;
    }, 200);
  }
 
  formData.value = {};
  dialog.value.dialogFormVisible = false;
};
// 树形懒加载
const loadNode = (node, resolve) => {
  lastClick.value[node.data.id] = { node, resolve } // 优化尽量尽量局部加载,这里先存数据
  if (node.level === 0) {
    getMenuListLevelOne();
  } else if (node.level >= 1) {
    selectMenuList({ parentId: node.data.id }).then((res) => {
      resolve(res);
    });
  }
};
// 初始加载一级菜单
const getMenuListLevelOne = () => {
  selectMenuList({ parentId: "0" }).then((res) => {
    treeData.value = res;
  });
};
const menuHeightFn = () => {
  menuHeight.value = window.innerHeight - 50 + "px";
};
const onContextmenu = (menu, el) => {

  // 右键菜单的位置
  const { clientX, clientY } = el;
  contextmenuRef.value.onShowContextmenu(menu, {
    x: clientX,
    y: clientY
  });
};
// 菜单的每个具体功能
const onContextmenuItem = (item) => {
  const { name, menu } = item;
  formData.value = {};
  needRefreshParentId.value = name === 'addItem' ? menu.id : menu.parentId// 记录需要刷新的父级
  switch (name) {
    case "addGroup":
      formData.value.parentId = "0";
      formData.value.title = "添加菜单组";
      dialog.value.dialogFormVisible = true;
      break;
    case "addItem":
      formData.value.parentId = menu.id;
      formData.value.title = "添加下级菜单";
      dialog.value.dialogFormVisible = true;
      break;
    case "edit":
      formData.value = { ...menu };
      formData.value.title = "菜单编辑";
      formData.value.showMode += "";
      formData.value.menuType += "";
      dialog.value.dialogFormVisible = true;
      break;
    case "delete":
      deleteMenu(menu.id);
      break;
    case "up":
      _changeOrderno(menu.id, "1");
      break;
    case "down":
      _changeOrderno(menu.id, "2");
      break;
  }
};
// 菜单更换位置
const _changeOrderno = (id, type) => {
  changeOrderno({ id, type }).then(() => {
    ElMessage.success("操作成功");
    saveSuccess();
  });
};
// 删除菜单数据
const deleteMenu = (id) => {
  ElMessageBox.confirm("确定删除该菜单数据?", "Warning").then(() => {
    deleteSysMenu({ id }).then(() => {
      ElMessage.success("删除成功");
      saveSuccess();
    });
  });
};
</script>

<style lang="scss" scoped>
.menu {
  padding: 10px 0;
  overflow-y: scroll;
}

.menuItem {
  width: 100%;

  .left_icon {
    margin: 0 10px;
    font-size: 18px;
  }

  .center_text {
    font-size: 15px;
  }
}

::v-deep .el-tree-node__content {
  .el-tree-node__expand-icon {
    display: none;
  }
}
</style>
