mirror of
				https://github.com/continew-org/continew-admin-ui.git
				synced 2025-11-04 10:57:08 +08:00 
			
		
		
		
	revert: 回退用户管理部门树组件(此树查询不应该校验功能权限)
This commit is contained in:
		@@ -1,67 +0,0 @@
 | 
			
		||||
<template>
 | 
			
		||||
  <a-menu class="right-menu">
 | 
			
		||||
    <a-menu-item @click="onClick('add')">
 | 
			
		||||
      <template #icon><icon-plus-circle :size="16" :stroke-width="3" /></template>
 | 
			
		||||
      <span>新增</span>
 | 
			
		||||
    </a-menu-item>
 | 
			
		||||
 | 
			
		||||
    <a-menu-item v-permission="['system:dept:update']" @click="onClick('update')">
 | 
			
		||||
      <template #icon><icon-edit :size="16" :stroke-width="3" /></template>
 | 
			
		||||
      <span>修改</span>
 | 
			
		||||
    </a-menu-item>
 | 
			
		||||
 | 
			
		||||
    <a-menu-item v-permission="['system:dept:delete']" :title="data.isSystem ? '系统内置数据不能删除' : undefined" :disabled="data.isSystem" @click="onClick('delete')">
 | 
			
		||||
      <template #icon><icon-delete :size="16" :stroke-width="3" /></template>
 | 
			
		||||
      <span>删除</span>
 | 
			
		||||
    </a-menu-item>
 | 
			
		||||
  </a-menu>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script lang="ts" setup>
 | 
			
		||||
import type { DeptResp } from '@/apis'
 | 
			
		||||
 | 
			
		||||
interface Props {
 | 
			
		||||
  data: DeptResp
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const props = withDefaults(defineProps<Props>(), {})
 | 
			
		||||
 | 
			
		||||
const emit = defineEmits<{
 | 
			
		||||
  (e: 'on-menu-item-click', mode: string, data: DeptResp): void
 | 
			
		||||
}>()
 | 
			
		||||
 | 
			
		||||
// 点击菜单项
 | 
			
		||||
const onClick = (mode: string) => {
 | 
			
		||||
  emit('on-menu-item-click', mode, props.data)
 | 
			
		||||
}
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<style lang="scss" scoped>
 | 
			
