摘要
这个项目面向蓝队防御和异常通信排查。后端负责 PCAP 解析、双向流聚合、候选筛选、UER-BERT 分类信号和报告产物,前端负责把任务、证据、模型边界和人工复核入口组织成可操作的研判工作区。
项目早期已经跑通了分析流程,但页面把上传、任务状态、结果摘要、报告和高风险流全部纵向堆在一起。功能虽然能用,用户却很难快速回答三个问题:现在发生了什么、我应该先看哪里、这个结论依据什么。
这次重构没有简单"换一套颜色",也没有让 AI Skill 直接替我决定设计。我把公开的 Frontend Design Skill 当成设计评审清单,用它检查页面是否存在模板化卡片、无意义装饰、错误的信息层级和移动端缺陷;再结合安全分析场景完成设计、编码和真实浏览器验证。
最终形成了四个独立工作区、一个有明确视觉焦点的分析首页、可追溯的候选证据抽屉,以及桌面端和移动端一致的研判路径。两组浏览器回归通过,pageerror 为 0,生产构建和依赖安全审计通过。
1. 先解决"看什么",再解决"好不好看"
原页面的问题不是颜色不够高级,而是所有功能权重相同。用户从页面顶部一路向下滚动,才能依次看到任务、结果、报告和候选流,页面长度随着结果数量增长。
可以把原来的信息结构简化为下面这张示意图:
┌──────────────────────────────────────┐
│ 上传文件 + 创建任务 │
├──────────────────────────────────────┤
│ 任务状态 + 进度 + 原始 JSON │
├──────────────────────────────────────┤
│ 最近任务表格 │
├──────────────────┬───────────────────┤
│ 结果摘要 │ 报告摘要 │
├──────────────────┴───────────────────┤
│ 高风险流预览(数据越多,页面越长) │
└──────────────────────────────────────┘
我先按用户任务重新划分信息架构,而不是继续在一页里增加折叠面板:
flowchart LR
A[分析工作台] --> B[新建分析]
A --> C[最近研判案卷]
A --> D[最近任务]
D --> E[任务中心]
E --> F[任务详情]
F --> G[研判概览]
F --> H[候选会话]
F --> I[证据与模型]
F --> J[报告与产物]
A --> K[知识检索]
四个一级入口各自只承担一个任务:
| 页面 | 核心问题 | 主要操作 |
|---|---|---|
| 工作台 | 最近发生了什么 | 新建分析、进入最近报告 |
| 任务中心 | 某个任务执行到哪里 | 搜索、筛选、打开任务 |
| 研判报告 | 结果和边界是什么 | 查看结论、协议分布、建议 |
| 知识检索 | 判断依据来自哪里 | 检索规则、协议和内部文档 |
这种拆分的价值是降低认知负担,而不只是减少页面长度。上传入口不再占据首页半屏,模型详情不会和任务列表争抢注意力,候选会话数量再多也由分页查询承接。
2. 我如何使用 Frontend Design Skill
Skill 给我的最大帮助不是生成 CSS,而是强迫我在编码前回答四类问题:
- 设计是否来自业务场景,而不是套用通用 SaaS 模板?
- 色彩、字体、布局和结构线是否承担真实信息含义?
- 页面是否只保留一个强视觉焦点,而不是每张卡片都抢注意力?
- 是否通过截图自评、键盘焦点、移动端和 reduced motion 验证质量底线?
我按"计划、审查、实现、自评"的顺序推进:
flowchart LR
A[理解安全研判任务] --> B[建立视觉 Token]
B --> C[检查模板化倾向]
C --> D[Vue 和 CSS 实现]
D --> E[Playwright 截图]
E --> F[视觉自评和错误检查]
F -->|发现问题| D
F -->|通过| G[自动化回归与构建]
这里有一个重要边界:Skill 是方法论和检查表,业务优先级、视觉方向、代码修改和验收标准仍由我负责。如果只说"我让 AI 帮我美化了页面",很难证明工程能力;如果能解释为什么这样分层、如何验证、哪里没有完成,才是可被追问的项目经验。
3. 视觉方向:借鉴品牌气质
最终 Token 如下:
| Token | 色值 | 语义 |
|---|---|---|
--nav |
#2c3031 |
固定导航与工作环境 |
--ink |
#252d30 |
主要标题和高对比文本 |
--accent |
#55aa2f |
主操作、当前状态、关键候选 |
--cyan |
#45bfc2 |
技术信号、协议分布、系统图标 |
--line |
#dde3e1 |
台账分隔与信息边界 |
对应的 CSS Token 直接覆盖 Element Plus 主色,避免业务组件和框架组件出现两套视觉系统:
:root {
font-family: "IBM Plex Sans Variable", "Microsoft YaHei UI", sans-serif;
--ink: #252d30;
--muted: #68777c;
--line: #dde3e1;
--accent: #55aa2f;
--cyan: #45bfc2;
--nav: #2c3031;
--el-color-primary: #55aa2f;
--el-border-radius-base: 4px;
}
字体使用项目自托管的 IBM Plex Sans Variable 表现英文、数字和模型名称,中文回退到本机无衬线字体。这样既强化了技术产品感,也没有依赖运行时访问公共字体 CDN。
4. 首页设计:把"最近研判"变成唯一视觉焦点
许多后台模板会把每个指标都做成独立圆角卡片,再给每张卡片加阴影。这样看起来整齐,却会让所有信息权重趋同。
我的处理方式是把四个指标合并为连续台账,用边线而不是阴影表达结构;再把最近一次研判设计成深色案卷。页面上只有这一区域使用深色网格和绿色识别线,用户进入系统后会自然先看到它。
.metric-grid {
display: grid;
grid-template-columns: repeat(4, minmax(0, 1fr));
gap: 0;
background: #fff;
border: 1px solid var(--line);
border-radius: 3px;
}
.latest-analysis {
background: linear-gradient(115deg, #303536, #3a4342);
border-left: 4px solid #62bd39;
color: #fff;
}
图 1:工作台只有一个强视觉焦点,周围模块保持克制。
指标下方没有直接写"发现 1 条恶意流量",而是写"调查候选"。这是安全业务中的关键语义:模型分类和规则命中只提供研判信号,不能自动等价为恶意结论。
5. 任务中心:让列表真正承担查询工作
任务中心保留状态筛选、任务 ID / 文件名搜索、模型筛选、后端分页和刷新。列表 DTO 不携带完整报告 JSON,详情按需查询,避免随着任务增加而让首页请求不断膨胀。
图 2:任务状态、分析方式和创建时间形成稳定扫描路径。
视觉上我避免给每行增加操作卡片。文件、模型、状态和时间按列对齐,绿色只用于当前选项和"查看报告",让主要动作更容易被定位。
6. 报告页:把结果、证据和模型边界分开
报告页是整个项目最需要克制的部分。一个风险分数很醒目,但它也最容易让人误以为系统已经完成安全定性。
因此我将详情拆成四个页签:
- 研判概览:候选数量、协议分布、人工复核建议。
- 候选会话:完整候选决策分页和会话搜索。
- 证据与模型:实际执行后端、筛选策略和模型能力边界。
- 报告与产物:JSON 产物下载及 LLM 辅助解读状态。
图 3:报告明确显示 UNKNOWN、待人工复核、兼容演示模型和 LLM 未启用。
这张页面没有为了"显得项目完整"而隐藏未完成能力。当前主模型检查点尚未完成商用 VPN 标签空间验收,因此实际执行后端显示为"UER-BERT 兼容演示模型";LLM 没有调用时显示"未启用"。对面试项目而言,可解释的边界比伪造一个高风险结论更重要。
7. 候选证据:从"给分"升级为"给依据"
用户点击候选会话后,右侧抽屉展示支持筛选的证据,包括观测值、规则阈值、证据分组和原始决策 ID。例如长会话和双向收发均衡属于两个不同证据组,前端不会把同组重复证据当成多个独立信号。
图 4:证据抽屉展示观测事实和阈值,不只展示一个无法复核的分数。
这个设计也为后续 Agent 链路预留了接口:LLM 可以接收候选流、UER-BERT 分类信号和知识检索片段,但输出必须引用证据 ID,不能绕过人工复核直接触发处置。
8. 移动端不是缩小桌面端
桌面端报告是双栏布局,移动端改为单列,并将四个统计指标调整为 2×2。页签保留横向滚动,主操作不被挤出屏幕;最近研判中的三个节点重新设置最小宽度,修复第三个"证据报告"被推到视口外的问题。
| 移动端工作台 | 移动端报告 |
|---|---|
图 5:390×844 视口下仍保留完整的信息顺序和操作路径。
除了布局,我还保留了键盘 focus-visible,并在自动化截图环境中启用 reduced motion,避免导航过渡导致截图停留在动画中间状态。
9. Playwright QA:让"看起来不错"变成可重复验证
视觉重构最容易出现的问题是桌面截图很好看,但真实交互、刷新、下载或移动端已经坏了。因此这次没有把 npm run build 作为唯一验收标准,而是使用 Playwright 驱动真实 Edge 浏览器完成回归。
核心检查包括:
| 检查项 | 验证方式 | 结果 |
|---|---|---|
| 工作台结构 | 真实离线产物,断言四个指标和最近报告入口 | 通过 |
| 任务筛选 | 状态、任务 ID 查询和空结果 | 通过 |
| 任务详情 | 直链进入、刷新和页签切换 | 通过 |
| 证据抽屉 | 打开候选并断言"持续时间"等真实证据 | 通过 |
| 报告下载 | 监听浏览器下载事件并校验文件名 | 通过 |
| 移动端 | 390×844 截图并断言无全页横向溢出 | 通过 |
| 浏览器异常 | 收集 pageerror |
0 |
| 依赖安全 | npm audit --audit-level=high |
0 漏洞 |
自动化流程使用的不是随手编造的 Dashboard 数据,而是项目已有真实 PCAP 分析产物生成的只读快照,地址已脱敏;另一组脚本直接读取 candidate_decisions.json 验证券据抽屉。
const errors = [];
page.on("pageerror", error => errors.push(error.message));
await page.goto(`${base}/?demo=1#/overview`);
assert.equal(await page.locator(".metric-card").count(), 4);
await page.setViewportSize({ width: 390, height: 844 });
assert.equal(
await page.evaluate(() => document.documentElement.scrollWidth > window.innerWidth + 1),
false
);
assert.deepEqual(errors, []);
10. 两个真实排障案例
10.1 字体精简路径写错,构建前被浏览器 QA 捕获
我最初为了减少字体资源,把入口写成了包中不存在的 latin.css。Vite HMR 页面立即显示导入错误。检查字体包的 exports 后,改用实际存在的 wght.css;字体文件带 Unicode Range,浏览器只请求页面需要的字形范围。
这个问题说明视觉开发也需要工程化验证。静态阅读 CSS 无法保证依赖入口存在,而真实浏览器复查可以在交付前捕获错误。
10.2 锁文件已经升级,运行时却仍是旧 Vite
依赖审计后,package-lock.json 显示 Vite 6.4.3,但磁盘中的实际包仍是 6.4.2。第一次超时返回的 npm ci 还在后台运行,后续安装与它并发清理 Element Plus,导致 Windows 报 ENOTEMPTY。
我通过进程命令行定位本轮遗留的 npm 进程,停止后单线程重装,最后从三个位置确认版本一致:
package.json version: 6.4.3
vite --version: 6.4.3
build banner: vite v6.4.3
这种排障比"删掉 node_modules 再试一次"更可解释,也避免误删其他项目进程或用户数据。
11. 可复现验证
在 frontend-web 目录启动前端:
npm install
npm run dev -- --port 5173
在项目根目录运行浏览器回归:
node scripts/check_workspace_ui.cjs
node scripts/check_candidate_ui.cjs storage/reports/DEMO-1a09e900ccda
生产构建与依赖审计:
cd frontend-web
npm run build
npm audit --audit-level=high
本轮实际结果:两组 UI 回归均为 PASS,桌面端和移动端 pageerror 为 0,Vite 生产构建通过。Element Plus 公共 chunk 仍约为 922 kB,这是当前已知问题。如果项目进入真实交付阶段,我会进一步做组件按需引入和 bundle 分析;当前项目用于本地演示,优先保证链路清晰、结果可复现,不为一个告警提前增加不必要复杂度。
12. 面试时如何讲这次重构
60 秒版本
这个平台最初已经能跑 PCAP 分析,但所有功能都堆在一个长页面里,用户不知道先看任务、模型还是报告。我先按蓝队研判流程重新划分工作台、任务中心、报告和知识检索,再使用 Frontend Design Skill 作为设计审查框架,重点排查通用卡片模板、无意义装饰和错误的信息权重。视觉上参考安全厂商的深灰、绿色和青色语言,但没有复制品牌资产;首页只把最近研判做成强焦点,报告页明确区分候选、证据、模型边界和人工复核。完成后我用 Playwright 基于真实脱敏产物验证桌面端、移动端、筛选、证据抽屉和下载,最后跑生产构建与依赖审计。这个过程证明的不只是页面美化,而是我能把业务语义、设计系统和工程 QA 串成闭环。
可能被追问的问题
为什么继续使用 Element Plus,而不是完全手写组件?
项目的目标是完成可演示的安全分析闭环。Element Plus 能快速提供表格、分页、抽屉和页签,我通过 CSS Token 和业务布局建立差异化视觉,而不是重复实现基础交互。若进入长期产品化阶段,再按 bundle 分析结果做组件级按需加载。
为什么模型结果不直接显示为恶意概率?
UER-BERT 的职责是流量分类信号,不是恶意行为定性。候选门还会组合规则和统计证据,最终页面使用"调查候选"和"待人工复核",避免把分类置信度误解为安全风险概率。
Skill 在项目里到底做了什么?
它提供了设计原则和自评清单,例如减少 SaaS 卡片套件、避免全大写装饰标签、只保留一个强焦点、截图复核和移动端质量底线。需求分析、视觉方案、Vue/CSS 实现、缺陷修复和验收由我完成。
如何证明不是只改了截图?
项目保留了浏览器回归脚本,会操作筛选、详情页签、证据抽屉和下载,并断言移动端无全页溢出、浏览器无 pageerror。设计结果可以通过同一组真实离线产物重复运行。
13. 我从这次实践中证明了什么
- 我能从业务流程而不是组件列表出发,完成信息架构和页面职责拆分。
- 我能把外部 Skill 转化为设计约束,而不是无判断地接受生成结果。
- 我能在 Vue 3 和 Element Plus 上建立一致的 Token、层级和响应式系统。
- 我理解安全产品中"分类信号、调查候选、恶意结论"之间的边界。
- 我会用真实浏览器、真实产物、构建和依赖审计完成可复现验证。
- 我能诚实保留未完成项,并说明如果进入生产阶段会如何继续优化。
结语
AI Skill 可以提高设计评审和实现效率,但它不能替代对业务语义、工程边界和质量结果负责。对这个 VPN 异常流量平台而言,真正有价值的不是把后台"做得像某个官网",而是让分析员在进入页面后的几秒内知道任务状态、候选数量、判断依据和下一步操作。
这次重构最终形成了一个可以运行、可以复查、可以继续扩展,也可以在面试中经得住追问的前端案例。





