Files
cn-rdms-web/src/components/custom/subordinate-selector.vue
2026-06-14 23:57:42 +08:00

109 lines
2.8 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<script setup lang="ts">
defineOptions({ name: 'SubordinateSelector' });
interface Props {
loading?: boolean;
data?: Api.SystemManage.MySubordinateTreeNode | null;
emptyText?: string;
}
const props = withDefaults(defineProps<Props>(), {
loading: false,
data: null,
emptyText: '暂无下属数据'
});
const selectedUserId = defineModel<string | null>('selectedUserId', {
default: null
});
function handleNodeClick(node: Api.SystemManage.MySubordinateTreeNode) {
selectedUserId.value = node.userId;
}
function renderNodeLabel(node: Api.SystemManage.MySubordinateTreeNode) {
const label = node.isRoot ? '全部下属' : node.userNickname;
return `${label}${node.subordinateCount ? `${node.subordinateCount}` : ''}`;
}
</script>
<template>
<ElCard class="subordinate-selector" body-class="subordinate-selector__body">
<template #header>
<div class="flex items-center justify-between gap-12px">
<span class="text-14px font-600">团队成员</span>
<ElTag v-if="props.data" effect="plain">{{ props.data.subordinateCount }}</ElTag>
</div>
</template>
<div v-loading="props.loading" class="subordinate-selector__content">
<ElEmpty v-if="!props.data" :image-size="88" :description="props.emptyText" />
<ElTree
v-else
:data="[props.data]"
node-key="userId"
:current-node-key="selectedUserId || undefined"
:props="{ label: 'userNickname', children: 'children' }"
highlight-current
default-expand-all
expand-on-click-node
class="subordinate-selector__tree"
@node-click="handleNodeClick"
>
<template #default="{ data: node }">
<span class="subordinate-selector__node-label">{{ renderNodeLabel(node) }}</span>
</template>
</ElTree>
</div>
</ElCard>
</template>
<style scoped lang="scss">
.subordinate-selector {
display: flex;
flex-direction: column;
height: 100%;
border: 1px solid var(--el-border-color-light);
box-shadow: none;
}
:deep(.subordinate-selector__body) {
display: flex;
flex: 1;
flex-direction: column;
min-height: 0;
padding: 12px;
}
.subordinate-selector__content {
flex: 1;
min-height: 240px;
overflow: auto;
}
.subordinate-selector__tree {
height: 100%;
background: transparent;
}
.subordinate-selector__node-label {
display: inline-flex;
align-items: center;
min-width: 0;
color: var(--el-text-color-regular);
}
:deep(.subordinate-selector__tree .el-tree-node__content) {
height: 36px;
border-radius: 8px;
}
:deep(.subordinate-selector__tree .el-tree-node__content:hover) {
background: var(--el-fill-color-light);
}
:deep(.subordinate-selector__tree .el-tree-node.is-current > .el-tree-node__content) {
background: var(--el-color-primary-light-9);
}
</style>