import { computed, ref, watch } from 'vue' import { buildReportAnalyticsQuery, getReportAnalytics, getReportOptions, type ReportAnalyticsDataset, type ReportOptions, } from '@/api/workbench/report-analytics' import { toUserMessage } from '@/utils/api-response' import { resolveDateWindow } from './aggregate' import { reportFilter } from './filter-store' const dataset = ref(null) const options = ref(null) const loading = ref(false) const errorMessage = ref('') const optionsError = ref('') let requestSequence = 0 let pendingOptions: Promise | null = null let filterWatcherInstalled = false let debounceTimer: ReturnType | null = null export function loadReportOptions(): Promise { if (options.value) return Promise.resolve() pendingOptions ??= (async () => { optionsError.value = '' try { options.value = await getReportOptions() } catch (error) { optionsError.value = toUserMessage(error, '报表筛选项加载失败') } finally { pendingOptions = null } })() return pendingOptions } export async function loadReportDataset(): Promise { const sequence = ++requestSequence dataset.value = null const dateWindow = resolveDateWindow(reportFilter) if (!dateWindow) { errorMessage.value = '' loading.value = false return } loading.value = true errorMessage.value = '' try { const query = buildReportAnalyticsQuery(reportFilter, dateWindow) const result = await getReportAnalytics(query) if (sequence === requestSequence) dataset.value = result } catch (error) { if (sequence === requestSequence) errorMessage.value = toUserMessage(error, '报表数据加载失败') } finally { if (sequence === requestSequence) loading.value = false } } function installFilterWatcher() { if (filterWatcherInstalled) return filterWatcherInstalled = true watch( () => [ reportFilter.dateRange, reportFilter.customFrom, reportFilter.customTo, reportFilter.campus, reportFilter.department, reportFilter.category, reportFilter.method, ], () => { if (debounceTimer) clearTimeout(debounceTimer) debounceTimer = setTimeout(() => void loadReportDataset(), 250) }, ) } export function resetReportDataset(): void { dataset.value = null requestSequence++ if (debounceTimer) clearTimeout(debounceTimer) } export function useReportDataset() { installFilterWatcher() const window = computed(() => resolveDateWindow(reportFilter)) const available = computed(() => dataset.value !== null) const generatedAt = computed(() => dataset.value?.generatedAt ?? '') const customRangeIncomplete = computed( () => reportFilter.dateRange === 'custom' && (!reportFilter.customFrom || !reportFilter.customTo), ) return { dataset, options, window, available, generatedAt, loading, errorMessage, optionsError, customRangeIncomplete, } }