Files
admin-web/src/modules/iam/components/PlatformTenantSelector.vue
T

91 lines
3.2 KiB
Vue
Raw Normal View History

2026-08-04 09:05:19 +08:00
<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,
2026-08-12 12:19:02 +08:00
label: '目标客户',
2026-08-04 09:05:19 +08:00
})
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
2026-08-12 12:19:02 +08:00
const name = tenant.tenantName?.trim()
2026-08-14 12:50:42 +08:00
return status ? `${name || '未命名客户'} · ${status}` : name || '未命名客户'
2026-08-04 09:05:19 +08:00
}
async function loadTenants() {
loading.value = true
error.value = ''
try {
2026-08-14 12:50:42 +08:00
const result = await listPlatformTenants({ page: 1, size: 200, status: 'ACTIVE' })
tenants.value = result.records.filter((tenant) => tenant.status === 'ACTIVE')
2026-08-04 09:05:19 +08:00
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) {
2026-08-12 12:19:02 +08:00
error.value = reason instanceof Error ? reason.message : '客户列表加载失败,请重试'
2026-08-04 09:05:19 +08:00
} 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"
2026-08-12 12:19:02 +08:00
:placeholder="loading ? '正在加载客户' : '请选择目标客户'"
:aria-label="label"
2026-08-04 09:05:19 +08:00
>
<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>