# 寻访网页方案 ## 目标 网页继续使用一个 Toy 包和一个 `index.html`,首页展示版本日历,并提供战斗数据解析和寻访统计两个入口。寻访云存档只使用 Toy CloudStorage,不接入 CloudBase。 ## 页面与路由 采用当前项目已经使用的 Hash 路由,不新增多个 Toy 入口页面: ```text #/ 首页(版本日历) #/combat 战斗数据解析与排行榜 #/gacha 寻访统计 #/archive 云存档管理 #/download 软件下载 #/record/ 公开战斗记录详情 ``` Toy 包的根目录仍然只放一个 `index.html`。Toy 文档允许 `share`/`getQrCode` 指向当前 Toy 内的其他相对路径,但真实路径路由刷新时必须有对应 HTML 文件,因此本项目继续采用 Hash 路由更稳定。`toy.navigate` 是跳转 B 站资源,不用于 Toy 内部页面切换。 ## 首页 默认首页使用版本日历图片作为第一视图,下方放两个较大的入口: - 战斗数据解析:进入现有战斗解析/排行榜流程。 - 寻访统计:进入寻访统计页。 图片和脚本全部使用相对资源路径,兼容 `/toy//` 部署路径。 ## URL 直达 桌面端可以打开以下形式的 URL: ```text index.html?mode=gacha#<压缩后的寻访快照> index.html?mode=combat&r=<公开战斗记录 ID> ``` 寻访快照放在 fragment 中,避免随 HTTP 请求发送;网页解码并展示后应使用 `history.replaceState` 清理快照,避免长期出现在地址栏、历史记录和复制链接中。query 只保留短的模式标识,不放完整记录。 带寻访快照时直接进入寻访页,带战斗记录 ID 时进入战斗详情;参数无效时显示可恢复的导入错误,不阻塞首页。 ## 寻访快照与增量 网页不接收游戏 Token,也不上传普通四星/五星明细。桌面端只发送网页显示和增量合并所需的紧凑状态: ```text schemaVersion 卡池元数据(poolId、类型、categoryId、显示名称、时间、规则组) 卡池聚合(总抽数、六星数、UP 数、歪数、当前垫数) 六星结果(角色/武器、是否 UP、抽数、免费十连标志) 各池 seqId 游标 ``` 六星结果必须带稳定去重 ID,推荐由 `poolId + seqId + itemId + gachaTs` 组成。网页端按 ID 合并后重新计算统计,重复导入不会重复计数。 ## Toy 云存档 Toy 云存储按“登录用户 + 当前 Toy”隔离,每个 Toy 最多 128 个 key,每个 value 最多 1024 字节。寻访使用固定命名空间并覆盖更新,不使用战斗存档的随机记录 ID: ```text gacha_v1_manifest gacha_v1_state_0 gacha_v1_state_1 ... ``` 先写分片、校验,再写 manifest;manifest 中包含版本、分片数、更新时间和摘要。读取时先读 manifest,再读取分片并校验。云存档是私有的,只能由同一 Toy 内的同一用户跨设备恢复,不能作为公开分享后端。 现有战斗存档和寻访存档共享 Toy 的 128 个 key 配额,因此寻访只保存聚合状态和六星结果,不能保存完整普通抽卡列表。 ## 分阶段实现 1. 本地侧稳定模型、接口、增量游标和 JSON 导入导出。 2. 网页侧 `gacha` 路由、快照解码和统计展示。 3. Toy 固定 key 的寻访云存档合并、校验和恢复。 4. 桌面端一键生成快照并打开网页。