refactor(chat): decouple chat state from auth and gate quota alerts to guests

- Remove ChatAuthStatusChanged dispatch from auth login flow; chat screen now subscribes directly to auth state machine (loginStatus) to derive isGuest and drive WS lifecycle
- Gate quota-exceeded and warning dialogs to guests only (non-guests have no message limit)
- Dispatch ChatLoadMoreHistory for non-guest initial load vs ChatInit for guests
- Fix AppConstants import path from @/core/constants/app_constants to @/core/app_constants
- Add defensive isGuest checks in quota effects to prevent non-guest quota triggers
This commit is contained in:
2026-06-11 18:31:08 +08:00
parent e3d069e49f
commit ed4ccddae3
11 changed files with 233 additions and 63 deletions
+8 -5
View File
@@ -8,8 +8,8 @@
* 兼容性:保持原 `useChatState()` / `useChatDispatch()` API。
* 内部将 XState 状态机快照映射回原 `ChatState` 形状。
*
* 注:WebSocket 长生命周期 actor 暂未集成到状态机(保留在 chat-side-effects.ts
* 由外部 chat-side-effects 模块管理),待下一轮迁移
* 注:WebSocket 长生命周期 actor **由 chat-screen.tsx 监听 auth 状态机驱动**——
* 鉴权解耦(loginStatus 在 authchat 机器**不**感知鉴权)
*/
import {
type Dispatch,
@@ -24,13 +24,17 @@ import { chatMachine } from "./chat-machine";
import type { ChatEvent, ChatState as MachineContext } from "./chat-machine";
/**
* 对外暴露的 State 形状(保持与原 ChatState 兼容)
* 对外暴露的 State 形状
*
* **isGuest 字段已删** —— 由 chat-screen 派生自 `auth.loginStatus === "guest"`。
* 消费方(chat-screen)通过 `useAuthState()` 取 loginStatus,本地派生 isGuest。
*/
interface ChatState {
messages: MachineContext["messages"];
isReplyingAI: boolean;
isGuest: boolean;
/** 游客剩余配额(次/天)—— 业务展示用,鉴权判断由 chat-screen 派生 loginStatus */
guestRemainingQuota: number;
/** 游客总配额 */
guestTotalQuota: number;
quotaExceededTrigger: number;
isLoadingMore: boolean;
@@ -53,7 +57,6 @@ export function ChatProvider({ children }: ChatProviderProps) {
() => ({
messages: state.context.messages,
isReplyingAI: state.context.isReplyingAI,
isGuest: state.context.isGuest,
guestRemainingQuota: state.context.guestRemainingQuota,
guestTotalQuota: state.context.guestTotalQuota,
quotaExceededTrigger: state.context.quotaExceededTrigger,