mrr.sj.front/utils/request.js

333 lines
7.1 KiB
JavaScript
Raw Normal View History

2026-03-24 11:45:13 +08:00
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({
2026-03-25 13:29:04 +08:00
url: 'https://api.mrrwlkj.top/api/openPuc/getSjApiUrl', // 接口地址
2026-03-24 11:45:13 +08:00
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') {
2026-04-10 15:02:24 +08:00
baseURL = url; // 发布到生产环境时,此处代码会被摇树移除掉。
2026-04-13 14:33:52 +08:00
baseURL = 'http://60.247.146.5:93'; // 发布到生产环境时,此处代码会被摇树移除掉。
2026-03-25 13:34:16 +08:00
//baseURL = 'http://60.247.146.5:96'; // 发布到生产环境时,此处代码会被摇树移除掉。
2026-03-24 11:45:13 +08:00
//baseURL = 'https://app.mrrweb.com.cn';
} else {
2026-04-10 15:02:24 +08:00
baseURL = url; // 发布到生产环境时,此处代码会被摇树移除掉。
2026-04-13 14:33:52 +08:00
baseURL = 'http://60.247.146.5:93'; // 发布到生产环境时,此处代码会被摇树移除掉。
2026-03-25 13:34:16 +08:00
//baseURL = 'http://60.247.146.5:96'; // 发布到生产环境时,此处代码会被摇树移除掉。
2026-03-25 13:29:04 +08:00
//baseURL = 'https://app.mrrweb.com.cn';
2026-03-24 11:45:13 +08:00
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({
2026-03-25 13:29:04 +08:00
url: '/sj/refreshtoken',
2026-03-24 11:45:13 +08:00
data: {
refresh_token: uni.getStorageSync('refreshToken'),
deviceid: getApp().globalData.deviceid
},
method: 'POST'
})
2026-03-25 13:29:04 +08:00
if (res.state == 1 || res.code == 200) {
2026-03-24 11:45:13 +08:00
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
})
}
}