333 lines
7.1 KiB
JavaScript
333 lines
7.1 KiB
JavaScript
import {
|
||
getToken,
|
||
setToken,
|
||
removeToken
|
||
} from './auth'
|
||
import {
|
||
setVersion
|
||
} from '../utils/version.js'
|
||
import {
|
||
getBaseUrl
|
||
} from '../utils/version.js'
|
||
|
||
let baseURL;
|
||
setVersion()
|
||
|
||
let isRefreshing = false
|
||
let subscribers = []
|
||
|
||
// 订阅 Token 刷新
|
||
function subscribeTokenRefresh(cb) {
|
||
subscribers.push(cb)
|
||
}
|
||
|
||
// 发布 Token 刷新完成
|
||
function onRrefreshed(token) {
|
||
subscribers.forEach(cb => cb(token))
|
||
subscribers = []
|
||
}
|
||
|
||
// 请求拦截器
|
||
const requestInterceptor = (options) => {
|
||
// 获取token
|
||
const token = uni.getStorageSync('accessToken')
|
||
if (token) {
|
||
options.header = {
|
||
...options.header,
|
||
'Authorization': `Bearer ${token}`
|
||
}
|
||
}
|
||
|
||
// #ifdef H5
|
||
// H5端跨域处理
|
||
options.header = {
|
||
...options.header,
|
||
'Access-Control-Allow-Origin': '*'
|
||
}
|
||
// #endif
|
||
|
||
return options
|
||
}
|
||
|
||
// 响应拦截器
|
||
const responseInterceptor = async (options, response, resolve, reject) => {
|
||
const {
|
||
statusCode,
|
||
data
|
||
} = response
|
||
// 请求成功
|
||
if (statusCode >= 200 && statusCode < 300) {
|
||
return data
|
||
}
|
||
|
||
// 处理错误
|
||
if (statusCode === 401) {
|
||
|
||
return await handleUnauthorized(options, resolve, reject)
|
||
}
|
||
|
||
// 其他错误
|
||
uni.showToast({
|
||
title: data.message || '请求失败',
|
||
icon: 'none'
|
||
})
|
||
return Promise.reject(data)
|
||
}
|
||
// 创建 uni.request 的封装
|
||
// const request = (options) => {
|
||
// return new Promise((resolve, reject) => {
|
||
// uni.request({
|
||
// ...options,
|
||
// success: (res) => {
|
||
// if (res.statusCode === 401) {
|
||
// // 处理 401 逻辑
|
||
// handleUnauthorized(options, resolve, reject)
|
||
// } else {
|
||
// resolve(res)
|
||
// }
|
||
// },
|
||
// fail: (err) => {
|
||
// reject(err)
|
||
// }
|
||
// })
|
||
// })
|
||
// }
|
||
|
||
// 请求方法
|
||
const request = async (options, isUpdate) => {
|
||
// 合并配置
|
||
let url = uni.getStorageSync('baseUrl')
|
||
if (uni.getStorageSync('setVersion').VersionCode == '') {
|
||
setVersion()
|
||
}
|
||
|
||
if (!url) {
|
||
await new Promise((resolve, reject) => {
|
||
uni.request({
|
||
url: 'https://api.mrrwlkj.top/api/openPuc/getSjApiUrl', // 接口地址
|
||
method: 'GET', // 请求方法(默认 GET)
|
||
header: {
|
||
'Content-Type': 'application/json', // 请求头
|
||
'VersionCode': uni.getStorageSync('setVersion').VersionCode,
|
||
'DeviceBrand': uni.getStorageSync('setVersion').DeviceBrand,
|
||
'DeviceType': uni.getStorageSync('setVersion').DeviceType
|
||
},
|
||
success: (res) => {
|
||
if (res.data.code == 200) {
|
||
uni.setStorageSync('baseUrl', res.data.data.url)
|
||
url = res.data.data.url
|
||
resolve(url)
|
||
}
|
||
console.log('请求成功', res.data);
|
||
},
|
||
fail: (err) => {
|
||
console.log('请求失败', err);
|
||
},
|
||
complete: () => {
|
||
console.log('请求完成(无论成功失败都会执行)');
|
||
}
|
||
});
|
||
})
|
||
|
||
}
|
||
|
||
|
||
|
||
if (process.env.NODE_ENV === 'development') {
|
||
//baseURL = url; // 发布到生产环境时,此处代码会被摇树移除掉。
|
||
baseURL = 'http://60.247.146.5:93'; // 发布到生产环境时,此处代码会被摇树移除掉。
|
||
//baseURL = 'http://60.247.146.5:96'; // 发布到生产环境时,此处代码会被摇树移除掉。
|
||
//baseURL = 'https://app.mrrweb.com.cn';
|
||
} else {
|
||
//baseURL = url; // 发布到生产环境时,此处代码会被摇树移除掉。
|
||
baseURL = 'http://60.247.146.5:93'; // 发布到生产环境时,此处代码会被摇树移除掉。
|
||
//baseURL = 'http://60.247.146.5:96'; // 发布到生产环境时,此处代码会被摇树移除掉。
|
||
//baseURL = 'https://app.mrrweb.com.cn';
|
||
|
||
console.log('生产环境');
|
||
}
|
||
|
||
// 基础配置
|
||
const config = {
|
||
baseURL: baseURL, // APP和H5的开发URL
|
||
baseURL: baseURL, // APP和H5的开发URL
|
||
// baseURL: 'https://app.mrrweb.com.cn', // APP和H5的生产URL
|
||
|
||
header: {
|
||
'content-type': 'application/json',
|
||
'VersionCode': uni.getStorageSync('setVersion').VersionCode,
|
||
'DeviceBrand': uni.getStorageSync('setVersion').DeviceBrand,
|
||
'DeviceType': uni.getStorageSync('setVersion').DeviceType
|
||
},
|
||
timeout: 60000 // 超时时间
|
||
}
|
||
|
||
|
||
options = {
|
||
...config,
|
||
...options,
|
||
url: !isUpdate ? `${config.baseURL}${options.url}` : options.url
|
||
}
|
||
|
||
|
||
// 请求拦截
|
||
options = requestInterceptor(options)
|
||
|
||
// 发起请求
|
||
return new Promise((resolve, reject) => {
|
||
// #ifdef H5
|
||
// H5端添加loading
|
||
if (!options.hideLoading) {
|
||
uni.showLoading({
|
||
title: '加载中...'
|
||
})
|
||
}
|
||
// #endif
|
||
|
||
uni.request({
|
||
...options,
|
||
success: (res) => {
|
||
// #ifdef H5
|
||
if (!options.hideLoading) {
|
||
uni.hideLoading()
|
||
}
|
||
// #endif
|
||
resolve(responseInterceptor(options, res, resolve, reject))
|
||
},
|
||
fail: (err) => {
|
||
// #ifdef H5
|
||
if (!options.hideLoading) {
|
||
uni.hideLoading()
|
||
}
|
||
// #endif
|
||
|
||
// 网络错误处理
|
||
let errorMsg = '网络错误,请稍后重试'
|
||
// #ifdef H5
|
||
if (err.errMsg.includes('timeout')) {
|
||
errorMsg = '请求超时,请检查网络'
|
||
}
|
||
// #endif
|
||
|
||
uni.showToast({
|
||
title: errorMsg,
|
||
icon: 'none'
|
||
})
|
||
reject(err)
|
||
}
|
||
})
|
||
})
|
||
}
|
||
// 处理 401 未授权
|
||
async function handleUnauthorized(originalRequest, resolve, reject) {
|
||
if (!getToken()) {
|
||
return redirectToLogin()
|
||
}
|
||
// 如果正在刷新 Token,将请求加入队列
|
||
if (isRefreshing) {
|
||
return subscribeTokenRefresh(token => {
|
||
originalRequest.header['Authorization'] = `Bearer ${token}`
|
||
request(originalRequest, true).then(resolve).catch(reject)
|
||
})
|
||
}
|
||
|
||
isRefreshing = true
|
||
|
||
try {
|
||
const newToken = await refreshToken()
|
||
setToken(newToken)
|
||
onRrefreshed(newToken)
|
||
|
||
// 用新 Token 重试原始请求
|
||
originalRequest.header['Authorization'] = `Bearer ${newToken}`
|
||
const response = await request(originalRequest, true)
|
||
// resolve(response)
|
||
return response
|
||
} catch (error) {
|
||
removeToken()
|
||
redirectToLogin()
|
||
// reject(error)
|
||
return error
|
||
} finally {
|
||
isRefreshing = false
|
||
}
|
||
}
|
||
|
||
// 刷新 Token
|
||
async function refreshToken() {
|
||
const refreshToken = uni.getStorageSync('refreshToken')
|
||
if (!refreshToken) {
|
||
throw new Error('No refresh token')
|
||
}
|
||
const res = await request({
|
||
url: '/sj/refreshtoken',
|
||
data: {
|
||
refresh_token: uni.getStorageSync('refreshToken'),
|
||
deviceid: getApp().globalData.deviceid
|
||
},
|
||
method: 'POST'
|
||
})
|
||
|
||
if (res.state == 1 || res.code == 200) {
|
||
uni.setStorageSync('accessToken', res.access_token)
|
||
uni.setStorageSync('refreshToken', res.refresh_token)
|
||
return res.access_token
|
||
}
|
||
|
||
throw new Error('Refresh token failed')
|
||
}
|
||
|
||
// 跳转到登录页
|
||
function redirectToLogin() {
|
||
// uni.reLaunch({
|
||
// url: '/pages/login/login'
|
||
// })
|
||
//一键登录测试
|
||
// uni.oprPresentLogin()
|
||
uni.navigateTo({
|
||
url: '/pages/blogPopup/blogPopup'
|
||
});
|
||
}
|
||
|
||
// 导出请求方法
|
||
export default {
|
||
// GET请求
|
||
get(url, data = {}, options = {}) {
|
||
return request({
|
||
url,
|
||
data,
|
||
method: 'GET',
|
||
...options
|
||
})
|
||
},
|
||
|
||
// POST请求
|
||
post(url, data = {}, options = {}) {
|
||
return request({
|
||
url,
|
||
data,
|
||
method: 'POST',
|
||
...options
|
||
})
|
||
},
|
||
|
||
// PUT请求
|
||
put(url, data = {}, options = {}) {
|
||
return request({
|
||
url,
|
||
data,
|
||
method: 'PUT',
|
||
...options
|
||
})
|
||
},
|
||
|
||
// DELETE请求
|
||
delete(url, data = {}, options = {}) {
|
||
return request({
|
||
url,
|
||
data,
|
||
method: 'DELETE',
|
||
...options
|
||
})
|
||
}
|
||
} |