From 5e1e1a7529d7a7a6beac39bc0680faa465656f0b Mon Sep 17 00:00:00 2001 From: shy3130 Date: Wed, 24 Jun 2026 23:24:51 +0800 Subject: [PATCH] =?UTF-8?q?feat(sidebar):=20=E6=95=B0=E6=8D=AE=E8=8F=9C?= =?UTF-8?q?=E5=8D=95=E9=A1=B9=E5=90=8C=E6=AD=A5=E7=8A=B6=E6=80=81=E6=8C=87?= =?UTF-8?q?=E7=A4=BA=E5=99=A8=20(=E8=BD=AC=E5=9C=88/=E5=AE=8C=E6=88=90?= =?UTF-8?q?=E9=97=AA=E7=83=81)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 轮询 pipelineJobs: 有活跃 job 每 2s, 无活跃每 15s - 同步中: 数据菜单项右侧显示蓝色转圈 Loader2 - 同步完成: 切换为绿色对勾 CheckCircle2 + pulse 闪烁, 3 秒后消失 (用 ref 检测 isDataSyncing true→false 跳变触发) --- backend/app/__init__.py | 2 +- backend/pyproject.toml | 2 +- frontend/package.json | 2 +- frontend/src/components/Layout.tsx | 35 +++++++++++++++++++++++++++++- 4 files changed, 37 insertions(+), 4 deletions(-) diff --git a/backend/app/__init__.py b/backend/app/__init__.py index 7efdd83..4778f59 100644 --- a/backend/app/__init__.py +++ b/backend/app/__init__.py @@ -2,7 +2,7 @@ import sys -__version__ = "0.1.40" +__version__ = "0.1.41" # Windows 默认 stdout/stderr 编码为 GBK(cp936),TickFlow SDK 内部输出含 emoji 的 # 指数/标的名称(如 \U0001f193)时会抛 UnicodeEncodeError,导致请求失败。 diff --git a/backend/pyproject.toml b/backend/pyproject.toml index 17607b3..ba458f0 100644 --- a/backend/pyproject.toml +++ b/backend/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "tickflow-stock-panel-backend" -version = "0.1.40" +version = "0.1.41" description = "A 股选股 + 监控 + 回测面板 — TickFlow 适配" readme = "../README.md" requires-python = ">=3.11" diff --git a/frontend/package.json b/frontend/package.json index b76ab79..582ed66 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -1,7 +1,7 @@ { "name": "tickflow-stock-panel-frontend", "private": true, - "version": "0.1.40", + "version": "0.1.41", "type": "module", "scripts": { "dev": "vite", diff --git a/frontend/src/components/Layout.tsx b/frontend/src/components/Layout.tsx index debe33a..0af878b 100644 --- a/frontend/src/components/Layout.tsx +++ b/frontend/src/components/Layout.tsx @@ -1,4 +1,4 @@ -import { useEffect } from 'react' +import { useEffect, useRef, useState } from 'react' import { NavLink, Outlet, useNavigate } from 'react-router-dom' import { useQuery, useQueryClient } from '@tanstack/react-query' import { motion } from 'framer-motion' @@ -26,6 +26,7 @@ import { Key, Database, Timer, + Loader2, LayoutDashboard, Tags, TrendingUp, @@ -36,6 +37,7 @@ import { Landmark, Cable, RadioTower, + CheckCircle2, } from 'lucide-react' import { Logo } from './Logo' import { api, type IndexQuote } from '@/lib/api' @@ -258,6 +260,30 @@ 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 qc = useQueryClient() const navigate = useNavigate() const version = versionData?.version @@ -392,6 +418,13 @@ export function Layout() { <> {label} + {/* 数据同步状态: 同步中转圈, 刚完成显示绿色对勾闪烁 3 秒 */} + {to === '/data' && isDataSyncing && ( + + )} + {to === '/data' && !isDataSyncing && dataSyncJustDone && ( + + )} {/* 监控中心徽标: 仅非监控页且有未读时显示 */} {to === '/monitor' && }