Files
zt-closet-wxmini-frontend/.codebuddy/plans/fix-skyline-render-error-and-login-loop_e6d774eb.md
T
2026-09-13 01:27:21 +08:00

110 lines
6.4 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
name: fix-skyline-render-error-and-login-loop
overview: 关闭 Skyline 渲染引擎消除「FLOW_INITIAL_CREATION / Expected updated data」渲染层报错,并修复首次登录后被踢回登录页且按钮卡死的三处缺陷(silentAuth 仍清 token、登录页礼包请求触发登出、loading 不复位)。
todos:
- id: disable-skyline
content: 关闭 Skyline:私配 skylineRenderEnable 改 false,app.json 加 renderer webview
status: completed
- id: fix-silent-auth
content: 修复 request.ts:silentAuth 请求 401 时不再清空 token
status: completed
- id: fix-login-loading
content: 修复 login.ts:礼包请求加 silentAuth,统一 loading 全分支复位
status: completed
dependencies:
- fix-silent-auth
- id: mark-quota-silent
content: 给 profile、wardrobe、mall 的 fetchQuota 加 silentAuth 静默降级
status: completed
dependencies:
- fix-silent-auth
- id: tabbar-nexttick
content: custom-tab-bar 首帧 setData 延到 nextTick 做加固
status: completed
dependencies:
- disable-skyline
- id: verify-build
content: 执行类型检查并通读改动链路,确认无报错与登录闭环正常
status: completed
dependencies:
- disable-skyline
- fix-login-loading
- mark-quota-silent
---
## 产品概述
微信小程序「衣橱」项目,需修复两类问题:调试器刷屏的渲染层内部错误,以及新用户首次登录后被踢回登录页、登录按钮彻底失效的阻断性 Bug。
## 核心功能(修复项)
- 关闭 Skyline 渲染引擎,消除 `expect FLOW_INITIAL_CREATION end but get FLOW_CREATE_NODE` 与 `Expected updated data but get first rendering data` 渲染层报错
- 修复 `silentAuth` 静默请求仍清空 token 的缺陷,避免非关键接口 401 把已登录用户变成未登录
- 修复登录页 `loading` 永不复位导致登录按钮点击失效的问题
- 登录礼包额度、各页额度展示等非关键请求标记为静默失败,401 时只降级不登出
- 加固自定义 tabBar:首帧 setData 延后,避免再次触发首帧渲染冲突
## 技术栈
微信小程序原生框架 + TypeScript(`useCompilerPlugins: typescript`),基础库 3.17.2,`miniprogramRoot: miniprogram/`,无测试框架,通过微信开发者工具编译调试。
## 实现思路
分两条独立链路:**渲染引擎回归 WebView**(配置层,零业务逻辑改动)与**登录态生命周期收敛**(请求层 + 页面层)。
1. **渲染报错:关闭 Skyline**
- `project.private.config.json` 的 `skylineRenderEnable: true` 覆盖了 `project.config.json` 的 `false`,本地编译实际走 Skyline。
- 已全量确认项目未使用任何 Skyline 专属能力(无 `worklet`、无 `scroll-view type="list"`、无 `share-element`/`snapshot`/`grid-view`/`page-meta`,`<navigation-bar>` 全项目 0 处使用),关闭无功能损失。
- 同时存在 `tabBar.custom: true`(自定义 tabBar)与 `lazyCodeLoading: requiredComponents`(按需注入),这是 Skyline 下首帧报错的典型组合。
- 方案:私配置 `false` 立即生效;`app.json` 根目录补 `"renderer": "webview"` 作为全局兜底,防止其他机器私配误开。改后需「清缓存 → 重新编译」。
2. **登录被踢回:静默请求不得清空 token**
- 现网代码 `request.ts` 在 401 分支对 `silentAuth` 请求**仍然执行 `auth.clearTokens()`**,只是不跳转,导致 token 被悄悄抹掉。
- 修复:把 `auth.clearTokens()` 移入 `if (!silentAuth)` 分支内,静默请求仅 reject,不动登录态。这是「登录成功却被清登录态」的根因。
3. **按钮点不动:loading 全分支复位**
- `login.ts onLogin()` 仅在失败路径复位 `loading`;`showWelcomeGift` 的 then/catch、`showBirthGuide()`、成功 `switchTab` 分支均不复位,故 `if (this.data.loading) return` 使按钮永久禁用。
- 修复:抽取 `finishLoading()`(或在 `.finally` 中复位),保证任何分支最终都会 `setData({ loading: false })`。
4. **非关键请求不触发登出**
- `/quota/info`(礼包额度、上传额度展示)属展示型接口,401 不应踢人。给登录页 `showWelcomeGift` 与 `profile/wardrobe/mall` 的 `fetchQuota` 加 `silentAuth: true`,失败仅降级。
## 实现要点(防回归)
- `redirectToLogin()` 的幂等锁与「已在登录页则跳过」判断保持不变,它是消除并发 `reLaunch`(`routeDone with a webviewId not found`)的关键,不得回退。
- 页面 `onShow` 的登录守卫(`!auth.isLoggedIn() → redirectToLogin()`)保持不变:修复后静默请求不再清 token,正常用户不会被误踢。
- `app.ts` 的 `setAuthExpiredHandler` 只负责清登录态,跳转仍由 `request.ts` 单一入口负责,维持单一职责。
- 配置改动需提醒用户重启开发者工具并清缓存;`checkInvalidKey: true` 下 `renderer` 为 app.json 合法全局字段,不会告警。
## 架构设计
```mermaid
flowchart TD
A[页面/组件发起请求] --> B{needAuth 且未登录?}
B -- 是 --> C[直接 reject 11001 不发请求]
B -- 否 --> D[wx.request]
D -- 401/11001/11002/11004 --> E[doRefresh 刷新 token]
E -- 成功 --> D
E -- 失败 --> F{silentAuth?}
F -- 是 --> G[仅 reject 保留登录态]
F -- 否 --> H[clearTokens + onAuthExpired + 幂等 redirectToLogin]
```
## 目录结构
```
zt-closet-wxmini-frontend/
├── project.private.config.json # [MODIFY] setting.skylineRenderEnable 改 false,关闭本地 Skyline 调试
├── miniprogram/
│ ├── app.json # [MODIFY] 根目录新增 "renderer": "webview",全局兜底渲染引擎
│ ├── utils/request.ts # [MODIFY] 401 分支把 auth.clearTokens() 移入 !silentAuth 内,静默请求保留登录态
│ ├── pages/login/login.ts # [MODIFY] 礼包请求加 silentAuth;新增统一 loading 复位,覆盖礼包/引导/跳转全分支
│ ├── pages/profile/profile.ts # [MODIFY] fetchQuota 加 silentAuth: true
│ ├── pages/wardrobe/wardrobe.ts # [MODIFY] fetchQuota 加 silentAuth: true
│ ├── pages/mall/mall.ts # [MODIFY] fetchQuota 加 silentAuth: true
│ └── custom-tab-bar/index.ts # [MODIFY] attached 内首次 setData 与 syncUnread 延到 wx.nextTick,规避首帧冲突
```