Files
one-pipe-system/src/components/business/AgentSelector.vue
2026-01-23 17:18:24 +08:00

128 lines
2.9 KiB
Vue

<template>
<el-tree-select
v-model="selectedValue"
:data="agentTreeData"
:props="treeProps"
:placeholder="placeholder"
:clearable="clearable"
:disabled="disabled"
:filterable="filterable"
:check-strictly="checkStrictly"
:multiple="multiple"
:size="size"
:render-after-expand="false"
@change="handleChange"
@visible-change="handleVisibleChange"
>
<template #default="{ data }">
<div class="agent-node">
<span class="agent-name">{{ data.name }}</span>
<span v-if="data.level" class="agent-level">{{ data.level }}</span>
</div>
</template>
</el-tree-select>
</template>
<script setup lang="ts">
import { ref, computed, onMounted } from 'vue'
import type { Agent } from '@/types/api'
interface Props {
modelValue?: string | number | (string | number)[]
placeholder?: string
clearable?: boolean
disabled?: boolean
filterable?: boolean
checkStrictly?: boolean
multiple?: boolean
size?: 'large' | 'default' | 'small'
// 预加载的代理商树数据
agents?: Agent[]
// 远程获取方法
fetchMethod?: () => Promise<Agent[]>
}
interface Emits {
(e: 'update:modelValue', value: string | number | (string | number)[] | undefined): void
(e: 'change', value: string | number | (string | number)[] | undefined): void
}
const props = withDefaults(defineProps<Props>(), {
placeholder: '请选择代理商',
clearable: true,
disabled: false,
filterable: true,
checkStrictly: false,
multiple: false,
size: 'default'
})
const emit = defineEmits<Emits>()
const loading = ref(false)
const agentTreeData = ref<Agent[]>([])
const treeProps = {
value: 'id',
label: 'name',
children: 'children'
}
const selectedValue = computed({
get: () => props.modelValue,
set: (val) => {
emit('update:modelValue', val)
}
})
const handleChange = (value: string | number | (string | number)[] | undefined) => {
emit('change', value)
}
const handleVisibleChange = (visible: boolean) => {
if (visible && agentTreeData.value.length === 0) {
loadAgents()
}
}
const loadAgents = async () => {
if (props.agents) {
agentTreeData.value = props.agents
} else if (props.fetchMethod) {
loading.value = true
try {
agentTreeData.value = await props.fetchMethod()
} finally {
loading.value = false
}
}
}
onMounted(() => {
if (props.agents) {
agentTreeData.value = props.agents
}
})
</script>
<style scoped lang="scss">
.agent-node {
display: flex;
gap: 8px;
align-items: center;
.agent-name {
font-weight: 500;
color: var(--el-text-color-primary);
}
.agent-level {
padding: 2px 8px;
font-size: 12px;
color: var(--el-color-primary);
background-color: var(--el-color-primary-light-9);
border-radius: 4px;
}
}
</style>