# AgentEvalTool 前端开发日志 — 评测执行页改版 **日期**: 2026-07-15 **基线版本**: v0.2.0-dev **状态**: 已部署至 t480 开发线 **作者**: AgentEval Team --- ## 一、背景 本次开发在 v0.2.0-dev 基础上,对评测执行页(Runs)进行全面 UI 改版,同时修复了若干历史遗留的基础 Bug。 --- ## 二、关键 Bug 修复 ### 2.1 `index.css` 从未被引入(历史遗留) **症状**: 所有全局 CSS(动画、hover、布局覆盖规则)完全无效,但无报错提示。 **根因**: `main.tsx` 缺少 `import './index.css'`,Vite 不会自动包含未被引用的 CSS 文件,导致该文件从项目创建以来就从未生效。 **修复**: 在 `main.tsx` 顶部添加: ```tsx import './index.css' ``` **影响**: 修复后构建产物首次出现独立 `.css` 文件(`dist/assets/index-*.css`),全局 CSS 规则一次性全部生效。 --- ### 2.2 UTC 时间戳显示偏差 8 小时 **症状**: 评测记录时间比实际时间早 8 小时(如显示 16:40 实为次日 00:40 北京时间)。 **根因(三层叠加)**: ``` utc_now() → datetime(UTC) ↓ SQLite 不保存时区 "2026-07-14T16:40:00"(无 Z 后缀) ↓ ECMAScript 规范:无时区字符串按本地时间解析 new Date("2026-07-14T16:40:00") → 北京时间 16:40(比 UTC 多 8 小时) ``` **修复**: 在 `frontend/web/src/utils/date.ts` 添加 `toDate()` 工具函数: ```ts export function toDate(iso: string): Date { if (iso.endsWith('Z') || /[+-]\d{2}:\d{2}$/.test(iso)) return new Date(iso) return new Date(iso + 'Z') // 追加 Z,强制按 UTC 解析 } ``` 所有解析后端时间戳的地方统一使用 `toDate()`,不再直接 `new Date(str)`。 **注意**: 此问题根本解决方式是后端序列化时附带时区(如 `datetime.isoformat()` → `+00:00`),前端修复为应急兜底。 --- ### 2.3 时间过滤器与显示时区不一致 **症状**: 今天发起的记录显示为正确的北京时间,但选择「当天」时过滤器找不到这些记录。 **根因**: `shortDateTime()` 已使用 `toDate()`(UTC 解析正确),但 `RunList` 过滤器仍用 `new Date(r.started_at)` 按本地时间解析,两者时间基准不一致,差了 8 小时导致过滤失败。 **修复**: 过滤器改用 `toDate()` 统一时间基准: ```ts const t = r.started_at ? toDate(r.started_at).getTime() : null ``` --- ## 三、评测执行页改版详情 ### 3.1 全局布局修复 | 问题 | 修复方案 | |---|---| | 页面产生外层滚动条 | `App.tsx` tab 容器改为 `height: 100%, boxSizing: border-box`,消除 `minHeight + padding` 叠加导致的溢出 | | 页面顶部出现空隙 | `html, body { margin: 0; padding: 0 }` + 覆盖 Ant Design `editable-card` Tabs 默认 `paddingTop` | | Grid 子元素高度失效 | 增加 `gridTemplateRows: '1fr'`,显式让单行撑满 Grid 高度 | | 魔法数字 `calc(100vh - 152px)` | 用 `PageWrapper fullHeight` + flex 链代替,彻底去除硬编码数字 | | 内容区未贴边 | `Layout.Content` 及所有容器 padding 归零,内容贴合浏览器边缘 | ### 3.2 左侧面板 — 启动区 - **两行布局**: 第一行「评测对象」Select 全宽;第二行「评测场景 + 启动」并排 - **Select 增强**: `showSearch`(输入过滤)+ `allowClear`(清除按钮) - **背景色**: 区域改为 `colors.bgSubtle`(`#fafafa`)浅底色,与列表区视觉分隔 ### 3.3 左侧面板 — 筛选区 **三行布局:** ``` Row 1: [搜索框 full-width] Row 2: [全部 进行中 成功 失败] [当天][1天][7天][30天] [N条] ``` **时间快捷标签**(替代 DatePicker): - 当天:自然日 00:00 ~ 23:59(本地时间) - 1天:昨天 + 今天 - 7天:最近 7 天含今天 - 30天:最近 30 天含今天 - 默认选中「当天」;再次点击取消(回到全部时间) **状态分段**: 默认「全部」,选中态蓝底白字(ConfigProvider Segmented token) **时间标签颜色**: 激活态蓝色实心背景 + 白字;未激活态深灰边框 + 深色文字 ### 3.4 左侧面板 — 列表 | 项目 | 改动 | |---|---| | 行结构 | 三行固定(名称/元信息/进度条),等高不抖动 | | 进度条 | pending/running 显示蓝色动态进度(来自 liveProgress);completed 显示通过率色阶 | | 分页 | 每页 10 条,底部固定分页栏(始终占位,布局稳定) | | 排序 | 去掉错误的 `.reverse()`,API 已按 `started_at DESC` 返回 | | hover | 去掉 `onMouseEnter/Leave` 直接操作 DOM,改为 CSS `.run-row:hover` | ### 3.5 右侧面板 — Tab 滚动 **问题**: 三个 Tab(实时对话、规则总览、用例明细)内容区无法独立滚动。 **根因**: Ant Design v5 使用 CSS-in-JS(emotion)在运行时注入样式,覆盖了静态 CSS 文件中的 `flex`/`height` 规则,导致 Tab 内容区高度链断裂。 **最终方案(导航与内容分离)**: ``` Tabs(.nav-only-tabs):只渲染导航头,内容区 display: none ↓ 三个内容 div(直接 flex 子元素): flex: 1, min-height: 0, overflowY: auto → 高度由 flex 算法直接确定,不经过 Ant Design 内部 DOM ``` ```css .ant-tabs.nav-only-tabs .ant-tabs-content-holder { display: none !important; } ``` 三个 Tab 的滚动各自独立,互不干扰。 --- ## 四、其他优化 | 项目 | 内容 | |---|---| | 代码去重 | 提取 `startRun()` 函数,消除 `handleStart` 与 `onRerun` 重复逻辑 | | 死代码清理 | 删除 `sessionReducer` 中从未被 dispatch 的 `SET_RUN` action | | 工具函数复用 | `RunList` 改用 `shortDateTime` / `elapsedStr`,删除本地重复的 `formatStart` / `durationStr` | | 类型安全 | `run.summary as any` 改为 `Record` 类型收窄 | | Bundle 瘦身 | 用时间标签替代 DatePicker,vendor chunk 缩小约 107KB | | CSS 组件化 | Segmented 选中态、Run list hover 统一移入 ConfigProvider token / CSS 类,不再散落在组件 inline style | --- ## 五、t480 部署记录 **部署前环境补全**(首次排查发现): `.env` 只有 1 个键(`AGENTEVAL_ALLOWED_ORIGINS`),缺失以下配置: ```bash AGENTEVAL_API_KEY= AGENTEVAL_OPENCLAW_UPSTREAM=http://openclaw-eval:18789 AGENTEVAL_OPENCLAW_WS_UPSTREAM=ws://openclaw-eval:18789 AGENTEVAL_OPENCLAW_PROXY_USER=agenteval AGENTEVAL_OPENCLAW_AUTH_TOKEN=change-me-in-production ``` 已通过 SSH 补全,OpenClaw 代理功能恢复正常。 --- ## 六、遗留问题 | 问题 | 状态 | 说明 | |---|---|---| | case-001 无发送气泡 | 待查 | 只有智能体回复,无用户发送内容;需确认 DB 中 `turn.sent_message` 字段内容 | | UTC 时间后缀 | 待优化 | 当前前端追加 `Z` 兜底;根本修复需后端序列化附带时区标记 | --- ## 七、文件变更清单 **前端** - `src/main.tsx` — 添加 `import './index.css'` - `src/index.css` — html/body 重置、nav-only-tabs、TabBar padding 覆盖、Segmented 样式 - `src/App.tsx` — 布局修复(overflow、padding),Segmented token - `src/components/PageWrapper.tsx` — 新增 `fullHeight` prop - `src/pages/Runs.tsx` — 完整重构:布局、启动区、内联头部、Tab 分离 - `src/components/RunList.tsx` — 筛选区三行布局、时间标签、toDate 对齐、分页 - `src/utils/date.ts` — 新增 `toDate()`(export),修复时区 - `src/hooks/sessionReducer.ts` — 删除 `SET_RUN` 死代码