| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798 |
- import { API_BASE, TOKEN_KEY, REFRESH_TOKEN_KEY, USER_INFO_KEY } from '@/config/api'
- let clearingAuth = false
- function createUnauthorizedError(rawUrl = '') {
- const loginApiPattern = /\/mini\/auth\/login(?:$|\?)/
- const message = loginApiPattern.test(String(rawUrl))
- ? '用户名或密码错误,请重新输入'
- : '登录状态已失效,请重新登录'
- const error = new Error(message)
- error.name = 'UnauthorizedError'
- return error
- }
- async function onHttpUnauthorized() {
- if (clearingAuth) return
- clearingAuth = true
- // 先同步清理本地登录态,避免 store 动态导入失败时仍被识别为已登录
- uni.removeStorageSync(TOKEN_KEY)
- uni.removeStorageSync(REFRESH_TOKEN_KEY)
- uni.removeStorageSync(USER_INFO_KEY)
- try {
- const { useUserStore } = await import('@/stores/user')
- useUserStore().clearLoginInfo()
- } catch (error) {
- // ignore
- }
- const pages = typeof getCurrentPages === 'function' ? getCurrentPages() : []
- const currentRoute = pages.length ? pages[pages.length - 1].route : ''
- if (currentRoute === 'pages/login/login') {
- clearingAuth = false
- return
- }
- uni.showToast({ title: '登录已失效,请重新登录', icon: 'none' })
- uni.reLaunch({
- url: '/pages/login/login',
- fail: () => {
- // 某些端在请求回调中 reLaunch 可能失败,使用 redirectTo 兜底
- uni.redirectTo({ url: '/pages/login/login' })
- },
- complete: () => {
- setTimeout(() => {
- clearingAuth = false
- }, 800)
- }
- })
- }
- function isBizUnauthorized(data) {
- if (!data || typeof data !== 'object') return false
- return data.code === 401
- }
- export function request(options) {
- if (clearingAuth) {
- return Promise.reject(createUnauthorizedError(options?.url))
- }
- const rawToken = uni.getStorageSync(TOKEN_KEY)
- const token = typeof rawToken === 'string' ? rawToken.trim() : ''
- const rawUrl = options.url || ''
- const url = rawUrl.startsWith('http')
- ? rawUrl
- : `${API_BASE}${rawUrl.startsWith('/') ? rawUrl : `/${rawUrl}`}`
- return new Promise((resolve, reject) => {
- uni.request({
- ...options,
- url,
- header: {
- 'Content-Type': 'application/json',
- ...(token ? { Authorization: `Bearer ${token}` } : {}),
- ...(options.header || {})
- },
- success: (res) => {
- if (res.statusCode === 401 || isBizUnauthorized(res.data)) {
- onHttpUnauthorized()
- reject(createUnauthorizedError(rawUrl))
- return
- }
- resolve(res)
- },
- fail: (err) => reject(err)
- })
- })
- }
- export function parseResponseJson(res) {
- const d = res.data
- if (d == null) return d
- if (typeof d === 'string') {
- try {
- return JSON.parse(d)
- } catch (error) {
- return d
- }
- }
- return d
- }
|