import config from '@/config/index.js' function buildUrl(url, baseURL = config.baseURL) { const normalizedBaseURL = baseURL.endsWith('/') ? baseURL.slice(0, -1) : baseURL const path = url.startsWith('/') ? url : `/${url}` return `${normalizedBaseURL}${path}` } function getNetworkErrorMessage(error) { const errorMessage = String(error?.errMsg || '') if (errorMessage.toLowerCase().includes('timeout')) { return '请求超时,请稍后重试' } return '无法连接服务器,请检查网络后重试' } function getHeaders(headers = {}, includeJsonContentType = true) { const token = uni.getStorageSync(config.tokenKey) const result = { ...(includeJsonContentType ? { 'Content-Type': 'application/json' } : {}), [config.channelHeaderKey]: config.channel, ...headers } if (token) { result[config.tokenHeaderKey] = String(token).startsWith('Bearer ') ? token : `Bearer ${token}` } return result } function request(url, method, data = {}, options = {}) { const baseURL = options.baseURL || config.baseURL return new Promise((resolve, reject) => { const requestUrl = buildUrl(url, baseURL) uni.request({ url: requestUrl, method, data, header: getHeaders(options.headers), timeout: options.timeout || 15000, success: (res) => { let body = res.data || {} if (typeof body === 'string') { try { body = JSON.parse(body) } catch (error) { body = { msg: body } } } if (Number(body.code) === 0) { resolve(options.returnFullResponse ? body : body.data) return } const message = body.msg || `请求失败(HTTP ${res.statusCode || 0},code ${body.code ?? 'unknown'})` console.error('[scanapp] 请求失败', { url: requestUrl, statusCode: res.statusCode, code: body.code, message, body }) if (options.showError !== false) { uni.showToast({ title: message, icon: 'none' }) } reject(new Error(message)) }, fail: (error) => { const message = getNetworkErrorMessage(error) console.error('[scanapp] 网络请求失败', { url: requestUrl, rawMessage: error?.errMsg, message, error }) if (options.showError !== false) { uni.showToast({ title: message, icon: 'none' }) } reject(new Error(message)) } }) }) } export function uploadFile(url, filePath, formData = {}, options = {}) { const baseURL = options.baseURL || config.baseURL return new Promise((resolve, reject) => { const requestUrl = buildUrl(url, baseURL) const token = uni.getStorageSync(config.tokenKey) const header = getHeaders(options.headers, false) if (token) { header[config.tokenHeaderKey] = String(token).startsWith('Bearer ') ? token : `Bearer ${token}` } uni.uploadFile({ url: requestUrl, filePath, name: options.name || 'file', formData, header, timeout: options.timeout || 30000, success: (res) => { let body = res.data || {} if (typeof body === 'string') { try { body = JSON.parse(body) } catch (error) { body = { msg: body } } } if (Number(body.code) === 0) { resolve(options.returnFullResponse ? body : body.data) return } const message = body.msg || `上传失败(HTTP ${res.statusCode || 0},code ${body.code ?? 'unknown'})` if (options.showError !== false) { uni.showToast({ title: message, icon: 'none' }) } reject(new Error(message)) }, fail: (error) => { const message = getNetworkErrorMessage(error) if (options.showError !== false) { uni.showToast({ title: message, icon: 'none' }) } reject(new Error(message)) } }) }) } export default { get(url, data = {}, options = {}) { return request(url, 'GET', data, options) }, post(url, data = {}, options = {}) { return request(url, 'POST', data, options) }, put(url, data = {}, options = {}) { return request(url, 'PUT', data, options) }, delete(url, data = {}, options = {}) { return request(url, 'DELETE', data, options) } }