campus-errand/miniapp/utils/request.js
18631081161 bc1a8e6b3f
All checks were successful
continuous-integration/drone/push Build is passing
聊天记录
2026-04-02 17:18:57 +08:00

141 lines
3.4 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
* 网络请求封装
* - 自动携带 JWT token
* - 401 自动跳转登录页
* - 统一错误处理
*/
// API 基础地址,按环境切换
// const BASE_URL = 'http://localhost:5099'
const BASE_URL = 'http://api.zwz.shhmkjgs.cn'
/**
* 获取本地存储的 token
*/
function getToken() {
return uni.getStorageSync('token') || ''
}
/**
* 清除本地登录凭证
*/
function clearAuth() {
uni.removeStorageSync('token')
uni.removeStorageSync('userInfo')
}
/**
* 跳转到登录页
*/
function redirectToLogin() {
clearAuth()
uni.reLaunch({ url: '/pages/login/login' })
}
/**
* 通用请求方法
* @param {Object} options - 请求配置
* @param {string} options.url - 请求路径(不含 BASE_URL
* @param {string} [options.method='GET'] - 请求方法
* @param {Object} [options.data] - 请求数据
* @param {Object} [options.header] - 自定义请求头
* @returns {Promise<any>} 响应数据
*/
function request(options) {
const { url, method = 'GET', data, header = {} } = options
const token = getToken()
if (token) {
header['Authorization'] = `Bearer ${token}`
}
return new Promise((resolve, reject) => {
uni.request({
url: `${BASE_URL}${url}`,
method,
data,
header: {
'Content-Type': 'application/json',
...header
},
success: (res) => {
const { statusCode, data: resData } = res
if (statusCode === 200 || statusCode === 201) {
resolve(resData)
return
}
// 未登录或 token 过期
if (statusCode === 401) {
// 清除过期的凭证
clearAuth()
// 非静默请求时提示用户重新登录
const pages = getCurrentPages()
const currentPage = pages[pages.length - 1]
const isTabPage = ['pages/index/index', 'pages/order-hall/order-hall', 'pages/message/message', 'pages/mine/mine'].includes(currentPage?.route)
if (!isTabPage) {
uni.showToast({ title: '登录已过期,请重新登录', icon: 'none' })
}
reject(new Error('未登录或登录已过期'))
return
}
// 权限不足
if (statusCode === 403) {
uni.showToast({ title: '权限不足', icon: 'none' })
reject(new Error('权限不足'))
return
}
// 业务错误,展示服务端返回的 message
const errMsg = resData?.message || '请求失败'
uni.showToast({ title: errMsg, icon: 'none' })
reject(new Error(errMsg))
},
fail: (err) => {
uni.showToast({ title: '网络异常,请重试', icon: 'none' })
reject(new Error(err.errMsg || '网络异常'))
}
})
})
}
/**
* 上传文件
* @param {string} filePath - 本地文件路径
* @param {string} [url='/api/upload/image'] - 上传接口路径
* @returns {Promise<any>} 响应数据
*/
function uploadFile(filePath, url = '/api/upload/image') {
const token = getToken()
const header = {}
if (token) {
header['Authorization'] = `Bearer ${token}`
}
return new Promise((resolve, reject) => {
uni.uploadFile({
url: `${BASE_URL}${url}`,
filePath,
name: 'file',
header,
success: (res) => {
if (res.statusCode === 401) {
reject(new Error('未登录或登录已过期'))
return
}
const data = JSON.parse(res.data)
resolve(data)
},
fail: (err) => {
uni.showToast({ title: '上传失败', icon: 'none' })
reject(new Error(err.errMsg || '上传失败'))
}
})
})
}
export { BASE_URL, getToken, clearAuth, redirectToLogin, uploadFile }
export default request