		||||
:deep(.arco-menu-inner) {
 | 
			
		||||
  padding: 4px;
 | 
			
		||||
 | 
			
		||||
  .arco-menu-item {
 | 
			
		||||
    height: 34px;
 | 
			
		||||
 | 
			
		||||
    &:not(.arco-menu-selected) {
 | 
			
		||||
      color: $color-text-1;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    &:last-child {
 | 
			
		||||
      margin-bottom: 0;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.right-menu {
 | 
			
		||||
  width: 120px;
 | 
			
		||||
  box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
 | 
			
		||||
  border-radius: 4px;
 | 
			
		||||
  border: 1px solid var(--color-border-2);
 | 
			
		||||
  box-sizing: border-box;
 | 
			
		||||
 | 
			
		||||
  .arrow-icon {
 | 
			
		||||
    margin-right: 0;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
</style>
 | 
			
		||||
@@ -9,51 +9,27 @@
 | 
			
		||||
      <div class="left-tree__tree">
 | 
			
		||||
        <a-tree
 | 
			
		||||
          ref="treeRef"
 | 
			
		||||
          :data="(treeData as unknown as TreeNodeData[])"
 | 
			
		||||
          :field-names="{ key: 'id' }"
 | 
			
		||||
          :data="deptList"
 | 
			
		||||
          show-line
 | 
			
		||||
          block-node
 | 
			
		||||
          default-expand-all
 | 
			
		||||
          :selected-keys="selectedKeys"
 | 
			
		||||
          @select="select"
 | 
			
		||||
        >
 | 
			
		||||
          <template #title="node">
 | 
			
		||||
            <a-trigger
 | 
			
		||||
              v-model:popup-visible="node.popupVisible"
 | 
			
		||||
              trigger="contextMenu"
 | 
			
		||||
              align-point
 | 
			
		||||
              animation-name="slide-dynamic-origin"
 | 
			
		||||
              auto-fit-transform-origin
 | 
			
		||||
              position="bl"
 | 
			
		||||
              scroll-to-close
 | 
			
		||||
            >
 | 
			
		||||
              <a-tooltip v-if="node.description" :content="node.description" background-color="rgb(var(--primary-6))" position="right">
 | 
			
		||||
                <div @contextmenu="onContextmenu(node)">{{ node.name }}</div>
 | 
			
		||||
              </a-tooltip>
 | 
			
		||||
              <div v-else @contextmenu="onContextmenu(node)">{{ node.name }}</div>
 | 
			
		||||
              <template #content>
 | 
			
		||||
                <RightMenu
 | 
			
		||||
                  v-if="has.hasPermOr(['system:dept:update', 'system:dept:delete'])"
 | 
			
		||||
                  :data="node"
 | 
			
		||||
                  @on-menu-item-click="onMenuItemClick"
 | 
			
		||||
                />
 | 
			
		||||
              </template>
 | 
			
		||||
            </a-trigger>
 | 
			
		||||
          <template #switcher-icon="node, { isLeaf }">
 | 
			
		||||
            <IconCaretDown v-if="!isLeaf" />
 | 
			
		||||
            <IconIdcard v-else />
 | 
			
		||||
          </template>
 | 
			
		||||
        </a-tree>
 | 
			
		||||
      </div>
 | 
			
		||||
    </div>
 | 
			
		||||
  </div>
 | 
			
		||||
  <DeptAddModal ref="DeptAddModalRef" @save-success="getTreeData" />
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script setup lang="tsx">
 | 
			
		||||
import type { Message, Modal, TreeInstance, TreeNodeData } from '@arco-design/web-vue'
 | 
			
		||||
import { mapTree } from 'xe-utils'
 | 
			
		||||
import DeptAddModal from '../../dept/DeptAddModal.vue'
 | 
			
		||||
import RightMenu from './RightMenu.vue'
 | 
			
		||||
import { type DeptQuery, type DeptResp, deleteDept, listDept } from '@/apis'
 | 
			
		||||
import has from '@/utils/has'
 | 
			
		||||
import type { TreeInstance } from '@arco-design/web-vue'
 | 
			
		||||
import { ref } from 'vue'
 | 
			
		||||
import { useDept } from '@/hooks/app'
 | 
			
		||||
 | 
			
		||||
interface Props {
 | 
			
		||||
  placeholder?: string
 | 
			
		||||
@@ -71,92 +47,25 @@ const select = (keys: Array<any>) => {
 | 
			
		||||
  emit('node-click', keys)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const queryForm = reactive<DeptQuery>({
 | 
			
		||||
  sort: ['parentId,asc', 'sort,asc', 'createTime,desc']
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
interface TreeItem extends DeptResp {
 | 
			
		||||
  popupVisible: boolean
 | 
			
		||||
}
 | 
			
		||||
const treeRef = ref<TreeInstance>()
 | 
			
		||||
const treeData = ref<TreeItem[]>([])
 | 
			
		||||
const loading = ref(false)
 | 
			
		||||
// 查询树列表
 | 
			
		||||
const getTreeData = async (query: DeptQuery = { ...queryForm }) => {
 | 
			
		||||
  try {
 | 
			
		||||
    loading.value = true
 | 
			
		||||
    const { data } = await listDept(query)
 | 
			
		||||
    treeData.value = mapTree(data, (i) => ({
 | 
			
		||||
      ...i,
 | 
			
		||||
      popupVisible: false,
 | 
			
		||||
      switcherIcon: (node: any) => {
 | 
			
		||||
        if (!node.isLeaf) {
 | 
			
		||||
          return <icon-caret-down />
 | 
			
		||||
        }
 | 
			
		||||
        return <icon-idcard />
 | 
			
		||||
      }
 | 
			
		||||
    }))
 | 
			
		||||
    await nextTick(() => {
 | 
			
		||||
const { deptList, getDeptList } = useDept({
 | 
			
		||||
  onSuccess: () => {
 | 
			
		||||
    nextTick(() => {
 | 
			
		||||
      treeRef.value?.expandAll(true)
 | 
			
		||||
      select([data[0].id])
 | 
			
		||||
      select([deptList.value[0]?.key])
 | 
			
		||||
    })
 | 
			
		||||
  } finally {
 | 
			
		||||
    loading.value = false
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
// 树查询
 | 
			
		||||
const inputValue = ref('')
 | 
			
		||||
watch(inputValue, (val) => {
 | 
			
		||||
  queryForm.description = val
 | 
			
		||||
  getTreeData()
 | 
			
		||||
  getDeptList(val)
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
// 保存当前右键的节点
 | 
			
		||||
const contextmenuNode = ref<TreeItem | null>(null)
 | 
			
		||||
const onContextmenu = (node: TreeItem) => {
 | 
			
		||||
  contextmenuNode.value = node
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// 关闭右键菜单弹框
 | 
			
		||||
const closeRightMenuPopup = () => {
 | 
			
		||||
  if (contextmenuNode.value?.popupVisible) {
 | 
			
		||||
    contextmenuNode.value.popupVisible = false
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const DeptAddModalRef = ref<InstanceType<typeof DeptAddModal>>()
 | 
			
		||||
// 右键菜单项点击
 | 
			
		||||
const onMenuItemClick = (mode: string, node: DeptResp) => {
 | 
			
		||||
  closeRightMenuPopup()
 | 
			
		||||
  if (mode === 'add') {
 | 
			
		||||
    DeptAddModalRef.value?.onAdd(node.id)
 | 
			
		||||
  } else if (mode === 'update') {
 | 
			
		||||
    DeptAddModalRef.value?.onUpdate(node.id)
 | 
			
		||||
  } else if (mode === 'delete') {
 | 
			
		||||
    Modal.warning({
 | 
			
		||||
      title: '提示',
 | 
			
		||||
      content: `是否确定删除 [${node.name}]?`,
 | 
			
		||||
      hideCancel: false,
 | 
			
		||||
      okButtonProps: { status: 'danger' },
 | 
			
		||||
      onBeforeOk: async () => {
 | 
			
		||||
        try {
 | 
			
		||||
          const res = await deleteDept(node.id)
 | 
			
		||||
          if (res.success) {
 | 
			
		||||
            Message.success('删除成功')
 | 
			
		||||
            getTreeData()
 | 
			
		||||
          }
 | 
			
		||||
          return res.success
 | 
			
		||||
        } catch (error) {
 | 
			
		||||
          return false
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    })
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
onMounted(() => {
 | 
			
		||||
  getTreeData()
 | 
			
		||||
  getDeptList()
 | 
			
		||||
})
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user