You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
298 lines
6.9 KiB
298 lines
6.9 KiB
import {
|
|
Api_url,
|
|
isMockEnabled,
|
|
isDebug
|
|
} from './config'
|
|
import mockService from '@/mock/index.js'
|
|
// import {Token} from './token.js'
|
|
// var token = new Token();
|
|
|
|
// 防抖函数
|
|
const debounce = (fn, delay = 1000) => {
|
|
let timer = null;
|
|
return function (...args) {
|
|
return new Promise((resolve, reject) => {
|
|
if (timer) clearTimeout(timer);
|
|
timer = setTimeout(async () => {
|
|
try {
|
|
const result = await fn.apply(this, args);
|
|
resolve(result);
|
|
} catch (error) {
|
|
reject(error);
|
|
}
|
|
}, delay);
|
|
});
|
|
}
|
|
}
|
|
|
|
// 请求拦截器
|
|
const requestInterceptor = (config) => {
|
|
// 在这里可以统一处理请求头、token等
|
|
const token = uni.getStorageSync("token");
|
|
if (token) {
|
|
config.header = {
|
|
...config.header,
|
|
'token': token
|
|
}
|
|
}
|
|
return config;
|
|
}
|
|
|
|
// 响应拦截器
|
|
const responseInterceptor = (response) => {
|
|
const { statusCode, data } = response;
|
|
console.log('响应拦截器处理:', { statusCode, data });
|
|
|
|
// 处理HTTP状态码
|
|
if (statusCode >= 200 && statusCode < 300) {
|
|
// 处理业务状态码
|
|
if (data && typeof data.code !== 'undefined') {
|
|
console.log('业务状态码:', data.code);
|
|
if (data.code === 1) { // 成功状态码为1
|
|
// 登录成功,保存token
|
|
if (data.data && data.data.token) {
|
|
uni.setStorageSync("token", data.data.token);
|
|
// 保存用户类型
|
|
if (data.data.user_type) {
|
|
uni.setStorageSync("userType", data.data.user_type);
|
|
}
|
|
// 保存过期时间
|
|
if (data.data.expires_time) {
|
|
uni.setStorageSync("expires_time", data.data.expires_time);
|
|
}
|
|
}
|
|
// 成功情况直接返回数据
|
|
} else if (data.code === 401) {
|
|
console.error('401错误 - 未授权');
|
|
// 未授权或token过期,清除所有用户缓存信息
|
|
// 清除token
|
|
uni.removeStorageSync("token");
|
|
// 清除用户信息
|
|
uni.removeStorageSync("userInfo");
|
|
// 清除用户类型
|
|
uni.removeStorageSync("userType");
|
|
// 清除用户角色
|
|
uni.removeStorageSync("userRoles");
|
|
// 清除过期时间
|
|
uni.removeStorageSync("expires_time");
|
|
// 清除底部菜单选中状态
|
|
uni.removeStorageSync("tabBerIndex");
|
|
|
|
// 检查是否是从登录页退出的请求
|
|
const pages = getCurrentPages();
|
|
const currentPage = pages[pages.length - 1];
|
|
const isFromLoginPage = currentPage && currentPage.route && currentPage.route.includes('/pages/student/login/login');
|
|
|
|
// 如果不是从登录页退出的请求,才显示提示信息
|
|
if (!isFromLoginPage) {
|
|
uni.showToast({
|
|
title: data.msg || '登录已过期,请重新登录',
|
|
icon: 'none'
|
|
});
|
|
}
|
|
|
|
setTimeout(() => {
|
|
uni.reLaunch({
|
|
url: '/pages/student/login/login?code=401'
|
|
});
|
|
}, 1500);
|
|
throw new Error(data.msg || '未授权');
|
|
} else {
|
|
// 不要在这里显示toast,让业务层自己处理错误信息
|
|
// uni.showToast({
|
|
// title: data.msg || '请求失败',
|
|
// icon: 'none'
|
|
// });
|
|
}
|
|
}
|
|
// 始终返回数据,让业务层判断成功失败
|
|
return data;
|
|
}
|
|
};
|
|
|
|
export default {
|
|
// 存储正在进行的请求
|
|
pendingRequests: new Map(),
|
|
|
|
// 生成请求的唯一key
|
|
generateRequestKey(config) {
|
|
const { url, method, data } = config;
|
|
return [url, method, JSON.stringify(data)].join('&');
|
|
},
|
|
|
|
// 取消重复请求
|
|
cancelRequest(config) {
|
|
const requestKey = this.generateRequestKey(config);
|
|
if (this.pendingRequests.has(requestKey)) {
|
|
const controller = this.pendingRequests.get(requestKey);
|
|
controller.abort();
|
|
this.pendingRequests.delete(requestKey);
|
|
}
|
|
},
|
|
|
|
// 增强请求处理,支持Mock数据回退
|
|
async uni_request(options) {
|
|
if (isDebug) {
|
|
console.log('发起请求:', options);
|
|
}
|
|
|
|
// 检查是否应该使用Mock数据
|
|
if (mockService.shouldUseMock(options.url)) {
|
|
if (isDebug) {
|
|
console.log('使用Mock数据:', options.url);
|
|
}
|
|
try {
|
|
const mockResponse = await mockService.getMockData(options.url, options.data);
|
|
if (mockResponse) {
|
|
return mockResponse;
|
|
}
|
|
} catch (error) {
|
|
console.error('Mock数据获取失败:', error);
|
|
}
|
|
}
|
|
|
|
return new Promise((resolve, reject) => {
|
|
// 创建请求配置
|
|
// 确保URL正确拼接,避免缺少斜杠的问题
|
|
let fullUrl = Api_url;
|
|
if (!fullUrl.endsWith('/') && !options.url.startsWith('/')) {
|
|
fullUrl += '/';
|
|
}
|
|
fullUrl += options.url;
|
|
|
|
const config = {
|
|
url: fullUrl,
|
|
data: options.data,
|
|
method: options.method || 'GET',
|
|
header: {
|
|
'token': uni.getStorageSync("token")
|
|
},
|
|
timeout: 10000 // 设置10秒超时
|
|
};
|
|
|
|
if (isDebug) {
|
|
console.log('请求配置:', config);
|
|
}
|
|
|
|
// 应用请求拦截器
|
|
const interceptedConfig = requestInterceptor(config);
|
|
|
|
uni.showLoading({
|
|
title: '加载中...'
|
|
});
|
|
|
|
if (isDebug) {
|
|
console.log('即将发起uni.request');
|
|
}
|
|
|
|
uni.request({
|
|
...interceptedConfig,
|
|
success: (res) => {
|
|
if (isDebug) {
|
|
console.log('请求成功响应:', res);
|
|
}
|
|
try {
|
|
const response = responseInterceptor(res);
|
|
resolve(response);
|
|
} catch (error) {
|
|
reject(error);
|
|
}
|
|
},
|
|
fail: (error) => {
|
|
console.error('请求失败:', error);
|
|
// API失败时尝试使用Mock数据
|
|
this.tryMockFallback(options, resolve, reject);
|
|
},
|
|
complete: () => {
|
|
if (isDebug) {
|
|
console.log('请求完成');
|
|
}
|
|
uni.hideLoading();
|
|
}
|
|
});
|
|
});
|
|
},
|
|
// 封装请求方法
|
|
post(url, data = {}) {
|
|
return this.uni_request({
|
|
url,
|
|
data,
|
|
method: 'POST'
|
|
});
|
|
},
|
|
|
|
get(url, data = {}) {
|
|
console.log('调用get方法:', { url, data });
|
|
return this.uni_request({
|
|
url,
|
|
data,
|
|
method: 'GET'
|
|
});
|
|
},
|
|
|
|
put(url, data = {}) {
|
|
return this.uni_request({
|
|
url,
|
|
data,
|
|
method: 'PUT'
|
|
});
|
|
},
|
|
|
|
// 文件上传方法
|
|
uploadFile({ url, filePath, name = 'file', formData = {} }) {
|
|
return new Promise((resolve, reject) => {
|
|
// 获取token
|
|
const token = uni.getStorageSync("token");
|
|
|
|
// 显示加载状态
|
|
uni.showLoading({
|
|
title: '上传中...',
|
|
mask: true
|
|
});
|
|
|
|
// 构建完整URL
|
|
let fullUrl = Api_url;
|
|
if (!fullUrl.endsWith('/') && !url.startsWith('/')) {
|
|
fullUrl += '/';
|
|
}
|
|
fullUrl += url;
|
|
|
|
console.log('文件上传请求:', {
|
|
url: fullUrl,
|
|
filePath,
|
|
name,
|
|
formData
|
|
});
|
|
|
|
uni.uploadFile({
|
|
url: fullUrl,
|
|
filePath: filePath,
|
|
name: name,
|
|
formData: formData,
|
|
header: {
|
|
'token': token
|
|
},
|
|
success: (res) => {
|
|
console.log('文件上传成功:', res);
|
|
try {
|
|
const data = JSON.parse(res.data);
|
|
resolve({
|
|
data: data,
|
|
statusCode: res.statusCode
|
|
});
|
|
} catch (error) {
|
|
console.error('解析上传响应失败:', error);
|
|
reject(new Error('响应数据格式错误'));
|
|
}
|
|
},
|
|
fail: (error) => {
|
|
console.error('文件上传失败:', error);
|
|
reject(error);
|
|
},
|
|
complete: () => {
|
|
uni.hideLoading();
|
|
}
|
|
});
|
|
});
|
|
}
|
|
}
|
|
|