diff --git a/src/app/sidebar/components/sidebar-screen.tsx b/src/app/sidebar/components/sidebar-screen.tsx index 5f67b668..6af18836 100644 --- a/src/app/sidebar/components/sidebar-screen.tsx +++ b/src/app/sidebar/components/sidebar-screen.tsx @@ -44,7 +44,6 @@ export function SidebarScreen() { // 等价 Dart: BlocConsumer 的 listener(profile_view.dart:24-34) // 仅在 currentUser 由非 null 跳到 null 时触发清理 - // 注:chat 机器不再需要 `ChatAuthStatusChanged` 通知(已删)—— chat-screen // 通过 `useAuthState()` 主动订阅 loginStatus;这里只需重置 auth + 跳 /chat const prevUserRef = useRef(user.currentUser); useEffect(() => { diff --git a/src/data/services/api/auth_api.ts b/src/data/services/api/auth_api.ts index 84562d57..ce618471 100644 --- a/src/data/services/api/auth_api.ts +++ b/src/data/services/api/auth_api.ts @@ -17,7 +17,6 @@ import { GuestLoginRequest } from "@/data/dto/auth/guest_login_request"; import { GuestLoginResponse } from "@/data/dto/auth/guest_login_response"; import { LoginRequest } from "@/data/dto/auth/login_request"; import { LoginResponse } from "@/data/dto/auth/login_response"; -import { LogoutResponse } from "@/data/dto/auth/logout_response"; import { RefreshTokenRequest } from "@/data/dto/auth/refresh_token_request"; import { RefreshTokenResponse } from "@/data/dto/auth/refresh_token_response"; import { RegisterRequest } from "@/data/dto/auth/register_request"; @@ -102,13 +101,18 @@ export class AuthApi { } /** - * 退出登录 + * 退出登录(fire-and-forget) + * + * 后端 logout 端点的 envelope `data` 字段常为 `null`(登出端点没有业务数据), + * 不要再用 `unwrap` + `LogoutResponse.fromJson` 解析 —— Zod schema 是 z.object, + * 对 null 会抛 ZodError "Invalid input: expected object, received null"。 + * + * 对齐 `register` / `sendCode` 的写法:调通就完事,不解析响应体。 */ - async logout(): Promise { - const env = await httpClient>(ApiPath.logout, { + async logout(): Promise { + await httpClient>(ApiPath.logout, { method: "POST", }); - return LogoutResponse.fromJson(unwrap(env) as Record); } /** diff --git a/src/stores/chat/chat-machine.actors.ts b/src/stores/chat/chat-machine.actors.ts index d5c7bbb7..b64286c7 100644 --- a/src/stores/chat/chat-machine.actors.ts +++ b/src/stores/chat/chat-machine.actors.ts @@ -1,18 +1,5 @@ /** * Chat 状态机:4 个 XState actor - * - * 从 `chat-machine.ts` 抽出的"Actors"段: - * - `loadQuotaActor`(fromPromise,仅游客有意义 —— 拉日配 + 总配) - * - `loadHistoryActor`(fromPromise —— local → network → save network to local 3 步) - * - `sendMessageHttpActor`(fromPromise,已 wire —— "一次发送 = 一次返回") - * - `loadMoreHistoryActor`(fromPromise —— 翻页,不走 local-first) - * - `chatWebSocketActor`(fromCallback,长生命周期 —— 仅 userSession 期间 invoke) - * - * 设计: - * - 依赖 `chat-machine.helpers.ts`(纯函数 + 数据加载) - * - 依赖 `createChatWebSocket`(`@/core/net/chat-websocket`) - * - 保留全链日志(用户要求"不要将其删除") - * - 命名约定:`[chat-machine]` 前缀 —— 与 `chat-machine.ts` 的日志对齐 */ import { fromPromise, fromCallback } from "xstate"; diff --git a/src/stores/user/user-machine.actors.ts b/src/stores/user/user-machine.actors.ts index 2ae19b6f..020a5bbb 100644 --- a/src/stores/user/user-machine.actors.ts +++ b/src/stores/user/user-machine.actors.ts @@ -70,5 +70,4 @@ export const userFetchActor = fromPromise(async () => { */ export const userLogoutActor = fromPromise(async () => { await authRepo.logout(); - await userStorage.clearUserData(); }); \ No newline at end of file diff --git a/src/stores/user/user-machine.ts b/src/stores/user/user-machine.ts index 4e33e8a8..f36a3a73 100644 --- a/src/stores/user/user-machine.ts +++ b/src/stores/user/user-machine.ts @@ -1,19 +1,5 @@ /** * User 状态机(XState v5) - * - * 原始 Dart: lib/ui/user/bloc/user bloc + user state + user event - * - * 设计要点: - * - XState v5 `setup({...}).createMachine({...})` 声明式 API - * - HTTP 操作用 `fromPromise` actor(一次性 Promise)→ 见 `user-machine.actors.ts` - * - 纯函数 / 数据加载 → 见 `user-machine.helpers.ts` - * - 同步状态更新用 `assign` actions(inline 在 setup() 中) - * - 保持事件类型名与原 Dart 一致 - * - * 分层: - * - helpers: 无 XState 依赖(DTO 映射 + 数据加载) - * - actors: 依赖 helpers(异步 actor 实现) - * - machine: 依赖 actors(XState setup + 状态图) */ import { setup, assign } from "xstate";