/** * Token 失效(code:201 / HTTP 401)错误与登录引导,供 request 复用。 */ import { ROUTE_LOGIN, ROUTE_WORKBENCH } from '@/constants/routes' /** 弹窗展示文案(不使用后端技术向 Token 提示) */ export const RELOGIN_MODAL_CONTENT = '登录已失效,请重新登录' /** Token 失效专用错误:业务 catch 中应跳过 toast */ export class NeedLoginError extends Error { readonly needLogin = true constructor(message?: string) { super(message || RELOGIN_MODAL_CONTENT) this.name = 'NeedLoginError' } } export function isNeedLoginError(error: unknown): boolean { return Boolean( error && typeof error === 'object' && (error as NeedLoginError).needLogin === true ) } /** 登录失效类文案:已由弹窗/跳转处理,不再 toast */ export function shouldSuppressAuthErrorToast(errorOrMessage: unknown): boolean { if (isNeedLoginError(errorOrMessage)) return true const msg = typeof errorOrMessage === 'string' ? errorOrMessage : errorOrMessage instanceof Error ? errorOrMessage.message : '' if (!msg) return false return /未能读取到有效Token|请重新登录|登录已失效|登录超时|Token/i.test(msg) } let lastTokenExpirePromptAt = 0 /** 清理登录态后直接跳登录页(3s 内只触发一次,防多请求并发重复弹窗) */ export function promptReLogin(): void { const now = Date.now() if (now - lastTokenExpirePromptAt < 3000) return lastTokenExpirePromptAt = now uni.showToast({ title: RELOGIN_MODAL_CONTENT, icon: 'none' }) uni.reLaunch({ url: ROUTE_LOGIN, fail: () => uni.switchTab({ url: ROUTE_WORKBENCH }) }) }