/** * 网络请求封装 * 预留后端接口对接 */ import { getEnvConfig, useMock, STORAGE_KEYS } from './config.uts' import { getMockData } from './mock.uts' // 请求配置类型 type RequestOptions = { url : string method ?: 'GET' | 'POST' | 'PUT' | 'DELETE' data ?: UTSJSONObject | null header ?: UTSJSONObject | null showLoading ?: boolean loadingText ?: string } // 响应数据类型 type ResponseData = { code : number message : string data : any | null } /** * 请求拦截器 */ const requestInterceptor = (options : RequestOptions) : RequestOptions => { // 添加token const token = uni.getStorageSync(STORAGE_KEYS.TOKEN) as string if (token != '') { if (options.header == null) { options.header = {} as UTSJSONObject } options.header!['Authorization'] = `Bearer ${token}` } return options } /** * 响应拦截器 */ const responseInterceptor = (response : UTSJSONObject) : ResponseData => { const statusCode = response['statusCode'] as number const data = response['data'] as UTSJSONObject | null console.log('响应拦截器 - statusCode:', statusCode) console.log('响应拦截器 - data:', data) // 处理空响应 if (data == null) { return { code: statusCode, message: '响应数据为空', data: null } as ResponseData } if (statusCode == 200) { const code = (data['code'] ?? 0) as number console.log('响应拦截器 - 解析的 code:', code) if (code == 0 || code == 200) { const result = { code: 0, message: (data['message'] ?? 'success') as string, data: data['data'] ?? null } as ResponseData console.log('响应拦截器 - 返回成功结果:', result) return result } else if (code == 401) { // token过期,跳转登录 uni.removeStorageSync(STORAGE_KEYS.TOKEN) uni.showToast({ title: '请重新登录', icon: 'none' }) return { code: code, message: (data['message'] ?? '请重新登录') as string, data: null } as ResponseData } else { return { code: code, message: (data['message'] ?? '请求失败') as string, data: data['data'] ?? null } as ResponseData } } else { return { code: statusCode, message: '网络请求失败', data: null } as ResponseData } } /** * 统一请求方法 */ export const request = (options : RequestOptions) : Promise => { return new Promise((resolve, reject) => { // 使用Mock数据 if (useMock) { const mockData = getMockData(options.url, options.method ?? 'GET', options.data) if (mockData != null) { setTimeout(() => { resolve({ code: 0, message: 'success', data: mockData } as ResponseData) }, 300) // 模拟网络延迟 return } } // 请求拦截 const finalOptions = requestInterceptor(options) // 显示loading if (finalOptions.showLoading == true) { uni.showLoading({ title: finalOptions.loadingText ?? '加载中...' }) } const config = getEnvConfig() const BASE_URL = 'http://192.168.1.43:3000/api' const baseUrl = config['baseUrl'] as string // 清理 data 中的 undefined 字段,避免被序列化为 'undefined' if (finalOptions.data && typeof finalOptions.data === 'object') { for (const key in finalOptions.data) { if (finalOptions.data[key] === undefined) { delete finalOptions.data[key] } } } uni.request({ url: baseUrl + finalOptions.url, method: finalOptions.method ?? 'GET', data: finalOptions.data as UTSJSONObject | null, header: finalOptions.header as UTSJSONObject | null, success: (res) => { if (finalOptions.showLoading == true) { uni.hideLoading() } console.log('请求成功原始响应:', res) const result = responseInterceptor(res as UTSJSONObject) console.log('拦截器处理后结果:', result) console.log('result.code 类型:', typeof result.code, '值:', result.code) if (result.code == 0) { console.log('判断为成功,resolve') resolve(result) } else { console.log('判断为失败,显示 toast 并 reject') uni.showToast({ title: result.message, icon: 'none' }) reject(result) } }, fail: (err) => { if (finalOptions.showLoading == true) { uni.hideLoading() } uni.showToast({ title: '网络连接失败', icon: 'none' }) reject({ code: -1, message: '网络连接失败', data: null } as ResponseData) } }) }) } /** * GET请求 */ export const get = (url : string, data ?: UTSJSONObject | null) : Promise => { return request({ url: url, method: 'GET', data: data } as RequestOptions) } /** * POST请求 */ export const post = (url : string, data ?: UTSJSONObject | null) : Promise => { return request({ url: url, method: 'POST', data: data } as RequestOptions) }