Files
star-chart-search-enhancer/docs/superpowers/specs/2026-07-17-market-favorites-design.md
T
2026-07-17 11:27:47 +08:00

8.4 KiB

星图达人收藏夹设计

背景

星图达人市场页已有列表筛选、导出和提交批次能力,但用户无法保存跨筛选条件、跨页面发现的优质达人。本功能新增本地收藏夹:用户可将达人归入多个不同主题的收藏夹,在需要时从收藏夹批量导入秒探。

收藏数据只保存在当前浏览器的当前插件配置中,不提供跨设备同步、团队共享或后端持久化。

目标

  • 支持创建、改名和删除收藏夹。
  • 支持将同一达人加入多个收藏夹;同一达人在同一收藏夹内只保留一条关联。
  • 在市场列表每一行提供独立收藏入口,收藏时立即选择一个或多个收藏夹。
  • 在页面右侧提供常驻的收藏夹入口和抽屉,用于浏览、整理、筛选和导入已收藏达人。
  • 从抽屉内复用既有批次提交接口导入秒探,不重新采集星图列表。

非目标

  • 不改变星图原生筛选、列表、下单或右侧服务栏功能。
  • 不把收藏夹塞入现有导出和筛选工具栏。
  • 不做插件弹窗中的第二套收藏夹管理界面。
  • 不保存完整市场行、视频、指标和画像快照;收藏夹不是历史报表。
  • 不实现跨设备同步、协作共享、后端备份或导入历史。

方案选择

方案 A:右侧入口 + 抽屉 + 行内收藏选择器

页面右侧提供收藏夹入口,点击后打开抽屉;每行收藏图标只打开贴近图标的收藏夹选择器。

优点:收藏、查看和导入各自处于最合适的位置;不挤占现有工具栏;适合频繁浏览和长期整理。

缺点:需要处理与星图原生右侧服务栏的空间和层级关系。

方案 B:行内图标直接打开右侧抽屉

每次收藏都先打开抽屉,再在抽屉中选择收藏夹。

优点:交互组件较少。

缺点:单个达人收藏需要跨越页面宽度,频繁操作成本高。

方案 C:工具栏按钮 + 模态框

在现有插件工具栏中增加收藏相关按钮,使用模态框管理收藏夹。

优点:实现边界集中。

缺点:工具栏已经承担导出、提交和筛选;收藏夹作为长期资产放在这里会造成信息和操作拥挤。

采用方案 A。

页面与交互

右侧入口

  • 在星图原生右侧服务栏左侧固定一个窄入口,使用书签图标和 收藏夹 文本。
  • 入口避开原生的帮助、联系和客服按钮;在窄视口保持图标入口,不遮挡页面内容。
  • 入口可显示总收藏数,但不使用红色未读角标,以免被理解为通知。
  • 点击入口打开右侧抽屉;再次点击入口或抽屉关闭按钮可关闭抽屉。

行内收藏

  • 在每个有效达人行的原生 操作/下单 控件之前增加书签图标,不修改或覆盖原生操作。
  • 未收藏时显示描边书签,悬停提示 加入收藏夹
  • 已收藏至至少一个收藏夹时显示粉色实心书签,悬停提示 已收藏至 N 个收藏夹
  • 点击图标在图标附近打开小型选择器,列出所有收藏夹及该达人的当前归属状态;用户可多选或取消选择。
  • 小型选择器提供 新建收藏夹,成功创建后立即把当前达人加入新收藏夹。
  • 达人没有可用 authorId 时,图标不可用并说明无法收藏该达人。

收藏夹抽屉

  • 抽屉从右侧滑入,宽度为 380-420px,位于原生右侧服务栏左侧;打开或关闭都不改变星图列表的筛选、滚动和横向滚动位置。
  • 顶部包含 收藏夹 标题和 新建收藏夹 操作。
  • 默认显示 全部达人。同一达人即使在多个收藏夹中,也只显示一条记录。
  • 用户可切换为某个收藏夹,只查看该收藏夹中的达人;支持按达人名称搜索。
  • 每个达人显示最小身份信息、加入时间和操作菜单。操作菜单支持从当前收藏夹移除;在 全部达人 中仅展示归属,不提供破坏性的一键全局删除。
  • 抽屉列表支持复选,底部固定操作区显示已选人数。

