实现了包含药物信息管理、服药记录追踪、统计分析、自动状态更新和推送提醒的完整药物管理系统。 核心功能: - 药物 CRUD 操作,支持多种剂型和自定义服药时间 - 惰性生成服药记录策略,查询时才生成当天记录 - 定时任务自动更新过期记录状态(每30分钟) - 服药前15分钟自动推送提醒(每5分钟检查) - 每日/范围/总体统计分析功能 - 完整的 API 文档和数据库建表脚本 技术实现: - 使用 Sequelize ORM 管理 MySQL 数据表 - 集成 @nestjs/schedule 实现定时任务 - 复用现有推送通知系统发送提醒 - 采用软删除和权限验证保障数据安全
947 lines
21 KiB
Markdown
947 lines
21 KiB
Markdown
# 药物管理 API 文档 - 客户端版本
|
||
|
||
## 基础信息
|
||
|
||
**Base URL**: `https://your-domain.com/api`
|
||
**认证方式**: Bearer Token (JWT)
|
||
**Content-Type**: `application/json`
|
||
|
||
## 认证说明
|
||
|
||
所有接口都需要在 HTTP Header 中携带 JWT Token:
|
||
|
||
```http
|
||
Authorization: Bearer <your_jwt_token>
|
||
```
|
||
|
||
## 数据类型定义
|
||
|
||
### MedicationForm(药物剂型)
|
||
|
||
```typescript
|
||
enum MedicationForm {
|
||
CAPSULE = "capsule", // 胶囊
|
||
PILL = "pill", // 药片
|
||
INJECTION = "injection", // 注射
|
||
SPRAY = "spray", // 喷雾
|
||
DROP = "drop", // 滴剂
|
||
SYRUP = "syrup", // 糖浆
|
||
OTHER = "other", // 其他
|
||
}
|
||
```
|
||
|
||
### RepeatPattern(重复模式)
|
||
|
||
```typescript
|
||
enum RepeatPattern {
|
||
DAILY = "daily", // 每日(目前仅支持每日模式)
|
||
}
|
||
```
|
||
|
||
### MedicationStatus(服药状态)
|
||
|
||
```typescript
|
||
enum MedicationStatus {
|
||
UPCOMING = "upcoming", // 待服用
|
||
TAKEN = "taken", // 已服用
|
||
MISSED = "missed", // 已错过
|
||
SKIPPED = "skipped", // 已跳过
|
||
}
|
||
```
|
||
|
||
### Medication(药物信息)
|
||
|
||
```typescript
|
||
interface Medication {
|
||
id: string; // 药物唯一标识
|
||
userId: string; // 用户ID
|
||
name: string; // 药物名称
|
||
photoUrl?: string; // 药物照片URL(可选)
|
||
form: MedicationForm; // 药物剂型
|
||
dosageValue: number; // 剂量数值(如 1、0.5)
|
||
dosageUnit: string; // 剂量单位(片、粒、毫升等)
|
||
timesPerDay: number; // 每日服用次数
|
||
medicationTimes: string[]; // 服药时间列表,格式:["08:00", "12:00", "18:00"]
|
||
repeatPattern: RepeatPattern; // 重复模式
|
||
startDate: string; // 开始日期,ISO 8601 格式
|
||
endDate?: string; // 结束日期(可选),ISO 8601 格式
|
||
note?: string; // 备注信息(可选)
|
||
isActive: boolean; // 是否激活
|
||
deleted: boolean; // 是否已删除
|
||
createdAt: string; // 创建时间,ISO 8601 格式
|
||
updatedAt: string; // 更新时间,ISO 8601 格式
|
||
}
|
||
```
|
||
|
||
### MedicationRecord(服药记录)
|
||
|
||
```typescript
|
||
interface MedicationRecord {
|
||
id: string; // 记录唯一标识
|
||
medicationId: string; // 关联的药物ID
|
||
userId: string; // 用户ID
|
||
scheduledTime: string; // 计划服药时间,ISO 8601 格式
|
||
actualTime?: string; // 实际服药时间(可选),ISO 8601 格式
|
||
status: MedicationStatus; // 服药状态
|
||
note?: string; // 备注(可选)
|
||
deleted: boolean; // 是否已删除
|
||
createdAt: string; // 创建时间,ISO 8601 格式
|
||
updatedAt: string; // 更新时间,ISO 8601 格式
|
||
medication?: Medication; // 关联的药物信息(可选,用于联表查询)
|
||
}
|
||
```
|
||
|
||
### DailyMedicationStats(每日统计)
|
||
|
||
```typescript
|
||
interface DailyMedicationStats {
|
||
date: string; // 日期,格式:YYYY-MM-DD
|
||
totalScheduled: number; // 计划服药总次数
|
||
taken: number; // 已服用次数
|
||
missed: number; // 已错过次数
|
||
upcoming: number; // 待服用次数
|
||
completionRate: number; // 完成率(百分比,0-100,保留两位小数)
|
||
}
|
||
```
|
||
|
||
### 统一响应格式
|
||
|
||
```typescript
|
||
interface ApiResponse<T> {
|
||
code: number; // 状态码:200成功,其他为错误
|
||
message: string; // 响应消息
|
||
data: T | null; // 响应数据
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## 药物管理接口
|
||
|
||
### 1. 获取药物列表
|
||
|
||
获取当前用户的药物列表。
|
||
|
||
**接口**: `GET /medications`
|
||
|
||
**请求参数**:
|
||
|
||
| 参数 | 类型 | 必填 | 说明 |
|
||
| -------- | ------- | ---- | ---------------------------------- |
|
||
| isActive | boolean | 否 | 是否只获取激活的药物,默认获取全部 |
|
||
| page | number | 否 | 页码,默认 1 |
|
||
| pageSize | number | 否 | 每页数量,默认 20 |
|
||
|
||
**请求示例**:
|
||
|
||
```http
|
||
GET /medications?isActive=true&page=1&pageSize=20
|
||
Authorization: Bearer <token>
|
||
```
|
||
|
||
**响应示例**:
|
||
|
||
```json
|
||
{
|
||
"code": 200,
|
||
"message": "查询成功",
|
||
"data": [
|
||
{
|
||
"id": "med_001",
|
||
"userId": "user_123",
|
||
"name": "阿司匹林",
|
||
"photoUrl": "https://cdn.example.com/medications/aspirin.jpg",
|
||
"form": "pill",
|
||
"dosageValue": 1,
|
||
"dosageUnit": "片",
|
||
"timesPerDay": 2,
|
||
"medicationTimes": ["08:00", "20:00"],
|
||
"repeatPattern": "daily",
|
||
"startDate": "2025-01-01T00:00:00.000Z",
|
||
"endDate": null,
|
||
"note": "饭后服用",
|
||
"isActive": true,
|
||
"deleted": false,
|
||
"createdAt": "2025-01-01T00:00:00.000Z",
|
||
"updatedAt": "2025-01-01T00:00:00.000Z"
|
||
}
|
||
]
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
### 2. 获取单个药物详情
|
||
|
||
获取指定药物的详细信息。
|
||
|
||
**接口**: `GET /medications/{id}`
|
||
|
||
**路径参数**:
|
||
|
||
| 参数 | 类型 | 必填 | 说明 |
|
||
| ---- | ------ | ---- | ------ |
|
||
| id | string | 是 | 药物ID |
|
||
|
||
**请求示例**:
|
||
|
||
```http
|
||
GET /medications/med_001
|
||
Authorization: Bearer <token>
|
||
```
|
||
|
||
**响应**: 同"获取药物列表"中的单个药物对象
|
||
|
||
---
|
||
|
||
### 3. 创建药物
|
||
|
||
创建新的药物信息。
|
||
|
||
**接口**: `POST /medications`
|
||
|
||
**请求体**:
|
||
|
||
```json
|
||
{
|
||
"name": "阿司匹林",
|
||
"photoUrl": "https://cdn.example.com/medications/aspirin.jpg",
|
||
"form": "pill",
|
||
"dosageValue": 1,
|
||
"dosageUnit": "片",
|
||
"timesPerDay": 2,
|
||
"medicationTimes": ["08:00", "20:00"],
|
||
"repeatPattern": "daily",
|
||
"startDate": "2025-01-01T00:00:00.000Z",
|
||
"endDate": null,
|
||
"note": "饭后服用"
|
||
}
|
||
```
|
||
|
||
**字段说明**:
|
||
|
||
| 字段 | 类型 | 必填 | 说明 |
|
||
| --------------- | -------------- | ---- | ---------------------------------------------------- |
|
||
| name | string | 是 | 药物名称,最大100字符 |
|
||
| photoUrl | string | 否 | 药物照片URL |
|
||
| form | MedicationForm | 是 | 药物剂型 |
|
||
| dosageValue | number | 是 | 剂量数值,必须大于0 |
|
||
| dosageUnit | string | 是 | 剂量单位,最大20字符 |
|
||
| timesPerDay | number | 是 | 每日服用次数,1-10次 |
|
||
| medicationTimes | string[] | 是 | 服药时间列表,格式:"HH:mm",数量必须等于timesPerDay |
|
||
| repeatPattern | RepeatPattern | 是 | 重复模式,目前仅支持"daily" |
|
||
| startDate | string | 是 | 开始日期,ISO 8601格式 |
|
||
| endDate | string | 否 | 结束日期,ISO 8601格式 |
|
||
| note | string | 否 | 备注信息 |
|
||
|
||
**响应示例**:
|
||
|
||
```json
|
||
{
|
||
"code": 200,
|
||
"message": "创建成功",
|
||
"data": {
|
||
"id": "med_001",
|
||
"userId": "user_123",
|
||
"name": "阿司匹林",
|
||
"photoUrl": "https://cdn.example.com/medications/aspirin.jpg",
|
||
"form": "pill",
|
||
"dosageValue": 1,
|
||
"dosageUnit": "片",
|
||
"timesPerDay": 2,
|
||
"medicationTimes": ["08:00", "20:00"],
|
||
"repeatPattern": "daily",
|
||
"startDate": "2025-01-01T00:00:00.000Z",
|
||
"endDate": null,
|
||
"note": "饭后服用",
|
||
"isActive": true,
|
||
"deleted": false,
|
||
"createdAt": "2025-01-01T00:00:00.000Z",
|
||
"updatedAt": "2025-01-01T00:00:00.000Z"
|
||
}
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
### 4. 更新药物信息
|
||
|
||
更新指定药物的信息。
|
||
|
||
**接口**: `PUT /medications/{id}`
|
||
|
||
**路径参数**:
|
||
|
||
| 参数 | 类型 | 必填 | 说明 |
|
||
| ---- | ------ | ---- | ------ |
|
||
| id | string | 是 | 药物ID |
|
||
|
||
**请求体**: 与创建药物相同,所有字段均为可选
|
||
|
||
**请求示例**:
|
||
|
||
```json
|
||
{
|
||
"dosageValue": 2,
|
||
"timesPerDay": 3,
|
||
"medicationTimes": ["08:00", "14:00", "20:00"],
|
||
"note": "饭后服用,加量"
|
||
}
|
||
```
|
||
|
||
**响应**: 同"创建药物"响应
|
||
|
||
---
|
||
|
||
### 5. 删除药物
|
||
|
||
删除指定药物(软删除)。
|
||
|
||
**接口**: `DELETE /medications/{id}`
|
||
|
||
**路径参数**:
|
||
|
||
| 参数 | 类型 | 必填 | 说明 |
|
||
| ---- | ------ | ---- | ------ |
|
||
| id | string | 是 | 药物ID |
|
||
|
||
**请求示例**:
|
||
|
||
```http
|
||
DELETE /medications/med_001
|
||
Authorization: Bearer <token>
|
||
```
|
||
|
||
**响应示例**:
|
||
|
||
```json
|
||
{
|
||
"code": 200,
|
||
"message": "删除成功",
|
||
"data": null
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
### 6. 停用药物
|
||
|
||
停用指定药物(将 isActive 设为 false)。
|
||
|
||
**接口**: `POST /medications/{id}/deactivate`
|
||
|
||
**路径参数**:
|
||
|
||
| 参数 | 类型 | 必填 | 说明 |
|
||
| ---- | ------ | ---- | ------ |
|
||
| id | string | 是 | 药物ID |
|
||
|
||
**请求示例**:
|
||
|
||
```http
|
||
POST /medications/med_001/deactivate
|
||
Authorization: Bearer <token>
|
||
```
|
||
|
||
**响应示例**:
|
||
|
||
```json
|
||
{
|
||
"code": 200,
|
||
"message": "停用成功",
|
||
"data": {
|
||
"id": "med_001",
|
||
"isActive": false,
|
||
"updatedAt": "2025-01-15T00:00:00.000Z"
|
||
}
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## 服药记录接口
|
||
|
||
### 1. 获取服药记录
|
||
|
||
查询服药记录,支持多种筛选条件。
|
||
|
||
**接口**: `GET /medication-records`
|
||
|
||
**请求参数**:
|
||
|
||
| 参数 | 类型 | 必填 | 说明 |
|
||
| ------------ | ---------------- | ---- | -------------------------------------- |
|
||
| date | string | 否 | 指定日期(YYYY-MM-DD),不填则返回所有 |
|
||
| startDate | string | 否 | 开始日期(YYYY-MM-DD) |
|
||
| endDate | string | 否 | 结束日期(YYYY-MM-DD) |
|
||
| medicationId | string | 否 | 指定药物ID |
|
||
| status | MedicationStatus | 否 | 状态筛选 |
|
||
|
||
**重要说明**:
|
||
|
||
- 首次查询某天的记录时,后端会自动生成该天的服药记录(惰性生成)
|
||
- 建议使用 `date` 参数查询特定日期,效率更高
|
||
|
||
**请求示例**:
|
||
|
||
```http
|
||
GET /medication-records?date=2025-01-15&status=upcoming
|
||
Authorization: Bearer <token>
|
||
```
|
||
|
||
**响应示例**:
|
||
|
||
```json
|
||
{
|
||
"code": 200,
|
||
"message": "查询成功",
|
||
"data": [
|
||
{
|
||
"id": "record_001",
|
||
"medicationId": "med_001",
|
||
"userId": "user_123",
|
||
"scheduledTime": "2025-01-15T08:00:00.000Z",
|
||
"actualTime": null,
|
||
"status": "upcoming",
|
||
"note": null,
|
||
"deleted": false,
|
||
"createdAt": "2025-01-15T00:00:00.000Z",
|
||
"updatedAt": "2025-01-15T00:00:00.000Z",
|
||
"medication": {
|
||
"id": "med_001",
|
||
"name": "阿司匹林",
|
||
"form": "pill",
|
||
"dosageValue": 1,
|
||
"dosageUnit": "片"
|
||
}
|
||
}
|
||
]
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
### 2. 获取今日服药记录
|
||
|
||
快捷获取今天的所有服药记录。
|
||
|
||
**接口**: `GET /medication-records/today`
|
||
|
||
**请求示例**:
|
||
|
||
```http
|
||
GET /medication-records/today
|
||
Authorization: Bearer <token>
|
||
```
|
||
|
||
**响应**: 同"获取服药记录"响应
|
||
|
||
---
|
||
|
||
### 3. 获取服药记录详情
|
||
|
||
获取指定服药记录的详细信息。
|
||
|
||
**接口**: `GET /medication-records/{id}`
|
||
|
||
**路径参数**:
|
||
|
||
| 参数 | 类型 | 必填 | 说明 |
|
||
| ---- | ------ | ---- | ------ |
|
||
| id | string | 是 | 记录ID |
|
||
|
||
**请求示例**:
|
||
|
||
```http
|
||
GET /medication-records/record_001
|
||
Authorization: Bearer <token>
|
||
```
|
||
|
||
**响应**: 同"获取服药记录"中的单个记录对象
|
||
|
||
---
|
||
|
||
### 4. 标记为已服用
|
||
|
||
将服药记录标记为已服用。
|
||
|
||
**接口**: `POST /medication-records/{id}/take`
|
||
|
||
**路径参数**:
|
||
|
||
| 参数 | 类型 | 必填 | 说明 |
|
||
| ---- | ------ | ---- | ------ |
|
||
| id | string | 是 | 记录ID |
|
||
|
||
**请求体**:
|
||
|
||
```json
|
||
{
|
||
"actualTime": "2025-01-15T08:10:00.000Z"
|
||
}
|
||
```
|
||
|
||
**字段说明**:
|
||
|
||
| 字段 | 类型 | 必填 | 说明 |
|
||
| ---------- | ------ | ---- | ---------------------------------------------- |
|
||
| actualTime | string | 否 | 实际服药时间,ISO 8601格式,不填则使用当前时间 |
|
||
|
||
**响应示例**:
|
||
|
||
```json
|
||
{
|
||
"code": 200,
|
||
"message": "已记录服药",
|
||
"data": {
|
||
"id": "record_001",
|
||
"medicationId": "med_001",
|
||
"userId": "user_123",
|
||
"scheduledTime": "2025-01-15T08:00:00.000Z",
|
||
"actualTime": "2025-01-15T08:10:00.000Z",
|
||
"status": "taken",
|
||
"note": null,
|
||
"deleted": false,
|
||
"createdAt": "2025-01-15T00:00:00.000Z",
|
||
"updatedAt": "2025-01-15T08:10:00.000Z"
|
||
}
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
### 5. 跳过服药
|
||
|
||
跳过本次服药,不计入已错过。
|
||
|
||
**接口**: `POST /medication-records/{id}/skip`
|
||
|
||
**路径参数**:
|
||
|
||
| 参数 | 类型 | 必填 | 说明 |
|
||
| ---- | ------ | ---- | ------ |
|
||
| id | string | 是 | 记录ID |
|
||
|
||
**请求体**:
|
||
|
||
```json
|
||
{
|
||
"note": "今天身体不适,暂时跳过"
|
||
}
|
||
```
|
||
|
||
**字段说明**:
|
||
|
||
| 字段 | 类型 | 必填 | 说明 |
|
||
| ---- | ------ | ---- | ------------ |
|
||
| note | string | 否 | 跳过原因备注 |
|
||
|
||
**响应示例**:
|
||
|
||
```json
|
||
{
|
||
"code": 200,
|
||
"message": "已跳过服药",
|
||
"data": {
|
||
"id": "record_001",
|
||
"medicationId": "med_001",
|
||
"userId": "user_123",
|
||
"scheduledTime": "2025-01-15T08:00:00.000Z",
|
||
"actualTime": null,
|
||
"status": "skipped",
|
||
"note": "今天身体不适,暂时跳过",
|
||
"deleted": false,
|
||
"createdAt": "2025-01-15T00:00:00.000Z",
|
||
"updatedAt": "2025-01-15T08:15:00.000Z"
|
||
}
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
### 6. 更新服药记录
|
||
|
||
更新服药记录的状态和信息。
|
||
|
||
**接口**: `PUT /medication-records/{id}`
|
||
|
||
**路径参数**:
|
||
|
||
| 参数 | 类型 | 必填 | 说明 |
|
||
| ---- | ------ | ---- | ------ |
|
||
| id | string | 是 | 记录ID |
|
||
|
||
**请求体**:
|
||
|
||
```json
|
||
{
|
||
"status": "taken",
|
||
"actualTime": "2025-01-15T08:15:00.000Z",
|
||
"note": "延迟服用"
|
||
}
|
||
```
|
||
|
||
**字段说明**: 所有字段均为可选
|
||
|
||
| 字段 | 类型 | 必填 | 说明 |
|
||
| ---------- | ---------------- | ---- | -------------------------- |
|
||
| status | MedicationStatus | 否 | 服药状态 |
|
||
| actualTime | string | 否 | 实际服药时间,ISO 8601格式 |
|
||
| note | string | 否 | 备注信息 |
|
||
|
||
**响应**: 同"标记为已服用"响应
|
||
|
||
---
|
||
|
||
## 统计接口
|
||
|
||
### 1. 获取每日统计
|
||
|
||
获取指定日期的服药统计数据。
|
||
|
||
**接口**: `GET /medication-stats/daily`
|
||
|
||
**请求参数**:
|
||
|
||
| 参数 | 类型 | 必填 | 说明 |
|
||
| ---- | ------ | ---- | ---------------------- |
|
||
| date | string | 是 | 日期,格式:YYYY-MM-DD |
|
||
|
||
**请求示例**:
|
||
|
||
```http
|
||
GET /medication-stats/daily?date=2025-01-15
|
||
Authorization: Bearer <token>
|
||
```
|
||
|
||
**响应示例**:
|
||
|
||
```json
|
||
{
|
||
"code": 200,
|
||
"message": "查询成功",
|
||
"data": {
|
||
"date": "2025-01-15",
|
||
"totalScheduled": 6,
|
||
"taken": 4,
|
||
"missed": 1,
|
||
"upcoming": 1,
|
||
"completionRate": 66.67
|
||
}
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
### 2. 获取日期范围统计
|
||
|
||
获取指定日期范围内每天的统计数据。
|
||
|
||
**接口**: `GET /medication-stats/range`
|
||
|
||
**请求参数**:
|
||
|
||
| 参数 | 类型 | 必填 | 说明 |
|
||
| --------- | ------ | ---- | -------------------------- |
|
||
| startDate | string | 是 | 开始日期,格式:YYYY-MM-DD |
|
||
| endDate | string | 是 | 结束日期,格式:YYYY-MM-DD |
|
||
|
||
**请求示例**:
|
||
|
||
```http
|
||
GET /medication-stats/range?startDate=2025-01-01&endDate=2025-01-15
|
||
Authorization: Bearer <token>
|
||
```
|
||
|
||
**响应示例**:
|
||
|
||
```json
|
||
{
|
||
"code": 200,
|
||
"message": "查询成功",
|
||
"data": [
|
||
{
|
||
"date": "2025-01-15",
|
||
"totalScheduled": 6,
|
||
"taken": 4,
|
||
"missed": 1,
|
||
"upcoming": 1,
|
||
"completionRate": 66.67
|
||
},
|
||
{
|
||
"date": "2025-01-14",
|
||
"totalScheduled": 6,
|
||
"taken": 6,
|
||
"missed": 0,
|
||
"upcoming": 0,
|
||
"completionRate": 100.0
|
||
}
|
||
]
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
### 3. 获取总体统计
|
||
|
||
获取用户的总体服药统计概览。
|
||
|
||
**接口**: `GET /medication-stats/overall`
|
||
|
||
**请求示例**:
|
||
|
||
```http
|
||
GET /medication-stats/overall
|
||
Authorization: Bearer <token>
|
||
```
|
||
|
||
**响应示例**:
|
||
|
||
```json
|
||
{
|
||
"code": 200,
|
||
"message": "查询成功",
|
||
"data": {
|
||
"totalMedications": 5,
|
||
"totalRecords": 120,
|
||
"completionRate": 85.5,
|
||
"streak": 7
|
||
}
|
||
}
|
||
```
|
||
|
||
**字段说明**:
|
||
|
||
| 字段 | 类型 | 说明 |
|
||
| ---------------- | ------ | ---------------------------------- |
|
||
| totalMedications | number | 药物总数 |
|
||
| totalRecords | number | 服药记录总数 |
|
||
| completionRate | number | 总体完成率(百分比,保留两位小数) |
|
||
| streak | number | 连续完成天数 |
|
||
|
||
---
|
||
|
||
## 错误码说明
|
||
|
||
| 错误码 | 说明 |
|
||
| ------ | ------------------------- |
|
||
| 200 | 操作成功 |
|
||
| 400 | 请求参数错误 |
|
||
| 401 | 未授权,Token无效或已过期 |
|
||
| 403 | 权限不足,无法访问该资源 |
|
||
| 404 | 资源不存在 |
|
||
| 409 | 资源冲突(如重复创建) |
|
||
| 500 | 服务器内部错误 |
|
||
|
||
**错误响应格式**:
|
||
|
||
```json
|
||
{
|
||
"code": 400,
|
||
"message": "请求参数错误:药物名称不能为空",
|
||
"data": null
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## 业务逻辑说明
|
||
|
||
### 1. 服药记录的惰性生成
|
||
|
||
- 服药记录不会在创建药物时预先生成
|
||
- 当首次查询某天的记录时,后端会自动生成该天的所有服药记录
|
||
- 生成规则:根据药物的 `timesPerDay` 和 `medicationTimes` 生成对应数量的记录
|
||
|
||
**示例**:
|
||
|
||
- 如果药物设置为每天2次,服药时间为 08:00 和 20:00
|
||
- 首次查询 2025-01-15 的记录时,会自动生成该天 08:00 和 20:00 两条记录
|
||
|
||
### 2. 状态自动更新
|
||
|
||
- 后端每30分钟运行一次定时任务
|
||
- 自动将已过期的 `upcoming` 状态更新为 `missed`
|
||
- 客户端无需手动更新状态
|
||
|
||
**示例**:
|
||
|
||
- 08:00 的服药记录,到了 08:30 还未标记为已服用
|
||
- 定时任务会自动将其状态改为 `missed`
|
||
|
||
### 3. 推送提醒
|
||
|
||
- 后端每5分钟检查一次即将到来的服药时间(15-20分钟后)
|
||
- 自动发送推送通知提醒用户服药
|
||
- 客户端需要正确配置推送通知权限
|
||
|
||
### 4. 时区处理
|
||
|
||
- **重要**:所有时间字段使用 UTC 时间存储和传输
|
||
- 客户端需要:
|
||
1. 发送请求时:将本地时间转换为 UTC
|
||
2. 接收响应时:将 UTC 时间转换为本地时间显示
|
||
|
||
**示例代码(JavaScript)**:
|
||
|
||
```javascript
|
||
// 本地时间转 UTC
|
||
const localTime = new Date("2025-01-15 08:00");
|
||
const utcTime = localTime.toISOString(); // "2025-01-15T00:00:00.000Z" (假设时区为UTC+8)
|
||
|
||
// UTC 转本地时间
|
||
const utcTime = "2025-01-15T00:00:00.000Z";
|
||
const localTime = new Date(utcTime);
|
||
console.log(localTime.toLocaleString()); // "2025-01-15 08:00:00" (UTC+8)
|
||
```
|
||
|
||
---
|
||
|
||
## 最佳实践建议
|
||
|
||
### 1. 获取今日服药记录
|
||
|
||
推荐使用专用接口而非通用查询:
|
||
|
||
```http
|
||
✅ 推荐
|
||
GET /medication-records/today
|
||
|
||
❌ 不推荐
|
||
GET /medication-records?date=2025-01-15
|
||
```
|
||
|
||
### 2. 批量操作
|
||
|
||
如果需要更新多个记录,建议单独调用每个接口,后端暂不支持批量操作。
|
||
|
||
### 3. 错误处理
|
||
|
||
建议在客户端统一处理 API 错误:
|
||
|
||
```javascript
|
||
async function callApi(url, options) {
|
||
try {
|
||
const response = await fetch(url, options);
|
||
const data = await response.json();
|
||
|
||
if (data.code !== 200) {
|
||
// 显示错误提示
|
||
showError(data.message);
|
||
return null;
|
||
}
|
||
|
||
return data.data;
|
||
} catch (error) {
|
||
// 网络错误
|
||
showError("网络连接失败,请稍后重试");
|
||
return null;
|
||
}
|
||
}
|
||
```
|
||
|
||
### 4. 数据缓存
|
||
|
||
建议在客户端缓存以下数据以提升性能:
|
||
|
||
- 药物列表(有变更时刷新)
|
||
- 今日服药记录(实时更新)
|
||
- 统计数据(按天缓存)
|
||
|
||
### 5. 定时刷新
|
||
|
||
建议定时刷新今日服药记录以获取最新状态:
|
||
|
||
```javascript
|
||
// 每5分钟刷新一次今日记录
|
||
setInterval(
|
||
async () => {
|
||
const records = await getTodayRecords();
|
||
updateUI(records);
|
||
},
|
||
5 * 60 * 1000
|
||
);
|
||
```
|
||
|
||
---
|
||
|
||
## 完整使用流程示例
|
||
|
||
### 1. 创建药物并查看今日记录
|
||
|
||
```javascript
|
||
// Step 1: 创建药物
|
||
const medication = await createMedication({
|
||
name: "阿司匹林",
|
||
form: "pill",
|
||
dosageValue: 1,
|
||
dosageUnit: "片",
|
||
timesPerDay: 2,
|
||
medicationTimes: ["08:00", "20:00"],
|
||
repeatPattern: "daily",
|
||
startDate: new Date().toISOString(),
|
||
note: "饭后服用",
|
||
});
|
||
|
||
// Step 2: 获取今日服药记录(会自动生成)
|
||
const todayRecords = await getTodayRecords();
|
||
|
||
// Step 3: 显示记录列表
|
||
showRecordsList(todayRecords);
|
||
```
|
||
|
||
### 2. 标记服用并查看统计
|
||
|
||
```javascript
|
||
// Step 1: 标记为已服用
|
||
await takeMedication(recordId, {
|
||
actualTime: new Date().toISOString(),
|
||
});
|
||
|
||
// Step 2: 刷新今日记录
|
||
const todayRecords = await getTodayRecords();
|
||
|
||
// Step 3: 获取今日统计
|
||
const todayStats = await getDailyStats(formatDate(new Date()));
|
||
|
||
// Step 4: 显示完成率
|
||
showCompletionRate(todayStats.completionRate);
|
||
```
|
||
|
||
### 3. 查看历史统计
|
||
|
||
```javascript
|
||
// 获取最近7天的统计
|
||
const startDate = formatDate(daysAgo(7));
|
||
const endDate = formatDate(new Date());
|
||
|
||
const rangeStats = await getRangeStats(startDate, endDate);
|
||
|
||
// 绘制趋势图表
|
||
drawChart(rangeStats);
|
||
```
|
||
|
||
---
|
||
|
||
## 技术支持
|
||
|
||
如有疑问或需要帮助,请联系:
|
||
|
||
- **技术文档**: 本文档
|
||
- **API 基础URL**: https://your-domain.com/api
|
||
- **更新日期**: 2025-01-15
|
||
- **文档版本**: v1.0
|
||
|
||
---
|
||
|
||
## 更新日志
|
||
|
||
### v1.0 (2025-01-15)
|
||
|
||
- 初始版本发布
|
||
- 完整的药物管理功能
|
||
- 服药记录追踪
|
||
- 统计分析功能
|
||
- 自动状态更新
|
||
- 推送提醒支持
|