diff --git a/serve/frontend/src/components/Layout.tsx b/serve/frontend/src/components/Layout.tsx
index e154944..176b92a 100644
--- a/serve/frontend/src/components/Layout.tsx
+++ b/serve/frontend/src/components/Layout.tsx
@@ -1,4 +1,3 @@
-import { useEffect, useRef, useState } from 'react'
import { NavLink, Outlet } from 'react-router-dom'
import { useQuery } from '@tanstack/react-query'
import { motion } from 'framer-motion'
@@ -20,8 +19,6 @@ import {
FileText,
Settings,
Key,
- Database,
- Loader2,
LayoutDashboard,
Tags,
TrendingUp,
@@ -30,14 +27,11 @@ import {
Sparkles,
Layers3,
Landmark,
- RadioTower,
- CheckCircle2,
BookOpenCheck,
} from 'lucide-react'
import { Logo } from './Logo'
import { api } from '@/lib/api'
import { cn } from '@/lib/cn'
-import { setCurrentTotal as setAlertTotal, useUnreadAlerts } from '@/lib/monitorBadge'
// 品牌色 — 只用于 logo / brand 区域,不影响功能语义色
const BRAND = '#8B5CF6'
@@ -50,27 +44,10 @@ const nav = [
{ to: '/concept-analysis', label: '概念分析', icon: Layers3 },
{ to: '/industry-analysis', label: '行业分析', icon: Landmark },
{ to: '/financials', label: '财务分析', icon: FileText },
- { to: '/monitor', label: '监控中心', icon: RadioTower },
{ to: '/review', label: '复盘', icon: BookOpenCheck },
{ to: '/indices', label: '指数', icon: BarChart3 },
- { to: '/data', label: '数据', icon: Database },
] as const
-/** 监控中心未读徽标 — 仅在非监控页且有未读时显示。 */
-function MonitorBadge({ active }: { active: boolean }) {
- const unread = useUnreadAlerts()
- // 尊重用户设置: 可在菜单设置里关闭数字提示
- const badgeEnabled = (() => {
- try { return localStorage.getItem('monitor_badge_enabled') !== '0' } catch { return true }
- })()
- if (active || unread <= 0 || !badgeEnabled) return null
- return (
-
- {unread > 99 ? '99+' : unread}
-
- )
-}
-
// ===== 档位卡片 =====
function TierBadge({ label, hasKey }: { label: string; hasKey?: boolean }) {
const base = label.split(' ')[0].split('+')[0].toLowerCase()
@@ -196,46 +173,8 @@ export function Layout() {
queryFn: api.analysisMenus,
})
- // 数据同步状态轮询: 有活跃 job 时「数据」菜单项显示转圈
- const { data: pipelineJobs } = useQuery({
- queryKey: QK.pipelineJobs,
- queryFn: () => api.pipelineJobs(1),
- refetchInterval: (query) => (query.state.data?.active_id ? 2000 : 15000),
- refetchIntervalInBackground: true,
- })
- const isDataSyncing = !!pipelineJobs?.active_id
-
- // 数据同步完成的"瞬时反馈": isDataSyncing 从 true→false 时显示绿色对勾,
- // 闪烁约 3 秒后自动消失。
- const [dataSyncJustDone, setDataSyncJustDone] = useState(false)
- const prevSyncingRef = useRef(false)
- useEffect(() => {
- // 仅在"刚结束"(true→false)且非首次挂载时触发
- if (prevSyncingRef.current && !isDataSyncing) {
- setDataSyncJustDone(true)
- const t = setTimeout(() => setDataSyncJustDone(false), 3000)
- prevSyncingRef.current = isDataSyncing
- return () => clearTimeout(t)
- }
- prevSyncingRef.current = isDataSyncing
- }, [isDataSyncing])
-
const version = versionData?.version
- // 轮询触发记录总数 → 更新监控中心徽标 (每 15 秒)
- const alertsTotalQuery = useQuery({
- queryKey: ['alerts-total'],
- queryFn: () => api.alertsList({ days: 7, limit: 1 }),
- refetchInterval: 15000,
- refetchIntervalInBackground: true,
- select: (data) => data.total,
- })
- // 只在拿到真实总数时同步徽标 (避免 data=undefined 时传 0 重置 lastSeen)
- const alertsTotal = alertsTotalQuery.data
- useEffect(() => {
- if (alertsTotal != null) setAlertTotal(alertsTotal)
- }, [alertsTotal])
-
// 合并内置页面 + 可见的扩展分析菜单
const analysisNav = (analysisMenus?.items ?? [])
.filter(m => m.visible)
@@ -321,15 +260,6 @@ export function Layout() {
Beta
)}
- {/* 数据同步状态: 同步中转圈, 刚完成显示绿色对勾闪烁 3 秒 */}
- {to === '/data' && isDataSyncing && (
-