import { defineStore } from 'pinia'; import { ref } from 'vue'; import { getScreenerSyncStatus, runScreener, startScreenerSync } from '@/api/client'; import type { ScreenerRunResponse, ScreenerSyncStatus } from '@/api/types'; export const useScreenerStore = defineStore('screener', () => { const loading = ref(false); const stage = ref<'idle' | 'parsing' | 'screening'>('idle'); const note = ref(null); const error = ref(null); const result = ref(null); const syncStatus = ref(null); let pollTimer: ReturnType | null = null; async function run(text: string) { loading.value = true; error.value = null; result.value = null; note.value = 'AI 解析条件中…'; stage.value = 'parsing'; try { // 条件解析与全市场筛选在后端一气呵成;切到筛选阶段给个过渡提示 setTimeout(() => { if (loading.value && stage.value === 'parsing') { stage.value = 'screening'; note.value = '全市场筛选中…'; } }, 1200); result.value = await runScreener({ text }); } catch (e) { error.value = e instanceof Error ? e.message : '选股失败'; } finally { loading.value = false; stage.value = 'idle'; note.value = null; } } async function fetchStatus() { try { syncStatus.value = await getScreenerSyncStatus(); } catch { /* 静默:状态拉取失败不阻塞页面 */ } } function stopPolling() { if (pollTimer) { clearInterval(pollTimer); pollTimer = null; } } async function startSync(days = 90) { error.value = null; try { await startScreenerSync({ days }); await fetchStatus(); stopPolling(); pollTimer = setInterval(async () => { await fetchStatus(); if (syncStatus.value && !syncStatus.value.running) stopPolling(); }, 2000); } catch (e) { error.value = e instanceof Error ? e.message : '启动同步失败'; } } return { loading, stage, note, error, result, syncStatus, run, fetchStatus, startSync, stopPolling }; });