91 lines
3.2 KiB
Vue
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>
|