168 lines
3.5 KiB
JavaScript
168 lines
3.5 KiB
JavaScript
/**
|
||
* 请求封装模块
|
||
* 封装 uni.request 支持 GET/POST/PUT/DELETE
|
||
* 实现 JWT Token 自动携带
|
||
* 实现 401 状态码拦截和重新认证
|
||
* Requirements: 1.2, 1.4
|
||
*/
|
||
|
||
import { getToken, removeToken, removeUserInfo } from '../utils/storage'
|
||
|
||
// API 基础地址
|
||
const BASE_URL = 'http://localhost:5000/api/app'
|
||
|
||
// 请求状态
|
||
let isRefreshing = false
|
||
|
||
/**
|
||
* 处理401错误 - 清除token(不自动跳转,避免循环)
|
||
* Property 2: Auth Redirect on Invalid Token
|
||
*/
|
||
export function handleUnauthorized() {
|
||
removeToken()
|
||
removeUserInfo()
|
||
|
||
// 不自动跳转,让调用方处理
|
||
// 避免在首页加载时触发循环跳转
|
||
}
|
||
|
||
/**
|
||
* 发起请求
|
||
* @param {Object} options 请求配置
|
||
* @returns {Promise}
|
||
*/
|
||
export function request(options) {
|
||
const {
|
||
url,
|
||
method = 'GET',
|
||
data = {},
|
||
header = {},
|
||
needAuth = true
|
||
} = options
|
||
|
||
return new Promise((resolve, reject) => {
|
||
const token = getToken()
|
||
|
||
// 构建请求头
|
||
const requestHeader = {
|
||
'Content-Type': 'application/json',
|
||
...header
|
||
}
|
||
|
||
// 如果需要认证且有token,添加Authorization头
|
||
// Property 1: Token Storage Consistency - token从storage获取后自动携带
|
||
if (needAuth && token) {
|
||
requestHeader['Authorization'] = `Bearer ${token}`
|
||
}
|
||
|
||
uni.request({
|
||
url: `${BASE_URL}${url}`,
|
||
method,
|
||
data,
|
||
header: requestHeader,
|
||
success: (res) => {
|
||
const { statusCode, data: responseData } = res
|
||
|
||
// 处理401未授权 - Property 2: Auth Redirect on Invalid Token
|
||
if (statusCode === 401) {
|
||
handleUnauthorized()
|
||
reject(new Error('未授权,请重新登录'))
|
||
return
|
||
}
|
||
|
||
// 处理其他HTTP错误
|
||
if (statusCode >= 400) {
|
||
const errorMsg = responseData?.message || '请求失败'
|
||
reject(new Error(errorMsg))
|
||
return
|
||
}
|
||
|
||
// 处理业务响应
|
||
if (responseData.success === false) {
|
||
reject(new Error(responseData.message || '操作失败'))
|
||
return
|
||
}
|
||
|
||
resolve(responseData)
|
||
},
|
||
fail: (err) => {
|
||
console.error('Request failed:', err)
|
||
reject(new Error('网络连接失败,请检查网络设置'))
|
||
}
|
||
})
|
||
})
|
||
}
|
||
|
||
/**
|
||
* GET 请求
|
||
* @param {string} url 请求地址
|
||
* @param {Object} data 请求参数
|
||
* @param {Object} options 其他配置
|
||
* @returns {Promise}
|
||
*/
|
||
export function get(url, data = {}, options = {}) {
|
||
return request({
|
||
url,
|
||
method: 'GET',
|
||
data,
|
||
...options
|
||
})
|
||
}
|
||
|
||
/**
|
||
* POST 请求
|
||
* @param {string} url 请求地址
|
||
* @param {Object} data 请求数据
|
||
* @param {Object} options 其他配置
|
||
* @returns {Promise}
|
||
*/
|
||
export function post(url, data = {}, options = {}) {
|
||
return request({
|
||
url,
|
||
method: 'POST',
|
||
data,
|
||
...options
|
||
})
|
||
}
|
||
|
||
/**
|
||
* PUT 请求
|
||
* @param {string} url 请求地址
|
||
* @param {Object} data 请求数据
|
||
* @param {Object} options 其他配置
|
||
* @returns {Promise}
|
||
*/
|
||
export function put(url, data = {}, options = {}) {
|
||
return request({
|
||
url,
|
||
method: 'PUT',
|
||
data,
|
||
...options
|
||
})
|
||
}
|
||
|
||
/**
|
||
* DELETE 请求
|
||
* @param {string} url 请求地址
|
||
* @param {Object} data 请求数据
|
||
* @param {Object} options 其他配置
|
||
* @returns {Promise}
|
||
*/
|
||
export function del(url, data = {}, options = {}) {
|
||
return request({
|
||
url,
|
||
method: 'DELETE',
|
||
data,
|
||
...options
|
||
})
|
||
}
|
||
|
||
export default {
|
||
request,
|
||
get,
|
||
post,
|
||
put,
|
||
del,
|
||
handleUnauthorized
|
||
}
|