236 lines
6.5 KiB
JavaScript
236 lines
6.5 KiB
JavaScript
// HTTP请求配置
|
||
import { getApiBaseUrl, getCurrentEnv, getUserAuth, isDebugMode } from './env.js'
|
||
|
||
/**
|
||
* 自定义API错误类
|
||
*/
|
||
class ApiError extends Error {
|
||
constructor(message, options = {}) {
|
||
super(message)
|
||
this.name = 'ApiError'
|
||
this.status = options.status || null // HTTP状态码
|
||
this.errorCode = options.errorCode || null // 业务错误码 (如: 6010)
|
||
this.errorCodeName = options.errorCodeName || null // 错误码名称 (如: "TEAM_NOT_FOUND")
|
||
this.errorMsg = options.errorMsg || null // 业务错误消息
|
||
this.time = options.time || null // API响应时间戳
|
||
this.extValues = options.extValues || null // 扩展值
|
||
this.response = options.response || null // 原始响应数据
|
||
this.type = options.type || 'unknown' // 错误类型: 'http' | 'business' | 'network'
|
||
}
|
||
}
|
||
|
||
const API_BASE_URL = getApiBaseUrl()
|
||
const NODE_ENV = getCurrentEnv()
|
||
const DEBUG_MODE = isDebugMode()
|
||
|
||
// 环境信息日志
|
||
if (DEBUG_MODE) {
|
||
console.log('🌍 Current Environment:', NODE_ENV)
|
||
console.log('🔗 API Base URL:', API_BASE_URL)
|
||
}
|
||
|
||
const token = getUserAuth()
|
||
// 默认公共请求头配置
|
||
let COMMON_HEADERS = {
|
||
authorization: `Bearer ${token}`,
|
||
'req-app-intel': 'version=1.0.0;build=1;model=SM-G9550;sysVersion=9;channel=Google',
|
||
'req-client': 'Android',
|
||
'req-imei': '8fa54d728ab449e04f9292329ed44bda',
|
||
'req-lang': 'id-ID',
|
||
'req-sys-origin': 'origin=LIKEI;originChild=LIKEI',
|
||
'req-version': 'V2',
|
||
'req-zone': 'Asia/Shanghai',
|
||
}
|
||
|
||
/**
|
||
* 更新公共请求头
|
||
* @param {object} headers - 要更新的请求头
|
||
*/
|
||
export function updateCommonHeaders(headers) {
|
||
COMMON_HEADERS = {
|
||
...COMMON_HEADERS,
|
||
...headers,
|
||
}
|
||
console.debug('🔄 Updated common headers:', COMMON_HEADERS)
|
||
}
|
||
|
||
/**
|
||
* 从APP头部信息设置HTTP请求头
|
||
* @param {object} headerInfo - APP传递的头部信息
|
||
*/
|
||
export function setHeadersFromApp(headerInfo) {
|
||
const updatedHeaders = {}
|
||
|
||
// 设置Authorization
|
||
if (headerInfo.authorization) {
|
||
updatedHeaders.authorization = headerInfo.authorization
|
||
}
|
||
|
||
// 设置语言
|
||
if (headerInfo.reqLang) {
|
||
updatedHeaders['req-lang'] = headerInfo.reqLang
|
||
}
|
||
|
||
// 设置APP信息
|
||
if (headerInfo.appVersion || headerInfo.buildVersion || headerInfo.appChannel) {
|
||
const appIntelParts = []
|
||
if (headerInfo.appVersion) appIntelParts.push(`version=${headerInfo.appVersion}`)
|
||
if (headerInfo.buildVersion) appIntelParts.push(`build=${headerInfo.buildVersion}`)
|
||
if (headerInfo.appChannel) appIntelParts.push(`channel=${headerInfo.appChannel}`)
|
||
|
||
if (appIntelParts.length > 0) {
|
||
updatedHeaders['req-app-intel'] = appIntelParts.join(';')
|
||
}
|
||
}
|
||
|
||
// 设置设备信息
|
||
if (headerInfo.reqImei) {
|
||
updatedHeaders['req-imei'] = headerInfo.reqImei
|
||
}
|
||
|
||
// 设置系统来源
|
||
if (headerInfo.sysOrigin) {
|
||
const sysOriginParts = [`origin=${headerInfo.sysOrigin}`]
|
||
if (headerInfo.sysOriginChild) {
|
||
sysOriginParts.push(`child=${headerInfo.sysOriginChild}`)
|
||
}
|
||
updatedHeaders['req-sys-origin'] = sysOriginParts.join(';')
|
||
}
|
||
|
||
updateCommonHeaders(updatedHeaders)
|
||
}
|
||
|
||
// 在http.js中添加导出
|
||
export { COMMON_HEADERS, ApiError }
|
||
|
||
/**
|
||
* 通用HTTP请求函数
|
||
* @param {string} url - 请求URL
|
||
* @param {object} options - 请求选项
|
||
* @returns {Promise} - 返回Promise对象
|
||
*/
|
||
export async function request(url, options = {}) {
|
||
const { method = 'GET', data = null, headers = {}, ...otherOptions } = options
|
||
const fullUrl = url.startsWith('http') ? url : `${API_BASE_URL}${url}`
|
||
|
||
const config = {
|
||
method,
|
||
headers: {
|
||
...COMMON_HEADERS,
|
||
...headers,
|
||
},
|
||
...otherOptions,
|
||
}
|
||
|
||
// 如果是POST、PUT等方法且有数据,添加body
|
||
if (data && ['POST', 'PUT', 'PATCH'].includes(method.toUpperCase())) {
|
||
if (data instanceof FormData) {
|
||
// FormData类型:由浏览器自动设置Content-Type
|
||
config.body = data
|
||
// 删除手动设置的Content-Type(重要!)
|
||
if (config.headers['Content-Type']) {
|
||
delete config.headers['Content-Type']
|
||
}
|
||
} else {
|
||
// 非FormData:按JSON处理
|
||
config.body = JSON.stringify(data)
|
||
config.headers['Content-Type'] = 'application/json'
|
||
}
|
||
}
|
||
|
||
try {
|
||
const response = await fetch(fullUrl, config)
|
||
|
||
if (!response.ok) {
|
||
// 尝试解析响应体获取更多错误信息
|
||
let errorData = await response.json()
|
||
|
||
throw new ApiError(`HTTP Error: ${response.status} ${response.statusText}`, {
|
||
type: 'http',
|
||
status: response.status,
|
||
response: errorData,
|
||
errorCode: errorData.errorCode,
|
||
errorCodeName: errorData.errorCodeName,
|
||
errorMsg: errorData.errorMsg,
|
||
time: errorData.time,
|
||
})
|
||
}
|
||
|
||
const result = await response.json()
|
||
|
||
// 检查业务状态
|
||
if (result.status === false) {
|
||
throw new ApiError(result.errorMsg || result.message || `API Error: ${result.errorCode}`, {
|
||
type: 'business',
|
||
status: response.status,
|
||
response: result,
|
||
errorCode: result.errorCode,
|
||
errorCodeName: result.errorCodeName,
|
||
errorMsg: result.errorMsg,
|
||
time: result.time,
|
||
|
||
extValues: result.extValues,
|
||
})
|
||
}
|
||
|
||
return result
|
||
} catch (error) {
|
||
if (DEBUG_MODE) {
|
||
console.error('❌ API Error:', error)
|
||
}
|
||
|
||
// 如果是网络错误或其他未知错误,包装成ApiError
|
||
if (!(error instanceof ApiError)) {
|
||
throw new ApiError(error.message || 'Network or unknown error', {
|
||
type: 'network',
|
||
originalError: error,
|
||
code: 'NETWORK_ERROR',
|
||
})
|
||
}
|
||
|
||
throw error
|
||
}
|
||
}
|
||
|
||
/**
|
||
* GET请求
|
||
* @param {string} url - 请求URL
|
||
* @param {object} options - 请求选项
|
||
* @returns {Promise}
|
||
*/
|
||
export function get(url, options = {}) {
|
||
return request(url, { ...options, method: 'GET' })
|
||
}
|
||
|
||
/**
|
||
* POST请求
|
||
* @param {string} url - 请求URL
|
||
* @param {object} data - 请求数据
|
||
* @param {object} options - 请求选项
|
||
* @returns {Promise}
|
||
*/
|
||
export function post(url, data, options = {}) {
|
||
return request(url, { ...options, method: 'POST', data })
|
||
}
|
||
|
||
/**
|
||
* PUT请求
|
||
* @param {string} url - 请求URL
|
||
* @param {object} data - 请求数据
|
||
* @param {object} options - 请求选项
|
||
* @returns {Promise}
|
||
*/
|
||
export function put(url, data, options = {}) {
|
||
return request(url, { ...options, method: 'PUT', data })
|
||
}
|
||
|
||
/**
|
||
* DELETE请求
|
||
* @param {string} url - 请求URL
|
||
* @param {object} options - 请求选项
|
||
* @returns {Promise}
|
||
*/
|
||
export function del(url, options = {}) {
|
||
return request(url, { ...options, method: 'DELETE' })
|
||
}
|