189 lines
3.9 KiB
JavaScript
189 lines
3.9 KiB
JavaScript
|
|
/**
|
|||
|
|
* 网络请求封装
|
|||
|
|
* 包含Token自动刷新机制
|
|||
|
|
*/
|
|||
|
|
|
|||
|
|
// 从配置文件导入API_BASE
|
|||
|
|
import { API_BASE } from '@/config/api.js';
|
|||
|
|
|
|||
|
|
let isRefreshing = false; // 是否正在刷新token
|
|||
|
|
let requests = []; // 存储待重试的请求
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 统一请求方法
|
|||
|
|
*/
|
|||
|
|
const request = (options) => {
|
|||
|
|
return new Promise((resolve, reject) => {
|
|||
|
|
// 获取token
|
|||
|
|
const token = uni.getStorageSync('token');
|
|||
|
|
|
|||
|
|
// 设置请求头
|
|||
|
|
const header = {
|
|||
|
|
'Content-Type': 'application/json',
|
|||
|
|
...options.header
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
if (token) {
|
|||
|
|
header['Authorization'] = `Bearer ${token}`;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
uni.request({
|
|||
|
|
url: API_BASE + options.url,
|
|||
|
|
method: options.method || 'GET',
|
|||
|
|
data: options.data || {},
|
|||
|
|
header: header,
|
|||
|
|
success: (res) => {
|
|||
|
|
// 请求成功
|
|||
|
|
if (res.statusCode === 200) {
|
|||
|
|
resolve(res.data);
|
|||
|
|
}
|
|||
|
|
// Token过期
|
|||
|
|
else if (res.statusCode === 401) {
|
|||
|
|
// 如果正在刷新token,将请求加入队列
|
|||
|
|
if (isRefreshing) {
|
|||
|
|
requests.push(() => {
|
|||
|
|
request(options).then(resolve).catch(reject);
|
|||
|
|
});
|
|||
|
|
} else {
|
|||
|
|
// 开始刷新token
|
|||
|
|
isRefreshing = true;
|
|||
|
|
|
|||
|
|
refreshToken()
|
|||
|
|
.then((newToken) => {
|
|||
|
|
// 刷新成功,重试当前请求
|
|||
|
|
isRefreshing = false;
|
|||
|
|
|
|||
|
|
// 重试当前请求
|
|||
|
|
request(options).then(resolve).catch(reject);
|
|||
|
|
|
|||
|
|
// 重试队列中的请求
|
|||
|
|
requests.forEach(cb => cb());
|
|||
|
|
requests = [];
|
|||
|
|
})
|
|||
|
|
.catch((err) => {
|
|||
|
|
// 刷新失败,跳转登录
|
|||
|
|
isRefreshing = false;
|
|||
|
|
requests = [];
|
|||
|
|
|
|||
|
|
uni.showToast({
|
|||
|
|
title: '登录已过期,请重新登录',
|
|||
|
|
icon: 'none'
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
setTimeout(() => {
|
|||
|
|
uni.reLaunch({
|
|||
|
|
url: '/pages/login/login'
|
|||
|
|
});
|
|||
|
|
}, 1500);
|
|||
|
|
|
|||
|
|
reject(err);
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
// 其他错误
|
|||
|
|
else {
|
|||
|
|
reject(res);
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
fail: (err) => {
|
|||
|
|
reject(err);
|
|||
|
|
}
|
|||
|
|
});
|
|||
|
|
});
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 刷新Token
|
|||
|
|
*/
|
|||
|
|
const refreshToken = () => {
|
|||
|
|
return new Promise((resolve, reject) => {
|
|||
|
|
const refreshToken = uni.getStorageSync('refreshToken');
|
|||
|
|
|
|||
|
|
if (!refreshToken) {
|
|||
|
|
reject(new Error('No refresh token'));
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
uni.request({
|
|||
|
|
url: API_BASE + '/api/users/refresh-token',
|
|||
|
|
method: 'POST',
|
|||
|
|
data: {
|
|||
|
|
refreshToken: refreshToken
|
|||
|
|
},
|
|||
|
|
success: (res) => {
|
|||
|
|
if (res.statusCode === 200 && res.data.success) {
|
|||
|
|
// 保存新token
|
|||
|
|
const newToken = res.data.data.token;
|
|||
|
|
const newRefreshToken = res.data.data.refreshToken;
|
|||
|
|
|
|||
|
|
uni.setStorageSync('token', newToken);
|
|||
|
|
uni.setStorageSync('refreshToken', newRefreshToken);
|
|||
|
|
|
|||
|
|
resolve(newToken);
|
|||
|
|
} else {
|
|||
|
|
reject(new Error('Refresh token failed'));
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
fail: (err) => {
|
|||
|
|
reject(err);
|
|||
|
|
}
|
|||
|
|
});
|
|||
|
|
});
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* GET请求
|
|||
|
|
*/
|
|||
|
|
export const get = (url, data = {}, header = {}) => {
|
|||
|
|
return request({
|
|||
|
|
url,
|
|||
|
|
method: 'GET',
|
|||
|
|
data,
|
|||
|
|
header
|
|||
|
|
});
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* POST请求
|
|||
|
|
*/
|
|||
|
|
export const post = (url, data = {}, header = {}) => {
|
|||
|
|
return request({
|
|||
|
|
url,
|
|||
|
|
method: 'POST',
|
|||
|
|
data,
|
|||
|
|
header
|
|||
|
|
});
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* PUT请求
|
|||
|
|
*/
|
|||
|
|
export const put = (url, data = {}, header = {}) => {
|
|||
|
|
return request({
|
|||
|
|
url,
|
|||
|
|
method: 'PUT',
|
|||
|
|
data,
|
|||
|
|
header
|
|||
|
|
});
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* DELETE请求
|
|||
|
|
*/
|
|||
|
|
export const del = (url, data = {}, header = {}) => {
|
|||
|
|
return request({
|
|||
|
|
url,
|
|||
|
|
method: 'DELETE',
|
|||
|
|
data,
|
|||
|
|
header
|
|||
|
|
});
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
export default {
|
|||
|
|
get,
|
|||
|
|
post,
|
|||
|
|
put,
|
|||
|
|
del,
|
|||
|
|
request
|
|||
|
|
};
|