Update API endpoints and enhance UI components. Changed appid in manifest.json, modified profile and log update methods from PUT to POST in profile.js and smoke.js, respectively. Added new statistics retrieval function in smoke.js and improved the smoke record dialog with updated styles and validation logic. Updated configuration for development environment and refined documentation for health recovery and savings calculations.

This commit is contained in:
nepiedg
2026-01-26 22:16:20 +08:00
parent 35405efcdf
commit 0d482e3a1c
11 changed files with 1103 additions and 509 deletions
+55 -131
View File
@@ -434,158 +434,82 @@ AI 生成说明:
- `reduced_from_yesterday`:较昨日减少的支数(允许为负数;为负时表示“今天超出昨日”)。
- `exceeded_yesterday`:是否超出昨日(`true` 表示今天超出昨日,前端可用作单独标识)。
## 14) 获取健康与储蓄统计(合并接口
## 14) 数据统计分析(趋势 + 健康 + 省钱
`GET /api/v1/smoke/health_savings?period=week&start=2026-01-01&end=2026-01-07`
说明:
- 合并了"肺部功能恢复"和"节省金额"两个指标,专用于统计页面展示。
- 支持按周/月/年查询,通过 `period` 参数指定时间范围类型。
`GET /api/v1/smoke/stats?range=week|month|year&date=2026-01-07`
参数:
- `period`(必填):时间范围类型,可选值:
- `week`:周(默认本周一至本周日)
- `month`:月(默认本月1日至本月最后一日)
- `year`:年(默认本年1月1日至本年12月31日)
- `start`(可选):起始日期(格式 `YYYY-MM-DD`),不传则根据 `period` 自动计算
- `end`(可选):截止日期(格式 `YYYY-MM-DD`),不传则根据 `period` 自动计算
- `range``week|month|year`,默认 `week`
- `date`:锚点日期(`YYYY-MM-DD`),默认今天
**计算逻辑**
1. **肺部功能恢复百分比**
- 基于用户最后一次实际抽烟时间(忽略 `level=0 && num=0` 的忍住记录)
- 计算无烟时长(分钟)
- 根据医学研究恢复时间线计算恢复百分比(详见 `docs/ALGORITHM.md`
- 公式:
```
无烟天数 = (当前时间 - 最后抽烟时间) / (24 * 60) 分钟
恢复百分比计算:
- < 14天: (天数 / 14) * 15%
- 14-30天: 15% + ((天数 - 14) / 16) * 15%
- 30-90天: 30% + ((天数 - 30) / 60) * 20%
- > 90天: 50% + ((天数 - 90) / 275) * 50%,最高 100%
```
2. **节省金额**
- 基于用户在统计周期内的实际抽烟量与基线对比
- 计算公式:
```
预期总支数 = baseline_cigs_per_day * 周期天数
实际总支数 = 周期内所有记录的 num 累加(排除 level=0 && num=0
节省支数 = 预期总支数 - 实际总支数
节省包数 = 节省支数 / 20(假设每包20支)
节省金额(分)= 节省包数 * pack_price_cent
```
- 若实际总支数 > 预期总支数,则节省金额为 0(不显示负数)
3. **目标金额**
- 默认目标:`baseline_cigs_per_day * 周期天数 / 20 * pack_price_cent`(即完全戒烟节省的金额)
- 或使用用户设定的目标金额(如有)
成功响应示例:
说明
- 用于“统计页”一屏数据整合(趋势、均值、环比、健康恢复、省钱、连续记录、已拒绝次数)。
- `trend_unit``day``month`,用于前端图表横轴显示。
成功响应(示例):
```json
{
"code": 200,
"message": "success",
"data": {
"period": "week",
"range": "week",
"start": "2026-01-01",
"end": "2026-01-07",
"days": 7,
"health": {
"lung_recovery_percent": 40.5,
"smoke_free_minutes": 11520,
"smoke_free_days": 8,
"last_smoke_at": "2025-12-24T14:30:00+08:00",
"recovery_stage": "early", // early(0-14天) / mid(14-30天) / late(30-90天) / advanced(>90天)
"next_milestone": {
"days_until": 6,
"milestone": "2周 - 肺功能提升15%",
"percent_at_milestone": 15
}
},
"savings": {
"saved_amount_cent": 14500, // 已节省金额(分)
"saved_amount_yuan": 145.00, // 已节省金额(元,前端展示用)
"target_amount_cent": 20000, // 目标金额(分)
"target_amount_yuan": 200.00, // 目标金额(元)
"saved_cigs": 58, // 节省支数
"expected_cigs": 140, // 预期总支数
"actual_cigs": 82, // 实际总支数
"progress_percent": 72.5, // 完成进度百分比
"pack_price_cent": 2500, // 单包价格(分)
"cigs_per_pack": 20 // 每包支数
},
"profile": {
"baseline_cigs_per_day": 20,
"trend_unit": "day",
"trend": [
{ "label": "2026-01-01", "count": 2 },
{ "label": "2026-01-02", "count": 1 },
{ "label": "2026-01-03", "count": 0 },
{ "label": "2026-01-04", "count": 0 },
{ "label": "2026-01-05", "count": 3 },
{ "label": "2026-01-06", "count": 0 },
{ "label": "2026-01-07", "count": 0 }
],
"daily_average": 4,
"change_percent": -20,
"money": {
"available": true,
"pack_price_cent": 2500,
"smoking_years": 8
"cigs_per_pack": 20,
"expected_total": 140,
"actual_total": 92,
"saved_cent": 6000
},
"calculated_at": "2026-01-08T10:00:00+08:00"
"health": {
"available": true,
"smoke_free_minutes": 420,
"lung_recovery_percent": 12,
"milestones": [
{ "name": "心率血压恢复正常", "minutes": 20, "reached": true },
{ "name": "血氧水平恢复", "minutes": 480, "reached": false }
]
},
"streak_days": 12,
"resisted_total": 24
}
}
```
字段说明:
- `change_percent`:与上一个同周期对比的变化比例(可为负)。
- `money.available=false`:表示缺少 `baseline_cigs_per_day``pack_price_cent`
- `health.available=false`:表示无历史记录。
**health(健康数据)**
- `lung_recovery_percent`:肺部功能恢复百分比(0-100
- `smoke_free_minutes`:无烟时长(分钟)
- `smoke_free_days`:无烟天数(保留1位小数)
- `last_smoke_at`:最后一次实际抽烟时间(RFC3339格式)
- `recovery_stage`:恢复阶段标识
- `next_milestone`:下一个里程碑信息
## 15) 激励语(后端统一生成)
**savings(储蓄数据)**
- `saved_amount_cent`:已节省金额(分,用于计算)
- `saved_amount_yuan`:已节省金额(元,用于前端展示)
- `target_amount_cent`:目标金额(分)
- `target_amount_yuan`:目标金额(元)
- `saved_cigs`:节省的支数
- `expected_cigs`:预期总支数(基线 × 天数)
- `actual_cigs`:实际总支数
- `progress_percent`:完成进度百分比(saved_amount / target_amount * 100
- `pack_price_cent`:单包价格(分)
- `cigs_per_pack`:每包支数(默认20
`GET /api/v1/smoke/motivation`
**period 参数说明**
说明
- 基于当日数据(如 `today_count``resisted_count``last_smoke_at`)与 `quit_motivations` 生成一句激励语。
- `period=week`(周):
- 默认:本周一 00:00:00 至 本周日 23:59:59
- 若传 `start`,则 `end = start + 6 天`
- `period=month`(月):
- 默认:本月1日 00:00:00 至 本月最后一日 23:59:59
- 若传 `start`,则 `end = start 所在月的最后一日`
- `period=year`(年):
- 默认:本年1月1日 00:00:00 至 本年12月31日 23:59:59
- 若传 `start`,则 `end = start 所在年的12月31日`
curl 示例:
```bash
# 查询本周数据
curl -X GET 'http://127.0.0.1:8080/api/v1/smoke/health_savings?period=week' \
-H 'Authorization: Bearer wx-session-key'
# 查询本月数据
curl -X GET 'http://127.0.0.1:8080/api/v1/smoke/health_savings?period=month' \
-H 'Authorization: Bearer wx-session-key'
# 查询本年数据
curl -X GET 'http://127.0.0.1:8080/api/v1/smoke/health_savings?period=year' \
-H 'Authorization: Bearer wx-session-key'
# 查询指定日期范围
curl -X GET 'http://127.0.0.1:8080/api/v1/smoke/health_savings?period=week&start=2026-01-01&end=2026-01-07' \
-H 'Authorization: Bearer wx-session-key'
成功响应(示例):
```json
{
"code": 200,
"message": "success",
"data": {
"message": "今天的表现很稳,继续保持!记住你的目标:身体健康。",
"type": "encourage"
}
}
```
**注意事项**
1. 若用户尚未补全 `profile`(缺少 `baseline_cigs_per_day` 或 `pack_price_cent`),相关计算字段可能为 0 或使用默认值
2. 若用户从未抽烟(无历史记录),`last_smoke_at` 可能不存在,肺部恢复百分比按最大恢复计算
3. 节省金额计算时,若实际支数 > 预期支数,`saved_amount_cent` 为 0(不显示负数)
4. 时间范围计算时,使用用户所在时区(后端需根据用户配置或默认使用 UTC+8)