导入秒探

  • 导入已选 N 位达人:抽屉内至少勾选一位达人后可用。
  • 导入当前收藏夹全部达人:仅在查看具体收藏夹时可用,点击后必须显示二次确认,并写明本次导入人数。
  • 两个入口都先按 authorId 去重,再映射为既有批次 payload 所需的最小 MarketRecord 数据。
  • 沿用既有登录校验、批次名称输入、createBatchPayload() 和秒探批次提交客户端。
  • 导入成功后保留收藏和收藏夹成员关系;失败时不改变本地数据,并显示既有提交错误或明确的收藏夹错误。

本地数据

使用 chrome.storage.local,不使用内容脚本页面的 window.localStorage。插件清单已声明 storage 权限,插件存储不会与星图网页站点数据混用。

首版数据采用一个版本化根对象,便于整体校验和迁移:

type FavoritesStateV1 = {
  version: 1;
  folders: Array<{
    id: string;
    name: string;
    createdAt: string;
    updatedAt: string;
  }>;
  creators: Array<{
    authorId: string;
    authorName: string;
    coreUserId?: string;
    savedAt: string;
  }>;
  memberships: Array<{
    authorId: string;
    folderId: string;
    addedAt: string;
  }>;
};
  • creatorauthorId 唯一;多收藏夹通过 memberships 表达,避免复制达人数据。
  • memberships(folderId, authorId) 唯一。
  • 删除收藏夹只删除其成员关联;没有任何关联的达人记录可以一并清理。
  • 导入时若存在 coreUserId,继续作为现有 payload 的 authorUid 发送。
  • 读取缺失、格式错误或未知版本时视为未初始化状态,不应阻断市场页其他能力;写入失败必须向用户反馈。

模块边界

  • 收藏数据仓库:读写、迁移、去重、收藏夹和成员关系规则;不依赖 DOM 或批次接口。
  • 行内收藏装饰:从市场行读取最小达人身份,渲染书签和选择器;不负责抽屉列表。
  • 收藏夹抽屉:呈现文件夹和达人,处理搜索、选择和管理操作;通过数据仓库获取状态。
  • 收藏夹导入适配层:将收藏达人转换为最小 MarketRecord[],调用现有批次提交流程;不直接读写浏览器存储。
  • 市场控制器:组装这些模块并协调抽屉、行内状态与繁忙态。

状态与错误处理

  • 收藏或取消收藏后,行内图标、选择器和已打开抽屉必须立刻同步。
  • 新建、改名和删除收藏夹时,名称去除首尾空格;空名称不可保存。删除前确认。
  • 导入执行期间,抽屉的导入和管理操作禁用,结束后恢复。
  • 导入前没有有效达人时,不打开批次名称输入,也不调用提交接口。
  • 对包含多个收藏夹成员的导入,提交前按 authorId 去重,避免发送重复作者。
  • 读取或写入插件存储失败时,只提示收藏夹操作失败,不影响星图原生页面或既有导出/提交功能。

验收标准

  1. 用户可创建、改名和删除收藏夹;删除收藏夹不删除其他收藏夹中相同达人。
  2. 同一达人可加入多个收藏夹,但不会在同一收藏夹重复出现。
  3. 每个有效达人行均有独立收藏图标,且不会影响星图原生 下单 等操作。
  4. 行内图标可以打开多选收藏夹选择器,选择器可即时新建收藏夹并完成收藏。
  5. 右侧入口不与星图原生右侧服务栏重叠;点击后抽屉能显示全部达人和具体收藏夹中的达人。
  6. 抽屉的 全部达人 视图对跨收藏夹的同一达人去重;具体收藏夹视图只显示该收藏夹成员。
  7. 用户可导入已选达人;用户也可导入当前收藏夹全部达人,但必须经过人数明确的二次确认。
  8. 导入复用现有批次 payload 和提交接口,携带已有的 authorIdauthorName 和可选 authorUid;成功后收藏不丢失。
  9. 浏览器存储不可用、达人缺少 ID、空收藏夹、空选择和提交失败均有清晰反馈。

验证范围

  • 收藏数据仓库的创建、改名、删除、成员去重、跨收藏夹关联、序列化错误恢复测试。
  • 行内书签、选择器、新建收藏夹和状态同步的 DOM 测试。
  • 抽屉的默认视图、文件夹切换、搜索、移除、选择和全量导入确认测试。
  • 收藏达人到批次 payload 的映射、跨收藏夹去重、登录失败、提交成功/失败测试。
  • 运行相关 Vitest 测试和 npm run build