122 lines
3.2 KiB
JavaScript
122 lines
3.2 KiB
JavaScript
/**
|
|
* 统一请求封装:baseURL、Bearer Token、业务 code 处理。
|
|
* 接口地址统一从 .env 的 VITE_API_BASE_URL 读取(见 api/config.js)。
|
|
*/
|
|
import { getToken, logout } from '@/utils/auth.js'
|
|
import { resolveBaseURL, getBaseURL } from '@/api/config.js'
|
|
|
|
const BASE_URL = resolveBaseURL()
|
|
|
|
export { getBaseURL }
|
|
|
|
/**
|
|
* @param {{ url: string, method?: string, data?: object, header?: object, silent?: boolean }} options
|
|
* @returns {Promise<any>} 业务 data 字段(若无 data 则返回整包)
|
|
*/
|
|
export function request(options = {}) {
|
|
const { url, method = 'GET', data, header = {}, silent = false, timeout = 30000 } = options
|
|
const token = getToken()
|
|
const headers = {
|
|
'Content-Type': 'application/json',
|
|
...header
|
|
}
|
|
if (token) {
|
|
headers.Authorization = `Bearer ${token}`
|
|
}
|
|
|
|
const fullUrl = BASE_URL.replace(/\/$/, '') + url
|
|
|
|
return new Promise((resolve, reject) => {
|
|
uni.request({
|
|
url: fullUrl,
|
|
method: method.toUpperCase(),
|
|
data: data || {},
|
|
header: headers,
|
|
timeout,
|
|
success(res) {
|
|
const status = res.statusCode
|
|
const body = res.data || {}
|
|
|
|
if (status === 401 || body.code === 401) {
|
|
logout()
|
|
if (!silent) {
|
|
uni.showToast({ title: body.msg || '请重新登录', icon: 'none' })
|
|
}
|
|
setTimeout(() => {
|
|
uni.reLaunch({ url: '/pages/login/login' })
|
|
}, 400)
|
|
reject(new Error(body.msg || '未授权'))
|
|
return
|
|
}
|
|
|
|
if (status < 200 || status >= 300) {
|
|
const msg = body.msg || `请求失败(${status})`
|
|
if (!silent) uni.showToast({ title: msg, icon: 'none' })
|
|
reject(new Error(msg))
|
|
return
|
|
}
|
|
|
|
// 统一后端 { code, msg, data }
|
|
if (typeof body.code !== 'undefined' && body.code !== 200) {
|
|
const msg = body.msg || '操作失败'
|
|
if (!silent) uni.showToast({ title: msg, icon: 'none' })
|
|
const err = new Error(msg)
|
|
err.code = body.code
|
|
err.response = body
|
|
reject(err)
|
|
return
|
|
}
|
|
|
|
resolve(typeof body.data !== 'undefined' ? body.data : body)
|
|
},
|
|
fail(err) {
|
|
const detail = (err && err.errMsg) || ''
|
|
console.error('[request fail]', fullUrl, detail)
|
|
if (!silent) {
|
|
uni.showToast({
|
|
title: detail.includes('timeout') ? '请求超时' : '网络异常,请检查接口地址',
|
|
icon: 'none'
|
|
})
|
|
}
|
|
reject(new Error(detail || '网络异常'))
|
|
}
|
|
})
|
|
})
|
|
}
|
|
|
|
/** 返回完整响应体(含 code/msg),用于需要自行判断 code 的场景 */
|
|
export function requestRaw(options = {}) {
|
|
const { url, method = 'GET', data, header = {} } = options
|
|
const token = getToken()
|
|
const headers = {
|
|
'Content-Type': 'application/json',
|
|
...header
|
|
}
|
|
if (token) {
|
|
headers.Authorization = `Bearer ${token}`
|
|
}
|
|
|
|
const fullUrl = BASE_URL.replace(/\/$/, '') + url
|
|
|
|
return new Promise((resolve, reject) => {
|
|
uni.request({
|
|
url: fullUrl,
|
|
method: method.toUpperCase(),
|
|
data: data || {},
|
|
header: headers,
|
|
timeout: 30000,
|
|
success(res) {
|
|
resolve(res.data || {})
|
|
},
|
|
fail(err) {
|
|
console.error('[requestRaw fail]', fullUrl, err)
|
|
reject(err)
|
|
}
|
|
})
|
|
})
|
|
}
|
|
|
|
export function generateId() {
|
|
return `${Date.now().toString(36)}${Math.random().toString(36).slice(2, 8)}`
|
|
}
|