campus-errand/miniapp/utils/request.js
18631081161 5a04e003ca
All checks were successful
continuous-integration/drone/push Build is passing
聊天,金额,UI
2026-04-01 21:26:13 +08:00

134 lines
3.0 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()
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) {
clearAuth()
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