215 lines
6.1 KiB
TypeScript
215 lines
6.1 KiB
TypeScript
import { api } from './api';
|
|
|
|
// ==================== 数据类型定义 ====================
|
|
|
|
export interface WorkoutSession {
|
|
id: string;
|
|
userId: string;
|
|
trainingPlanId?: string;
|
|
name: string;
|
|
scheduledDate: string;
|
|
startedAt?: string;
|
|
completedAt?: string;
|
|
status: 'planned' | 'in_progress' | 'completed' | 'cancelled';
|
|
totalDurationSec?: number;
|
|
caloriesBurned?: number;
|
|
stats?: {
|
|
totalExercises: number;
|
|
completedExercises: number;
|
|
totalSets: number;
|
|
completedSets: number;
|
|
totalReps: number;
|
|
completedReps: number;
|
|
};
|
|
createdAt: string;
|
|
updatedAt: string;
|
|
deleted: boolean;
|
|
|
|
// 关联数据
|
|
trainingPlan?: {
|
|
id: string;
|
|
name: string;
|
|
goal: string;
|
|
};
|
|
exercises?: WorkoutExercise[];
|
|
}
|
|
|
|
export interface WorkoutExercise {
|
|
id: string;
|
|
workoutSessionId: string;
|
|
userId: string;
|
|
exerciseKey?: string;
|
|
name: string;
|
|
plannedSets?: number;
|
|
plannedReps?: number;
|
|
plannedDurationSec?: number;
|
|
completedSets?: number;
|
|
completedReps?: number;
|
|
actualDurationSec?: number;
|
|
restSec?: number;
|
|
note?: string;
|
|
itemType: 'exercise' | 'rest' | 'note';
|
|
status: 'pending' | 'in_progress' | 'completed' | 'skipped';
|
|
sortOrder: number;
|
|
startedAt?: string;
|
|
completedAt?: string;
|
|
performanceData?: Record<string, any>;
|
|
createdAt: string;
|
|
updatedAt: string;
|
|
deleted: boolean;
|
|
|
|
// 关联的动作信息
|
|
exercise?: {
|
|
key: string;
|
|
name: string;
|
|
description: string;
|
|
categoryKey: string;
|
|
categoryName: string;
|
|
};
|
|
}
|
|
|
|
// ==================== DTO 类型定义 ====================
|
|
|
|
export interface StartWorkoutDto {
|
|
startedAt?: string;
|
|
}
|
|
|
|
export interface StartWorkoutExerciseDto {
|
|
startedAt?: string;
|
|
}
|
|
|
|
export interface CompleteWorkoutExerciseDto {
|
|
completedAt?: string;
|
|
completedSets?: number;
|
|
completedReps?: number;
|
|
actualDurationSec?: number;
|
|
performanceData?: Record<string, any>;
|
|
}
|
|
|
|
export interface AddWorkoutExerciseDto {
|
|
exerciseKey?: string;
|
|
name: string;
|
|
plannedSets?: number;
|
|
plannedReps?: number;
|
|
plannedDurationSec?: number;
|
|
restSec?: number;
|
|
note?: string;
|
|
itemType?: 'exercise' | 'rest' | 'note';
|
|
}
|
|
|
|
export interface UpdateWorkoutExerciseDto {
|
|
name?: string;
|
|
plannedSets?: number;
|
|
plannedReps?: number;
|
|
plannedDurationSec?: number;
|
|
restSec?: number;
|
|
note?: string;
|
|
itemType?: 'exercise' | 'rest' | 'note';
|
|
}
|
|
|
|
export interface CreateWorkoutSessionDto {
|
|
name: string;
|
|
trainingPlanId?: string;
|
|
scheduledDate?: string;
|
|
}
|
|
|
|
export interface WorkoutSessionListResponse {
|
|
sessions: WorkoutSession[];
|
|
pagination: {
|
|
page: number;
|
|
limit: number;
|
|
total: number;
|
|
totalPages: number;
|
|
};
|
|
}
|
|
|
|
export interface WorkoutSessionStatsResponse {
|
|
status: string;
|
|
duration?: number;
|
|
calories?: number;
|
|
stats?: {
|
|
totalExercises: number;
|
|
completedExercises: number;
|
|
totalSets: number;
|
|
completedSets: number;
|
|
totalReps: number;
|
|
completedReps: number;
|
|
};
|
|
exerciseCount: number;
|
|
completedExercises: number;
|
|
}
|
|
|
|
// ==================== API 服务类 ====================
|
|
|
|
class WorkoutsApi {
|
|
// ==================== 训练会话管理 ====================
|
|
|
|
async getSessions(page: number = 1, limit: number = 10): Promise<WorkoutSessionListResponse> {
|
|
return api.get<WorkoutSessionListResponse>(`/workouts/sessions?page=${page}&limit=${limit}`);
|
|
}
|
|
|
|
async createSession(dto: CreateWorkoutSessionDto): Promise<WorkoutSession> {
|
|
return api.post<WorkoutSession>('/workouts/sessions', dto);
|
|
}
|
|
|
|
async getSessionDetail(sessionId: string): Promise<WorkoutSession> {
|
|
return api.get<WorkoutSession>(`/workouts/sessions/${sessionId}`);
|
|
}
|
|
|
|
async startSession(sessionId: string, dto: StartWorkoutDto = {}): Promise<WorkoutSession> {
|
|
return api.post<WorkoutSession>(`/workouts/sessions/${sessionId}/start`, dto);
|
|
}
|
|
|
|
async deleteSession(sessionId: string): Promise<{ success: boolean }> {
|
|
return api.delete<{ success: boolean }>(`/workouts/sessions/${sessionId}`);
|
|
}
|
|
|
|
// ==================== 训练动作管理 ====================
|
|
|
|
async getSessionExercises(sessionId: string): Promise<WorkoutExercise[]> {
|
|
return api.get<WorkoutExercise[]>(`/workouts/sessions/${sessionId}/exercises`);
|
|
}
|
|
|
|
async getExerciseDetail(sessionId: string, exerciseId: string): Promise<WorkoutExercise> {
|
|
return api.get<WorkoutExercise>(`/workouts/sessions/${sessionId}/exercises/${exerciseId}`);
|
|
}
|
|
|
|
async startExercise(sessionId: string, exerciseId: string, dto: StartWorkoutExerciseDto = {}): Promise<WorkoutExercise> {
|
|
return api.post<WorkoutExercise>(`/workouts/sessions/${sessionId}/exercises/${exerciseId}/start`, dto);
|
|
}
|
|
|
|
async completeExercise(sessionId: string, exerciseId: string, dto: CompleteWorkoutExerciseDto): Promise<WorkoutExercise> {
|
|
return api.post<WorkoutExercise>(`/workouts/sessions/${sessionId}/exercises/${exerciseId}/complete`, dto);
|
|
}
|
|
|
|
async skipExercise(sessionId: string, exerciseId: string): Promise<WorkoutExercise> {
|
|
return api.post<WorkoutExercise>(`/workouts/sessions/${sessionId}/exercises/${exerciseId}/skip`);
|
|
}
|
|
|
|
async updateExercise(sessionId: string, exerciseId: string, dto: UpdateWorkoutExerciseDto): Promise<WorkoutExercise> {
|
|
return api.put<WorkoutExercise>(`/workouts/sessions/${sessionId}/exercises/${exerciseId}`, dto);
|
|
}
|
|
|
|
async addExercise(sessionId: string, dto: AddWorkoutExerciseDto): Promise<WorkoutExercise> {
|
|
return api.post<WorkoutExercise>(`/workouts/sessions/${sessionId}/exercises`, dto);
|
|
}
|
|
|
|
// ==================== 统计和分析 ====================
|
|
|
|
async getSessionStats(sessionId: string): Promise<WorkoutSessionStatsResponse> {
|
|
return api.get<WorkoutSessionStatsResponse>(`/workouts/sessions/${sessionId}/stats`);
|
|
}
|
|
|
|
// ==================== 快捷操作 ====================
|
|
|
|
async getTodayWorkout(): Promise<WorkoutSession> {
|
|
return api.get<WorkoutSession>('/workouts/today');
|
|
}
|
|
|
|
async getRecentWorkouts(days: number = 7, limit: number = 10): Promise<{ sessions: WorkoutSession[]; period: string }> {
|
|
return api.get<{ sessions: WorkoutSession[]; period: string }>(`/workouts/recent?days=${days}&limit=${limit}`);
|
|
}
|
|
}
|
|
|
|
export const workoutsApi = new WorkoutsApi();
|