star-chart-search-enhancer/docs/superpowers/specs/2026-04-21-market-export-range-design.md
2026-04-21 17:10:06 +08:00

258 lines
6.9 KiB
Markdown

# 星图市场导出范围设计
## 背景
当前插件的 `导出CSV` 只导出当前页数据,并在星图默认列后追加两列:
- `单视频看后搜率`
- `个人视频看后搜率`
现阶段用户希望把导出范围扩展为可配置页数,而不是固定当前页。同时需要保留当前默认列导出逻辑,避免重新引入之前“全量扫描导致页面闪动、卡顿、排序异常”的问题。
## 目标
- 支持导出范围配置,默认导出前 `5` 页。
- 支持以下范围选项:
- `当前页`
- `前5页`
- `前10页`
- `全部`
- `自定义`
- 保留当前 CSV 规则:
- 先导出星图页面默认列
- 末尾追加两列插件字段
- 批量导出时真实翻页采集当前筛选结果页,不改变当前页面筛选条件来源。
- 保持当前“筛选/排序只作用当前页”的行为,不重新绑定多页扫描逻辑。
## 非目标
- 不改为直接调用星图列表接口拉多页数据。
- 不让插件筛选或排序自动跨页生效。
- 不处理“导出后自动回到最初分页位置”的复杂恢复,首版只要求滚动位置恢复到单页采集前。
## 交互设计
在插件工具栏中保留一个 `导出CSV` 按钮,同时新增导出范围控件。
### 范围控件
- 默认值:`前5页`
- 可选项:
- `当前页`
- `前5页`
- `前10页`
- `全部`
- `自定义`
- 选择 `自定义` 时,展示页数输入框
- 仅接受正整数
- 无效值时禁止导出并提示错误
### 任务状态
- 导出开始后:
- `导出CSV` 按钮禁用
- 筛选按钮、排序按钮、范围控件、自定义输入框一并禁用
- 按钮文案根据任务模式更新:
- 当前页:`导出中...`
- 前 N 页:`导出中 3/5 页...`
- 全部:`导出中 第3页...`
- 全部导出时额外显示轻提示:
- `全部导出可能耗时较长,页面会自动翻页。`
### 失败反馈
- 任一页采集失败时直接终止
- 通过按钮附近状态文本或 `alert` 提示:
- `第 N 页导出失败,请稍后重试`
- 失败时不下载残缺 CSV
## 执行流程
### 当前页导出
当前页模式沿用现有逻辑:
1. 等待当前页表格可读取
2. 自动滚动当前页一次,补齐懒加载字段
3. 读取当前页星图默认列
4. 合并插件两列
5. 生成 CSV 并下载
### 多页导出
多页模式仅在导出任务中启用,不影响平时筛选和排序。
1. 读取导出范围配置
2. 初始化批量任务状态与结果聚合器
3. 对当前页执行:
- 等待表格稳定
- 自动滚动当前页以采全默认列
- 读取当前页记录
-`authorId` 合并入结果集
4. 判断是否达到目标页数
5. 若未完成,则点击下一页
6. 等待“页切换完成”信号
7. 重复步骤 3 到 6
8. 汇总所有记录,生成单个 CSV 下载
### 全部导出停止条件
`全部` 模式从当前页开始向后翻页,直到任一条件成立:
- 下一页按钮不可点击
- 当前页签名不再变化
- 页面无法继续翻页并达到超时阈值
## 页切换判定
批量导出不能只依赖固定 `setTimeout`。翻页完成需要同时满足至少一个强信号:
- 当前页作者 ID 集合发生变化
- 当前页首行作者 ID 变化
- 当前页活动分页按钮变化
- 下一页按钮状态变化
为避免误判,翻页流程需要:
1. 记录翻页前页签名
2. 点击下一页
3. 轮询直到签名变化或超时
4. 签名变化后再执行一次当前页表格稳定等待
## 当前页采集策略
当前页导出已知存在懒加载问题:页面初加载时后半段行的默认列为空,滚动后才补齐。
因此无论当前页导出还是多页导出,每一页都必须执行:
1. 初次读取当前页快照并写入 store
2. 查找当前市场列表滚动容器
3. 逐步向下滚动直到该页底部
4. 每次滚动后等待 DOM 稳定,再采集一轮
5. 恢复滚动位置并再采集一轮
这一步只针对“当前已打开的页”,不跨页扫描。
## 数据合并规则
### 去重键
- 使用 `authorId` 去重
### 字段合并
- 新页记录有值时,补充到已有记录
- 新页记录为空时,不覆盖已有非空值
- 插件两列沿用当前已有的合并规则
### CSV 表头
- 先保留星图默认列顺序
- 再追加:
- `单视频看后搜率`
- `个人视频看后搜率`
## 错误处理
### 单页失败
以下情况视为单页失败:
- 找不到表格根节点
- 找不到下一页按钮但目标尚未完成
- 翻页后页签名未变化且超时
- 当前页采集过程中出现异常
处理方式:
- 立即终止任务
- 恢复工具栏控件状态
- 显示页级错误信息
- 不触发下载
### 用户干预
首版不额外提供取消按钮,但应防御以下情况:
- 用户手动切换筛选
- 用户手动翻页
- 用户再次点击导出
处理方式:
- 导出期间禁用插件控件
- 对关键节点重新校验表格和页签名
- 如环境已被破坏,终止任务并报错
## 实现建议
建议按以下边界组织实现:
### `plugin-toolbar`
- 新增导出范围选择器
- 新增自定义页数输入框
- 新增导出过程中的状态展示
### `market/index`
- 保留当前页导出逻辑作为单页模式
- 新增批量导出入口
- 管理任务状态、按钮禁用、进度回写
### 新建批量导出控制器
建议新增类似 `export-range-controller.ts` 的模块,职责包括:
- 读取当前页记录
- 控制翻页
- 等待页切换
- 聚合多页数据
- 统一返回最终 `MarketRecord[]`
这样可以避免把 `market/index.ts` 继续堆大。
### `dom-sync` 或新辅助模块
- 提供读取当前页签名
- 提供定位下一页按钮
- 提供判断下一页是否可点击
## 测试策略
### 单元测试
- 默认导出范围为前 5 页
- 选择 `当前页` 时只导出一页
- 选择 `前10页` 时最多导出 10 页
- `自定义` 输入非法值时不启动导出
- `全部` 模式在没有下一页时停止
- 多页合并时按 `authorId` 去重
- 空字段不会覆盖已有非空字段
### 集成测试
- 批量导出时会依次点击下一页
- 翻页后等待新页签名再采集
- 每一页在导出前都会执行滚动采集
- 中途某页失败时不生成 CSV
- 导出期间工具栏控件被禁用
## 风险
- 星图分页 DOM 结构可能不稳定,下一页按钮定位需要做降级兼容。
- 全部导出在高页数场景下耗时会较长。
- 页面中途刷新或筛选重算可能打断批量任务。
## 推荐实施顺序
1. 工具栏新增范围选择与自定义输入
2. 抽出批量导出控制器
3. 实现前 N 页导出
4. 在前 N 页能力稳定后开放 `全部`
5. 补齐全部相关失败与超时测试
## 决策结论
采用“一个导出按钮 + 范围选择器”的方案,默认导出前 `5` 页,支持 `全部``自定义`。批量模式通过真实翻页逐页采集当前筛选结果,不把多页扫描重新引入到筛选和排序链路中。