diff --git a/serve/frontend/src/pages/Financials.tsx b/serve/frontend/src/pages/Financials.tsx index 886f5c8..c2e3075 100644 --- a/serve/frontend/src/pages/Financials.tsx +++ b/serve/frontend/src/pages/Financials.tsx @@ -1,5 +1,5 @@ -import { useState, useEffect } from 'react' -import { RefreshCw, Lock, Loader2, X, Search, FileText, Database, CheckCircle2, Hourglass, Lightbulb, ExternalLink } from 'lucide-react' +import { useState } from 'react' +import { Loader2, Search, FileText, Database, Lightbulb, ExternalLink, X } from 'lucide-react' import { PageHeader } from '@/components/PageHeader' import { EmptyState } from '@/components/EmptyState' import { useFinancialStatus } from '@/lib/useFinancials' @@ -9,7 +9,6 @@ import { ReportHistoryPanel } from '@/components/financials/ReportHistoryPanel' import { LastStockChip } from '@/components/LastStockChip' import { useLastStock } from '@/lib/useLastStock' import { fmtBigNum } from '@/lib/format' -import { toast } from '@/components/Toast' const TABLE_LABELS: Record = { metrics: '核心指标', @@ -68,72 +67,15 @@ export function Financials() { 前往 Issues 推荐 - ) } // 有同步数据, 继续展示 - } - - const handleSync = (table: string) => { - // 防重复点击:syncing 中不再触发(后端 trigger 也有 _is_syncing 兜底) - if (syncing) return - // 记录开始时间: 全量同步判断所有 4 张表, 单表同步只判断这一张 - setSyncStartedAt(Date.now()) - setSyncSingleTable(table === 'all' ? null : table) - syncMut.mutate(table, { - onSuccess: (r) => { - // 后端 trigger 立即返回 started 状态;若被防并发跳过(已有同步在进行), - // 给用户明确反馈,并清空本次误设的记录。 - if (!r.synced?.started) { - if (r.synced?.reason === 'already running') { - toast('财务数据正在同步中,请稍候', 'success') - } else if (r.synced?.reason === 'no FINANCIAL capability') { - // 能力未就绪:通常发生在升级/刷新 Key 后调度器状态未同步 —— 提示用户检查 Key - toast('财务数据能力未就绪,请检查 API Key 或刷新页面后重试', 'error') - } else { - toast(`同步未能开始${r.synced?.reason ? `:${r.synced.reason}` : ''}`, 'error') - } - setSyncStartedAt(null) - setSyncSingleTable(null) - } - }, - onError: () => { - // 请求失败:清空本次记录(request 已弹错误 toast) - setSyncStartedAt(null) - setSyncSingleTable(null) - }, - }) - } const tables = status?.tables ?? {} const available = status?.available ?? false - const lastSync = status?.last_sync ?? {} - // 本次同步进度: 仅当 syncStartedAt 存在且 syncing 时, 按 last_sync 时间戳判断 - const isFullSync = syncing && syncStartedAt && !syncSingleTable // 全量同步 - const isSingleSync = syncing && syncStartedAt && !!syncSingleTable // 单表同步 - const TABLE_ORDER = ['metrics', 'income', 'balance_sheet', 'cash_flow'] as const - const tableDoneThisRound = (key: string): boolean => { - if (!syncStartedAt || !syncing) return false - // 单表同步: 只判断这一张表是否完成 - if (syncSingleTable && key !== syncSingleTable) return false - const ls = lastSync[key] - if (!ls) return false - return new Date(ls).getTime() >= syncStartedAt - } - // 当前正在同步的表: - // 全量同步 → 第一个未完成的; 单表同步 → 那张表(未完成时) - const currentSyncingTable = syncing && syncStartedAt - ? (syncSingleTable - ? (tableDoneThisRound(syncSingleTable) ? null : syncSingleTable) - : TABLE_ORDER.find(t => !tableDoneThisRound(t)) ?? null) - : null - const syncedCount = TABLE_ORDER.filter(t => tableDoneThisRound(t)).length - // 卡片三态: 仅全量同步时未轮到的表显示"等待"; 单表同步时其他表保持原样 - const isWaitingTable = (key: string): boolean => - !!isFullSync && !tableDoneThisRound(key) && currentSyncingTable !== key return ( <> @@ -143,40 +85,13 @@ export function Financials() { right={
- {syncing && ( - - - {isFullSync - ? `已同步 ${syncedCount}/4 张表…` - : isSingleSync - ? `同步${TABLE_LABELS[syncSingleTable!] ?? syncSingleTable}…` - : '同步中…'} - - )} - {hasFinancial && ( - - )} +
} />
- {syncing && ( -
- - 正在从 TickFlow 拉取财务数据,请稍候… -
- )} + {/* 同步状态卡片 —— 始终显示,反映本地财务数据概况 */} {!isLoading && available && ( @@ -187,49 +102,22 @@ export function Financials() { const TIcon = TABLE_ICON[key] ?? Database const hasData = (info?.rows ?? 0) > 0 // 本次同步三态: 完成 / 同步中 / 等待 (仅全量同步时未轮到的表才"等待") - const doneThisRound = tableDoneThisRound(key) - const isThisSyncing = currentSyncingTable === key - const isWaiting = isWaitingTable(key) + return (
- {doneThisRound ? ( - - ) : isThisSyncing ? ( - - ) : isWaiting ? ( - - ) : ( - - )} + {label}
- {hasFinancial ? ( - - ) : ( -
- )} +
{fmtBigNum(info?.rows ?? 0)}