Files
eryao/.trellis/tasks/archive/2026-05/05-09-settings-page-interaction-optimization/prd.md
T

3.6 KiB
Raw Blame History

优化设置页面交互:返回逻辑与保存等待机制

Goal

优化设置相关二级页面的交互体验:

  1. 二级页面返回按钮应返回其隶属的一级页面,而非路由栈上一页
  2. 通用设置页面的开关切换应等待后端成功响应后再更新 UI,不使用乐观更新

What I already know

现有实现问题:

返回逻辑

  • GeneralSettingsPage.tsx 第 145-149 行:使用 navigate(-1) 返回路由栈上一页
  • FeedbackPage.tsx 第 113-117 行:同样使用 navigate(-1)
  • 这意味着如果用户从设置页进入通用设置,再进入语言选择弹窗,返回时会回到语言弹窗而非设置页

保存逻辑

  • GeneralSettingsPage.tsx 第 103-128 行:handleToggleChange 函数先调用 setSettings(newSettings) 乐观更新 UI,再调用 saveSettings
  • 用户看不到保存过程,失败时也没有明确的错误反馈

页面层级关系:

  • 一级页面:SettingsPage (/settings)
  • 二级页面:
    • GeneralSettingsPage (/settings/general)
    • FeedbackPage (/settings/feedback)

Requirements

R1: 二级页面返回逻辑

  • 点击返回按钮时,导航到隶属的一级页面(/${locale}/settings),而非路由栈上一页
  • 涉及页面:GeneralSettingsPage、FeedbackPage

R2: 通用设置保存等待机制

  • 开关切换时显示 loading 状态
  • 等待后端成功响应后再更新 UI 状态
  • 保存失败时显示 toast 错误提示,开关状态保持不变
  • 保存成功时不显示 toast
  • 涉及设置项:canSell(隐私设置)、allowNotifications(通知设置)

R3: 删除硬编码默认值

  • SettingsPage: 删除 displayName 默认值 'User' 和 email 默认值 'user@example.com'
  • ProfileDetailPage: 删除 email 默认值 'user@example.com'
  • AppShell 侧边栏: 显示真实头像和用户名,而非邮箱前缀
  • 邮箱从 auth token 获取(后端 profile API 不返回 email

R4: 语言 URL 同步

  • 页面加载时检查 URL 语言与用户偏好是否一致
  • 不一致则重定向到用户偏好的语言 URL
  • 防止用户手动修改 URL 导致语言不一致

Acceptance Criteria

  • GeneralSettingsPage 返回按钮点击后导航到 /settings
  • FeedbackPage 返回按钮点击后导航到 /settings
  • 切换 canSell 开关时,开关显示 loading 状态,后端成功后才切换
  • 切换 allowNotifications 开关时,开关显示 loading 状态,后端成功后才切换
  • 保存失败时显示 toast 错误提示,开关状态回滚
  • SettingsPage 无硬编码用户名/邮箱默认值
  • ProfileDetailPage 无硬编码邮箱默认值
  • AppShell 侧边栏显示真实头像和用户名
  • URL 语言与用户偏好不一致时自动重定向

Definition of Done

  • 功能测试通过
  • 代码 lint 无错误

Out of Scope

  • 语言选择的保存逻辑(已有页面刷新机制,不在本次修改范围)
  • 其他页面的返回逻辑
  • 后端 API 修改

Technical Notes

涉及文件:

  • web/src/components/GeneralSettingsPage.tsx
  • web/src/components/FeedbackPage.tsx
  • web/src/components/SettingsPage.tsx
  • web/src/components/ProfileDetailPage.tsx
  • web/src/components/AppShell.tsx

修改方案:

返回逻辑

navigate(-1) 改为 navigate('/${locale}/settings')

保存等待机制

  1. 移除乐观更新 setSettings(newSettings)
  2. 保存开始时设置 saving: true(已有)
  3. 保存成功后调用 setSettings(newSettings)
  4. 保存失败时显示 toast 错误提示
  5. 需要 props 传入 toast 相关文案(saveSuccess、saveFailed