Files
GEAR-OA/gear-ui3/src/components/UserSelect/index.vue
2025-08-07 13:03:28 +08:00

140 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.

<template>
<el-tree-select
:model-value="modelVal"
:data="treeData"
style="width: 300px;"
:props="defaultProps"
searchable
clearable
v-bind="$attrs"
@update:model-value="updateValue"
@change="handleChange"
/>
</template>
<script setup>
import { ref, onMounted, computed } from 'vue'
import { listDept } from '@/api/system/dept'
import { listUser } from '@/api/system/user'
defineOptions({
name: 'UserSelect'
})
const emit = defineEmits(['update:modelValue', 'change'])
const props = defineProps({
modelValue: {
type: [String, Number, Array],
default: undefined
},
// 是否只选择用户false 表示部门也可以选择
userOnly: {
type: Boolean,
default: false
},
// 是否多选
multiple: {
type: Boolean,
default: false
}
})
const treeData = ref([])
const defaultProps = {
value: 'id',
label: 'label',
children: 'children'
}
// 加载部门和用户数据
const loadData = async () => {
try {
// 获取部门列表
const { data: deptList } = await listDept()
// 获取用户列表
const { rows: userList } = await listUser()
// 转换部门数据
const transformedDeptList = deptList.map(dept => ({
id: `dept_${dept.deptId}`,
label: dept.deptName,
parentId: dept.parentId === 0 ? null : `dept_${dept.parentId}`,
type: 'dept'
}))
// 转换用户数据
const transformedUserList = userList.map(user => ({
id: `${user.userId}`,
label: user.nickName || user.userName,
parentId: `dept_${user.deptId}`,
type: 'user'
}))
// 如果只选择用户,过滤掉部门节点
let allNodes = props.userOnly
? transformedUserList
: [...transformedDeptList, ...transformedUserList]
// 构建树形结构
treeData.value = buildTree(allNodes)
} catch (error) {
console.error('加载数据失败:', error)
}
}
// 构建树形结构
const buildTree = (nodes) => {
const map = {}
const result = []
// 创建节点映射
nodes.forEach(node => {
map[node.id] = { ...node, children: [] }
})
// 构建树形关系
nodes.forEach(node => {
const current = map[node.id]
if (node.parentId) {
const parent = map[node.parentId]
if (parent) {
parent.children.push(current)
}
} else {
result.push(current)
}
})
return result
}
// 使用计算属性处理双向绑定
const modelVal = computed({
get: () => props.modelValue,
set: (value) => {
emit('update:modelValue', value)
}
})
// 处理值更新
const updateValue = (value) => {
modelVal.value = value
}
// 处理选择变化
const handleChange = (value) => {
emit('change', value)
}
// 组件挂载时加载数据
onMounted(() => {
loadData()
})
</script>
<style scoped>
.el-tree-select {
width: 100%;
}
</style>