diff --git a/src/api/request/errorUI.ts b/src/api/request/errorUI.ts index aaa8d87..f525b6d 100644 --- a/src/api/request/errorUI.ts +++ b/src/api/request/errorUI.ts @@ -1,6 +1,5 @@ import { ElMessage } from 'element-plus' import { eventBus, AppEvents } from '@/utils' -import type { RequestErrorEvent } from './types' /** * 注册请求错误 UI 展示 @@ -8,7 +7,6 @@ import type { RequestErrorEvent } from './types' * 订阅应用级 REQUEST_ERROR 事件,统一展示错误提示, * 实现网络模块与 UI 的解耦。 */ -eventBus.on(AppEvents.REQUEST_ERROR, (payload: unknown) => { - const { message: errorMessage } = payload as RequestErrorEvent - ElMessage.error(errorMessage) +eventBus.on(AppEvents.REQUEST_ERROR, (payload) => { + ElMessage.error(payload.message) }) diff --git a/src/api/request/requestClient.ts b/src/api/request/requestClient.ts index 52c800e..ce3c0cd 100644 --- a/src/api/request/requestClient.ts +++ b/src/api/request/requestClient.ts @@ -1,7 +1,7 @@ import axios, { type AxiosInstance, type CreateAxiosDefaults } from 'axios' import { useAccountStore } from '@/stores' import { eventBus, AppEvents } from '@/utils' -import type { ApiResponse, InternalRequestConfig, RequestErrorEvent } from './types' +import type { ApiResponse, InternalRequestConfig } from './types' import { createRefreshTokenInterceptor } from './refreshInterceptor' /** @@ -106,7 +106,7 @@ class RequestClient { type: 'business', code: data.code, message: data.message || '请求失败' - } satisfies RequestErrorEvent) + }) return Promise.reject(data) }, (error) => { @@ -121,7 +121,7 @@ class RequestClient { message: error.response ? `请求错误 (${error.response.status})` : '网络异常,请检查网络连接' - } satisfies RequestErrorEvent) + }) return Promise.reject(error) } ) diff --git a/src/common/hooks/useSse.ts b/src/common/hooks/useSse.ts index ee9381c..a754b3e 100644 --- a/src/common/hooks/useSse.ts +++ b/src/common/hooks/useSse.ts @@ -43,7 +43,8 @@ export function useSse() { } // Vite 代理: /api/sse/subscribe → 后端 /sse/subscribe - const url = `/api/sse/subscribe?token=${encodeURIComponent(token)}` + // 鉴权走 Cookie(登录后 Sa-Token 写入同名 Cookie,EventSource 同域请求自动携带) + const url = `/api/sse/subscribe` es = new EventSource(url) es.onopen = () => { diff --git a/src/utils/eventBus.ts b/src/utils/eventBus.ts index e7e70b9..08e190b 100644 --- a/src/utils/eventBus.ts +++ b/src/utils/eventBus.ts @@ -1,16 +1,25 @@ -/** 事件处理器类型 */ -type EventHandler = (...args: unknown[]) => void +import mitt from 'mitt' + +/** 应用级事件类型定义 */ +type AppEventsMap = { + /** 401 未授权 */ + 'app:unauthorized': void + /** 请求错误(业务错误 / HTTP 错误 / 网络错误) */ + 'app:request:error': { + type: 'business' | 'http' | 'network' + code?: number + message: string + } +} /** 应用级事件常量 */ export const AppEvents = { - /** 401 未授权 */ UNAUTHORIZED: 'app:unauthorized', - /** 请求错误(业务错误 / HTTP 错误 / 网络错误) */ REQUEST_ERROR: 'app:request:error' } as const /** - * 发布订阅事件总线 + * 应用级事件总线(基于 mitt) * * @example * ```ts @@ -23,69 +32,4 @@ export const AppEvents = { * eventBus.emit(AppEvents.UNAUTHORIZED) * ``` */ -class EventBus { - /** 事件名 → 处理器集合 */ - private handlers = new Map>() - - /** - * 注册事件处理器 - * @param event - 事件名 - * @param handler - 处理器函数 - */ - on(event: string, handler: EventHandler): void { - if (!this.handlers.has(event)) { - this.handlers.set(event, new Set()) - } - this.handlers.get(event)!.add(handler) - } - - /** - * 注册一次性事件处理器(触发后自动取消注册) - * @param event - 事件名 - * @param handler - 处理器函数 - */ - once(event: string, handler: EventHandler): void { - const wrapper: EventHandler = (...args: unknown[]) => { - handler(...args) - this.off(event, wrapper) - } - this.on(event, wrapper) - } - - /** - * 取消注册事件处理器 - * @param event - 事件名 - * @param handler - 要取消的处理器函数 - */ - off(event: string, handler: EventHandler): void { - this.handlers.get(event)?.delete(handler) - } - - /** - * 发布事件 - * @param event - 事件名 - * @param args - 传递给处理器的参数 - */ - emit(event: string, ...args: unknown[]): void { - const handlers = this.handlers.get(event) - if (!handlers) return - handlers.forEach((handler) => { - handler(...args) - }) - } - - /** - * 清除指定事件的所有处理器,或清除所有事件 - * @param event - 可选,不传则清除全部 - */ - clear(event?: string): void { - if (event) { - this.handlers.delete(event) - } else { - this.handlers.clear() - } - } -} - -/** 事件总线单例 */ -export const eventBus = new EventBus() +export const eventBus = mitt()