279 lines
6.1 KiB
JavaScript
279 lines
6.1 KiB
JavaScript
|
|
/**
|
|||
|
|
* 统一请求模块
|
|||
|
|
* 封装所有 API 请求,支持拦截器、错误处理等
|
|||
|
|
*/
|
|||
|
|
|
|||
|
|
const { API_BASE, TIMEOUT, ENABLE_LOG, IS_DEV } = require('./config.js')
|
|||
|
|
const httpClient = require('./httpClient.js')
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 统一请求方法
|
|||
|
|
* @param {Object} options 请求配置
|
|||
|
|
* @param {String} options.url 请求路径(相对路径,会自动拼接 API_BASE)
|
|||
|
|
* @param {String} options.method 请求方法 GET/POST/PUT/DELETE
|
|||
|
|
* @param {Object} options.data 请求数据
|
|||
|
|
* @param {Object} options.header 自定义请求头
|
|||
|
|
* @param {Boolean} options.showLoading 是否显示加载提示
|
|||
|
|
* @param {String} options.loadingText 加载提示文字
|
|||
|
|
* @param {Boolean} options.showError 是否显示错误提示
|
|||
|
|
* @returns {Promise}
|
|||
|
|
*/
|
|||
|
|
function request(options = {}) {
|
|||
|
|
const {
|
|||
|
|
url,
|
|||
|
|
method = 'GET',
|
|||
|
|
data = {},
|
|||
|
|
header = {},
|
|||
|
|
showLoading = false,
|
|||
|
|
loadingText = '加载中...',
|
|||
|
|
showError = true
|
|||
|
|
} = options
|
|||
|
|
|
|||
|
|
// 显示加载提示
|
|||
|
|
if (showLoading) {
|
|||
|
|
wx.showLoading({
|
|||
|
|
title: loadingText,
|
|||
|
|
mask: true
|
|||
|
|
})
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 拼接完整URL
|
|||
|
|
const fullUrl = url.startsWith('http') ? url : `${API_BASE}${url}`
|
|||
|
|
|
|||
|
|
// 构建请求头
|
|||
|
|
const requestHeader = {
|
|||
|
|
'Content-Type': 'application/json',
|
|||
|
|
...header
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 添加 token(如果存在)
|
|||
|
|
const token = wx.getStorageSync('token')
|
|||
|
|
if (token) {
|
|||
|
|
requestHeader['Authorization'] = `Bearer ${token}`
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 日志输出
|
|||
|
|
if (ENABLE_LOG) {
|
|||
|
|
console.log('[API Request]', {
|
|||
|
|
url: fullUrl,
|
|||
|
|
method,
|
|||
|
|
data,
|
|||
|
|
header: requestHeader
|
|||
|
|
})
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return new Promise((resolve, reject) => {
|
|||
|
|
wx.request({
|
|||
|
|
url: fullUrl,
|
|||
|
|
method,
|
|||
|
|
data,
|
|||
|
|
header: requestHeader,
|
|||
|
|
timeout: TIMEOUT,
|
|||
|
|
success: (res) => {
|
|||
|
|
// 隐藏加载提示
|
|||
|
|
if (showLoading) {
|
|||
|
|
wx.hideLoading()
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 日志输出
|
|||
|
|
if (ENABLE_LOG) {
|
|||
|
|
console.log('[API Response]', res.data)
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 统一处理响应
|
|||
|
|
const { statusCode, data: resData } = res
|
|||
|
|
|
|||
|
|
// HTTP 状态码检查
|
|||
|
|
if (statusCode >= 200 && statusCode < 300) {
|
|||
|
|
// 业务状态码检查
|
|||
|
|
if (resData.code === 200 || resData.success === true) {
|
|||
|
|
resolve(resData)
|
|||
|
|
} else {
|
|||
|
|
// 业务错误
|
|||
|
|
const errorMsg = resData.msg || resData.message || '请求失败'
|
|||
|
|
if (showError) {
|
|||
|
|
wx.showToast({
|
|||
|
|
title: errorMsg,
|
|||
|
|
icon: 'none',
|
|||
|
|
duration: 2000
|
|||
|
|
})
|
|||
|
|
}
|
|||
|
|
reject({
|
|||
|
|
code: resData.code,
|
|||
|
|
msg: errorMsg,
|
|||
|
|
data: resData
|
|||
|
|
})
|
|||
|
|
}
|
|||
|
|
} else {
|
|||
|
|
// HTTP 错误
|
|||
|
|
const errorMsg = `服务器错误 (${statusCode})`
|
|||
|
|
if (showError) {
|
|||
|
|
wx.showToast({
|
|||
|
|
title: errorMsg,
|
|||
|
|
icon: 'none',
|
|||
|
|
duration: 2000
|
|||
|
|
})
|
|||
|
|
}
|
|||
|
|
reject({
|
|||
|
|
code: statusCode,
|
|||
|
|
msg: errorMsg,
|
|||
|
|
data: res
|
|||
|
|
})
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
fail: (err) => {
|
|||
|
|
// 隐藏加载提示
|
|||
|
|
if (showLoading) {
|
|||
|
|
wx.hideLoading()
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 日志输出
|
|||
|
|
if (ENABLE_LOG) {
|
|||
|
|
console.error('[API Error]', err)
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 网络错误
|
|||
|
|
const errorMsg = err.errMsg || '网络请求失败'
|
|||
|
|
if (showError) {
|
|||
|
|
wx.showToast({
|
|||
|
|
title: errorMsg,
|
|||
|
|
icon: 'none',
|
|||
|
|
duration: 2000
|
|||
|
|
})
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
reject({
|
|||
|
|
code: -1,
|
|||
|
|
msg: errorMsg,
|
|||
|
|
data: err
|
|||
|
|
})
|
|||
|
|
}
|
|||
|
|
})
|
|||
|
|
})
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* GET 请求
|
|||
|
|
*/
|
|||
|
|
function get(url, data = {}, options = {}) {
|
|||
|
|
// 直接使用 httpClient,它会自动处理环境切换
|
|||
|
|
return httpClient.get(url, data, options)
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* POST 请求
|
|||
|
|
*/
|
|||
|
|
function post(url, data = {}, options = {}) {
|
|||
|
|
// 直接使用 httpClient,它会自动处理环境切换
|
|||
|
|
return httpClient.post(url, data, options)
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* PUT 请求
|
|||
|
|
*/
|
|||
|
|
function put(url, data = {}, options = {}) {
|
|||
|
|
// 直接使用 httpClient,它会自动处理环境切换
|
|||
|
|
return httpClient.put(url, data, options)
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* DELETE 请求
|
|||
|
|
*/
|
|||
|
|
function del(url, data = {}, options = {}) {
|
|||
|
|
// 直接使用 httpClient,它会自动处理环境切换
|
|||
|
|
return httpClient.del(url, data, options)
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 上传文件
|
|||
|
|
* @param {String} url 上传地址
|
|||
|
|
* @param {String} filePath 文件路径
|
|||
|
|
* @param {Object} formData 额外的表单数据
|
|||
|
|
* @param {Object} options 其他配置
|
|||
|
|
*/
|
|||
|
|
function uploadFile(filePath, formData = {}) {
|
|||
|
|
const {
|
|||
|
|
name = 'file',
|
|||
|
|
showLoading = true,
|
|||
|
|
loadingText = '上传中...',
|
|||
|
|
showError = true
|
|||
|
|
} = options
|
|||
|
|
|
|||
|
|
if (showLoading) {
|
|||
|
|
wx.showLoading({
|
|||
|
|
title: loadingText,
|
|||
|
|
mask: true
|
|||
|
|
})
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
const fullUrl = url.startsWith('http') ? url : `${API_BASE}${url}`
|
|||
|
|
|
|||
|
|
// 构建请求头
|
|||
|
|
const header = {}
|
|||
|
|
const token = wx.getStorageSync('token')
|
|||
|
|
if (token) {
|
|||
|
|
header['Authorization'] = `Bearer ${token}`
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return new Promise((resolve, reject) => {
|
|||
|
|
wx.uploadFile({
|
|||
|
|
url: fullUrl,
|
|||
|
|
filePath,
|
|||
|
|
name,
|
|||
|
|
formData,
|
|||
|
|
header,
|
|||
|
|
timeout: TIMEOUT,
|
|||
|
|
success: (res) => {
|
|||
|
|
if (showLoading) {
|
|||
|
|
wx.hideLoading()
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
const data = JSON.parse(res.data)
|
|||
|
|
if (data.code === 200 || data.success === true) {
|
|||
|
|
resolve(data)
|
|||
|
|
} else {
|
|||
|
|
const errorMsg = data.msg || data.message || '上传失败'
|
|||
|
|
if (showError) {
|
|||
|
|
wx.showToast({
|
|||
|
|
title: errorMsg,
|
|||
|
|
icon: 'none'
|
|||
|
|
})
|
|||
|
|
}
|
|||
|
|
reject({
|
|||
|
|
code: data.code,
|
|||
|
|
msg: errorMsg,
|
|||
|
|
data
|
|||
|
|
})
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
fail: (err) => {
|
|||
|
|
if (showLoading) {
|
|||
|
|
wx.hideLoading()
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
const errorMsg = err.errMsg || '上传失败'
|
|||
|
|
if (showError) {
|
|||
|
|
wx.showToast({
|
|||
|
|
title: errorMsg,
|
|||
|
|
icon: 'none'
|
|||
|
|
})
|
|||
|
|
}
|
|||
|
|
reject({
|
|||
|
|
code: -1,
|
|||
|
|
msg: errorMsg,
|
|||
|
|
data: err
|
|||
|
|
})
|
|||
|
|
}
|
|||
|
|
})
|
|||
|
|
})
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
module.exports = {
|
|||
|
|
request,
|
|||
|
|
get,
|
|||
|
|
post,
|
|||
|
|
put,
|
|||
|
|
del,
|
|||
|
|
uploadFile
|
|||
|
|
}
|