303 lines
6.7 KiB
JavaScript
303 lines
6.7 KiB
JavaScript
/**
|
||
* HTTP请求封装
|
||
* 基于uni.request进行二次封装
|
||
*/
|
||
|
||
import config from '@/config/api.config.js'
|
||
|
||
class Request {
|
||
constructor() {
|
||
this.baseURL = config.baseURL
|
||
this.timeout = config.timeout
|
||
}
|
||
|
||
/**
|
||
* 核心请求方法
|
||
* @param {Object} options 请求配置
|
||
* @returns {Promise}
|
||
*/
|
||
request(options) {
|
||
// 显示loading
|
||
if (options.loading !== false) {
|
||
uni.showLoading({
|
||
title: options.loadingText || '加载中...',
|
||
mask: true
|
||
})
|
||
}
|
||
|
||
// 打印请求信息(仅POST请求)
|
||
if (options.method === 'POST') {
|
||
console.log('=== HTTP POST 请求 ===')
|
||
console.log('URL:', this.baseURL + options.url)
|
||
console.log('Method:', options.method)
|
||
console.log('请求数据:', options.data)
|
||
console.log('请求头:', this.getHeaders(options.header))
|
||
}
|
||
|
||
return new Promise((resolve, reject) => {
|
||
uni.request({
|
||
url: this.baseURL + options.url,
|
||
method: options.method || 'GET',
|
||
data: options.data || {},
|
||
header: this.getHeaders(options.header),
|
||
timeout: options.timeout || this.timeout,
|
||
success: (res) => {
|
||
// 隐藏loading
|
||
if (options.loading !== false) {
|
||
uni.hideLoading()
|
||
}
|
||
|
||
console.log('=== HTTP 响应 ===')
|
||
console.log('状态码:', res.statusCode)
|
||
console.log('响应数据:', res.data)
|
||
|
||
// 处理响应
|
||
this.handleResponse(res, resolve, reject)
|
||
},
|
||
fail: (err) => {
|
||
// 隐藏loading
|
||
if (options.loading !== false) {
|
||
uni.hideLoading()
|
||
}
|
||
|
||
console.log('=== HTTP 请求失败 ===')
|
||
console.log('错误信息:', err)
|
||
|
||
// 处理错误
|
||
this.handleError(err, reject)
|
||
}
|
||
})
|
||
})
|
||
}
|
||
|
||
/**
|
||
* 获取请求头
|
||
* @param {Object} customHeader 自定义请求头
|
||
* @returns {Object}
|
||
*/
|
||
getHeaders(customHeader = {}) {
|
||
// 获取token
|
||
const token = uni.getStorageSync('token') || ''
|
||
|
||
return {
|
||
'Content-Type': 'application/json',
|
||
'Blade-Auth': token ? `Bearer ${token}` : '',
|
||
...customHeader
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 处理响应数据
|
||
* @param {Object} res 响应对象
|
||
* @param {Function} resolve Promise resolve
|
||
* @param {Function} reject Promise reject
|
||
*/
|
||
handleResponse(res, resolve, reject) {
|
||
const data = res.data
|
||
|
||
// 判断HTTP状态码
|
||
// 2xx 和 304 都是成功的状态码
|
||
if (res.statusCode < 200 || (res.statusCode >= 300 && res.statusCode !== 304)) {
|
||
this.showError('网络请求失败')
|
||
reject({
|
||
code: res.statusCode,
|
||
message: '网络请求失败'
|
||
})
|
||
return
|
||
}
|
||
|
||
// 判断业务状态码
|
||
if (data.code === 200 || data.success === true) {
|
||
// 请求成功,返回数据
|
||
resolve(data.data)
|
||
} else {
|
||
// 业务错误处理
|
||
const errorMsg = data.msg || data.message || '请求失败'
|
||
|
||
// 特殊错误码处理
|
||
if (data.code === 401 || data.code === 403) {
|
||
// token过期或无权限
|
||
this.handleTokenExpired()
|
||
}
|
||
|
||
this.showError(errorMsg)
|
||
reject({
|
||
code: data.code,
|
||
message: errorMsg,
|
||
data: data.data
|
||
})
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 处理请求错误
|
||
* @param {Object} err 错误对象
|
||
* @param {Function} reject Promise reject
|
||
*/
|
||
handleError(err, reject) {
|
||
console.error('请求失败:', err)
|
||
console.error('请求URL:', this.baseURL)
|
||
|
||
let message = '网络请求失败'
|
||
|
||
if (err.errMsg) {
|
||
if (err.errMsg.includes('timeout')) {
|
||
message = '请求超时,请检查网络'
|
||
} else if (err.errMsg.includes('fail')) {
|
||
message = '网络连接失败,请检查服务器地址'
|
||
}
|
||
}
|
||
|
||
this.showError(message)
|
||
reject({
|
||
code: undefined,
|
||
message: '请求失败',
|
||
data: undefined,
|
||
error: err,
|
||
url: this.baseURL
|
||
})
|
||
}
|
||
|
||
/**
|
||
* 显示错误提示
|
||
* @param {String} message 错误信息
|
||
*/
|
||
showError(message) {
|
||
uni.showToast({
|
||
title: message,
|
||
icon: 'none',
|
||
duration: 2000
|
||
})
|
||
}
|
||
|
||
/**
|
||
* 处理token过期
|
||
*/
|
||
handleTokenExpired() {
|
||
// 清除token
|
||
uni.removeStorageSync('token')
|
||
uni.removeStorageSync('userInfo')
|
||
|
||
// 提示用户
|
||
uni.showToast({
|
||
title: '登录已过期,请重新登录',
|
||
icon: 'none',
|
||
duration: 2000
|
||
})
|
||
|
||
// 跳转到登录页(如果有)
|
||
setTimeout(() => {
|
||
// uni.reLaunch({
|
||
// url: '/pages/login/login'
|
||
// })
|
||
}, 2000)
|
||
}
|
||
|
||
/**
|
||
* GET请求
|
||
* @param {String} url 请求地址
|
||
* @param {Object} data 请求参数
|
||
* @param {Object} options 额外配置
|
||
* @returns {Promise}
|
||
*/
|
||
get(url, data = {}, options = {}) {
|
||
return this.request({
|
||
url,
|
||
method: 'GET',
|
||
data,
|
||
...options
|
||
})
|
||
}
|
||
|
||
/**
|
||
* POST请求
|
||
* @param {String} url 请求地址
|
||
* @param {Object} data 请求参数
|
||
* @param {Object} options 额外配置
|
||
* @returns {Promise}
|
||
*/
|
||
post(url, data = {}, options = {}) {
|
||
return this.request({
|
||
url,
|
||
method: 'POST',
|
||
data,
|
||
...options
|
||
})
|
||
}
|
||
|
||
/**
|
||
* PUT请求
|
||
* @param {String} url 请求<E8AFB7><E6B182>址
|
||
* @param {Object} data 请求参数
|
||
* @param {Object} options 额外配置
|
||
* @returns {Promise}
|
||
*/
|
||
put(url, data = {}, options = {}) {
|
||
return this.request({
|
||
url,
|
||
method: 'PUT',
|
||
data,
|
||
...options
|
||
})
|
||
}
|
||
|
||
/**
|
||
* DELETE请求
|
||
* @param {String} url 请求地址
|
||
* @param {Object} data 请求参数
|
||
* @param {Object} options 额外配置
|
||
* @returns {Promise}
|
||
*/
|
||
delete(url, data = {}, options = {}) {
|
||
return this.request({
|
||
url,
|
||
method: 'DELETE',
|
||
data,
|
||
...options
|
||
})
|
||
}
|
||
|
||
/**
|
||
* 文件上传
|
||
* @param {String} url 上传地址
|
||
* @param {String} filePath 文件路径
|
||
* @param {Object} formData 额外数据
|
||
* @returns {Promise}
|
||
*/
|
||
upload(url, filePath, formData = {}) {
|
||
uni.showLoading({
|
||
title: '上传中...',
|
||
mask: true
|
||
})
|
||
|
||
return new Promise((resolve, reject) => {
|
||
uni.uploadFile({
|
||
url: this.baseURL + url,
|
||
filePath,
|
||
name: 'file',
|
||
formData,
|
||
header: this.getHeaders(),
|
||
success: (res) => {
|
||
uni.hideLoading()
|
||
|
||
const data = JSON.parse(res.data)
|
||
if (data.code === 200) {
|
||
resolve(data.data)
|
||
} else {
|
||
this.showError(data.msg || '上传失败')
|
||
reject(data)
|
||
}
|
||
},
|
||
fail: (err) => {
|
||
uni.hideLoading()
|
||
this.showError('上传失败')
|
||
reject(err)
|
||
}
|
||
})
|
||
})
|
||
}
|
||
}
|
||
|
||
// 导出实例
|
||
export default new Request()
|