11
This commit is contained in:
parent
e757cb5c77
commit
0adc144dc4
120
utils/request.js
120
utils/request.js
@ -1,13 +1,17 @@
|
|||||||
import { BASE_URL } from "./config";
|
import { BASE_URL } from "./config";
|
||||||
|
|
||||||
// 获取本地 Token 的同步方法
|
// 获取本地 Token 的同步方法
|
||||||
const getToken = () => {
|
const getToken = () => {
|
||||||
try {
|
try {
|
||||||
return uni.getStorageSync('token') || null
|
return uni.getStorageSync('token') || null;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error('获取本地Token失败:', e)
|
console.error('获取本地Token失败:', e);
|
||||||
return null
|
return null;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 是否正在跳转登录页,防止重复弹窗
|
||||||
|
let isRedirectingToLogin = false;
|
||||||
|
|
||||||
// 统一请求方法
|
// 统一请求方法
|
||||||
export const request = (options) => {
|
export const request = (options) => {
|
||||||
@ -16,53 +20,105 @@ export const request = (options) => {
|
|||||||
const header = {
|
const header = {
|
||||||
'Content-Type': 'application/json',
|
'Content-Type': 'application/json',
|
||||||
...(options.header || {}), // 允许覆盖默认 header
|
...(options.header || {}), // 允许覆盖默认 header
|
||||||
Authorization: getToken() ? `Bearer ${getToken()}` : undefined
|
Authorization: getToken() ? `Bearer ${getToken()}` : undefined,
|
||||||
}
|
};
|
||||||
|
|
||||||
// 过滤掉 undefined 的 header 项
|
// 过滤掉 undefined 的 header 项
|
||||||
const filteredHeader = Object.fromEntries(
|
const filteredHeader = Object.fromEntries(
|
||||||
Object.entries(header).filter(([_, v]) => v !== undefined)
|
Object.entries(header).filter(([_, v]) => v !== undefined)
|
||||||
)
|
);
|
||||||
|
|
||||||
uni.request({
|
uni.request({
|
||||||
url: `${BASE_URL}${options.url}`,
|
url: `${BASE_URL}${options.url}`,
|
||||||
method: options.method || 'GET',
|
method: options.method || 'GET',
|
||||||
data: options.data || {},
|
data: options.data || {},
|
||||||
header: filteredHeader,
|
header: filteredHeader,
|
||||||
|
timeout: options.timeout || 10000, // 建议设置超时时间
|
||||||
success: (res) => {
|
success: (res) => {
|
||||||
// 处理401未授权
|
const { statusCode } = res;
|
||||||
if (res.statusCode === 401) {
|
|
||||||
uni.removeStorageSync('token')
|
// 处理 401 未授权(登录过期/未登录)
|
||||||
// uni.showToast({ title: '请前往"个人中心页"登录', icon: 'none' })
|
if (statusCode === 401) {
|
||||||
// uni.navigateTo({ url: '/pages/mine/index' })
|
// 防止多次弹窗和重复跳转
|
||||||
return reject(new Error('登录状态已过期'))
|
if (!isRedirectingToLogin) {
|
||||||
|
isRedirectingToLogin = true;
|
||||||
|
|
||||||
|
uni.removeStorageSync('token');
|
||||||
|
|
||||||
|
// 友好提示 + 延迟跳转
|
||||||
|
uni.showToast({
|
||||||
|
title: '暂未登录,请登录后使用',
|
||||||
|
icon: 'none',
|
||||||
|
duration: 1500,
|
||||||
|
});
|
||||||
|
|
||||||
|
setTimeout(() => {
|
||||||
|
isRedirectingToLogin = false;
|
||||||
|
uni.navigateTo({
|
||||||
|
url: '/pages/mine/index',
|
||||||
|
fail: () => {
|
||||||
|
uni.reLaunch({ url: '/pages/mine/index' });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}, 1500);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 处理其他错误状态码
|
return reject(new Error('未登录或登录已过期'));
|
||||||
if (res.statusCode < 200 || res.statusCode >= 300) {
|
|
||||||
const errorMsg = res.data?.message || `请求失败 (${res.statusCode})`
|
|
||||||
uni.showToast({ title: errorMsg, icon: 'none' })
|
|
||||||
return reject(new Error(errorMsg))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
resolve(res.data)
|
// 处理其他非 2xx 状态码
|
||||||
|
if (statusCode < 200 || statusCode >= 300) {
|
||||||
|
const errorMsg = res.data?.message || `请求失败 (HTTP ${statusCode})`;
|
||||||
|
uni.showToast({ title: errorMsg, icon: 'none', duration: 2000 });
|
||||||
|
return reject(new Error(errorMsg));
|
||||||
|
}
|
||||||
|
|
||||||
|
const responseData = res.data;
|
||||||
|
|
||||||
|
if (responseData && typeof responseData === 'object' && 'code' in responseData) {
|
||||||
|
if (responseData.code !== 0) {
|
||||||
|
const bizMsg = responseData.message || '请求异常';
|
||||||
|
uni.showToast({ title: bizMsg, icon: 'none' });
|
||||||
|
return reject(new Error(bizMsg));
|
||||||
|
}
|
||||||
|
// 成功:返回 data 字段
|
||||||
|
resolve(responseData.data);
|
||||||
|
} else {
|
||||||
|
// 兼容没有统一响应格式的接口
|
||||||
|
resolve(responseData);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
fail: (err) => {
|
fail: (err) => {
|
||||||
const errorMsg = err.errMsg.includes('timeout')
|
const errMsg = err.errMsg || '';
|
||||||
? '网络请求超时'
|
let errorMsg = '网络连接失败';
|
||||||
: '网络连接失败'
|
|
||||||
uni.showToast({ title: errorMsg, icon: 'none' })
|
if (errMsg.includes('timeout')) {
|
||||||
reject(new Error(errorMsg))
|
errorMsg = '网络请求超时,请检查网络';
|
||||||
}
|
} else if (errMsg.includes('Network Error')) {
|
||||||
})
|
errorMsg = '网络异常,请检查网络设置';
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 封装常用方法
|
uni.showToast({
|
||||||
export const get = (url, data, header) => request({ url, method: 'GET', data, header })
|
title: errorMsg,
|
||||||
|
icon: 'none',
|
||||||
|
duration: 2000,
|
||||||
|
});
|
||||||
|
|
||||||
export const post = (url, data, header) => request({ url, method: 'POST', data, header })
|
reject(new Error(errorMsg));
|
||||||
|
},
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
export const put = (url, data, header) => request({ url, method: 'PUT', data, header })
|
// 封装常用方法(支持传入额外配置,比如 timeout、skipAuth 等)
|
||||||
|
export const get = (url, data, header, options = {}) =>
|
||||||
|
request({ url, method: 'GET', data, header, ...options });
|
||||||
|
|
||||||
export const del = (url, data, header) => request({ url, method: 'DELETE', data, header })
|
export const post = (url, data, header, options = {}) =>
|
||||||
|
request({ url, method: 'POST', data, header, ...options });
|
||||||
|
|
||||||
|
export const put = (url, data, header, options = {}) =>
|
||||||
|
request({ url, method: 'PUT', data, header, ...options });
|
||||||
|
|
||||||
|
export const del = (url, data, header, options = {}) =>
|
||||||
|
request({ url, method: 'DELETE', data, header, ...options });
|
||||||
Loading…
x
Reference in New Issue
Block a user