Generating commit message...

This commit is contained in:
2025-08-30 14:33:49 +08:00
parent 4d469e95f0
commit 7f9bfbb381
99 changed files with 69225 additions and 35 deletions

230
mini-program/api/request.js Normal file
View File

@@ -0,0 +1,230 @@
import config from './config.js'
// 请求队列用于处理token刷新
const requestQueue = []
let isRefreshing = false
class Request {
constructor() {
this.baseURL = config.baseURL
this.timeout = config.timeout
this.interceptors = {
request: [],
response: []
}
}
// 添加请求拦截器
addRequestInterceptor(interceptor) {
this.interceptors.request.push(interceptor)
}
// 添加响应拦截器
addResponseInterceptor(interceptor) {
this.interceptors.response.push(interceptor)
}
// 执行请求拦截器
async runRequestInterceptors(config) {
for (const interceptor of this.interceptors.request) {
config = await interceptor(config)
}
return config
}
// 执行响应拦截器
async runResponseInterceptors(response) {
for (const interceptor of this.interceptors.response) {
response = await interceptor(response)
}
return response
}
// 核心请求方法
async request(options) {
try {
// 合并配置
const requestConfig = {
url: options.url.startsWith('http') ? options.url : `${this.baseURL}${options.url}`,
method: options.method || 'GET',
header: {
'Content-Type': 'application/json',
...options.header
},
data: options.data,
timeout: this.timeout
}
// 执行请求拦截器
const finalConfig = await this.runRequestInterceptors(requestConfig)
// 发起请求
const response = await uni.request(finalConfig)
// 执行响应拦截器
const finalResponse = await this.runResponseInterceptors(response)
return finalResponse[1] // uni.request返回的是数组[error, success]
} catch (error) {
console.error('Request error:', error)
throw error
}
}
// GET请求
get(url, data = {}, options = {}) {
return this.request({
url,
method: 'GET',
data,
...options
})
}
// POST请求
post(url, data = {}, options = {}) {
return this.request({
url,
method: 'POST',
data,
...options
})
}
// PUT请求
put(url, data = {}, options = {}) {
return this.request({
url,
method: 'PUT',
data,
...options
})
}
// DELETE请求
delete(url, data = {}, options = {}) {
return this.request({
url,
method: 'DELETE',
data,
...options
})
}
// 上传文件
upload(url, filePath, formData = {}, options = {}) {
return new Promise((resolve, reject) => {
uni.uploadFile({
url: `${this.baseURL}${url}`,
filePath,
name: 'file',
formData,
success: resolve,
fail: reject,
...options
})
})
}
// 下载文件
download(url, options = {}) {
return new Promise((resolve, reject) => {
uni.downloadFile({
url: `${this.baseURL}${url}`,
success: resolve,
fail: reject,
...options
})
})
}
}
// 创建请求实例
const request = new Request()
// 添加请求拦截器 - Token处理
request.addRequestInterceptor(async (config) => {
const token = uni.getStorageSync('token')
if (token) {
config.header.Authorization = `Bearer ${token}`
}
return config
})
// 添加响应拦截器 - 错误处理
request.addResponseInterceptor(async (response) => {
const { statusCode, data } = response
if (statusCode === 200) {
if (data.code === 0) {
return data.data
} else {
// 业务错误
const error = new Error(data.message || '业务错误')
error.code = data.code
throw error
}
} else if (statusCode === 401) {
// Token过期尝试刷新
return handleTokenExpired(response)
} else {
// 网络错误
throw new Error(`网络错误: ${statusCode}`)
}
})
// Token过期处理
async function handleTokenExpired(response) {
if (isRefreshing) {
// 如果正在刷新,将请求加入队列
return new Promise((resolve) => {
requestQueue.push(() => resolve(request.request(response.config)))
})
}
isRefreshing = true
const refreshToken = uni.getStorageSync('refreshToken')
if (!refreshToken) {
// 没有refreshToken跳转到登录页
uni.navigateTo({ url: '/pages/auth/login' })
throw new Error('请重新登录')
}
try {
// 尝试刷新Token
const result = await request.post(config.endpoints.USER.REFRESH_TOKEN, {
refreshToken
})
// 保存新Token
uni.setStorageSync('token', result.token)
uni.setStorageSync('refreshToken', result.refreshToken)
// 重试原始请求
const retryResponse = await request.request(response.config)
// 处理队列中的请求
processRequestQueue()
return retryResponse
} catch (error) {
// 刷新失败清空Token并跳转登录
uni.removeStorageSync('token')
uni.removeStorageSync('refreshToken')
uni.navigateTo({ url: '/pages/auth/login' })
throw error
} finally {
isRefreshing = false
}
}
// 处理请求队列
function processRequestQueue() {
while (requestQueue.length > 0) {
const retry = requestQueue.shift()
retry()
}
}
export default request