import Taro from '@tarojs/taro'; import { cached } from './cache'; // API 基址 // - 开发:指向本地 web 后端(project.config.json 需 urlCheck:false) // - 生产:真实备案 HTTPS 域名(小程序要求) export const API_BASE = process.env.TARO_APP_API_BASE || 'https://opc.pinesound.cn'; // 云超服 FastAPI 后端(备案 HTTPS 域名;开发可用 TARO_APP_API_BASE 覆盖) /** * 统一请求封装(对齐 web 端 fetch 契约) * 公开端点不鉴权;管理端点传 withAuth=true(带 token) */ export function request(method, path, data = {}, withAuth = false) { return new Promise((resolve, reject) => { const header = { 'Content-Type': 'application/json', 'X-Client': 'miniprogram' }; if (withAuth) { const token = Taro.getStorageSync('pine_token'); if (token) header.Authorization = `Bearer ${token}`; } Taro.request({ url: `${API_BASE}${path}`, method, data, header, timeout: 10000, // 后端未启动时快速失败,避免界面一直"加载中" success: (res) => { const d = res.data || {}; if (res.statusCode >= 200 && res.statusCode < 300 && d.ok !== false) { resolve(d); } else { reject(new Error(d.detail || d.error || '请求失败,请稍后重试')); } }, fail: () => reject(new Error('网络连接失败,请检查网络后重试')) }); }); } /** 带短缓存的请求:命中未过期直接返回(用于列表类接口,减少重复请求与"空→内容"跳变) */ export function cachedRequest(method, path, ttl = 30000, data = {}, withAuth = false) { return cached(`req:${method}:${path}:${JSON.stringify(data)}`, ttl, () => request(method, path, data, withAuth)); }