新增完整的喝水记录管理功能,支持用户记录每日喝水情况、设置目标和查看统计信息。功能包括: - 创建、查询、更新和删除喝水记录 - 设置和管理每日喝水目标 - 获取今日喝水统计和完成率分析 - 支持分页查询和日期范围筛选 - 完整的数据验证和错误处理机制 该模块已从用户模块中独立出来,提供REST API接口,包含数据库迁移脚本和详细文档。
146 lines
5.0 KiB
TypeScript
146 lines
5.0 KiB
TypeScript
import {
|
||
Controller,
|
||
Get,
|
||
Post,
|
||
Body,
|
||
Param,
|
||
HttpCode,
|
||
HttpStatus,
|
||
Put,
|
||
Delete,
|
||
Query,
|
||
Logger,
|
||
UseGuards,
|
||
NotFoundException,
|
||
} from '@nestjs/common';
|
||
import { ApiOperation, ApiBody, ApiResponse, ApiTags, ApiQuery } from '@nestjs/swagger';
|
||
import { WaterRecordsService } from './water-records.service';
|
||
import {
|
||
CreateWaterRecordDto,
|
||
UpdateWaterRecordDto,
|
||
WaterRecordResponseDto,
|
||
GetWaterRecordsQueryDto,
|
||
WaterRecordsListResponseDto,
|
||
UpdateWaterGoalDto,
|
||
WaterGoalResponseDto,
|
||
TodayWaterStatsResponseDto
|
||
} from './dto/water-record.dto';
|
||
import { JwtAuthGuard } from '../common/guards/jwt-auth.guard';
|
||
import { CurrentUser } from '../common/decorators/current-user.decorator';
|
||
import { AccessTokenPayload } from '../users/services/apple-auth.service';
|
||
|
||
@ApiTags('water-records')
|
||
@Controller('water-records')
|
||
export class WaterRecordsController {
|
||
private readonly logger = new Logger(WaterRecordsController.name);
|
||
|
||
constructor(
|
||
private readonly waterRecordsService: WaterRecordsService,
|
||
) { }
|
||
|
||
/**
|
||
* 创建喝水记录
|
||
*/
|
||
@UseGuards(JwtAuthGuard)
|
||
@Post()
|
||
@HttpCode(HttpStatus.CREATED)
|
||
@ApiOperation({ summary: '创建喝水记录' })
|
||
@ApiBody({ type: CreateWaterRecordDto })
|
||
@ApiResponse({ status: 201, description: '成功创建喝水记录', type: WaterRecordResponseDto })
|
||
async createWaterRecord(
|
||
@Body() createDto: CreateWaterRecordDto,
|
||
@CurrentUser() user: AccessTokenPayload,
|
||
): Promise<WaterRecordResponseDto> {
|
||
this.logger.log(`创建喝水记录 - 用户ID: ${user.sub}, 喝水量: ${createDto.amount}ml`);
|
||
return this.waterRecordsService.createWaterRecord(user.sub, createDto);
|
||
}
|
||
|
||
/**
|
||
* 获取喝水记录列表
|
||
*/
|
||
@UseGuards(JwtAuthGuard)
|
||
@Get()
|
||
@HttpCode(HttpStatus.OK)
|
||
@ApiOperation({ summary: '获取喝水记录列表' })
|
||
@ApiQuery({ name: 'startDate', required: false, description: '开始日期 (YYYY-MM-DD)' })
|
||
@ApiQuery({ name: 'endDate', required: false, description: '结束日期 (YYYY-MM-DD)' })
|
||
@ApiQuery({ name: 'page', required: false, description: '页码,默认1' })
|
||
@ApiQuery({ name: 'limit', required: false, description: '每页数量,默认20' })
|
||
@ApiResponse({ status: 200, description: '成功获取喝水记录列表', type: WaterRecordsListResponseDto })
|
||
async getWaterRecords(
|
||
@Query() query: GetWaterRecordsQueryDto,
|
||
@CurrentUser() user: AccessTokenPayload,
|
||
): Promise<WaterRecordsListResponseDto> {
|
||
this.logger.log(`获取喝水记录列表 - 用户ID: ${user.sub}`);
|
||
return this.waterRecordsService.getWaterRecords(user.sub, query);
|
||
}
|
||
|
||
/**
|
||
* 更新喝水记录
|
||
*/
|
||
@UseGuards(JwtAuthGuard)
|
||
@Put(':id')
|
||
@HttpCode(HttpStatus.OK)
|
||
@ApiOperation({ summary: '更新喝水记录' })
|
||
@ApiBody({ type: UpdateWaterRecordDto })
|
||
@ApiResponse({ status: 200, description: '成功更新喝水记录', type: WaterRecordResponseDto })
|
||
async updateWaterRecord(
|
||
@Param('id') recordId: string,
|
||
@Body() updateDto: UpdateWaterRecordDto,
|
||
@CurrentUser() user: AccessTokenPayload,
|
||
): Promise<WaterRecordResponseDto> {
|
||
this.logger.log(`更新喝水记录 - 用户ID: ${user.sub}, 记录ID: ${recordId}`);
|
||
return this.waterRecordsService.updateWaterRecord(user.sub, parseInt(recordId), updateDto);
|
||
}
|
||
|
||
/**
|
||
* 删除喝水记录
|
||
*/
|
||
@UseGuards(JwtAuthGuard)
|
||
@Delete(':id')
|
||
@HttpCode(HttpStatus.NO_CONTENT)
|
||
@ApiOperation({ summary: '删除喝水记录' })
|
||
@ApiResponse({ status: 204, description: '成功删除喝水记录' })
|
||
async deleteWaterRecord(
|
||
@Param('id') recordId: string,
|
||
@CurrentUser() user: AccessTokenPayload,
|
||
): Promise<void> {
|
||
this.logger.log(`删除喝水记录 - 用户ID: ${user.sub}, 记录ID: ${recordId}`);
|
||
const success = await this.waterRecordsService.deleteWaterRecord(user.sub, parseInt(recordId));
|
||
if (!success) {
|
||
throw new NotFoundException('喝水记录不存在');
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 更新喝水目标
|
||
*/
|
||
@UseGuards(JwtAuthGuard)
|
||
@Put('goal/daily')
|
||
@HttpCode(HttpStatus.OK)
|
||
@ApiOperation({ summary: '更新每日喝水目标' })
|
||
@ApiBody({ type: UpdateWaterGoalDto })
|
||
@ApiResponse({ status: 200, description: '成功更新喝水目标', type: WaterGoalResponseDto })
|
||
async updateWaterGoal(
|
||
@Body() updateDto: UpdateWaterGoalDto,
|
||
@CurrentUser() user: AccessTokenPayload,
|
||
): Promise<WaterGoalResponseDto> {
|
||
this.logger.log(`更新喝水目标 - 用户ID: ${user.sub}, 目标: ${updateDto.dailyWaterGoal}ml`);
|
||
return this.waterRecordsService.updateWaterGoal(user.sub, updateDto);
|
||
}
|
||
|
||
/**
|
||
* 获取今日喝水统计
|
||
*/
|
||
@UseGuards(JwtAuthGuard)
|
||
@Get('stats/today')
|
||
@HttpCode(HttpStatus.OK)
|
||
@ApiOperation({ summary: '获取今日喝水统计' })
|
||
@ApiResponse({ status: 200, description: '成功获取今日喝水统计', type: TodayWaterStatsResponseDto })
|
||
async getTodayWaterStats(
|
||
@CurrentUser() user: AccessTokenPayload,
|
||
): Promise<TodayWaterStatsResponseDto> {
|
||
this.logger.log(`获取今日喝水统计 - 用户ID: ${user.sub}`);
|
||
return this.waterRecordsService.getTodayWaterStats(user.sub);
|
||
}
|
||
} |