MaterialGroupTree.vue 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  1. <template>
  2. <div class="head-container">
  3. <el-input v-model="materialGroupName" class="mb-20px" clearable placeholder="请输入分类名称">
  4. <template #prefix>
  5. <Icon icon="ep:search" />
  6. </template>
  7. </el-input>
  8. </div>
  9. <div class="head-container">
  10. <el-tree
  11. ref="treeRef"
  12. :data="materialGroupList"
  13. :expand-on-click-node="false"
  14. :filter-node-method="filterNode"
  15. :props="defaultProps"
  16. :default-expand-all="false"
  17. :default-expanded-keys="firstLevelKeys"
  18. highlight-current
  19. node-key="id"
  20. @node-click="handleNodeClick"
  21. @node-contextmenu="handleRightClick"
  22. style="height: 35em"
  23. />
  24. </div>
  25. <div
  26. v-show="menuVisible"
  27. class="custom-menu"
  28. :style="{ left: menuX + 'px', top: menuY + 'px' }"
  29. >
  30. <ul>
  31. <li @click="handleMenuClick('add')">新增子节点</li>
  32. <li @click="handleMenuClick('edit')">重命名</li>
  33. <li @click="handleMenuClick('delete')">删除</li>
  34. </ul>
  35. </div>
  36. </template>
  37. <script lang="ts" setup>
  38. import { ElTree } from 'element-plus'
  39. import * as MaterialGroupApi from '@/api/pms/materialgroup'
  40. import { defaultProps, handleTree } from '@/utils/tree'
  41. import { useTreeStore } from '@/store/modules/materialGroupTreeStore'
  42. defineOptions({ name: 'MaterialGroupTree' })
  43. const treeStore = useTreeStore();
  44. const materialGroupName = ref('')
  45. const materialGroupList = ref<Tree[]>([]) // 树形结构
  46. const treeRef = ref<InstanceType<typeof ElTree>>()
  47. const menuVisible = ref(false);
  48. const menuX = ref(0);
  49. const menuY = ref(0);
  50. let selectedNode = null;
  51. const firstLevelKeys = ref([])
  52. const handleRightClick = (event, { node, data }) => {
  53. event.preventDefault();
  54. menuX.value = event.clientX;
  55. menuY.value = event.clientY;
  56. selectedNode = data; // 存储当前操作的节点数据 ‌:ml-citation{ref="7" data="citationList"}
  57. menuVisible.value = true;
  58. };
  59. const handleMenuClick = (action) => {
  60. switch(action) {
  61. case 'add':
  62. // 调用新增节点逻辑 ‌:ml-citation{ref="4" data="citationList"}
  63. break;
  64. case 'edit':
  65. // 调用编辑节点逻辑 ‌:ml-citation{ref="7" data="citationList"}
  66. break;
  67. case 'delete':
  68. // 调用删除节点逻辑 ‌:ml-citation{ref="4" data="citationList"}
  69. break;
  70. }
  71. menuVisible.value = false;
  72. };
  73. /** 获得物料组树 */
  74. const getTree = async () => {
  75. const res = await MaterialGroupApi.getSimpleMaterialGroupList()
  76. materialGroupList.value = []
  77. let device: Tree = { id: 0, name: '物料组分类', children: [] }
  78. device.children = handleTree(res)
  79. materialGroupList.value.push(device)
  80. // materialGroupList.value.push(...handleTree(res))
  81. firstLevelKeys.value = materialGroupList.value.map(node => node.id);
  82. }
  83. /** 基于名字过滤 */
  84. const filterNode = (name: string, data: Tree) => {
  85. if (!name) return true
  86. return data.name.includes(name)
  87. }
  88. /** 处理物料组被点击 */
  89. const handleNodeClick = async (row: { [key: string]: any }) => {
  90. emits('node-click', row)
  91. treeStore.setSelectedId(row.id);
  92. }
  93. const emits = defineEmits(['node-click'])
  94. /** 监听 materialGroupName */
  95. watch(materialGroupName, (val) => {
  96. treeRef.value!.filter(val)
  97. })
  98. /** 初始化 */
  99. onMounted(async () => {
  100. await getTree()
  101. })
  102. </script>
  103. <style lang="scss" scoped>
  104. .custom-menu {
  105. position: fixed;
  106. background: white;
  107. border: 1px solid #ccc;
  108. box-shadow: 2px 2px 5px rgba(0,0,0,0.1);
  109. z-index: 1000;
  110. }
  111. .custom-menu ul {
  112. list-style: none;
  113. padding: 0;
  114. margin: 0;
  115. }
  116. .custom-menu li {
  117. padding: 8px 20px;
  118. cursor: pointer;
  119. }
  120. .custom-menu li:hover {
  121. background: #f5f5f5;
  122. }
  123. </style>