diff --git a/src/water-records/dto/water-record.dto.ts b/src/water-records/dto/water-record.dto.ts index 272798d..79f66c7 100644 --- a/src/water-records/dto/water-record.dto.ts +++ b/src/water-records/dto/water-record.dto.ts @@ -242,11 +242,25 @@ export class WaterGoalResponseDto extends BaseResponseDto { } /** - * 今日喝水统计响应DTO + * 获取喝水统计查询参数DTO */ -export class TodayWaterStatsResponseDto extends BaseResponseDto { +export class GetWaterStatsQueryDto { @ApiProperty({ - description: '今日喝水统计', + description: '查询日期 (YYYY-MM-DD),不传则默认为今天', + example: '2023-12-01', + required: false, + }) + @IsOptional() + @IsDateString({}, { message: '日期格式不正确,请使用 YYYY-MM-DD 格式' }) + date?: string; +} + +/** + * 喝水统计响应DTO + */ +export class WaterStatsResponseDto extends BaseResponseDto { + @ApiProperty({ + description: '喝水统计数据', example: { date: '2023-12-01', totalAmount: 1500, diff --git a/src/water-records/water-records.controller.ts b/src/water-records/water-records.controller.ts index 14a0444..f99efea 100644 --- a/src/water-records/water-records.controller.ts +++ b/src/water-records/water-records.controller.ts @@ -23,7 +23,8 @@ import { WaterRecordsListResponseDto, UpdateWaterGoalDto, WaterGoalResponseDto, - TodayWaterStatsResponseDto + GetWaterStatsQueryDto, + WaterStatsResponseDto } from './dto/water-record.dto'; import { JwtAuthGuard } from '../common/guards/jwt-auth.guard'; import { CurrentUser } from '../common/decorators/current-user.decorator'; @@ -130,17 +131,20 @@ export class WaterRecordsController { } /** - * 获取今日喝水统计 + * 获取指定日期的喝水统计 */ @UseGuards(JwtAuthGuard) - @Get('stats/today') + @Get('stats') @HttpCode(HttpStatus.OK) - @ApiOperation({ summary: '获取今日喝水统计' }) - @ApiResponse({ status: 200, description: '成功获取今日喝水统计', type: TodayWaterStatsResponseDto }) - async getTodayWaterStats( + @ApiOperation({ summary: '获取指定日期的喝水统计' }) + @ApiQuery({ name: 'date', required: false, description: '查询日期 (YYYY-MM-DD),不传则默认为今天' }) + @ApiResponse({ status: 200, description: '成功获取喝水统计', type: WaterStatsResponseDto }) + async getWaterStats( + @Query() query: GetWaterStatsQueryDto, @CurrentUser() user: AccessTokenPayload, - ): Promise { - this.logger.log(`获取今日喝水统计 - 用户ID: ${user.sub}`); - return this.waterRecordsService.getTodayWaterStats(user.sub); + ): Promise { + const targetDate = query.date || new Date().toISOString().split('T')[0]; + this.logger.log(`获取喝水统计 - 用户ID: ${user.sub}, 日期: ${targetDate}`); + return this.waterRecordsService.getWaterStats(user.sub, targetDate); } } \ No newline at end of file diff --git a/src/water-records/water-records.service.ts b/src/water-records/water-records.service.ts index 25ac468..a207b41 100644 --- a/src/water-records/water-records.service.ts +++ b/src/water-records/water-records.service.ts @@ -10,7 +10,7 @@ import { WaterRecordsListResponseDto, UpdateWaterGoalDto, WaterGoalResponseDto, - TodayWaterStatsResponseDto + WaterStatsResponseDto } from './dto/water-record.dto'; import { Op } from 'sequelize'; @@ -214,17 +214,21 @@ export class WaterRecordsService { } /** - * 获取今日喝水统计 + * 获取指定日期的喝水统计 */ - async getTodayWaterStats(userId: string): Promise { + async getWaterStats(userId: string, date: string): Promise { try { - // 获取今天的开始和结束时间 - const today = new Date(); - const startOfDay = new Date(today.getFullYear(), today.getMonth(), today.getDate()); - const endOfDay = new Date(today.getFullYear(), today.getMonth(), today.getDate(), 23, 59, 59, 999); + // 解析日期并获取当天的开始和结束时间 + const targetDate = new Date(date); + if (isNaN(targetDate.getTime())) { + throw new BadRequestException('日期格式不正确'); + } - // 获取今日喝水记录 - const todayRecords = await this.userWaterHistoryModel.findAll({ + const startOfDay = new Date(targetDate.getFullYear(), targetDate.getMonth(), targetDate.getDate()); + const endOfDay = new Date(targetDate.getFullYear(), targetDate.getMonth(), targetDate.getDate(), 23, 59, 59, 999); + + // 获取指定日期的喝水记录 + const dayRecords = await this.userWaterHistoryModel.findAll({ where: { userId, recordedAt: { @@ -234,8 +238,8 @@ export class WaterRecordsService { order: [['recordedAt', 'ASC']], }); - // 计算今日总喝水量 - const totalAmount = todayRecords.reduce((sum, record) => sum + record.amount, 0); + // 计算当日总喝水量 + const totalAmount = dayRecords.reduce((sum, record) => sum + record.amount, 0); // 获取用户的喝水目标 const userProfile = await this.userProfileModel.findOne({ @@ -247,14 +251,14 @@ export class WaterRecordsService { return { success: true, - message: '获取今日喝水统计成功', + message: '获取喝水统计成功', data: { date: startOfDay.toISOString().split('T')[0], totalAmount, dailyGoal, completionRate: Math.round(completionRate * 100) / 100, - recordCount: todayRecords.length, - records: todayRecords.map(record => ({ + recordCount: dayRecords.length, + records: dayRecords.map(record => ({ id: record.id, amount: record.amount, recordedAt: record.recordedAt, @@ -263,8 +267,11 @@ export class WaterRecordsService { }, }; } catch (error) { - this.logger.error(`获取今日喝水统计失败: ${error.message}`, error.stack); - throw new BadRequestException('获取今日喝水统计失败'); + this.logger.error(`获取喝水统计失败: ${error.message}`, error.stack); + if (error instanceof BadRequestException) { + throw error; + } + throw new BadRequestException('获取喝水统计失败'); } } } \ No newline at end of file