feat(medications): 新增完整的药物管理和服药提醒功能

实现了包含药物信息管理、服药记录追踪、统计分析、自动状态更新和推送提醒的完整药物管理系统。

核心功能:
- 药物 CRUD 操作,支持多种剂型和自定义服药时间
- 惰性生成服药记录策略,查询时才生成当天记录
- 定时任务自动更新过期记录状态(每30分钟)
- 服药前15分钟自动推送提醒(每5分钟检查)
- 每日/范围/总体统计分析功能
- 完整的 API 文档和数据库建表脚本

技术实现:
- 使用 Sequelize ORM 管理 MySQL 数据表
- 集成 @nestjs/schedule 实现定时任务
- 复用现有推送通知系统发送提醒
- 采用软删除和权限验证保障数据安全
This commit is contained in:
richarjiang
2025-11-07 17:29:11 +08:00
parent 37cc2a729b
commit 188b4addca
27 changed files with 3464 additions and 0 deletions

View File

@@ -0,0 +1,104 @@
import { ApiProperty } from '@nestjs/swagger';
import {
IsString,
IsNotEmpty,
IsEnum,
IsNumber,
IsInt,
IsArray,
IsDateString,
IsOptional,
Min,
ArrayMinSize,
Matches,
} from 'class-validator';
import { MedicationFormEnum } from '../enums/medication-form.enum';
import { RepeatPatternEnum } from '../enums/repeat-pattern.enum';
/**
* 创建药物 DTO
*/
export class CreateMedicationDto {
@ApiProperty({ description: '药物名称', example: 'Metformin' })
@IsString()
@IsNotEmpty()
name: string;
@ApiProperty({
description: '药物照片URL',
example: 'https://cdn.example.com/medications/med_001.jpg',
required: false,
})
@IsString()
@IsOptional()
photoUrl?: string;
@ApiProperty({
description: '药物剂型',
enum: MedicationFormEnum,
example: MedicationFormEnum.CAPSULE,
})
@IsEnum(MedicationFormEnum)
@IsNotEmpty()
form: MedicationFormEnum;
@ApiProperty({ description: '剂量数值', example: 1 })
@IsNumber()
@Min(0.01)
dosageValue: number;
@ApiProperty({ description: '剂量单位', example: '粒' })
@IsString()
@IsNotEmpty()
dosageUnit: string;
@ApiProperty({ description: '每日服用次数', example: 2 })
@IsInt()
@Min(1)
timesPerDay: number;
@ApiProperty({
description: '服药时间列表格式HH:mm',
example: ['08:00', '20:00'],
type: [String],
})
@IsArray()
@ArrayMinSize(1)
@IsString({ each: true })
@Matches(/^([01]\d|2[0-3]):([0-5]\d)$/, {
each: true,
message: '服药时间格式必须为 HH:mm',
})
medicationTimes: string[];
@ApiProperty({
description: '重复模式',
enum: RepeatPatternEnum,
example: RepeatPatternEnum.DAILY,
})
@IsEnum(RepeatPatternEnum)
@IsNotEmpty()
repeatPattern: RepeatPatternEnum;
@ApiProperty({
description: '开始日期ISO 8601 格式',
example: '2025-01-01T00:00:00.000Z',
})
@IsDateString()
@IsNotEmpty()
startDate: string;
@ApiProperty({
description: '结束日期ISO 8601 格式(可选)',
example: '2025-12-31T23:59:59.999Z',
required: false,
})
@IsDateString()
@IsOptional()
endDate?: string;
@ApiProperty({ description: '备注信息', example: '饭后服用', required: false })
@IsString()
@IsOptional()
note?: string;
}