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
|
||
}
|