Files
digital-pilates/services/checkins.ts
richarjiang e3e2f1b8c6 feat: 优化 AI 教练聊天和打卡功能
- 在 AI 教练聊天界面中添加会话缓存功能,支持冷启动时恢复聊天记录
- 实现轻量防抖机制,确保会话变动时及时保存缓存
- 在打卡功能中集成按月加载打卡记录,提升用户体验
- 更新 Redux 状态管理,支持打卡记录的按月加载和缓存
- 新增打卡日历页面,允许用户查看每日打卡记录
- 优化样式以适应新功能的展示和交互
2025-08-14 09:57:13 +08:00

74 lines
2.6 KiB
TypeScript

import { api } from '@/services/api';
export type CheckinMetrics = Record<string, any>;
export type CreateCheckinDto = {
workoutId?: string;
planId?: string;
title?: string;
checkinDate?: string; // YYYY-MM-DD
startedAt?: string; // ISO
notes?: string;
metrics?: CheckinMetrics;
};
export type UpdateCheckinDto = Partial<CreateCheckinDto> & {
id: string;
status?: string; // 由后端验证为 CheckinStatus
completedAt?: string; // ISO
durationSeconds?: number;
};
export type CompleteCheckinDto = {
id: string;
completedAt?: string; // ISO
durationSeconds?: number;
notes?: string;
metrics?: CheckinMetrics;
};
export type RemoveCheckinDto = {
id: string;
};
export async function createCheckin(dto: CreateCheckinDto): Promise<{ id: string } & Record<string, any>> {
return await api.post('/api/checkins/create', dto);
}
export async function updateCheckin(dto: UpdateCheckinDto): Promise<{ id: string } & Record<string, any>> {
return await api.put('/api/checkins/update', dto);
}
export async function completeCheckin(dto: CompleteCheckinDto): Promise<{ id: string } & Record<string, any>> {
return await api.post('/api/checkins/complete', dto);
}
export async function removeCheckin(dto: RemoveCheckinDto): Promise<boolean | Record<string, any>> {
return await api.delete('/api/checkins/remove', { body: dto });
}
// 按天获取打卡列表(后端默认今天,不传 date 也可)
export async function fetchDailyCheckins(date?: string): Promise<any[]> {
const path = date ? `/api/checkins/daily?date=${encodeURIComponent(date)}` : '/api/checkins/daily';
const data = await api.get<any[]>(path);
// 返回值兼容 { data: T } 或直接 T 已由 api 封装处理
return Array.isArray(data) ? data : [];
}
// 优先尝试按区间批量获取(若后端暂未实现将抛错,由调用方回退到逐日请求)
export async function fetchCheckinsInRange(startDate: string, endDate: string): Promise<any[]> {
const path = `/api/checkins/range?start=${encodeURIComponent(startDate)}&end=${encodeURIComponent(endDate)}`;
const data = await api.get<any[]>(path);
return Array.isArray(data) ? data : [];
}
// 获取时间范围内每日是否已打卡(仅返回日期+布尔)
export type DailyStatusItem = { date: string; checkedIn: boolean };
export async function fetchDailyStatusRange(startDate: string, endDate: string): Promise<DailyStatusItem[]> {
const path = `/api/checkins/range/daily-status?startDate=${encodeURIComponent(startDate)}&endDate=${encodeURIComponent(endDate)}`;
const data = await api.get<DailyStatusItem[]>(path);
return Array.isArray(data) ? data : [];
}