Files
martial-mini/utils/request.js
2025-12-12 01:44:41 +08:00

303 lines
6.7 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.
/**
* 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()