242 lines
5.4 KiB
JavaScript
242 lines
5.4 KiB
JavaScript
/**
|
||
* API 请求封装
|
||
* baseURL 前缀: /app
|
||
* 统一 token 拦截器
|
||
*/
|
||
|
||
// 基础配置
|
||
const BASE_URL = '/app'
|
||
const TIMEOUT = 30000
|
||
|
||
/**
|
||
* 通用请求方法
|
||
* @param {string} url - 请求路径(会自动拼接 /app 前缀)
|
||
* @param {object} data - 请求数据
|
||
* @param {string} method - 请求方法 GET/POST/PUT/DELETE
|
||
* @param {object} header - 自定义请求头
|
||
* @returns {Promise}
|
||
*/
|
||
export function request(url, data = {}, method = 'GET', header = {}) {
|
||
return new Promise((resolve, reject) => {
|
||
// 获取 token
|
||
const token = uni.getStorageSync('token')
|
||
|
||
// 合并请求头
|
||
const headers = {
|
||
'Content-Type': 'application/json',
|
||
...header
|
||
}
|
||
|
||
// 添加 token
|
||
if (token) {
|
||
headers['Authorization'] = `Bearer ${token}`
|
||
}
|
||
|
||
// 完整 URL
|
||
const fullUrl = `${BASE_URL}${url}`
|
||
|
||
uni.request({
|
||
url: fullUrl,
|
||
data,
|
||
method,
|
||
header: headers,
|
||
timeout: TIMEOUT,
|
||
success: (res) => {
|
||
const { statusCode, data } = res
|
||
|
||
// HTTP 状态码判断
|
||
if (statusCode === 200) {
|
||
// 业务状态码判断(假设后端返回格式为 { code: 0, data, message })
|
||
if (data.code === 0 || data.code === 200) {
|
||
resolve(data)
|
||
} else if (data.code === 401) {
|
||
// token 过期或未授权
|
||
handleUnauthorized()
|
||
reject(new Error(data.message || '登录已过期,请重新登录'))
|
||
} else {
|
||
// 其他业务错误
|
||
uni.showToast({
|
||
title: data.message || '请求失败',
|
||
icon: 'none',
|
||
duration: 2000
|
||
})
|
||
reject(new Error(data.message || '请求失败'))
|
||
}
|
||
} else if (statusCode === 401) {
|
||
handleUnauthorized()
|
||
reject(new Error('登录已过期,请重新登录'))
|
||
} else if (statusCode === 403) {
|
||
reject(new Error('没有权限访问'))
|
||
} else if (statusCode === 404) {
|
||
reject(new Error('请求的资源不存在'))
|
||
} else if (statusCode >= 500) {
|
||
uni.showToast({
|
||
title: '服务器错误,请稍后重试',
|
||
icon: 'none'
|
||
})
|
||
reject(new Error('服务器错误'))
|
||
} else {
|
||
reject(new Error(`请求失败(${statusCode})`))
|
||
}
|
||
},
|
||
fail: (err) => {
|
||
console.error('Request failed:', err)
|
||
|
||
let errorMsg = '网络异常,请检查网络连接'
|
||
|
||
if (err.errMsg.includes('timeout')) {
|
||
errorMsg = '请求超时,请稍后重试'
|
||
} else if (err.errMsg.includes('abort')) {
|
||
errorMsg = '请求已取消'
|
||
}
|
||
|
||
uni.showToast({
|
||
title: errorMsg,
|
||
icon: 'none',
|
||
duration: 2000
|
||
})
|
||
|
||
reject(new Error(errorMsg))
|
||
}
|
||
})
|
||
})
|
||
}
|
||
|
||
/**
|
||
* 处理未授权(token 失效)
|
||
*/
|
||
function handleUnauthorized() {
|
||
// 清除本地存储
|
||
uni.removeStorageSync('token')
|
||
uni.removeStorageSync('userInfo')
|
||
|
||
// 提示用户
|
||
uni.showToast({
|
||
title: '登录已过期,请重新登录',
|
||
icon: 'none',
|
||
duration: 1500
|
||
})
|
||
|
||
// 跳转到登录页
|
||
setTimeout(() => {
|
||
uni.reLaunch({
|
||
url: '/pages/login/login'
|
||
})
|
||
}, 1500)
|
||
}
|
||
|
||
/**
|
||
* GET 请求
|
||
*/
|
||
export function get(url, data = {}, header = {}) {
|
||
return request(url, data, 'GET', header)
|
||
}
|
||
|
||
/**
|
||
* POST 请求
|
||
*/
|
||
export function post(url, data = {}, header = {}) {
|
||
return request(url, data, 'POST', header)
|
||
}
|
||
|
||
/**
|
||
* PUT 请求
|
||
*/
|
||
export function put(url, data = {}, header = {}) {
|
||
return request(url, data, 'PUT', header)
|
||
}
|
||
|
||
/**
|
||
* DELETE 请求
|
||
*/
|
||
export function del(url, data = {}, header = {}) {
|
||
return request(url, data, 'DELETE', header)
|
||
}
|
||
|
||
/**
|
||
* 文件上传
|
||
* @param {string} url - 上传接口路径
|
||
* @param {string} filePath - 本地文件路径
|
||
* @param {object} formData - 额外表单数据
|
||
*/
|
||
export function upload(url, filePath, formData = {}) {
|
||
return new Promise((resolve, reject) => {
|
||
const token = uni.getStorageSync('token')
|
||
|
||
const header = {}
|
||
if (token) {
|
||
header['Authorization'] = `Bearer ${token}`
|
||
}
|
||
|
||
uni.uploadFile({
|
||
url: `${BASE_URL}${url}`,
|
||
filePath,
|
||
name: 'file',
|
||
formData,
|
||
header,
|
||
success: (res) => {
|
||
if (res.statusCode === 200) {
|
||
const data = JSON.parse(res.data)
|
||
if (data.code === 0 || data.code === 200) {
|
||
resolve(data)
|
||
} else {
|
||
reject(new Error(data.message || '上传失败'))
|
||
}
|
||
} else {
|
||
reject(new Error('上传失败'))
|
||
}
|
||
},
|
||
fail: (err) => {
|
||
console.error('Upload failed:', err)
|
||
reject(new Error('上传失败'))
|
||
}
|
||
})
|
||
})
|
||
}
|
||
|
||
// ==================== 具体业务 API ====================
|
||
|
||
/**
|
||
* 发送短信验证码
|
||
*/
|
||
export function sendSmsCode(data) {
|
||
return post('/sms/send', data)
|
||
}
|
||
|
||
/**
|
||
* 手机号验证码登录
|
||
*/
|
||
export function phoneCodeLogin(data) {
|
||
return post('/login/phone', data)
|
||
}
|
||
|
||
/**
|
||
* 账号密码登录
|
||
*/
|
||
export function passwordLogin(data) {
|
||
return post('/login/password', data)
|
||
}
|
||
|
||
/**
|
||
* 退出登录
|
||
*/
|
||
export function logout() {
|
||
return post('/logout').finally(() => {
|
||
uni.removeStorageSync('token')
|
||
uni.removeStorageSync('userInfo')
|
||
})
|
||
}
|
||
|
||
export default {
|
||
request,
|
||
get,
|
||
post,
|
||
put,
|
||
del,
|
||
upload,
|
||
sendSmsCode,
|
||
phoneCodeLogin,
|
||
passwordLogin,
|
||
logout
|
||
}
|