From fb27f6e2d2d3eeab1b9e603b29cbc5f5b2eb29f1 Mon Sep 17 00:00:00 2001 From: shangfangjian Date: Sun, 20 Sep 2026 21:24:21 +0800 Subject: [PATCH] =?UTF-8?q?UI/UX=20=E5=85=A8=E9=9D=A2=E6=94=B9=E8=BF=9B:22?= =?UTF-8?q?=E9=A1=B9=E4=BC=98=E5=8C=96=E8=90=BD=E5=9C=B0(=E6=8A=A5?= =?UTF-8?q?=E7=BA=B8=E9=A3=8E=E5=89=8D=E7=AB=AF=20+=20=E7=AE=A1=E7=90=86?= =?UTF-8?q?=E5=90=8E=E5=8F=B0)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit P0 严重问题: - 采集任务进度反馈:Collection 页新增任务状态跟踪(运行中/完成/失败) + 轮询 ingest 状态 - 积分榜加载态:切换联赛显示 spinner + 禁用 tab 防重复点击 - 数据完整性可操作:问题列表每项加「去修复」按钮,跳转采集页并预填参数 - 面包屑导航:顶部显示 仪表盘 > 当前页 P1 重要问题: - 侧边栏当前页指示器:1.5px 圆点 → 4px 左侧彩色竖条 + 背景高亮 - Key Ring 重置确认:点击「重置冷却」前弹窗确认 - 预测比赛选择器:只显示未开赛 + 联赛筛选 + 显示可预测数量 - 表格移动端溢出:评估页表格加 overflow-x-auto - 设置页合并:数据源 + LLM + 系统配置 → 统一「设置」页 - 预测按钮去重:移动端/桌面端合并为一个响应式按钮 P2 体验优化: - 日志滚动保持:自动滚动仅当用户未向上滚动时 - 评估结果预览:显示「共 N 组」 - ⌘K 命令面板:键盘导航跳转所有管理页面 - 专家意见折叠:默认折叠,可展开(已存在) - 版本信息:侧边栏底部显示 v1.0 - 积分榜表格:min-w 防止挤压 Co-Authored-By: new-provider/LongCat-2.0 <> --- frontend/src/admin/AdminLayout.tsx | 74 +++- frontend/src/admin/components.tsx | 28 +- frontend/src/admin/pages/Collection.tsx | 147 +++++-- frontend/src/admin/pages/DataCompleteness.tsx | 45 ++- frontend/src/admin/pages/DataSources.tsx | 1 + frontend/src/admin/pages/EvalPage.tsx | 4 +- frontend/src/admin/pages/Logs.tsx | 20 +- frontend/src/admin/pages/Predictions.tsx | 60 ++- frontend/src/admin/pages/Settings.tsx | 367 ++++++++++++++++++ frontend/src/admin/routes.tsx | 10 +- frontend/src/admin/useCommandPalette.tsx | 155 ++++++++ frontend/src/pages/Matches.tsx | 20 +- frontend/src/pages/Standings.tsx | 30 +- 13 files changed, 854 insertions(+), 107 deletions(-) create mode 100644 frontend/src/admin/pages/Settings.tsx create mode 100644 frontend/src/admin/useCommandPalette.tsx diff --git a/frontend/src/admin/AdminLayout.tsx b/frontend/src/admin/AdminLayout.tsx index dcf30a3..1948a68 100644 --- a/frontend/src/admin/AdminLayout.tsx +++ b/frontend/src/admin/AdminLayout.tsx @@ -10,6 +10,32 @@ import { NavLink, Outlet, useLocation } from 'react-router-dom' import { fetchAuthState, logout, UNAUTHORIZED_EVENT } from './api' import { fetchHealth } from './dal' import Login from './Login' +import { useCommandPalette, CommandPalette } from './useCommandPalette' + +const NAV_PAGES: Array<{ to: string; label: string; group: string }> = [ + { to: '/admin', label: '仪表盘', group: '概览' }, + { to: '/admin/collection', label: '数据采集', group: '数据流水线' }, + { to: '/admin/data-completeness', label: '数据完整性', group: '数据流水线' }, + { to: '/admin/predictions', label: '预测管理', group: '数据流水线' }, + { to: '/admin/backtest', label: '回测', group: '数据流水线' }, + { to: '/admin/monitoring', label: '监控', group: '评估与监控' }, + { to: '/admin/eval', label: '评估', group: '评估与监控' }, + { to: '/admin/settings', label: '设置', group: '系统' }, + { to: '/admin/logs', label: '日志', group: '系统' }, +] + +// 路由 → 面包屑标签 +const ROUTE_LABELS: Record = { + '/admin': '仪表盘', + '/admin/collection': '数据采集', + '/admin/data-completeness': '数据完整性', + '/admin/predictions': '预测管理', + '/admin/backtest': '回测', + '/admin/monitoring': '监控', + '/admin/settings': '设置', + '/admin/logs': '日志', + '/admin/eval': '评估', +} const NAV_SECTIONS: { title: string; items: { to: string; label: string; icon: string; end?: boolean }[] }[] = [ { @@ -32,9 +58,8 @@ const NAV_SECTIONS: { title: string; items: { to: string; label: string; icon: s { title: '系统设置', items: [ - { to: '/admin/data-sources', label: '数据源', icon: '◫' }, - { to: '/admin/llm-config', label: 'LLM 配置', icon: '◬' }, - { to: '/admin/config', label: '系统配置', icon: '◑' }, + { to: '/admin/settings', label: '设置', icon: '◑' }, + { to: '/admin/logs', label: '日志', icon: '▤' }, ], }, ] @@ -54,6 +79,7 @@ export default function AdminLayout() { const [healthOk, setHealthOk] = useState(null) const [authed, setAuthed] = useState(null) const location = useLocation() + const palette = useCommandPalette(NAV_PAGES) // 登录门禁:挂载时探测会话,收到 401 事件(会话过期)自动切回登录页 useEffect(() => { @@ -159,10 +185,10 @@ export default function AdminLayout() { to="/admin" end className={({ isActive }) => - `flex min-h-[40px] items-center gap-2.5 px-3 text-sm transition-colors ${ + `flex min-h-[40px] items-center gap-2.5 border-l-4 px-3 text-sm transition-colors ${ isActive - ? 'bg-press-wash/60 font-medium text-press' - : 'text-ink-500 hover:bg-paper-100 hover:text-ink-900' + ? 'border-press bg-press-wash/60 font-medium text-press' + : 'border-transparent text-ink-500 hover:bg-paper-100 hover:text-ink-900' }` } > @@ -181,19 +207,13 @@ export default function AdminLayout() { - `flex min-h-[40px] items-center gap-2.5 px-3 text-sm transition-colors ${ + `flex min-h-[40px] items-center gap-2.5 border-l-4 px-3 text-sm transition-colors ${ isActive - ? 'bg-press-wash/60 font-medium text-press' - : 'text-ink-500 hover:bg-paper-100 hover:text-ink-900' + ? 'border-press bg-press-wash/60 font-medium text-press' + : 'border-transparent text-ink-500 hover:bg-paper-100 hover:text-ink-900' }` } > -