This commit is contained in:
2026-05-09 17:15:23 +08:00
parent 80a4183b45
commit a0ed128bde
43 changed files with 2573 additions and 381 deletions

View File

@@ -6,6 +6,8 @@
登录成功进入平台推荐页后,推荐页会自动加载一个公开作品并启动嵌入式运行态。实际联调中出现过:作品刚加载出来,前端又瞬间回到未登录状态;停留在其他页面,或推荐页没有成功加载出作品时不会复现。
后续复测又发现:登录成功后,从推荐页点进拼图公开作品详情并启动完整拼图运行态,也可能在开局或通关后瞬间退回未登录。两类现象的底层问题一致,都是玩法/展示层局部请求把 `401` 扩散成全局鉴权事件。
## 根因
推荐页首屏的作品运行态启动是后台自动副作用,不是用户主动点击的账号操作。它会触发多条受保护请求,例如:
@@ -16,6 +18,10 @@
这些请求一旦遇到本地代理错配、后端短暂不可用或 token 刷新失败,原请求层会按普通受保护请求处理 `401`,清空 access token 并广播全局鉴权变更。`AuthGate` 收到事件后重新 hydrate于是当前用户界面被切回未登录态。
推荐页里还有一类更隐蔽的触发点:`ResolvedAssetImage` / `useResolvedAssetReadUrl` 在挂载时会请求 `/api/assets/read-url` 给 generated 私有图片换签。它本质上也是展示层后台请求,若按普通受保护请求处理 `401`,同样会把一次图片换签失败放大成全局掉线。
公开拼图作品的完整运行态还会在用户进入作品后自动发起 `startPuzzleRun`,通关后自动 `submitPuzzleLeaderboard`,点击下一关时 `advancePuzzleNextLevel`。这些请求属于当前玩法的运行态同步,失败时应该落到当前拼图错误态;它们不能清空全局 access token也不能触发 `AuthGate` 重新 hydrate。
## 修复
本次把推荐页自动运行态请求定义为“卡片级后台请求”:
@@ -23,14 +29,18 @@
1. `apiClient` 增加 `clearAuthOnUnauthorized` 选项,允许局部请求在 `401` 时不清空全局 token。
2. 推荐页嵌入式运行态请求统一传入 `skipRefresh: true``notifyAuthStateChange: false``clearAuthOnUnauthorized: false`
3. 推荐页自动启动作品前必须满足 `canReadProtectedData`,避免 `AuthGate` 仍在恢复阶段就提前发起受保护写请求。
4. 普通用户主动点击“启动”、Remix、发布、点赞等路径继续保留默认全局鉴权处理。
4. generated 图片换签请求同样使用局部后台鉴权选项并跳过 refresh失败只让当前图片为空不触发全局登录态清理。
5. 公开拼图作品进入完整运行态后,把本次 run 标记为 `isolated` 鉴权模式;开局、重开、排行榜提交和下一关推进都沿用局部鉴权选项。
6. Remix、发布、点赞、账号设置、退出登录等真正账号动作继续保留默认全局鉴权处理。
## 验证
1. `npm run test -- src/services/apiClient.test.ts`
1. `npm run test -- src/services/apiClient.test.ts src/services/assetReadUrlService.test.ts`
2. `npm run test -- src/components/rpg-entry/RpgEntryFlowShell.agent.interaction.test.tsx -t "home recommendation starts embedded puzzle"`
3. `npm run typecheck`
4. `npm run check:encoding`
3. `npm run test -- src/components/rpg-entry/RpgEntryFlowShell.agent.interaction.test.tsx -t "formal puzzle runtime uses frontend move merge logic and backend leaderboard"`
4. `npm run test -- src/components/rpg-entry/RpgEntryFlowShell.agent.interaction.test.tsx -t "formal puzzle similar work keeps current run level progression"`
5. `npm run typecheck`
6. `npm run check:encoding`
## 关联文件