已登录用户从 Settings 进入的账号子菜单(TAPD #1003149)。只有登录态才能看到这一页——guest / BLE-only / legacy 用户不登录,永远不会走到这里(docs/planning/PLAN_ACCOUNT_SYSTEM.md §1)。内容按账号类型分支:邮箱账号显示邮箱地址 + "Change Password" 入口;Google/Apple(OAuth)账号显示 provider 提供的用户名,并把 "Email Address" 行变成一个可点的"为 OAuth 账号注册邮箱"入口。底部是 Sign Out 与红色的 Delete Account;它们和上面的条目一起放在 ListView 中,可随页面一起滚动,并不是固定在屏幕底部。
补充:登出流程除 wipeLocalDeviceData(ref) 外,还直接读取 accountSessionServiceProvider、accountMqttCredServiceProvider 和 cookLogProvider。确认登出后会先 deregister() 释放这台手机的账号登录槽位,再 clearLocal() 清掉本地缓存的账号 MQTT 凭据,并 clearAllLocal() 清空本地 cook log,之后才执行设备数据清理与 signOut()。
lib/features/auth/presentation/account_page.dart(290 行)authControllerProvider(读 user,判断 provider == AuthProvider.email)wipeLocalDeviceData(ref)(lib/core/providers/device_providers.dart,登出时用)AccountCredentialPage(详见 修改凭据,本身不是独立路由,靠本页直接 Navigator.push 一个 MaterialPageRoute)accountUsernameFor(AuthUser u)——邮箱账号显示邮箱本身,OAuth 账号显示 provider 用户名;Settings 页的 Account 行也复用同一个函数保证两处文案一致/account(AccountPage.routeName)lib/app.dart 静态 routes mapuser.email,点击进入 registerEmail 流程;按代码注释,这个入口既用于注册邮箱,也用于更换已登记的邮箱未登录(user == null,理论上不应该发生,因为本页只从已登录态的 Settings 进入)时 body 直接渲染一个空白 SizedBox。
Navigator.push(AccountCredentialPage(mode: CredentialMode.registerEmail))Navigator.push(AccountCredentialPage(mode: CredentialMode.changePassword))补充:wipeLocalDeviceData(ref) 内部会先停止 deviceBindingRealtimeProvider 的实时同步订阅,然后再下掉各设备的云连接/管理状态并清空本地设备与 WiFi 残留;因此登出不仅清本机数据,也会结束当前账号在这台手机上的设备列表实时同步。
_confirmSignOut()
→ 确认后:wipeLocalDeviceData(ref) // 清本机设备列表/WiFi配置/云连接,不动 Supabase 数据
→ authControllerProvider.notifier.signOut()
→ Navigator.pop(context) // 退出本页;Settings 的 Account 区块也随之消失
_confirmDelete()
→ 确认后:Navigator.push(AccountCredentialPage(mode: CredentialMode.deleteAccount))
watch authControllerProvider 读 user;账号类型分支(isEmailAccount)纯粹是同一次 build 里的条件判断,不需要额外状态。本页没有内部 State(ConsumerWidget 而非 ConsumerStatefulWidget)。
无。
无——本页职责单一(身份展示 + 三个跳转入口 + 登出确认),复杂度都在下游的修改凭据 页。