# 钱包登录 + 收藏：重设计与 Bug 修复 设计文档

日期：2026-06-02
分支：`terry-wallet-login`
范围：登录弹窗、Header/菜单钱包入口、收藏按钮、我的收藏页面、收藏入口
关联：
- 需求简报 `.unipi/docs/generated/2026-06-01-wallet-favorites-ui-redesign-requirements.md`
- 后端核对 `docs/backend-requirements-wallet-favorites.md`

---

## 1. 目标

把已上线的「钱包登录 + 收藏」从「功能能跑但设计未完善、桌面/手机均有 bug」提升到完成度合格：

1. 修复登录流程中的真实功能 bug（强制切链、桌面误导、手机死路）。
2. 按已批准的极简原则重做登录弹窗。
3. 补齐完全缺失的「我的收藏」入口。
4. 打磨收藏按钮状态与收藏页（移动端筛选、空/错误/不可用状态）。

**关键事实**：经核对后端，钱包认证、TokenPocket 扫码、收藏接口（筛选/排序/分页/可用性/计数）均已实现并符合契约。**本次为纯前端工作**，后端仅需确认 CORS（见后端文档 §2.1）。

---

## 2. 登录架构（决策已定）

三条路径共存，但 UI 上分主次：

| 路径 | 用途 | UI 位置 |
|---|---|---|
| `window.ethereum` 注入登录 | 桌面插件 / 钱包内置浏览器 | **主路径** |
| TokenPocket 自写扫码（deep link + 轮询） | 中国稳定扫码 | 「其他方式」折叠区 |
| RainbowKit / WalletConnect | MetaMask / imToken 扫码兜底 | 「其他方式」折叠区 |

**决策**：保留并**真正接上** RainbowKit（当前为未被调用的死代码）。
**前置项**：需在环境变量配置有效的 `VITE_WALLETCONNECT_PROJECT_ID`（当前默认 `ark-library-dev-only` 无效）。WalletConnect 兜底在部分中国网络不稳定，UI 需提示。

签名验证链无关（后端 EIP-191 personal_sign recover，消息不引用任何链）。

---

## 3. Bug 修复清单（前端）

| # | 严重度 | 问题 | 修复 |
|---|---|---|---|
| B1 | 🟠 | 每次登录强制切 BNB 链（`ensureBnbChain`），多一个换网络弹窗，常见失败点 | 删除强制切链；`personal_sign` 不需要链 |
| B2 | 🟠 | 桌面弹窗摆 3 个钱包按钮，点 TP/imToken 误弹「请安装」 | 桌面只留 1 个主操作「使用浏览器钱包登录」 |
| B3 | 🟠 | 桌面无扫码（TP 扫码被包在仅手机分支） | 扫码移入桌面「其他方式」 |
| B4 | 🟠 | 手机「打开钱包 App」是死路：无反馈、App 未装无兜底 | 加跳转反馈 + 未安装兜底（提示去下载） |
| B5 | 🔴 | RainbowKit 整套加载但从未被登录流程调用 | 真正接成「其他方式」扫码兜底 |
| B6 | 🔴 | 全站无「我的收藏」入口，页面只能手敲 URL | 加 3 处入口（见 §5） |
| B7 | 🔴 | 钱包下拉只有地址 + 断开 | 下拉加「我的收藏」 |
| B8 | 🟡 | 收藏 token 过期只弹失败 toast | 401 时自动登出并引导重新登录 |
| B9 | 🟡 | `isMobileDevice` 把触屏 Mac/iPad 判为手机 | 收紧检测，避免桌面被推进 App 跳转流 |
| B10 | 🟡 | 收藏页加载失败无重试 | 错误态加重试按钮 |
| B11 | 🟡 | WalletConnect projectId 默认无效值 | 用 env，缺失时禁用扫码兜底并提示 |

---

## 4. 登录弹窗设计

### 4.1 桌面版

结构（自上而下）：
1. 标题「连接钱包」
2. 说明「签名仅用于验证钱包地址，不会发起交易，也不需要 Gas」
3. **主按钮**「使用浏览器钱包登录」（金色）→ `window.ethereum` 注入流程
4. 辅助说明「请使用已安装钱包插件的浏览器，例如 MetaMask」
5. 折叠「其他登录方式」（**默认折叠**），展开后：
   - TokenPocket 扫码（第一项，中国常用）
   - MetaMask / imToken 扫码（WalletConnect，附不稳定提示）
6. 关闭按钮
7. 错误区（红色）

### 4.2 手机版

结构：
1. 标题「连接钱包」+ 说明「请在钱包 App 中打开本站并签名登录，无交易、无 Gas」
2. 若检测到注入钱包：**「使用当前钱包登录」**主按钮
3. 否则：分组「打开钱包 App」+ 三个按钮（TokenPocket / MetaMask / imToken），带品牌图标
   - 点按尝试 deep link；未跳转/未安装 → 提示去下载（**不再死路**，修 B4）
