Files
fangke/docs/superpowers/plans/2026-09-18-visitor-detail-tabs.md
T

171 lines
7.0 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 访客详情页三栏 Tab 化 — 实现计划
> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
**Goal:** 访客详情页重组为三栏布局——左栏 ElTabs(访问时间线默认/会话/原始数据),中栏 2×2 统计卡+来源证据,右栏访问环境;含三级响应式降级。
**Architecture:** 单文件(admin/src/views/tracker/visitor/detail.vue,1479 行)纯模板+样式重组,逻辑/API/抽屉零改动。
**Tech Stack:** Vue3 + Element Plus(ElTabs/ElTabPane)+ SCSS。
**Spec:** docs/superpowers/specs/2026-09-18-visitor-detail-tabs-design.md
**现状锚点(实现者必读)**:
- 模板:62-75 行 4 统计卡横排(`div.vd-stats`);77-228 行 `div.vd-main` 双栏(78-227 左=时间线卡 `vd-timeline-card`;167-227 右=`div.vd-side` 含来源证据+访问环境);230-370 行 `div.vd-bottom-card`(ElTabs:sessions/raw 两 pane)
- 状态:695 行 `const activeTab = ref<'sessions' | 'raw'>('sessions')`;811 行附近 `watch(activeTab, ...)` 只匹配 `'raw'`(懒加载 rawBatches,**无需改动**)
- 样式:1093-1099 `.vd-main`(`minmax(0,1fr) 340px`);1101-1106 `.vd-side`;1409-1412 `.vd-bottom-card`;1463-1478 旧媒体查询(1200px 单栏 + 900px stats 两列)
- 统计卡数据:`statTiles` computed(模板 v-for),**不改动**
---
### Task 1: 模板重组 + activeTab 扩展
**Files:**
- Modify: `admin/src/views/tracker/visitor/detail.vue`(模板 62-370 区段 + 695 行状态)
- [ ] **Step 1: activeTab 扩展**(695 行):
```ts
const activeTab = ref<'timeline' | 'sessions' | 'raw'>('timeline')
```
(TS 会强制模板 v-model 类型吻合;`watch(activeTab)` 只匹配 'raw' 不动。)
- [ ] **Step 2: 模板重组**(62-370 行区段重排,结构如下):
```
删除:div.vd-stats(62-75 全宽横排区)——statTiles v-for 块移入中栏
删除:div.vd-bottom-card 外壳(230-231 与 369-370 的开闭标签)——两个 ElTabPane 内容保留
新的主体结构(替换现 77-370):
<div class="vd-main">
<!-- 左栏:三 tab -->
<div class="vd-card vd-tabs-card">
<ElTabs v-model="activeTab" class="detail-tabs">
<ElTabPane label="访问时间线" name="timeline">
<!-- 时间线工具行(原 vd-card-tools 整块迁入,含 RadioGroup+正倒序) -->
<!-- truncated ElAlert(原 115-122) -->
<!-- tl-body 时间线主体(原 124-226,原样) -->
</ElTabPane>
<ElTabPane :label="`会话(${detail?.sessions.length ?? 0})`" name="sessions">
<!-- 原底部 sessions pane 内容原样迁入(235-272) -->
</ElTabPane>
<ElTabPane label="原始数据" name="raw">
<!-- 原底部 raw pane 内容原样迁入(276-368) -->
</ElTabPane>
</ElTabs>
</div>
<!-- 中栏:统计卡(2×2)+ 来源证据 -->
<div class="vd-side">
<div class="vd-stats"> <!-- statTiles v-for 原样,容器改由样式控制 2×2 -->
...原 64-74 卡片模板块...
</div>
...来源证据卡(原 168-204 原样)...
</div>
<!-- 右栏:访问环境(原 205-227 卡,提出 vd-side 成独立栏) -->
<div class="vd-side">
...访问环境卡原样...
</div>
</div>
```
注意:时间线卡的 `vd-card-head`(81-113)取消卡头形态——标题职能由 tab label 承担,工具行(`vd-card-tools` 内容)改为 pane 内顶部一行工具条(保留现有类名与功能,外层可套 `div.vd-tl-tools` flex 容器,样式 Task 2 补)。
- [ ] **Step 3: 编译验证**
Run: `cd admin && npx vue-tsc --noEmit 2>&1 | head -5`
Expected: 无与 detail.vue 相关错误
- [ ] **Step 4: Commit**
```bash
git add admin/src/views/tracker/visitor/detail.vue
git commit -m "feat(admin): 访客详情模板重组三栏Tabs——时间线/会话/原始数据合并左栏
Co-Authored-By: Claude Code <noreply@anthropic.com>"
```
---
### Task 2: 样式区更新(三栏 grid/统计卡 2×2/断点替换)
**Files:**
- Modify: `admin/src/views/tracker/visitor/detail.vue`(样式区 1092-1478)
- [ ] **Step 1: .vd-main 三栏**(1093-1099 替换):
```scss
.vd-main {
display: grid;
grid-template-columns: minmax(0, 2fr) minmax(0, 1fr) minmax(0, 1fr);
align-items: start;
gap: 20px;
margin-bottom: 16px;
}
```
- [ ] **Step 2: .vd-stats 2×2 窄卡形态**(找到现有 .vd-stats 样式块改写):`grid-template-columns: repeat(2, minmax(0, 1fr))`、gap 12px;卡片内缩(padding 减、`.vd-stat-value` 字号从现值降 2px 档)——保持客迹 V1 色板,具体值实现时按 460px 栏宽目测微调,方向:更紧凑。
- [ ] **Step 3: tabs 卡与工具条样式**:
- `.vd-tabs-card`:padding 收窄(tabs 自带间距,`padding: 0 20px 16px` 起)
- `.vd-tl-tools`:`display:flex; align-items:center; flex-wrap:wrap; justify-content:flex-end; gap:8px 12px; padding:12px 0 4px;`
- 原 `.vd-timeline-card` 专属样式保留复用(tl-body/tl-day 等不动)
- 删除 `.vd-bottom-card` 样式块(1409-1412);`.detail-tabs` 若有样式微调确保 tab 头部对齐卡 padding
- [ ] **Step 4: 断点替换**(1463-1478 整块替换):
```scss
// 响应式:两栏(访问环境下沉中栏底)→ 单栏
@media (max-width: 1400px) {
.vd-main {
grid-template-columns: minmax(0, 2fr) minmax(0, 1fr);
}
// 第三栏(访问环境)flow 到下方占满两栏
.vd-main > :last-child {
grid-column: 1 / -1;
}
}
@media (max-width: 1000px) {
.vd-main {
grid-template-columns: minmax(0, 1fr);
}
.vd-stats {
grid-template-columns: repeat(2, minmax(0, 1fr));
}
}
```
(900px 的 `.vd-hstat-divider { display:none }` 规则**保留**——属头部卡不动区,单独留下。)
- [ ] **Step 5: build 验证**
Run: `cd admin && pnpm build 2>&1 | tail -3`
Expected: ✓ built
- [ ] **Step 6: Commit**
```bash
git add admin/src/views/tracker/visitor/detail.vue
git commit -m "feat(admin): 访客详情三栏样式——2fr/1fr/1fr、统计卡2×2、断点1400/1000替换旧规则
Co-Authored-By: Claude Code <noreply@anthropic.com>"
```
---
### Task 3: 四档视口验证 + 部署
- [ ] **Step 1: dev server + Playwright 四档截图**(1920/1365/1100/900),需登录进访客详情(选一个有数据的访客):
- 1920:三栏 + tabs 默认时间线
- 1365:三栏(>1400 临界下)观察
- 1100:两栏(访问环境下沉)
- 900:单栏堆叠(顺序 tabs→统计→证据→环境)
- 冒烟:tab 切换三页、会话抽屉打开、原始抽屉打开、时间线 7/30/90 切换与正倒序
- 发现布局问题回 Task 1/2 修正
- [ ] **Step 2: 部署**(标准流程):`pnpm build` → tar dist → scp 经跳板 → 解压 /opt/cms-cj → **cp -rf dist/* admin/dist/**(真实 nginx 挂载点,勿只解压到 dist/)→ curl 验证新哈希
- [ ] **Step 3: 线上验证**:Playwright 登录 → 访客详情页截图核对三栏 tabs 生效;汇报版本哈希