feat: 更新喝水统计功能,支持指定日期查询并返回相应数据

This commit is contained in:
richarjiang
2025-09-02 11:32:22 +08:00
parent 2c2e964199
commit 730b1df35e
3 changed files with 53 additions and 28 deletions

View File

@@ -242,11 +242,25 @@ export class WaterGoalResponseDto extends BaseResponseDto {
} }
/** /**
* 今日喝水统计响应DTO * 获取喝水统计查询参数DTO
*/ */
export class TodayWaterStatsResponseDto extends BaseResponseDto { export class GetWaterStatsQueryDto {
@ApiProperty({ @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: { example: {
date: '2023-12-01', date: '2023-12-01',
totalAmount: 1500, totalAmount: 1500,

View File

@@ -23,7 +23,8 @@ import {
WaterRecordsListResponseDto, WaterRecordsListResponseDto,
UpdateWaterGoalDto, UpdateWaterGoalDto,
WaterGoalResponseDto, WaterGoalResponseDto,
TodayWaterStatsResponseDto GetWaterStatsQueryDto,
WaterStatsResponseDto
} from './dto/water-record.dto'; } from './dto/water-record.dto';
import { JwtAuthGuard } from '../common/guards/jwt-auth.guard'; import { JwtAuthGuard } from '../common/guards/jwt-auth.guard';
import { CurrentUser } from '../common/decorators/current-user.decorator'; import { CurrentUser } from '../common/decorators/current-user.decorator';
@@ -130,17 +131,20 @@ export class WaterRecordsController {
} }
/** /**
* 获取今日喝水统计 * 获取指定日期的喝水统计
*/ */
@UseGuards(JwtAuthGuard) @UseGuards(JwtAuthGuard)
@Get('stats/today') @Get('stats')
@HttpCode(HttpStatus.OK) @HttpCode(HttpStatus.OK)
@ApiOperation({ summary: '获取今日喝水统计' }) @ApiOperation({ summary: '获取指定日期的喝水统计' })
@ApiResponse({ status: 200, description: '成功获取今日喝水统计', type: TodayWaterStatsResponseDto }) @ApiQuery({ name: 'date', required: false, description: '查询日期 (YYYY-MM-DD),不传则默认为今天' })
async getTodayWaterStats( @ApiResponse({ status: 200, description: '成功获取喝水统计', type: WaterStatsResponseDto })
async getWaterStats(
@Query() query: GetWaterStatsQueryDto,
@CurrentUser() user: AccessTokenPayload, @CurrentUser() user: AccessTokenPayload,
): Promise<TodayWaterStatsResponseDto> { ): Promise<WaterStatsResponseDto> {
this.logger.log(`获取今日喝水统计 - 用户ID: ${user.sub}`); const targetDate = query.date || new Date().toISOString().split('T')[0];
return this.waterRecordsService.getTodayWaterStats(user.sub); this.logger.log(`获取喝水统计 - 用户ID: ${user.sub}, 日期: ${targetDate}`);
return this.waterRecordsService.getWaterStats(user.sub, targetDate);
} }
} }

View File

@@ -10,7 +10,7 @@ import {
WaterRecordsListResponseDto, WaterRecordsListResponseDto,
UpdateWaterGoalDto, UpdateWaterGoalDto,
WaterGoalResponseDto, WaterGoalResponseDto,
TodayWaterStatsResponseDto WaterStatsResponseDto
} from './dto/water-record.dto'; } from './dto/water-record.dto';
import { Op } from 'sequelize'; import { Op } from 'sequelize';
@@ -214,17 +214,21 @@ export class WaterRecordsService {
} }
/** /**
* 获取今日喝水统计 * 获取指定日期的喝水统计
*/ */
async getTodayWaterStats(userId: string): Promise<TodayWaterStatsResponseDto> { async getWaterStats(userId: string, date: string): Promise<WaterStatsResponseDto> {
try { try {
// 获取天的开始和结束时间 // 解析日期并获取天的开始和结束时间
const today = new Date(); const targetDate = new Date(date);
const startOfDay = new Date(today.getFullYear(), today.getMonth(), today.getDate()); if (isNaN(targetDate.getTime())) {
const endOfDay = new Date(today.getFullYear(), today.getMonth(), today.getDate(), 23, 59, 59, 999); throw new BadRequestException('日期格式不正确');
}
// 获取今日喝水记录 const startOfDay = new Date(targetDate.getFullYear(), targetDate.getMonth(), targetDate.getDate());
const todayRecords = await this.userWaterHistoryModel.findAll({ const endOfDay = new Date(targetDate.getFullYear(), targetDate.getMonth(), targetDate.getDate(), 23, 59, 59, 999);
// 获取指定日期的喝水记录
const dayRecords = await this.userWaterHistoryModel.findAll({
where: { where: {
userId, userId,
recordedAt: { recordedAt: {
@@ -234,8 +238,8 @@ export class WaterRecordsService {
order: [['recordedAt', 'ASC']], 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({ const userProfile = await this.userProfileModel.findOne({
@@ -247,14 +251,14 @@ export class WaterRecordsService {
return { return {
success: true, success: true,
message: '获取今日喝水统计成功', message: '获取喝水统计成功',
data: { data: {
date: startOfDay.toISOString().split('T')[0], date: startOfDay.toISOString().split('T')[0],
totalAmount, totalAmount,
dailyGoal, dailyGoal,
completionRate: Math.round(completionRate * 100) / 100, completionRate: Math.round(completionRate * 100) / 100,
recordCount: todayRecords.length, recordCount: dayRecords.length,
records: todayRecords.map(record => ({ records: dayRecords.map(record => ({
id: record.id, id: record.id,
amount: record.amount, amount: record.amount,
recordedAt: record.recordedAt, recordedAt: record.recordedAt,
@@ -263,8 +267,11 @@ export class WaterRecordsService {
}, },
}; };
} catch (error) { } catch (error) {
this.logger.error(`获取今日喝水统计失败: ${error.message}`, error.stack); this.logger.error(`获取喝水统计失败: ${error.message}`, error.stack);
throw new BadRequestException('获取今日喝水统计失败'); if (error instanceof BadRequestException) {
throw error;
}
throw new BadRequestException('获取喝水统计失败');
} }
} }
} }