智慧教务系统
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.
 
 
 
 
 
 

296 lines
6.8 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);
}
}
return data;
} 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 {
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();
}
});
});
}
}