Files
admin-web/src/modules/iam/components/PlatformTenantSelector.vue
T
2026-08-26 11:10:48 +08:00

91 lines
3.2 KiB
Vue

<script setup lang="ts">
import { computed, onMounted, ref } from 'vue'
import { RefreshCw } from '@lucide/vue'
import { listPlatformTenants, type PlatformTenantResource } from '../api/platformIam'
const props = withDefaults(defineProps<{
modelValue: string
disabled?: boolean
label?: string
}>(), {
disabled: false,
label: '目标客户',
})
const emit = defineEmits<{
'update:modelValue': [value: string]
}>()
const tenants = ref<PlatformTenantResource[]>([])
const loading = ref(false)
const error = ref('')
const selectedValue = computed({
get: () => props.modelValue,
set: (value: string) => emit('update:modelValue', value),
})
const statusLabels: Record<string, string> = {
PROFILE_REQUIRED: '待完善',
PENDING: '待审核',
ACTIVE: '启用',
REJECTED: '已驳回',
DISABLED: '已停用',
INACTIVE: '已停用',
ARCHIVED: '已归档',
}
function tenantLabel(tenant: PlatformTenantResource) {
const status = statusLabels[tenant.status] || tenant.status
const name = tenant.tenantName?.trim()
return status ? `${name || '未命名客户'} · ${status}` : name || '未命名客户'
}
async function loadTenants() {
loading.value = true
error.value = ''
try {
const result = await listPlatformTenants({ page: 1, size: 200, status: 'ACTIVE' })
tenants.value = result.records.filter((tenant) => tenant.status === 'ACTIVE')
if (!props.modelValue && tenants.value.length) {
emit('update:modelValue', String(tenants.value[0].id))
}
} catch (reason) {
error.value = reason instanceof Error ? reason.message : '客户列表加载失败,请重试'
} finally {
loading.value = false
}
}
onMounted(() => void loadTenants())
</script>
<template>
<div class="platform-tenant-selector">
<div class="platform-tenant-selector-label"><span>{{ label }}</span><span v-if="loading">加载中…</span></div>
<el-select
v-model="selectedValue"
class="platform-tenant-selector-input"
filterable
:disabled="disabled || loading || tenants.length === 0"
:placeholder="loading ? '正在加载客户' : '请选择目标客户'"
:aria-label="label"
>
<el-option v-for="tenant in tenants" :key="String(tenant.id)" :label="tenantLabel(tenant)" :value="String(tenant.id)" />
</el-select>
<div v-if="error" class="platform-tenant-selector-error" role="alert">
<span>{{ error }}</span>
<el-button link type="primary" :disabled="loading" @click="loadTenants"><RefreshCw :size="14" />重新加载</el-button>
</div>
</div>
</template>
<style scoped>
.platform-tenant-selector { display: grid; min-width: min(100%, 360px); gap: 6px; }
.platform-tenant-selector-label { display: flex; align-items: center; justify-content: space-between; gap: 12px; color: var(--cc-muted); font-size: 12px; }
.platform-tenant-selector-label span:last-child { color: var(--cc-primary); font-size: 11px; }
.platform-tenant-selector-input { width: 100%; }
.platform-tenant-selector-error { display: flex; align-items: center; justify-content: space-between; gap: 8px; color: var(--el-color-danger); font-size: 12px; line-height: 1.5; }
.platform-tenant-selector-error :deep(.el-button) { flex: 0 0 auto; }
</style>