4. 折叠「其他方式（扫码）」默认折叠
5. 关闭按钮 + 错误区

### 4.3 通用
- 钱包按钮配品牌彩色图标。
- 多语言预留文字长度（en/zh-CN/zh-TW/ko/ja/vi/id/ms），按钮不溢出。
- 弹窗在手机上可滚动、不被遮挡。

---

## 5. 钱包入口与收藏入口

### 5.1 Header 钱包入口
- 未登录：`Connect Wallet / 连接钱包` 主按钮（桌面右侧 / 手机菜单内）。
- 已登录：短地址 `0x12…ab34` + 绿点；点击展开下拉。

### 5.2 钱包下拉（已登录，修 B7）
顺序：完整地址 → **♥ 我的收藏**（新增）→ 断开连接。

### 5.3 「我的收藏」入口策略：**始终显示（方案 B）**
- 桌面钱包下拉、手机菜单中**始终**显示「我的收藏」入口。
- 未登录点击 → 落到 `/favorites` 的「连接钱包查看收藏」引导页（现状已有，保留）。
- 手机菜单导航项中加「♥ 我的收藏」。

### 5.4 收藏按钮触发登录（保留现状逻辑）
未登录点 ♥ → 打开登录弹窗 → 登录成功后自动补上本次收藏（`pendingAfterLogin` 已实现）。

---

## 6. 收藏按钮（`FavoriteButton`）

四态，一眼可分：
- 未收藏：空心 ♡，低对比底。
- 已收藏：实心 ♥，品牌金填充。
- 加载中：转圈（`LoaderCircle`）。
- 请求中：禁用 + 降透明。

行为：
- 点击 `preventDefault + stopPropagation`，不误触进详情（已实现，保留）。
- 增加点击微动效（`active:scale`）。
- 乐观更新，失败回滚 + 错误 toast（已实现，保留）。

摆放：推荐卡 / 最新 / 热门 / 内容流 / 收藏页卡片右上角，不挡主内容、不与下载/预览混淆。

---

## 7. 我的收藏页面 `/favorites`

### 7.1 未登录
图标 + 标题 + 说明 + 「连接钱包」CTA（现状已有，保留视觉打磨）。

### 7.2 已登录
- **桌面**筛选一行：搜索 + 排序 + 分类 + 搜索按钮（现状保留）。
- **移动端**：搜索框单独一行；排序/分类收进**「筛选抽屉」**，解决现状 4 控件挤压（新增）。
- 列表：收藏资源卡（封面/标题/描述/分类/类型/更新时间/收藏数/收藏按钮）。
- 分页：上一页/下一页 + 页码（现状保留）。
- 「清除筛选」当存在筛选时显示。

### 7.3 状态
- **不可用/下架**：黄边 + 「不可用」标 + 不可点进详情 + 保留移除按钮（后端 `availability` 已支持）。
- **空状态**：区分「还没有收藏」与「筛选无结果」，后者给清除筛选入口。
- **错误**：加载失败提示 +（新增）**重试按钮**（修 B10）。
- **加载**：4 张 skeleton，布局不跳。

排序选项：最近收藏 / 最近发布 / 热门（后端 `favorited_at`/`published_at`/`hot` 已支持）。

---

## 8. 多语言
所有新增/改动文案覆盖 8 语言（en、zh-CN、zh-TW、ko、ja、vi、id、ms），key 写入 `src/locales/*`。移动端按钮预留长文本。

---

## 9. 验收清单

登录：
- [ ] 桌面弹窗只有 1 个主操作；扫码在折叠区。
- [ ] 手机可打开 TP/MetaMask/imToken；未安装有兜底。
- [ ] 登录不再强制切链。
- [ ] RainbowKit 真正接通（projectId 有效时）；无效时扫码兜底禁用并提示。
- [ ] 已登录显示短地址，可断开。

收藏：
- [ ] 钱包下拉、手机菜单均有「我的收藏」入口（始终显示）。
- [ ] 收藏按钮四态清楚，不与卡片点击冲突。
- [ ] 未登录点收藏 → 引导登录 → 自动补收藏。
- [ ] token 过期自动登出并引导重登。

收藏页：
- [ ] 桌面一行筛选；移动端筛选抽屉。
- [ ] 不可用/空/错误(含重试)/骨架屏 完整。
- [ ] Desktop 与 mobile 均验证。

质量门槛（实现后）：`npx tsc --noEmit`、`npm run format:check`、`npm test` 全绿。

---

## 10. 不做（YAGNI）
- 服务端登出 / token 撤销（保持无状态 JWT）。
- ENS、链上读取、交易。
- 收藏分组/文件夹、批量操作（本期不做）。
- 收藏 `q` 全文索引优化（数据量小，暂不做）。
