Files
admin-web/src/modules/iam/components/PlatformTenantSelector.vue
T
2026-08-12 12:19:02 +08:00

93 lines
3.3 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">
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: '已停用',
}
function tenantLabel(tenant: PlatformTenantResource) {
const status = statusLabels[tenant.status] || tenant.status
const name = tenant.tenantName?.trim()
const code = tenant.tenantCode?.trim()
const identity = name && code ? `${name}(${code})` : name || code || '未命名客户'
return status ? `${identity} · ${status}` : identity
}
async function loadTenants() {
loading.value = true
error.value = ''
try {
const result = await listPlatformTenants({ page: 1, size: 200 })
tenants.value = result.records
if (!props.modelValue && result.records.length) {
const preferred = result.records.find((tenant) => String(tenant.id) === '10001') || result.records[0]
emit('update:modelValue', String(preferred.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>