203 lines
6.7 KiB
JavaScript
203 lines
6.7 KiB
JavaScript
import define from './define'
|
||
import { useLocale } from '@/locale/useLocale';
|
||
|
||
const { getBackLocale } = useLocale();
|
||
let host = define.baseURL
|
||
const defaultOpt = { load: true }
|
||
|
||
// ------------- token刷新核心配置 -------------
|
||
const whiteList = ['/login', '/system/auth/refresh-token']
|
||
let requestQueue = []
|
||
let isRefreshingToken = false
|
||
const isRelogin = { show: false }
|
||
|
||
// ------------- 核心request方法 -------------
|
||
function request(config) {
|
||
config.options = Object.assign(defaultOpt, config.options)
|
||
const token = uni.getStorageSync('token') || ''
|
||
const refreshToken = uni.getStorageSync('refreshToken') || ''
|
||
const tenantId = '1' || uni.getStorageSync('tenantId')
|
||
const systemCode = uni.getStorageSync('systemCode') || ''
|
||
const locale = getBackLocale()
|
||
|
||
// 构建请求头
|
||
let header = {
|
||
"accept": 'application/json, text/plain, */*',
|
||
"App-Code": systemCode,
|
||
"Content-Type": "application/json;charset=UTF-8",
|
||
"Jnpf-Origin": "app",
|
||
"Vue-Version": "3",
|
||
"Accept-Language": locale,
|
||
"tenant-id": tenantId,
|
||
...config.header
|
||
}
|
||
header['App-Code'] = encodeURIComponent(header['App-Code'])
|
||
if (token) header['Authorization'] = token
|
||
// let url = config.url.indexOf('http') > -1 ? config.url : host + config.url
|
||
let url = host + config.url
|
||
console.log(url,'url---')
|
||
|
||
// 显示加载中
|
||
if (config.options.load) {
|
||
uni.showLoading({ title: config.options.loadText || '正在加载' })
|
||
}
|
||
|
||
// 返回Promise,核心改造逻辑
|
||
return new Promise((resolve, reject) => {
|
||
// 封装核心请求逻辑
|
||
const coreRequest = () => {
|
||
uni.request({
|
||
url: url,
|
||
data: config.data || {},
|
||
method: config.method || 'GET',
|
||
header: header,
|
||
timeout: define.timeout,
|
||
success: async (res) => {
|
||
uni.hideLoading();
|
||
if (res.statusCode === 200) {
|
||
if (res.data.code == 200 || res.data.code == 0) {
|
||
resolve(res.data)
|
||
} else if ([401, 600, 601, 602].includes(res.data.code)) {
|
||
// 白名单接口不处理
|
||
const isWhiteList = whiteList.some(v => config.url.includes(v))
|
||
if (isWhiteList) {
|
||
// 仅提示错误,不触发登出
|
||
ajaxError(res.data, false)
|
||
reject(res.data.msg)
|
||
return
|
||
}
|
||
|
||
// ------------- 刷新token逻辑 -------------
|
||
if (!refreshToken) {
|
||
// 无刷新token,触发登出
|
||
await handleAuthorized()
|
||
reject(res.data.msg)
|
||
return
|
||
}
|
||
|
||
if (isRefreshingToken) {
|
||
requestQueue.push(() => coreRequest())
|
||
return
|
||
}
|
||
|
||
isRefreshingToken = true
|
||
try {
|
||
// 拼接URL参数
|
||
const refreshUrl = `${host}/admin-api/system/auth/refresh-token?refreshToken=${encodeURIComponent(refreshToken)}`
|
||
// 调用刷新token接口
|
||
const refreshRes = await uni.request({
|
||
url: refreshUrl,
|
||
method: 'POST',
|
||
header: {
|
||
'tenant-id': tenantId,
|
||
'Content-Type': 'application/json'
|
||
},
|
||
data: {}
|
||
})
|
||
|
||
// 刷新成功处理
|
||
if (refreshRes.data && (refreshRes.data.code == 0 || refreshRes.data.code == 200)) {
|
||
const newTokenData = refreshRes.data.data
|
||
// 存储新token
|
||
uni.setStorageSync('token', newTokenData.accessToken)
|
||
uni.setStorageSync('refreshToken', newTokenData.refreshToken)
|
||
// 更新请求头
|
||
header['Authorization'] = newTokenData.accessToken
|
||
// 重试当前请求
|
||
coreRequest()
|
||
// 执行队列请求
|
||
requestQueue.forEach(cb => cb())
|
||
requestQueue = []
|
||
} else {
|
||
// 刷新token失败,触发登出
|
||
await handleAuthorized()
|
||
reject('刷新token失败:' + (refreshRes.data?.msg || '接口返回异常'))
|
||
}
|
||
} catch (err) {
|
||
// 刷新token异常,触发登出
|
||
await handleAuthorized()
|
||
reject('刷新token异常:' + err.errMsg)
|
||
} finally {
|
||
isRefreshingToken = false
|
||
requestQueue = []
|
||
}
|
||
} else {
|
||
// 普通业务错误,仅提示,不登出
|
||
ajaxError(res.data, false)
|
||
reject(res.data.msg)
|
||
}
|
||
} else {
|
||
// HTTP状态码错误,仅提示,不登出
|
||
ajaxError(res.data, false)
|
||
reject(res.errMsg)
|
||
}
|
||
},
|
||
fail: (err) => {
|
||
uni.hideLoading();
|
||
// 网络错误,仅提示,不登出
|
||
uni.showToast({ title: '连接服务器失败', icon: 'none' })
|
||
reject(err)
|
||
}
|
||
})
|
||
}
|
||
|
||
coreRequest()
|
||
})
|
||
}
|
||
|
||
// ------------- 辅助函数 -------------
|
||
/**
|
||
* 错误提示函数
|
||
* @param {Object} data 错误数据
|
||
* @param {Boolean} isAuthError 是否是认证错误(是否需要触发登出)
|
||
*/
|
||
function ajaxError(data, isAuthError = false) {
|
||
uni.showToast({
|
||
title: data.msg || '请求出错,请重试',
|
||
icon: 'none',
|
||
duration: 2000, // 延长提示时间,提升体验
|
||
complete() {
|
||
// 只有明确的认证错误且不在刷新token过程中,才触发登出
|
||
if (isAuthError && [600, 601, 602, 401].includes(data.code) && !isRefreshingToken) {
|
||
setTimeout(() => handleAuthorized(), 1500)
|
||
}
|
||
}
|
||
})
|
||
}
|
||
|
||
/**
|
||
* 处理登录过期逻辑(仅token失效时调用)
|
||
*/
|
||
async function handleAuthorized() {
|
||
// 防止重复弹出登录弹窗
|
||
if (!isRelogin.show) {
|
||
isRelogin.show = true
|
||
try {
|
||
const res = await uni.showModal({
|
||
title: '登录过期',
|
||
content: '您的登录已过期,请重新登录',
|
||
showCancelButton: false,
|
||
confirmText: '重新登录'
|
||
})
|
||
if (res.confirm) {
|
||
// 清除登录相关缓存
|
||
uni.removeStorageSync('token')
|
||
uni.removeStorageSync('refreshToken')
|
||
uni.removeStorageSync('cid')
|
||
uni.removeStorageSync('userInfo')
|
||
uni.removeStorageSync('permissionList')
|
||
uni.removeStorageSync('sysVersion')
|
||
uni.removeStorageSync('dynamicModelExtra')
|
||
// 跳转到登录页
|
||
uni.reLaunch({ url: '/pages/login/index' })
|
||
}
|
||
} catch (err) {
|
||
console.error('处理登录过期异常:', err)
|
||
} finally {
|
||
isRefreshingToken = false
|
||
isRelogin.show = false
|
||
}
|
||
}
|
||
}
|
||
|
||
export default request |