import type { ApiResponse, PaginatedData } from '@mp-pilates/shared' const BASE_URL = (() => { try { const { miniProgram } = uni.getAccountInfoSync() if (miniProgram.envVersion !== 'develop') { return 'https://focus.richarjiang.com/api' } } catch { // 非小程序环境,使用开发地址 } return 'http://localhost:3000/api' })() interface RequestOptions { readonly url: string readonly method?: 'GET' | 'POST' | 'PUT' | 'DELETE' readonly data?: Record readonly header?: Record } export function request(options: RequestOptions): Promise { return new Promise((resolve, reject) => { const token = uni.getStorageSync('token') as string uni.request({ url: `${BASE_URL}${options.url}`, method: options.method || 'GET', data: options.data, header: { 'Content-Type': 'application/json', ...(token ? { Authorization: `Bearer ${token}` } : {}), ...options.header, }, success: (res) => { if (res.statusCode === 401) { uni.removeStorageSync('token') uni.showToast({ title: '请重新登录', icon: 'none' }) reject(new Error('Unauthorized')) return } if (res.statusCode >= 400) { const body = res.data as ApiResponse reject(new Error(body?.message || `请求失败 (${res.statusCode})`)) return } const body = res.data as ApiResponse if (body.success) { resolve(body.data as T) } else { reject(new Error(body.message || '请求失败')) } }, fail: (err) => { reject(new Error(err.errMsg || '网络请求失败')) }, }) }) } export function get(url: string, data?: Record): Promise { return request({ url, method: 'GET', data }) } export function post(url: string, data?: Record): Promise { return request({ url, method: 'POST', data }) } export function put(url: string, data?: Record): Promise { return request({ url, method: 'PUT', data }) } export function del(url: string, data?: Record): Promise { return request({ url, method: 'DELETE', data }) } export function getPaginated(url: string, params?: Record): Promise> { return request>({ url, method: 'GET', data: params }) }