All checks were successful
continuous-integration/drone/push Build is passing
141 lines
3.4 KiB
JavaScript
141 lines
3.4 KiB
JavaScript
/**
|
||
* 网络请求封装
|
||
* - 自动携带 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
|