Files
jnpf_app/utils/request.js
2026-01-30 11:48:35 +08:00

203 lines
6.7 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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