import axios from 'axios'; import { ApiEnvelope, MotionCard, MotionSession } from './types'; const API_BASE_URL = process.env.EXPO_PUBLIC_API_BASE_URL || '/api/app_order_box'; // 注意:MOTION_BASE 是相对于 axios baseURL 的路径,不要包含 API_BASE_URL 前缀 // 否则 axios 会双重拼接导致 404(如 /api/app_order_box/api/app_order_box/kits/...) const MOTION_BASE = '/kits/motion_reminder'; const api = axios.create({ baseURL: API_BASE_URL, timeout: 15000, headers: { 'Content-Type': 'application/json', }, }); const formatError = (error: any): string => { if (error?.response) { return `服务器响应 ${error.response.status}: ${error.response.statusText}\n${JSON.stringify(error.response.data)}`; } if (error?.request) { return `服务器无响应: 无法连接到 ${API_BASE_URL}`; } if (error?.message) { return `请求错误: ${error.message}`; } return '未知错误'; }; export const motionReminderApi = { async listCards(): Promise { try { const response = await api.get>(`${MOTION_BASE}/cards`); return response.data.data || []; } catch (error) { throw new Error(formatError(error)); } }, async saveCard(card: Partial): Promise { try { const response = card.id ? await api.put>(`${MOTION_BASE}/cards`, card) : await api.post>(`${MOTION_BASE}/cards`, card); if (!response.data.ok || !response.data.data) { throw new Error(response.data.error || '保存失败'); } return response.data.data; } catch (error) { throw new Error(formatError(error)); } }, async deleteCard(id: string): Promise { try { await api.delete(`${MOTION_BASE}/cards`, { params: { id } }); } catch (error) { throw new Error(formatError(error)); } }, async listHistory(): Promise { try { const response = await api.get>(`${MOTION_BASE}/history`); return response.data.data || []; } catch (error) { throw new Error(formatError(error)); } }, async startSession(card: MotionCard): Promise { try { const response = await api.post>(`${MOTION_BASE}/sessions/start`, { card }); if (!response.data.ok || !response.data.data) { throw new Error(response.data.error || '启动失败'); } return response.data.data; } catch (error) { throw new Error(formatError(error)); } }, async syncSession(payload: Partial & { id: string }): Promise { try { await api.post(`${MOTION_BASE}/sessions/sync`, payload); } catch (error) { throw new Error(formatError(error)); } }, async finishSession(payload: Partial & { id: string; status: 'completed' | 'stopped' }): Promise { try { await api.post(`${MOTION_BASE}/sessions/finish`, payload); } catch (error) { throw new Error(formatError(error)); } }, };