Files
admin-web/src/modules/iam/useActiveCustomerOptions.ts
T
2026-10-20 23:34:11 +08:00

71 lines
2.6 KiB
TypeScript

import { computed, onScopeDispose, ref, watch } from 'vue'
import { getApiErrorDetails, type ApiErrorDetails } from '@/shared/api/http'
import type { PlatformTenantPage, PlatformTenantQuery, PlatformTenantResource } from './api/platformIam'
export function useActiveCustomerOptions(selectedId: () => string | null | undefined, loadPage: (query: PlatformTenantQuery) => Promise<PlatformTenantPage>) {
const records = ref<PlatformTenantResource[]>([])
const selected = ref<PlatformTenantResource | null>(null)
const loading = ref(false)
const error = ref<ApiErrorDetails | null>(null)
const keyword = ref('')
const page = ref(0)
const hasMore = ref(false)
let sequence = 0
let disposed = false
watch(selectedId, id => {
selected.value = id ? records.value.find(row => String(row.id) === id) || (String(selected.value?.id) === id ? selected.value : null) : null
}, { flush: 'sync' })
const customers = computed(() => {
const current = selected.value
if (!current || records.value.some(row => String(row.id) === String(current.id))) return records.value
return [current, ...records.value]
})
async function fetchPage(nextPage: number, append: boolean) {
if (disposed) return
const request = ++sequence
loading.value = true
error.value = null
try {
const result = await loadPage({ page: nextPage, size: 50, status: 'ACTIVE', ...(keyword.value ? { keyword: keyword.value } : {}) })
if (request !== sequence || disposed) return
const rows = [...(append ? records.value : []), ...result.records.filter(row => row.status === 'ACTIVE')]
records.value = [...new Map(rows.map(row => [String(row.id), row])).values()]
page.value = nextPage
hasMore.value = nextPage < result.pages
} catch (cause) {
if (request === sequence && !disposed) error.value = getApiErrorDetails(cause, '客户选项加载失败,请重试')
} finally {
if (request === sequence && !disposed) loading.value = false
}
}
function search(value = '') {
if (disposed) return
keyword.value = value.trim()
records.value = []
page.value = 0
hasMore.value = false
return fetchPage(1, false)
}
function loadMore() {
if (loading.value || error.value || !hasMore.value) return
return fetchPage(page.value + 1, true)
}
function endReached(direction: string) {
if (direction === 'bottom') return loadMore()
}
function retry() {
if (loading.value) return
return fetchPage(page.value + 1, page.value > 0)
}
onScopeDispose(() => { disposed = true; sequence++ })
return { customers, loading, error, search, endReached, retry }
}