167 lines
5.0 KiB
TypeScript
167 lines
5.0 KiB
TypeScript
import { api } from './api';
|
||
|
||
// 喝水记录类型
|
||
export interface WaterRecord {
|
||
id: string;
|
||
userId?: string;
|
||
amount: number; // 喝水量(毫升)
|
||
source?: 'Manual' | 'Auto'; // 记录来源
|
||
note?: string; // 备注
|
||
recordedAt: string; // 记录时间 ISO格式
|
||
createdAt: string; // 创建时间 ISO格式
|
||
updatedAt: string; // 更新时间 ISO格式
|
||
}
|
||
|
||
export enum WaterRecordSource {
|
||
Manual = 'manual',
|
||
Auto = 'auto',
|
||
Other = 'other',
|
||
}
|
||
|
||
// 创建喝水记录请求
|
||
export interface CreateWaterRecordDto {
|
||
amount: number; // 喝水量(毫升)
|
||
recordedAt?: string; // 记录时间,默认为当前时间
|
||
source?: WaterRecordSource; // 记录来源,默认为 'manual'
|
||
}
|
||
|
||
// 更新喝水记录请求
|
||
export interface UpdateWaterRecordDto {
|
||
id: string;
|
||
amount?: number; // 喝水量(毫升)
|
||
recordedAt?: string; // 记录时间
|
||
source?: 'Manual' | 'Auto'; // 记录来源
|
||
note?: string; // 备注
|
||
}
|
||
|
||
// 删除喝水记录请求
|
||
export interface DeleteWaterRecordDto {
|
||
id: string;
|
||
}
|
||
|
||
// 今日喝水统计
|
||
export interface TodayWaterStats {
|
||
date: string; // 统计日期
|
||
totalAmount: number; // 当日总喝水量
|
||
dailyGoal: number; // 每日目标
|
||
completionRate: number; // 完成率(百分比)
|
||
recordCount: number; // 记录次数
|
||
records?: WaterRecord[]; // 当日所有记录(可选)
|
||
}
|
||
|
||
// 更新喝水目标请求
|
||
export interface UpdateWaterGoalDto {
|
||
dailyWaterGoal: number; // 每日喝水目标(毫升)
|
||
}
|
||
|
||
// 创建喝水记录
|
||
export async function createWaterRecord(dto: CreateWaterRecordDto): Promise<WaterRecord> {
|
||
return await api.post('/water-records', dto);
|
||
}
|
||
|
||
// 获取喝水记录列表
|
||
export async function getWaterRecords(params?: {
|
||
startDate?: string; // 开始日期 (YYYY-MM-DD)
|
||
endDate?: string; // 结束日期 (YYYY-MM-DD)
|
||
page?: number; // 页码,默认1
|
||
limit?: number; // 每页数量,默认20
|
||
date?: string; // 指定日期,格式:YYYY-MM-DD (向后兼容)
|
||
}): Promise<{
|
||
records: WaterRecord[];
|
||
total: number;
|
||
page: number;
|
||
limit: number;
|
||
hasMore: boolean;
|
||
}> {
|
||
const queryParams = new URLSearchParams();
|
||
|
||
// 处理日期范围查询
|
||
if (params?.startDate) queryParams.append('startDate', params.startDate);
|
||
if (params?.endDate) queryParams.append('endDate', params.endDate);
|
||
|
||
// 处理单日期查询(向后兼容)
|
||
if (params?.date) queryParams.append('startDate', params.date);
|
||
if (params?.date) queryParams.append('endDate', params.date);
|
||
|
||
// 处理分页
|
||
const page = params?.page || 1;
|
||
const limit = params?.limit || 20;
|
||
queryParams.append('page', page.toString());
|
||
queryParams.append('limit', limit.toString());
|
||
|
||
const path = `/water-records${queryParams.toString() ? `?${queryParams.toString()}` : ''}`;
|
||
const response = await api.get<{
|
||
records: WaterRecord[];
|
||
pagination: {
|
||
page: number;
|
||
limit: number;
|
||
total: number;
|
||
totalPages: number;
|
||
};
|
||
}>(path);
|
||
|
||
const pagination = response.pagination || { page, limit, total: 0, totalPages: 0 };
|
||
return {
|
||
records: response.records || [],
|
||
total: pagination.total,
|
||
page: pagination.page,
|
||
limit: pagination.limit,
|
||
hasMore: pagination.page < pagination.totalPages
|
||
};
|
||
}
|
||
|
||
// 更新喝水记录
|
||
export async function updateWaterRecord(dto: UpdateWaterRecordDto): Promise<WaterRecord> {
|
||
const { id, ...updateData } = dto;
|
||
return await api.put(`/water-records/${id}`, updateData);
|
||
}
|
||
|
||
// 删除喝水记录
|
||
export async function deleteWaterRecord(id: string): Promise<boolean> {
|
||
return await api.delete(`/water-records/${id}`);
|
||
}
|
||
|
||
// 更新喝水目标
|
||
export async function updateWaterGoal(dto: UpdateWaterGoalDto): Promise<{ dailyWaterGoal: number }> {
|
||
return await api.put('/water-records/goal/daily', dto);
|
||
}
|
||
|
||
// 获取今日喝水统计
|
||
export async function getTodayWaterStats(): Promise<TodayWaterStats> {
|
||
return await api.get('/water-records/stats');
|
||
}
|
||
|
||
// 获取指定日期的喝水统计
|
||
export async function getWaterStatsByDate(date: string): Promise<TodayWaterStats> {
|
||
return await api.get(`/water-records/stats?date=${date}`);
|
||
}
|
||
|
||
// 按小时分组获取喝水记录(用于图表显示)
|
||
export function groupWaterRecordsByHour(records: WaterRecord[]): { hour: number; amount: number }[] {
|
||
const hourlyData: { hour: number; amount: number }[] = Array.from({ length: 24 }, (_, i) => ({
|
||
hour: i,
|
||
amount: 0,
|
||
}));
|
||
|
||
records.forEach(record => {
|
||
// 优先使用 recordedAt,如果没有则使用 createdAt
|
||
const dateTime = record.recordedAt || record.createdAt;
|
||
const hour = new Date(dateTime).getHours();
|
||
if (hour >= 0 && hour < 24) {
|
||
hourlyData[hour].amount += record.amount;
|
||
}
|
||
});
|
||
|
||
return hourlyData;
|
||
}
|
||
|
||
// 获取指定日期的总喝水量
|
||
export function getTotalWaterAmount(records: WaterRecord[]): number {
|
||
return records.reduce((total, record) => total + record.amount, 0);
|
||
}
|
||
|
||
// 计算喝水目标完成率
|
||
export function calculateCompletionRate(totalAmount: number, dailyGoal: number): number {
|
||
if (dailyGoal <= 0) return 0;
|
||
return Math.min(totalAmount / dailyGoal, 1);
|
||
} |