This commit is contained in:
qiuyuan 2025-08-06 18:26:39 +08:00
parent e757cb5c77
commit 0adc144dc4

View File

@ -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 });