refactor: migrate to Tencent Cloud backend

这个提交包含在:
Guoguo
2026-04-28 22:56:47 +08:00
父节点 267c75718b
当前提交 444c91c0b0
修改 102 个文件,包含 17927 行新增1997 行删除
+25
查看文件
@@ -0,0 +1,25 @@
# Hox 文档目录
本目录集中存放项目说明、设计文档、协议资料、计划清单和原型文件,根目录只保留代码目录与仓库级配置。
## 目录结构
| 目录 | 内容 |
| --- | --- |
| `requirements/` | 产品说明、系统说明等需求来源文档 |
| `design/` | 业务流程、接口、数据库、后台、安全、测试等设计文档 |
| `protocols/` | BLE、云端通信、IoT/MQTT 等协议文档 |
| `planning/` | 开发计划、进度交接、待确认事项、缺口清单 |
| `reviews/` | 代码与文档对比、评审和分析材料 |
| `prototypes/` | 小程序和管理后台原型文件 |
| `reference/` | 原始资料包、UI 导出页、截图等参考材料 |
## 当前入口
- `requirements/软件系统说明.docx`
- `requirements/光子美容仪软件系统说明.docx`
- `design/01-BLE通信协议明细.md`
- `design/02-小程序业务流程与状态机.md`
- `planning/PROGRESS.md`
- `planning/需求缺口清单.md`
- `reviews/代码与设计文档对比分析.md`
+185
查看文件
@@ -0,0 +1,185 @@
# 腾讯云部署说明
本文档记录当前后端部署到腾讯云函数 SCF,并连接腾讯云数据库 MySQL 与 COS 的最小流程。
## 1. 数据库初始化
先确认 `server/.env` 或部署环境变量中已配置数据库:
```env
DB_HOST=
DB_PORT=3306
DB_USER=root
DB_PASSWORD=
DB_NAME=jw_beauty
```
本地直连公网数据库时,需要在腾讯云数据库的安全组/白名单中放行本机公网 IP。若本地无法直连,也可以临时通过支持 SOCKS5 的代理建立本地 TCP 隧道,再覆盖 `DB_HOST``DB_PORT` 执行初始化。
```bash
cd server
npm install
npm run db:init
```
初始化会创建业务表,并写入临时后台账号。生产环境首次登录后应立即更换默认密码。
## 2. SCF 函数配置
当前函数 `jw-beauty-api` 是腾讯云 HTTP 函数。HTTP 函数部署包根目录需要包含可执行的 `scf_bootstrap`,由它启动 HTTP 服务。
本项目的 HTTP 函数启动文件:
```text
scf_bootstrap
```
`scf_bootstrap` 会执行:
```bash
node scripts/local-server.js
```
HTTP 服务监听端口使用环境变量 `PORT`,建议配置为 `9000`
如果以后改为普通事件函数,入口才使用:
```text
index.main_handler
```
触发器:
```text
HTTP 触发器或函数 URL
```
触发器需要透传:
```text
method
path
headers
queryStringParameters
body
```
## 3. 环境变量
参考模板:
```text
server/.env.production.example
```
生产必须配置:
```env
NODE_ENV=production
TENCENT_SECRET_ID=
TENCENT_SECRET_KEY=
TENCENT_REGION=ap-guangzhou
DB_HOST=
DB_PORT=3306
DB_USER=
DB_PASSWORD=
DB_NAME=jw_beauty
COS_BUCKET=jw-bucket-1426323813
COS_REGION=ap-guangzhou
WECHAT_APPID=
WECHAT_SECRET=
JWT_SECRET=
ADMIN_JWT_SECRET=
ADMIN_USERNAME=admin
ADMIN_PASSWORD=
```
不要提交真实 `.env`、密钥、数据库密码或微信密钥。
## 4. 数据库网络
SCF 与腾讯云数据库建议使用同地域、同 VPC 内网连接。
如果使用公网地址,需要确认:
- 数据库已开启公网访问。
- 安全组允许 SCF 出口或本机出口访问数据库端口。
- `DB_PORT` 与控制台展示端口一致。
## 5. COS 固件
固件文件先上传到 COS,然后在后台登记对象 key。
相关接口:
```http
GET /api/v1/admin/firmware
POST /api/v1/admin/firmware
POST /api/v1/admin/firmware/:firmware_id/status
GET /api/v1/firmware/latest
```
小程序调用 `GET /api/v1/firmware/latest` 时,后端会返回短期有效的 COS 签名下载 URL。
## 6. 前端 API 地址
SCF HTTP 地址确认后,更新:
```text
miniprogram/config/env.js
admin-console/src/config/env.js
```
`test``prod` 改为腾讯云函数 HTTPS 地址。
微信小程序正式联调还需要在微信公众平台配置 `request 合法域名`
## 7. 管理后台 H5 部署到 COS
管理后台构建产物位于:
```text
admin-console/dist/build/h5
```
先确认 `admin-console/src/config/env.js` 已指向测试或生产 API,再执行:
```bash
cd admin-console
npm install
npm run build:h5
```
如需直接上传到 COS,可复用 `server/.env` 中的 COS 凭证:
```bash
cd admin-console
npm run deploy:cos
```
默认上传前缀:
```text
admin/
```
可通过环境变量覆盖:
```bash
ADMIN_COS_PREFIX=admin-test/ npm run deploy:cos
```
## 8. 部署后验证
建议按顺序验证:
```http
GET /health
POST /api/v1/admin/login
GET /api/v1/admin/dashboard
POST /api/v1/admin/devices
GET /api/v1/admin/devices
GET /api/v1/admin/firmware
```
再进入小程序验证:登录、扫码绑定、BLE 连接、绑定确认、普通模式护理、护理记录同步。
+196
查看文件
@@ -0,0 +1,196 @@
# BLE 通信协议明细
基于 `软件系统说明.docx` 整理。本文档用于把 BLE 通信协议推进到"可联调设计"层,把帧结构、服务、命令表和时序骨架补到足够继续细化的程度。
本文档仍然遵循一个原则:不虚构未被产品说明证实的命令字、UUID 或 payload 值。以下内容中,凡是来源仅为"推导"而非"文档原文确认"的,会标明"待确认"。
## 已确认事实
- 通信方式:`BLE 5.0 GATT`
- 协议帧格式:帧头 `0xAA 0x55`,随后是长度、类型、数据、XOR 校验
- 已知服务 UUID
- `FFE0`:设备信息服务
- `FFE1`:数据通信服务
- `FFE2`OTA 升级服务
- 业务流程中至少存在以下设备交互阶段:连接设备、确认佩戴、自动扫描、开始治疗
## 帧结构草案
### 帧总体格式
| 字段 | 偏移 | 长度 | 值域 | 来源 | 说明 |
| --- | --- | --- | --- | --- | --- |
| `header` | 0 | 2 字节 | `0xAA 0x55` | 文档确认 | 帧头标识 |
| `length` | 2 | 1 字节 | 待确认 | 文档确认存在,定义待补 | 数据长度 |
| `type` | 3 | 1 字节 | 待确认 | 文档确认存在,枚举待补 | 命令/数据/事件类型 |
| `payload` | 4 | N 字节 | 待确认 | 文档确认存在 | 业务载荷 |
| `checksum` | 4+N | 1 字节 | 待确认 | 文档确认为 XOR | 校验 |
### 必须补齐的帧定义
| 项目 | 当前状态 | 阻塞影响 |
| --- | --- | --- |
| `length` 是否包含 `type``checksum` | 未定义 | 无法正确解析帧 |
| `checksum` XOR 计算范围 | 未定义 | 无法正确校验帧 |
| 多字节字段字节序 | 未定义 | 数值解析错误 |
| 字符串编码方式 | 未定义 | 文本解析错误 |
| 最大 payload 长度 | 未定义 | 分包策略无法设计 |
| MTU 约束 | 未定义 | 传输效率与可靠性 |
### 建议帧计算规则(待确认)
以下为建议方案,非最终定义:
- `length`:建议仅表示 `payload` 的字节长度
- `checksum`:建议对 `length``type``payload` 所有字节做 XOR 运算
- 字节序:建议统一大端序(`Big-Endian`
- 字符串:建议统一 `UTF-8`
## 服务与 characteristic 草案
### `FFE0` 设备信息服务
职责:提供设备基础信息。
建议 characteristic 划分(待确认):
| 建议名称 | 建议属性 | 说明 |
| --- | --- | --- |
| `device_info` | `read` | 读取设备型号、固件版本、硬件版本、序列号 |
| `battery_level` | `read` / `notify` | 电量信息 |
UUID 值:待确认
### `FFE1` 数据通信服务
职责:承担主要业务通信。
建议 characteristic 划分(待确认):
| 建议名称 | 建议属性 | 说明 |
| --- | --- | --- |
| `write_cmd` | `write` / `writeWithoutResponse` | 小程序向设备发送命令 |
| `notify_data` | `notify` | 设备向小程序上报数据和事件 |
UUID 值:待确认
### `FFE2` OTA 升级服务
职责:固件升级传输。
建议 characteristic 划分(待确认):
| 建议名称 | 建议属性 | 说明 |
| --- | --- | --- |
| `ota_control` | `write` / `notify` | OTA 控制命令和状态通知 |
| `ota_data` | `writeWithoutResponse` | 升级包分片传输 |
UUID 值:待确认
## 命令表草案
以下命令基于业务流程推导,所有 `type` 值和 `payload` 结构都是待确认的占位。
### 设备信息类
| 建议命令名 | 建议方向 | 建议功能 | type 占位 | payload 请求 | payload 响应 | 待确认 |
| --- | --- | --- | --- | --- | --- | --- |
| `GET_DEVICE_INFO` | 小程序 -> 设备 | 读取设备型号、固件版本、序列号 | `0x??` | 空 | 设备信息结构体 | 是 |
| `GET_BATTERY` | 小程序 -> 设备 | 读取设备电量 | `0x??` | 空 | 电量值 | 是 |
| `GET_DEVICE_STATUS` | 小程序 -> 设备 | 读取设备当前状态 | `0x??` | 空 | 状态码 | 是 |
### 治疗流程类
| 建议命令名 | 建议方向 | 建议功能 | type 占位 | payload 请求 | payload 响应 | 待确认 |
| --- | --- | --- | --- | --- | --- | --- |
| `START_WEARING_CHECK` | 小程序 -> 设备 | 启动佩戴确认 | `0x??` | 空 | 佩戴检测结果 | 是 |
| `WEARING_CHECK_RESULT` | 设备 -> 小程序 | 上报佩戴确认结果 | `0x??` | 无(通知) | 佩戴状态 | 是 |
| `START_AUTO_SCAN` | 小程序 -> 设备 | 启动自动扫描 | `0x??` | 空 | 扫描结果 | 是 |
| `AUTO_SCAN_RESULT` | 设备 -> 小程序 | 上报自动扫描结果 | `0x??` | 无(通知) | 扫描数据 | 是 |
| `START_TREATMENT` | 小程序 -> 设备 | 开始治疗 | `0x??` | 治疗参数(待确认) | 确认/拒绝 | 是 |
| `PAUSE_TREATMENT` | 小程序 -> 设备 | 暂停治疗 | `0x??` | 空 | 确认 | 是 |
| `RESUME_TREATMENT` | 小程序 -> 设备 | 恢复治疗 | `0x??` | 空 | 确认 | 是 |
| `STOP_TREATMENT` | 小程序 -> 设备 | 结束治疗 | `0x??` | 空 | 治疗摘要 | 是 |
| `TREATMENT_PROGRESS` | 设备 -> 小程序 | 上报治疗进度 | `0x??` | 无(通知) | 进度数据 | 是 |
| `TREATMENT_ERROR` | 设备 -> 小程序 | 上报治疗异常 | `0x??` | 无(通知) | 错误码 | 是 |
### OTA 类
| 建议命令名 | 建议方向 | 建议功能 | type 占位 | payload 请求 | payload 响应 | 待确认 |
| --- | --- | --- | --- | --- | --- | --- |
| `OTA_START` | 小程序 -> 设备 | 启动 OTA | `0x??` | 固件版本、总大小 | 确认/拒绝 | 是 |
| `OTA_CHUNK` | 小程序 -> 设备 | 传输分片 | `0x??` | 分片序号、分片数据 | 确认 | 是 |
| `OTA_VERIFY` | 小程序 -> 设备 | 校验完整固件 | `0x??` | 校验值 | 校验结果 | 是 |
| `OTA_APPLY` | 小程序 -> 设备 | 应用新固件 | `0x??` | 空 | 结果 | 是 |
| `OTA_PROGRESS` | 设备 -> 小程序 | 上报 OTA 进度 | `0x??` | 无(通知) | 进度百分比 | 是 |
## 会话时序草案
### 连接后初始化时序(建议)
以下为建议流程,非最终定义:
1. 小程序扫描并连接设备 GATT
2. 发现 `FFE0``FFE1``FFE2` 服务
3. 订阅 `FFE1``notify_data` 通知
4. 读取 `FFE0``device_info` 获取设备基本信息
5. 根据业务需要发送后续命令
### 治疗主流程时序(建议)
1. 发送 `START_WEARING_CHECK`
2. 等待 `WEARING_CHECK_RESULT` 通知
3. 佩戴确认通过后发送 `START_AUTO_SCAN`
4. 等待 `AUTO_SCAN_RESULT` 通知
5. 扫描完成后发送 `START_TREATMENT`
6. 接收 `TREATMENT_PROGRESS` 周期通知
7. 治疗完成或用户主动停止后发送 `STOP_TREATMENT`
### 异常处理时序(建议)
- 命令超时:建议 3-5 秒未收到响应则重试,最多重试 3 次
- 断连重连:建议重连后重新订阅 notify 并查询设备当前状态
- 治疗中断:建议重连后查询是否需要恢复上次治疗会话
## ACK/NACK 机制建议
建议每个命令都存在对应的 ACK 或 NACK 响应(待确认):
| 响应类型 | 含义 |
| --- | --- |
| ACK | 命令已接收并执行成功 |
| NACK | 命令接收失败或执行失败,附带错误码 |
建议错误码表(待确认):
| 建议范围 | 含义 |
| --- | --- |
| `0x00` | 成功 |
| `0x01` - `0x0F` | 通用错误 |
| `0x10` - `0x1F` | 参数错误 |
| `0x20` - `0x2F` | 设备状态错误 |
| `0x30` - `0x3F` | 治疗相关错误 |
| `0x40` - `0x4F` | OTA 相关错误 |
## 分包与粘包建议
当前文档未定义,以下为建议方案(待确认):
- 建议每个 BLE 写入操作对应一个完整帧
- 若 payload 超过 MTU 限制,建议在应用层定义分包协议
- 每个分包建议携带:帧序号、是否最后一包的标记
- 接收端建议按序号拼装,收到最后一包后校验完整性
## 待确认问题
- 设备绑定是否依赖 BLE 返回的设备唯一标识,还是依赖扫码
- "确认佩戴"由什么传感器或状态判断,是自动还是手动
- "自动扫描"具体扫描什么数据
- 治疗模式、档位、时长是否由小程序下发
- 治疗记录是否由小程序组装后上传,还是由设备通过 MQTT 直接上报云端
- OTA 是否通过小程序中转升级包
- 是否需要设备端主动发起的连接认证或握手
## 当前结论
当前说明已经足够把 BLE 协议推进到"命令表草案"层。所有标为"待确认"的命令字、payload 和 UUID 都需要在下一步被确认或修正。最优先要补齐的是 `FFE1` 下的 characteristic UUID、命令字分配、ACK/NACK 机制和帧计算规则。
@@ -0,0 +1,209 @@
# 小程序业务流程与状态机
基于 `软件系统说明.docx` 整理。本文档用于把现有流程描述收敛成可继续细化的页面与状态框架,不补充未经确认的产品规则。
## 已确认范围
### 技术边界
- 小程序技术栈:微信原生 `WXML / WXSS / JS`
- 与设备通过 `BLE 5.0 GATT` 通信
- 与云端通过 `HTTPS/MQTT` 通信
### 页面范围
- 首页:设备连接、治疗开始
- 护理历史:记录和统计
- 发现:美容百科、公告
- 我的:用户中心、订阅管理
### 已确认流程
首次使用:
1. 扫码
2. 蓝牙授权
3. 设备绑定
4. 获得 7 天试用
5. 确认佩戴
6. 自动扫描
7. 开始治疗
日常使用:
1. 打开小程序
2. 连接设备
3. 确认佩戴
4. 自动扫描
5. 开始治疗
## 建议页面职责
### 首页
承载主链路:
- 设备连接状态展示
- 设备连接入口
- 佩戴确认结果
- 自动扫描结果或状态
- 开始治疗入口
- 治疗中状态展示
### 护理历史
承载治疗结果查询:
- 历史记录列表
- 单次治疗摘要
- 与云端同步状态
### 发现
承载弱业务内容:
- 美容百科
- 公告
### 我的
承载账号与订阅信息:
- 用户信息
- 设备绑定信息
- 订阅状态
- 试用状态
## 建议最小状态机
以下状态用于支撑第一阶段开发,不代表最终产品态。
| 状态 | 含义 | 是否由文档直接确认 |
| --- | --- | --- |
| `UNAUTHORIZED_BLE` | 未完成蓝牙授权 | 是 |
| `DISCONNECTED` | 未连接设备 | 是 |
| `CONNECTED_UNBOUND` | 已连接但未绑定 | 间接确认 |
| `BOUND_IDLE` | 已绑定,待治疗 | 间接确认 |
| `WEARING_CHECK` | 佩戴确认中 | 是 |
| `AUTO_SCAN` | 自动扫描中 | 是 |
| `READY_TO_TREAT` | 可开始治疗 | 间接确认 |
| `TREATING` | 治疗中 | 是 |
| `SYNC_PENDING` | 治疗完成待同步 | 间接确认 |
| `SYNC_FAILED` | 记录同步失败 | 间接确认 |
## 首次使用流程拆解
### 1. 扫码
已知:首次使用从扫码开始。
待确认:
- 扫码内容是设备 SN、激活码、绑定码还是 URL
- 扫码失败后的兜底方式
### 2. 蓝牙授权
已知:首次使用要求蓝牙授权。
待确认:
- 是否还需要定位权限
- 拒绝授权后的引导方式
### 3. 设备绑定
已知:首次使用需要绑定设备。
待确认:
- 绑定前是否必须先 BLE 连接成功
- 绑定成功由本地判断还是服务端返回
- 一人多设备/一设备多用户规则
### 4. 获得 7 天试用
已知:首次使用绑定后获得 7 天试用。
待确认:
- 试用按用户发还是按设备发
- 是否有领取次数限制
- 试用到期后的处理
### 5. 确认佩戴
已知:治疗前要确认佩戴。
待确认:
- 由设备自动判断还是用户手动确认
- 失败时的提示和重试机制
### 6. 自动扫描
已知:佩戴确认后进入自动扫描。
待确认:
- 自动扫描的业务含义
- 扫描结果是否决定治疗参数
### 7. 开始治疗
已知:自动扫描后可以开始治疗。
待确认:
- 是否允许用户手动调节模式、时长、档位
- 是否需要先校验订阅状态
## 日常使用流程拆解
日常使用与首次流程的区别在于不再强调扫码、绑定和试用发放,因此可视为:
1. 恢复登录态
2. 连接已绑定设备
3. 佩戴确认
4. 自动扫描
5. 开始治疗
6. 记录同步
## 异常流清单
以下异常流文档尚未定义,但开发前必须明确:
- 蓝牙授权被拒绝
- 扫描不到设备
- 设备连接中断
- 设备已被他人绑定
- 试用已到期
- 订阅无效
- 佩戴确认失败
- 自动扫描失败
- 治疗中断
- 记录同步失败
## 页面与状态的最低接口需求
为了让小程序能继续设计,云端和 BLE 至少需要提供这些能力:
- 查询当前用户信息
- 查询当前绑定设备
- 绑定/解绑设备
- 查询订阅状态
- 同步治疗记录
- BLE 读取设备状态
- BLE 执行佩戴确认、自动扫描、开始治疗
## 待确认问题
- 小程序是否直接使用 MQTT
- 首页是否需要展示实时传感器数据
- 护理历史中的“统计”是本地统计还是云端聚合统计
- 发现页内容是否来自 CMS 或静态配置
- 我的页面是否包含售后、反馈、设置等附加入口
## 当前结论
当前说明已经给出主流程,但还没有给出完整状态机、异常流和页面交互规则。后续应优先把首页主链路和绑定/订阅规则细化清楚。
+394
查看文件
@@ -0,0 +1,394 @@
# 云函数 API 接口清单
基于 `软件系统说明.docx` 整理。本文档用于把已知云函数职责推进到“接口草案”层,便于后续继续拆成真实路由和字段定义。
本文档仍然遵循一个原则:不把文档未确认的 URL、字段值、错误码和业务规则写成既定事实。以下内容中的“建议”是为了便于继续设计,不代表已定方案。
## 已确认云端职责
文档已确认云函数负责:
- 用户认证(微信登录)
- 设备绑定/解绑
- 订阅管理
- 护理记录同步
- 设备注册(动态获取 `DeviceSecret`
- 试用订阅管理
- 数据统计
## 设计目标
当前阶段,这份接口文档的目标不是给出最终 API,而是统一以下边界:
- 哪些接口是一定需要的
- 每类接口由谁调用
- 每类接口最少要交换哪些信息
- 每类接口执行时会影响哪些业务对象
## 调用方划分
当前系统至少存在四类调用方:
- 小程序
- 管理后台
- 设备或设备接入链路
- 云内部任务或异步处理链路
## 建议接口分组
### 1. 认证接口
至少需要:
- 微信登录
- Token 校验或续期
- 当前用户信息查询
### 2. 设备接口
至少需要:
- 设备绑定
- 设备解绑
- 当前绑定设备查询
- 设备详情查询
### 3. 订阅接口
至少需要:
- 当前订阅状态查询
- 试用订阅发放
- 订阅列表查询
- 订阅创建或续期
### 4. 护理记录接口
至少需要:
- 护理记录上传
- 护理记录列表查询
- 单条护理记录详情查询
### 5. 设备注册与 IoT 接口
至少需要:
- 设备注册
- `DeviceSecret` 下发
- 设备状态同步或查询
### 6. 统计接口
至少需要:
- 用户统计
- 设备统计
- 治疗统计
- 订阅统计
## 接口命名草案
下表中的“接口标识”仅用于当前设计阶段统一讨论,不代表最终路由。
| 分组 | 接口标识 | 主要调用方 | 文档是否确认需要 | 说明 |
| --- | --- | --- | --- | --- |
| 认证 | `auth.wx_login` | 小程序 | 是 | 微信登录换取系统身份 |
| 认证 | `auth.refresh_token` | 小程序 | 间接确认 | Token 续期 |
| 认证 | `auth.get_profile` | 小程序 | 间接确认 | 获取当前用户基础信息 |
| 设备 | `device.bind` | 小程序 | 是 | 绑定设备 |
| 设备 | `device.unbind` | 小程序 / 后台 | 是 | 解绑设备 |
| 设备 | `device.get_current_binding` | 小程序 | 间接确认 | 查询当前绑定设备 |
| 设备 | `device.get_detail` | 小程序 / 后台 | 间接确认 | 查询设备详情 |
| 订阅 | `subscription.get_current` | 小程序 | 间接确认 | 查询当前订阅状态 |
| 订阅 | `subscription.grant_trial` | 云内部任务 / 小程序链路 | 是 | 发放 7 天试用 |
| 订阅 | `subscription.list` | 后台 | 间接确认 | 查询订阅列表 |
| 订阅 | `subscription.create_or_renew` | 后台 | 是 | 创建或续期订阅 |
| 护理记录 | `record.sync` | 小程序 / 设备链路 | 是 | 同步护理记录 |
| 护理记录 | `record.list` | 小程序 / 后台 | 间接确认 | 查询护理记录列表 |
| 护理记录 | `record.detail` | 小程序 / 后台 | 间接确认 | 查询护理记录详情 |
| IoT | `iot.register_device` | 设备链路 / 云内部任务 | 是 | 注册设备 |
| IoT | `iot.issue_device_secret` | 设备链路 / 云内部任务 | 是 | 下发 `DeviceSecret` |
| IoT | `iot.get_device_status` | 后台 / 云内部任务 | 间接确认 | 查询设备状态 |
| 统计 | `stats.user_overview` | 后台 | 是 | 用户统计 |
| 统计 | `stats.device_overview` | 后台 | 是 | 设备统计 |
| 统计 | `stats.treatment_overview` | 后台 | 是 | 治疗统计 |
| 统计 | `stats.subscription_overview` | 后台 | 是 | 订阅统计 |
## 统一接口契约建议
后续细化每个接口时,建议统一补齐以下字段:
- 接口标识
- 调用方
- 请求方式
- 路由
- 鉴权要求
- 幂等要求
- 请求参数
- 返回结构
- 错误码
- 侧效应
- 依赖数据表
## 建议统一响应包络
当前文档没有确认具体返回格式,但为了后续接口设计一致,建议统一采用一个最小响应包络。
| 字段 | 是否建议保留 | 说明 |
| --- | --- | --- |
| `code` | 是 | 业务结果码 |
| `message` | 是 | 成功或失败说明 |
| `data` | 是 | 业务数据 |
| `request_id` | 建议 | 便于日志追踪 |
## 各接口组的最小信息集合
### 认证接口
#### `auth.wx_login`
最小目标:
- 接收小程序登录凭证
- 识别或创建用户身份
- 返回系统可识别的登录态
至少需要定义:
- 输入凭证类型
- 返回 token 结构
- 是否同时返回用户资料和订阅状态
可能影响的对象:
- `users`
- 登录态或会话存储
#### `auth.refresh_token`
最小目标:
- 延长有效登录态或重新签发 token
至少需要定义:
- 续期条件
- 旧 token 处理方式
- 是否支持滑动过期
### 设备接口
#### `device.bind`
最小目标:
- 建立用户与设备的绑定关系
至少需要定义:
- 设备标识来源
- 是否依赖扫码
- 是否要求设备在线
- 绑定成功后的试用发放关系
可能影响的对象:
- `devices`
- `bindings`
- `subscriptions`
- `operation_logs`
#### `device.unbind`
最小目标:
- 解除当前用户与设备的有效绑定关系
至少需要定义:
- 谁可发起解绑
- 解绑是否影响订阅归属
- 历史绑定如何保留
#### `device.get_current_binding`
最小目标:
- 返回当前用户的绑定设备摘要
至少需要定义:
- 是否允许无绑定返回空对象
- 返回摘要字段范围
### 订阅接口
#### `subscription.get_current`
最小目标:
- 返回当前用户或当前设备的有效订阅状态
至少需要定义:
- 查询口径是按用户还是按设备
- 返回是否包含试用信息
#### `subscription.grant_trial`
最小目标:
- 在满足条件时发放 7 天试用
至少需要定义:
- 触发时机
- 幂等规则
- 发放对象
#### `subscription.create_or_renew`
最小目标:
- 后台创建或续期订阅
至少需要定义:
- 是否存在订单概念
- 生效时间规则
- 是否允许覆盖现有有效期
### 护理记录接口
#### `record.sync`
最小目标:
- 接收一次护理记录并落入后续处理链路
至少需要定义:
- 上传主体
- 请求是完整记录还是过程数据
- 幂等键
- 同步成功与异步入库成功的关系
可能影响的对象:
- `sessions`
- `treatment_records`
- `pd_data`
- `operation_logs`
- `CMQ` 或其他异步链路
#### `record.list`
最小目标:
- 查询治疗记录列表
至少需要定义:
- 小程序和后台是否共用同一查询能力
- 过滤条件
- 排序字段
### IoT 接口
#### `iot.register_device`
最小目标:
- 为设备建立平台侧可识别身份
至少需要定义:
- 调用方
- 调用时机
- 注册成功后的返回值
#### `iot.issue_device_secret`
最小目标:
- 为设备签发或返回 `DeviceSecret`
至少需要定义:
- 签发条件
- 是否只可获取一次
- 返回方式与安全控制
### 统计接口
统计接口当前只确认“后台需要”,最先要补的是统计口径:
- 时间范围
- 去重规则
- 试用与正式订阅是否分开统计
- 设备在线数是否为实时值
## 建议接口字段模板
后续继续细化某个接口时,可直接套用以下模板:
| 项目 | 内容 |
| --- | --- |
| 接口标识 | 待定义 |
| 调用方 | 待定义 |
| 请求方式 | 待定义 |
| 路由 | 待定义 |
| 鉴权要求 | 待定义 |
| 幂等要求 | 待定义 |
| 请求参数 | 待定义 |
| 返回结构 | 待定义 |
| 错误码 | 待定义 |
| 侧效应 | 待定义 |
| 依赖数据表 | 待定义 |
## 最先需要定下来的横切规则
在继续细化具体接口前,建议先统一这几项横切规则:
- 统一响应包络
- 统一错误码风格
- 统一分页结构
- 统一时间字段格式
- 统一幂等键规则
- 统一日志追踪字段,如 `request_id`
## 关键接口待确认问题
### 微信登录
- 小程序提交给云端的是 `code` 还是其他凭证
- 云端返回自有 token 还是复用微信态
- Token 7 天有效期是否支持续期
### 设备绑定
- 绑定是否必须基于扫码
- 绑定时是否校验设备在线状态
- 重复绑定、换绑、解绑是否有限制
### 试用订阅
- 发放时机是否严格绑定在首次绑定成功后
- 试用对象是用户还是设备
- 到期后是否自动降级为不可治疗
### 护理记录同步
- 上传主体是小程序还是设备侧
- 同步是实时提交还是治疗结束后提交
- 异步写入与接口返回成功的关系
### 设备注册
- 调用方是生产工具、设备首次上线,还是小程序触发
- `DeviceSecret` 是否只签发一次
## 当前结论
当前说明已经足够把云函数职责推进到“接口草案”层,但还不能直接生成真实 API。最优先要继续细化的是 `auth.wx_login``device.bind``subscription.get_current``subscription.grant_trial``record.sync` 这五个核心接口。
+288
查看文件
@@ -0,0 +1,288 @@
# 数据库表结构设计
基于 `软件系统说明.docx` 整理。本文档用于把已知数据实体推进到表级字段草案,便于后续直接转成 DDL。
本文档仍然遵循一个原则:不把文档未确认的业务规则写成既定事实。以下字段草案中,凡是来源仅为"推导"而非"文档原文确认"的,会标明"待确认"。所有表名、字段名均为设计阶段讨论名,不代表最终数据库列名。
## 全局设计约定
以下约定建议在所有表统一采用:
- 主键:统一使用自增 `id`,类型 `BIGINT UNSIGNED`,具体方案待确认
- 时间字段:`created_at``updated_at`,类型 `DATETIME`,时区统一为待确认
- 软删:建议统一使用 `deleted_at`,值为 `NULL` 表示未删除,具体策略待确认
- 字符集:建议统一 `utf8mb4`
- 审计:建议所有表至少保留 `created_at``updated_at`
## 已确认逻辑表
- `users`
- `devices`
- `bindings`
- `subscriptions`
- `sessions`
- `treatment_records`
- `pd_data`
- `operation_logs`
## 表级字段草案
### `users`
承载用户身份与账号信息。
| 字段名 | 建议类型 | 是否必填 | 默认值 | 来源 | 说明 |
| --- | --- | --- | --- | --- | --- |
| `id` | `BIGINT UNSIGNED` | 是 | 自增 | 约定 | 主键 |
| `openid` | `VARCHAR(128)` | 是 | 无 | 推导 | 微信用户唯一标识,待确认字段名 |
| `union_id` | `VARCHAR(128)` | 否 | `NULL` | 推导 | 微信开放平台跨应用标识,待确认是否需要 |
| `nickname` | `VARCHAR(64)` | 否 | `NULL` | 推导 | 用户昵称,待确认是否存储 |
| `avatar_url` | `VARCHAR(512)` | 否 | `NULL` | 推导 | 用户头像地址,待确认是否存储 |
| `phone` | `VARCHAR(32)` | 否 | `NULL` | 推导 | 手机号,待确认是否需要 |
| `status` | `TINYINT UNSIGNED` | 是 | `1` | 推导 | 用户状态枚举,待确认 |
| `created_at` | `DATETIME` | 是 | `CURRENT_TIMESTAMP` | 约定 | 创建时间 |
| `updated_at` | `DATETIME` | 是 | `CURRENT_TIMESTAMP ON UPDATE` | 约定 | 更新时间 |
| `deleted_at` | `DATETIME` | 否 | `NULL` | 约定 | 软删时间 |
建议唯一索引:`openid`
建议状态枚举(待确认):
| 值 | 含义 |
| --- | --- |
| `1` | 正常 |
| `2` | 禁用 |
| `3` | 注销 |
### `devices`
承载设备主数据。
| 字段名 | 建议类型 | 是否必填 | 默认值 | 来源 | 说明 |
| --- | --- | --- | --- | --- | --- |
| `id` | `BIGINT UNSIGNED` | 是 | 自增 | 约定 | 主键 |
| `device_sn` | `VARCHAR(64)` | 是 | 无 | 推导 | 设备序列号,作为设备唯一业务标识,待确认字段名和格式 |
| `product_id` | `VARCHAR(64)` | 是 | 无 | 文档确认 | IoT 平台产品 ID |
| `device_name` | `VARCHAR(128)` | 是 | 无 | 文档确认 | IoT 平台设备名称 |
| `firmware_version` | `VARCHAR(32)` | 否 | `NULL` | 推导 | 当前固件版本 |
| `hardware_version` | `VARCHAR(32)` | 否 | `NULL` | 推导 | 硬件版本 |
| `status` | `TINYINT UNSIGNED` | 是 | `1` | 推导 | 设备状态枚举,待确认 |
| `activated_at` | `DATETIME` | 否 | `NULL` | 推导 | 首次激活时间 |
| `created_at` | `DATETIME` | 是 | `CURRENT_TIMESTAMP` | 约定 | 创建时间 |
| `updated_at` | `DATETIME` | 是 | `CURRENT_TIMESTAMP ON UPDATE` | 约定 | 更新时间 |
| `deleted_at` | `DATETIME` | 否 | `NULL` | 约定 | 软删时间 |
建议唯一索引:`device_sn`
建议状态枚举(待确认):
| 值 | 含义 |
| --- | --- |
| `1` | 未激活 |
| `2` | 已激活 |
| `3` | 禁用 |
| `4` | 故障 |
### `bindings`
承载用户与设备的绑定关系。
| 字段名 | 建议类型 | 是否必填 | 默认值 | 来源 | 说明 |
| --- | --- | --- | --- | --- | --- |
| `id` | `BIGINT UNSIGNED` | 是 | 自增 | 约定 | 主键 |
| `user_id` | `BIGINT UNSIGNED` | 是 | 无 | 推导 | 关联 `users.id` |
| `device_id` | `BIGINT UNSIGNED` | 是 | 无 | 推导 | 关联 `devices.id` |
| `status` | `TINYINT UNSIGNED` | 是 | `1` | 推导 | 绑定状态枚举,待确认 |
| `bound_at` | `DATETIME` | 是 | `CURRENT_TIMESTAMP` | 推导 | 绑定时间 |
| `unbound_at` | `DATETIME` | 否 | `NULL` | 推导 | 解绑时间 |
| `created_at` | `DATETIME` | 是 | `CURRENT_TIMESTAMP` | 约定 | 创建时间 |
| `updated_at` | `DATETIME` | 是 | `CURRENT_TIMESTAMP ON UPDATE` | 约定 | 更新时间 |
建议索引:`user_id` + `status``device_id` + `status`
建议状态枚举(待确认):
| 值 | 含义 |
| --- | --- |
| `1` | 有效 |
| `2` | 已解绑 |
待确认关系约束:
- 同一时刻一个用户是否只能绑定一台设备
- 同一时刻一台设备是否只能绑定一个用户
- 解绑后是否保留历史记录
### `subscriptions`
承载试用与正式订阅信息。
| 字段名 | 建议类型 | 是否必填 | 默认值 | 来源 | 说明 |
| --- | --- | --- | --- | --- | --- |
| `id` | `BIGINT UNSIGNED` | 是 | 自增 | 约定 | 主键 |
| `user_id` | `BIGINT UNSIGNED` | 是 | 无 | 推导 | 关联 `users.id`,待确认是否同时关联设备 |
| `device_id` | `BIGINT UNSIGNED` | 否 | `NULL` | 推导 | 关联 `devices.id`,待确认是否需要 |
| `type` | `TINYINT UNSIGNED` | 是 | 无 | 推导 | 订阅类型枚举 |
| `status` | `TINYINT UNSIGNED` | 是 | `1` | 推导 | 订阅状态枚举 |
| `started_at` | `DATETIME` | 是 | 无 | 推导 | 生效时间 |
| `expired_at` | `DATETIME` | 是 | 无 | 推导 | 到期时间 |
| `source` | `VARCHAR(32)` | 否 | `NULL` | 推导 | 来源说明,如 `trial_grant``manual_create``purchase`,待确认 |
| `source_id` | `VARCHAR(64)` | 否 | `NULL` | 推导 | 来源关联 ID,如订单号,待确认是否有订单概念 |
| `created_at` | `DATETIME` | 是 | `CURRENT_TIMESTAMP` | 约定 | 创建时间 |
| `updated_at` | `DATETIME` | 是 | `CURRENT_TIMESTAMP ON UPDATE` | 约定 | 更新时间 |
建议索引:`user_id` + `status``user_id` + `type`
建议类型枚举(待确认):
| 值 | 含义 |
| --- | --- |
| `1` | 试用 |
| `2` | 正式 |
| `3` | 赠送 |
建议状态枚举(待确认):
| 值 | 含义 |
| --- | --- |
| `1` | 有效 |
| `2` | 已过期 |
| `3` | 已停用 |
### `sessions`
承载一次治疗会话的过程态。
| 字段名 | 建议类型 | 是否必填 | 默认值 | 来源 | 说明 |
| --- | --- | --- | --- | --- | --- |
| `id` | `BIGINT UNSIGNED` | 是 | 自增 | 约定 | 主键 |
| `user_id` | `BIGINT UNSIGNED` | 是 | 无 | 推导 | 关联 `users.id` |
| `device_id` | `BIGINT UNSIGNED` | 是 | 无 | 推导 | 关联 `devices.id` |
| `status` | `TINYINT UNSIGNED` | 是 | `1` | 推导 | 会话状态枚举 |
| `started_at` | `DATETIME` | 否 | `NULL` | 推导 | 会话开始时间 |
| `ended_at` | `DATETIME` | 否 | `NULL` | 推导 | 会话结束时间 |
| `created_at` | `DATETIME` | 是 | `CURRENT_TIMESTAMP` | 约定 | 创建时间 |
| `updated_at` | `DATETIME` | 是 | `CURRENT_TIMESTAMP ON UPDATE` | 约定 | 更新时间 |
建议索引:`user_id` + `status``device_id`
建议状态枚举(待确认):
| 值 | 含义 |
| --- | --- |
| `1` | 进行中 |
| `2` | 已完成 |
| `3` | 已中断 |
| `4` | 失败 |
待确认边界:`sessions``treatment_records` 是否一对一。
### `treatment_records`
承载治疗结果记录。
| 字段名 | 建议类型 | 是否必填 | 默认值 | 来源 | 说明 |
| --- | --- | --- | --- | --- | --- |
| `id` | `BIGINT UNSIGNED` | 是 | 自增 | 约定 | 主键 |
| `session_id` | `BIGINT UNSIGNED` | 是 | 无 | 推导 | 关联 `sessions.id`,待确认一对一还是一对多 |
| `user_id` | `BIGINT UNSIGNED` | 是 | 无 | 推导 | 关联 `users.id`,冗余查询用 |
| `device_id` | `BIGINT UNSIGNED` | 是 | 无 | 推导 | 关联 `devices.id`,冗余查询用 |
| `duration_seconds` | `INT UNSIGNED` | 否 | `NULL` | 推导 | 治疗时长秒数,待确认字段名和单位 |
| `mode` | `TINYINT UNSIGNED` | 否 | `NULL` | 推导 | 治疗模式,待确认枚举 |
| `result_summary` | `VARCHAR(512)` | 否 | `NULL` | 推导 | 结果摘要,待确认格式 |
| `sync_status` | `TINYINT UNSIGNED` | 是 | `1` | 推导 | 同步状态,用于追踪异步写入 |
| `synced_at` | `DATETIME` | 否 | `NULL` | 推导 | 同步完成时间 |
| `started_at` | `DATETIME` | 否 | `NULL` | 推导 | 治疗开始时间 |
| `ended_at` | `DATETIME` | 否 | `NULL` | 推导 | 治疗结束时间 |
| `created_at` | `DATETIME` | 是 | `CURRENT_TIMESTAMP` | 约定 | 创建时间 |
| `updated_at` | `DATETIME` | 是 | `CURRENT_TIMESTAMP ON UPDATE` | 约定 | 更新时间 |
建议索引:`user_id` + `started_at``session_id``sync_status`
建议同步状态枚举(待确认):
| 值 | 含义 |
| --- | --- |
| `1` | 待同步 |
| `2` | 已同步 |
| `3` | 同步失败 |
### `pd_data`
承载与 `PD` 相关的数据。
当前只知道该表存在,字段无法推导。
| 字段名 | 建议类型 | 是否必填 | 默认值 | 来源 | 说明 |
| --- | --- | --- | --- | --- | --- |
| `id` | `BIGINT UNSIGNED` | 是 | 自增 | 约定 | 主键 |
| `session_id` | `BIGINT UNSIGNED` | 否 | `NULL` | 推导 | 关联 `sessions.id`,待确认 |
| `device_id` | `BIGINT UNSIGNED` | 否 | `NULL` | 推导 | 关联 `devices.id`,待确认 |
| `data_payload` | 待定义 | 待定义 | 待定义 | 待定义 | 数据内容,格式和结构完全未确认 |
| `recorded_at` | `DATETIME` | 否 | `NULL` | 推导 | 采集时间 |
| `created_at` | `DATETIME` | 是 | `CURRENT_TIMESTAMP` | 约定 | 创建时间 |
待确认:
- `PD` 的含义和数据来源
- 是否为高频时序数据
- 是否需要单独存储引擎
- 是否按会话切片
### `operation_logs`
承载操作日志。
| 字段名 | 建议类型 | 是否必填 | 默认值 | 来源 | 说明 |
| --- | --- | --- | --- | --- | --- |
| `id` | `BIGINT UNSIGNED` | 是 | 自增 | 约定 | 主键 |
| `operator_type` | `TINYINT UNSIGNED` | 是 | 无 | 推导 | 操作者类型,区分管理员和系统 |
| `operator_id` | `BIGINT UNSIGNED` | 否 | `NULL` | 推导 | 操作者 ID,关联 `users` 或后台管理员表 |
| `target_type` | `VARCHAR(32)` | 是 | 无 | 推导 | 操作对象类型,如 `user``device``subscription``binding` |
| `target_id` | `BIGINT UNSIGNED` | 否 | `NULL` | 推导 | 操作对象 ID |
| `action` | `VARCHAR(32)` | 是 | 无 | 推导 | 操作类型,如 `create``update``delete``bind``unbind` |
| `before_snapshot` | `TEXT` | 否 | `NULL` | 推导 | 操作前数据快照,待确认格式 |
| `after_snapshot` | `TEXT` | 否 | `NULL` | 推导 | 操作后数据快照,待确认格式 |
| `ip_address` | `VARCHAR(64)` | 否 | `NULL` | 推导 | 操作来源 IP |
| `user_agent` | `VARCHAR(256)` | 否 | `NULL` | 推导 | 操作来源客户端标识 |
| `remark` | `VARCHAR(256)` | 否 | `NULL` | 推导 | 备注说明 |
| `created_at` | `DATETIME` | 是 | `CURRENT_TIMESTAMP` | 约定 | 创建时间 |
建议索引:`target_type` + `target_id``operator_type` + `operator_id``created_at`
建议操作者类型枚举(待确认):
| 值 | 含义 |
| --- | --- |
| `1` | 管理员 |
| `2` | 系统自动 |
## 实体关系总结
| 关系 | 左侧 | 右侧 | 类型 | 待确认 |
| --- | --- | --- | --- | --- |
| 用户绑定设备 | `users` | `devices` | 通过 `bindings` 多对多 | 是,实际可能接近一对一 |
| 用户拥有订阅 | `users` | `subscriptions` | 一对多 | 否 |
| 设备关联订阅 | `devices` | `subscriptions` | 待确认 | 是,是否需要关联 |
| 用户发起会话 | `users` | `sessions` | 一对多 | 否 |
| 设备执行会话 | `devices` | `sessions` | 一对多 | 否 |
| 会话产生记录 | `sessions` | `treatment_records` | 待确认 | 是,一对一还是一对多 |
| 会话产生 PD 数据 | `sessions` | `pd_data` | 待确认 | 是 |
| 操作日志记录对象 | `operation_logs` | 各业务表 | 多态关联 | 否 |
## 每张表仍需补齐的设计项
后续推进到 DDL 时,每张表至少还需要:
- 确认主键方案
- 确认字段类型和长度
- 确认枚举值
- 确认时区约定
- 确认软删策略
- 补充 DDL
- 补充索引设计
- 补充迁移脚本
## 当前结论
当前说明已经足够把数据库推进到"字段草案"层。所有标为"推导"的字段都需要在下一步被确认或修正。最优先要确认的是 `users``devices` 的绑定约束、`subscriptions` 的归属模型、`sessions``treatment_records` 的关系。
@@ -0,0 +1,156 @@
# IoT 设备注册与 MQTT 消息规范
基于 `软件系统说明.docx` 整理。本文档用于固定当前已知的 IoT 与 MQTT 事实,并列出设备接入、消息定义和云端处理前必须补齐的规格项。
本文档不虚构未被文档确认的 topic、payload 或接入流程。
## 已确认事实
- 设备接入平台:`Tencent Cloud IoT Hub`
- 设备通过 `MQTT over TLS` 连接 IoT Hub
- 已知上报主题:`$iot/{product_id}/{device_name}/telemetry`
- 已知事件主题:`$iot/{product_id}/{device_name}/event`
- 云端业务组件包含:`SCF``MySQL``Redis``CLS``CMQ`
- 护理记录存在异步写入路径
- 云函数职责中包含:设备注册、动态获取 `DeviceSecret`
## 已知接入边界
从当前文档可确认以下边界:
- 设备端不是直接写业务数据库,而是先接入 IoT Hub
- 云端至少存在一条设备消息 -> 云端处理 -> 数据落库的链路
- 设备身份认证依赖 `DeviceSecret`
- 系统同时存在实时设备通信和异步消息处理
## 设备接入流程的最小骨架
当前文档没有给出完整时序,但从已知信息可整理出一条最小流程骨架:
1. 设备具备 `product_id``device_name`
2. 设备获取或持有 `DeviceSecret`
3. 设备通过 `MQTT over TLS` 连接 IoT Hub
4. 设备向指定 topic 上报 telemetry 和 event
5. 云端处理消息并执行日志、异步、入库等后续动作
## 待补齐的设备注册流程
当前最大缺口是 `DeviceSecret` 和设备注册流程,至少需要明确:
- 设备是在生产阶段预注册,还是首次使用时动态注册
- `DeviceSecret` 是一次性签发还是可轮换
- `DeviceSecret` 由谁调用云函数获取:生产工具、设备端、小程序端,还是后台系统
- 设备首次上线是否需要激活
- 设备注册与用户绑定是否是两个独立阶段
- 设备换绑、禁用、报废时如何处理 IoT 身份
## MQTT topic 已知信息
### 遥测主题
- Topic`$iot/{product_id}/{device_name}/telemetry`
- 作用:设备业务数据上报
当前缺失:
- payload 结构
- 上报频率
- 是否包含治疗过程数据
- 是否包含传感器原始数据
### 事件主题
- Topic`$iot/{product_id}/{device_name}/event`
- 作用:设备事件上报
当前缺失:
- 事件类型枚举
- 事件触发条件
- 事件 payload
- 错误事件与普通事件的区分
## 必须补齐的消息规范
### 1. Telemetry 消息
至少需要确认:
- 消息体格式:JSON、二进制或其他格式
- 核心字段
- 时间戳字段
- 设备状态字段
- 治疗相关字段
- 是否包含批量数据
- 是否需要签名或序列号
### 2. Event 消息
至少需要确认:
- 事件类型枚举
- 事件等级
- 事件时间
- 事件附加上下文
- 是否需要重试
### 3. 下行控制消息
当前文档没有明确写出下行 topic,但若系统需要远程控制或同步状态,必须明确:
- 是否存在云端 -> 设备的下发 topic
- 是否存在应答 topic
- 远程指令的触发方:小程序、后台、云端任务
- 指令时效和超时规则
## 消息处理链路待确认
当前只知道使用 `CMQ` 异步处理,至少需要明确:
- IoT Hub 消息如何进入云函数或消息队列
- 哪些消息同步处理,哪些消息异步处理
- 护理记录异步写入的触发条件
- 失败重试策略
- 死信消息处理策略
- 日志打点字段
## 建议补充的消息模板
后续可以按以下模板补齐实际 payload。
### Telemetry 模板
| 字段 | 类型 | 是否必填 | 说明 |
| --- | --- | --- | --- |
| 待定义 | 待定义 | 待定义 | 待定义 |
### Event 模板
| 字段 | 类型 | 是否必填 | 说明 |
| --- | --- | --- | --- |
| 待定义 | 待定义 | 待定义 | 待定义 |
## 设备状态建议先澄清的枚举
后续设计时建议先统一这些状态的定义:
- 未注册
- 已注册未激活
- 已激活未绑定
- 已绑定
- 在线
- 离线
- 禁用
- 故障
## 待确认问题
- `DeviceSecret` 是否通过云函数动态返回给设备
- 小程序在设备注册链路中扮演什么角色
- 设备是否需要主动上报固件版本、硬件版本、电量、错误状态
- `telemetry``event` 的边界如何划分
- 后台是否需要通过云端下发控制指令
## 当前结论
当前说明已足够确定 IoT 接入方式和两个基础 MQTT topic,但远不足以支持设备接入开发。最先要补的是设备注册流程、`DeviceSecret` 生命周期、payload 结构和消息处理链路。
@@ -0,0 +1,172 @@
# 管理后台功能与权限设计
基于 `软件系统说明.docx` 整理。本文档用于把管理后台的已知模块拆成可继续细化的功能和权限骨架。
本文档不虚构页面字段、角色名或权限编码,只保留已知边界和待确认项。
## 已确认事实
- 后台技术栈:`uniapp + Vue 3 + uView Plus`
- 部署方式:腾讯云静态网站托管
- 已确认功能模块:
- 仪表盘
- 设备管理
- 用户管理
- 订阅管理
- 护理记录
- 操作日志
- 系统设置
- 文档明确存在角色权限和 API 级别鉴权
## 模块职责拆解
### 仪表盘
文档已确认包含:
- 用户统计
- 设备统计
- 治疗统计
- 订阅统计
待确认:
- 统计口径
- 统计时间范围
- 是否支持趋势图、排行榜、分布图
- 是否区分实时统计和离线统计
### 设备管理
文档已确认包含:
- 设备列表
- 设备详情
- 设备绑定管理
待确认:
- 列表字段
- 筛选条件
- 是否支持设备禁用、解绑、查看在线状态
- 是否支持远程指令或仅查询
### 用户管理
文档已确认包含:
- 用户列表
- 用户详情
- 订阅管理
- 绑定管理
待确认:
- 用户详情页字段
- 是否支持用户禁用
- 是否支持人工调整订阅状态
### 订阅管理
文档已确认包含:
- 订阅列表
- 创建订阅
- 续期管理
待确认:
- 是否需要退款、停用、赠送功能
- 是否有订单概念
- 是否记录发放来源
### 护理记录
文档已确认包含:
- 治疗记录查询
- 数据导出
待确认:
- 查询维度
- 导出格式
- 是否支持查看原始传感器数据
### 操作日志
文档已确认包含:
- 日志查询
待确认:
- 记录哪些操作
- 是否区分管理员操作和系统操作
- 查询维度和保留时间
### 系统设置
文档已确认包含:
- 管理员管理
- 权限配置
待确认:
- 是否还包含公告管理、字典配置、设备参数配置等系统能力
## 建议最小后台版本
为了支持第一阶段上线,后台最小版本建议先覆盖:
- 用户列表与详情
- 设备列表与详情
- 绑定关系查询
- 订阅列表与续期
- 治疗记录查询
- 操作日志查询
## 权限模型待确认
文档只确认存在“角色权限”和“API 级别鉴权”,至少需要明确:
- 角色有哪些
- 每个角色可访问哪些菜单
- 每个角色可调用哪些接口
- 是否区分只读和可操作权限
- 高风险操作是否需要二次确认
## 建议权限拆分维度
后续可按以下维度细化:
- 菜单权限
- 页面按钮权限
- API 调用权限
- 数据范围权限
## 建议页面规格模板
后续细化每个页面时,至少需要明确:
- 页面名称
- 页面入口
- 访问角色
- 列表字段
- 查询条件
- 可执行操作
- 详情字段
- 导出字段
## 待确认问题
- 后台管理员如何登录
- 是否存在超级管理员
- 是否需要多组织或多租户隔离
- 仪表盘统计口径是否来自实时聚合还是离线任务
- 数据导出是否受角色限制
## 当前结论
当前说明已经能定义后台模块边界,但还不能直接进入页面和接口实现。最先要补的是角色定义、菜单结构、列表字段、操作权限和统计口径。
+112
查看文件
@@ -0,0 +1,112 @@
# 安全与鉴权方案
基于 `软件系统说明.docx` 整理。本文档用于把当前已知安全要求整理成可继续细化的设计骨架。
本文档不虚构签名算法、密钥管理方案或合规要求,只固定已知要求和必须补齐的实现细节。
## 已确认事实
- 全链路传输使用 `TLS 1.2+`
- 设备认证依赖 `DeviceSecret`
- 用户认证为微信登录 + Token
- Token 有效期为 7 天
- 敏感数据需要加密存储
- 需要 API 鉴权
- 需要角色权限控制
- 需要 API 级别鉴权
## 安全边界拆分
当前系统至少存在四类安全边界:
- 小程序用户身份安全
- 设备身份安全
- 云端 API 访问安全
- 后台管理权限安全
## 用户鉴权待补项
至少需要明确:
- 微信登录到自有 token 的完整链路
- Token 格式
- Token 签名算法
- Token 7 天有效期是否支持续期
- Token 失效、登出、吊销机制
- 多端并发登录规则
## 设备鉴权待补项
至少需要明确:
- `DeviceSecret` 的签发时机
- `DeviceSecret` 的保存位置
- `DeviceSecret` 是否可轮换
- 设备被盗用或泄露后的失效机制
- 设备认证失败后的告警与禁用策略
## API 安全待补项
至少需要明确:
- API 鉴权中间件规则
- 接口级权限定义
- 限流策略
- 防重放策略
- 防刷策略
- 请求日志中需要记录的审计字段
## 数据安全待补项
至少需要明确:
- 哪些字段属于敏感数据
- 加密字段范围
- 加密方式
- 脱敏展示规则
- 数据保留周期
- 备份与恢复的安全要求
## 后台权限安全待补项
至少需要明确:
- 管理员认证方式
- 角色权限模型
- 高风险操作的二次确认规则
- 操作日志保留策略
- 是否需要登录告警和异常操作审计
## 建议最先统一的安全对象
为了后续设计不混乱,建议先统一这些对象的定义:
- 用户身份
- 设备身份
- 管理员身份
- 访问 token
- 设备密钥
- 角色
- 权限
## 建议补充的安全设计模板
后续可按以下模板逐项补齐:
| 主题 | 已知要求 | 待确认实现 | 风险 |
| --- | --- | --- | --- |
| 用户登录 | 微信登录 + Token | 待定义 | 待评估 |
| 设备认证 | `DeviceSecret` | 待定义 | 待评估 |
| API 鉴权 | API 级别鉴权 | 待定义 | 待评估 |
| 数据加密 | 敏感数据加密存储 | 待定义 | 待评估 |
## 待确认问题
- 小程序 token 是否只用于云端 API,还是也影响设备绑定授权
- 后台是否与小程序共用用户体系
- 是否需要设备侧应用层签名或加密,而不仅是 TLS
- 是否有合规或审计的特殊要求
## 当前结论
当前说明已经明确安全目标,但没有给出实现方案。最先要补的是 token 生命周期、`DeviceSecret` 生命周期、权限模型和敏感数据定义。
+156
查看文件
@@ -0,0 +1,156 @@
# 测试与验收标准
基于 `软件系统说明.docx` 整理。本文档用于给后续研发和联调提供测试与验收的最小框架。
当前仓库没有源码、测试配置或 CI,因此本文档只定义应覆盖的测试范围和待确认项,不编造执行命令。
## 当前测试目标
基于说明文档,第一阶段测试至少需要覆盖四条主链路:
- 小程序登录与设备绑定
- BLE 连接、佩戴确认、自动扫描、开始治疗
- 云端护理记录同步与查询
- 后台用户、设备、订阅、治疗记录查询
## 建议测试分层
### 1. 设备与 BLE 联调测试
至少应覆盖:
- 扫描设备
- 连接设备
- 读取设备信息
- 佩戴确认
- 自动扫描
- 开始治疗
- 治疗中断与断连重连
- OTA 基础链路
当前缺失:
- 设备模拟方案
- BLE 协议明细
- 测试数据与预期结果
### 2. 云端接口测试
至少应覆盖:
- 微信登录
- 设备绑定/解绑
- 订阅状态查询
- 试用订阅发放
- 护理记录同步
- 治疗记录查询
当前缺失:
- API 契约
- 错误码规范
- 鉴权策略
### 3. IoT 与 MQTT 联调测试
至少应覆盖:
- 设备接入 IoT Hub
- telemetry 上报
- event 上报
- 云端消息处理
- 护理记录异步写入
- 异常重试
当前缺失:
- payload 结构
- 设备注册流程
- 重试与死信规则
### 4. 小程序端到端测试
至少应覆盖:
- 首次使用流程
- 日常使用流程
- 治疗记录同步
- 试用到期后的表现
- 网络异常、蓝牙异常、同步失败等异常流
当前缺失:
- 页面行为定义
- 状态机细节
- 异常流规则
### 5. 后台功能测试
至少应覆盖:
- 用户查询
- 设备查询
- 绑定关系查询
- 订阅管理
- 治疗记录查询
- 操作日志查询
当前缺失:
- 页面字段
- 权限矩阵
- 统计口径
## 建议验收主链路
第一阶段验收建议围绕以下主链路:
1. 新用户扫码并完成设备绑定
2. 绑定后自动获得 7 天试用
3. 小程序成功连接设备并完成佩戴确认
4. 自动扫描成功并开始治疗
5. 治疗完成后记录可在云端查询
6. 管理后台可查询用户、设备、订阅、治疗记录
## 建议异常流验收项
至少需要定义以下异常流是否通过验收:
- 蓝牙授权被拒绝
- 找不到设备
- 设备断连
- 设备已绑定他人
- 订阅失效
- 治疗中断
- 云端同步失败
- IoT 上报失败
## 建议验收模板
后续可按如下模板逐项编写测试用例:
| 用例名称 | 前置条件 | 操作步骤 | 预期结果 | 备注 |
| --- | --- | --- | --- | --- |
| 待定义 | 待定义 | 待定义 | 待定义 | 待定义 |
## 建议先补齐的测试前提
后续执行测试前,至少需要先明确:
- 是否存在设备测试机和模拟器
- 开发、测试、生产环境的联调边界
- 测试账号准备方式
- 测试数据初始化方式
- 日志排查入口
- 故障复现与回归流程
## 待确认问题
- 小程序是否有最低微信版本要求
- 设备联调是否依赖特定手机机型
- 护理记录异步写入的最终一致性验收口径是什么
- 后台导出是否属于第一阶段验收范围
## 当前结论
当前说明已经足够定义测试范围,但还不足以编写可执行测试用例。最先要补的是 BLE 协议、API 契约、状态机和验收口径。
+111
查看文件
@@ -0,0 +1,111 @@
# 待确认决策清单
本清单汇总自所有规格文档中的"待确认问题"和"歧义点",按主题归并去重。
每条标注来源文档和阻塞范围,方便定位和分工。
## 设备与 BLE
| # | 问题 | 来源 | 阻塞 |
| --- | --- | --- | --- |
| D1 | "确认佩戴"由什么传感器或状态判断,是自动还是手动 | 01-BLE | BLE 命令定义、小程序 UI |
| D2 | "自动扫描"具体扫描什么:肤质检测、佩戴检测、设备自检,还是其他 | 01-BLE, 需求缺口 | BLE 命令定义、治疗参数 |
| D3 | 治疗模式、档位、时长是否由小程序下发 | 01-BLE | BLE payload 定义 |
| D4 | 治疗记录由小程序组装上传,还是设备通过 MQTT 直接上报云端 | 01-BLE, 03-API | 护理记录接口、数据库写入链路 |
| D5 | OTA 是否通过小程序中转升级包 | 01-BLE | OTA 命令流程 |
| D6 | 是否需要设备端主动发起的连接认证或握手 | 01-BLE | BLE 连接时序 |
| D7 | 设备绑定是否依赖 BLE 返回的设备唯一标识,还是依赖扫码 | 01-BLE | 绑定流程 |
| D8 | 设备是否需要主动上报固件版本、硬件版本、电量、错误状态 | 05-IoT | telemetry payload 设计 |
## 小程序业务
| # | 问题 | 来源 | 阻塞 |
| --- | --- | --- | --- |
| M1 | 小程序是否直接使用 MQTT,还是仅通过 HTTPS API | 02-小程序, 需求缺口 | 通信架构、离线策略 |
| M2 | 首页是否需要展示实时传感器数据 | 02-小程序 | 首页 UI、BLE 通知频率 |
| M3 | 护理历史中的"统计"是本地统计还是云端聚合 | 02-小程序 | API 设计、前端逻辑 |
| M4 | 发现页内容是否来自 CMS 或静态配置 | 02-小程序 | 后台功能范围 |
| M5 | 我的页面是否包含售后、反馈、设置等附加入口 | 02-小程序 | 页面结构 |
| M6 | 扫码内容是设备 SN、激活码、绑定码还是 URL | 02-小程序 | 绑定流程 |
| M7 | 蓝牙授权是否还需要定位权限 | 02-小程序 | 小程序权限声明 |
| M8 | 一人多设备/一设备多用户规则 | 02-小程序, 04-DB | 数据库关系、绑定逻辑 |
| M9 | 试用按用户发还是按设备发,是否可重复领取 | 02-小程序, 03-API | 订阅模型、试用逻辑 |
| M10 | 试用到期后是否自动降级为不可治疗 | 03-API | 订阅校验逻辑 |
## 云端 API 与鉴权
| # | 问题 | 来源 | 阻塞 |
| --- | --- | --- | --- |
| A1 | 小程序提交给云端的是 `code` 还是其他凭证 | 03-API | 登录接口实现 |
| A2 | 云端返回自有 token 还是复用微信态 | 03-API | 认证架构 |
| A3 | Token 7 天有效期是否支持续期 | 03-API, 07-安全 | Token 生命周期 |
| A4 | 绑定是否必须基于扫码 | 03-API | 绑定接口参数 |
| A5 | 绑定时是否校验设备在线状态 | 03-API | 绑定逻辑 |
| A6 | 重复绑定、换绑、解绑是否有限制 | 03-API | 绑定逻辑 |
| A7 | 试用发放时机是否严格绑定在首次绑定成功后 | 03-API | 试用发放触发条件 |
| A8 | 护理记录同步是实时提交还是治疗结束后提交 | 03-API | 同步策略、UI 交互 |
| A9 | 异步写入与接口返回成功的关系 | 03-API | 前端状态管理 |
| A10 | 小程序 token 是否也影响设备绑定授权 | 07-安全 | 鉴权模型 |
## IoT 与设备注册
| # | 问题 | 来源 | 阻塞 |
| --- | --- | --- | --- |
| I1 | `DeviceSecret` 是否通过云函数动态返回给设备 | 05-IoT | 设备注册流程 |
| I2 | 小程序在设备注册链路中扮演什么角色 | 05-IoT | 注册时序 |
| I3 | 设备注册调用方是生产工具、设备首次上线,还是小程序触发 | 03-API, 05-IoT | 注册接口设计 |
| I4 | `DeviceSecret` 是否只签发一次 | 03-API, 05-IoT | 密钥管理策略 |
| I5 | `telemetry``event` 的边界如何划分 | 05-IoT | MQTT payload 设计 |
| I6 | 后台是否需要通过云端下发控制指令 | 05-IoT | 下行 topic 设计 |
## 管理后台
| # | 问题 | 来源 | 阻塞 |
| --- | --- | --- | --- |
| B1 | 后台管理员如何登录 | 06-后台 | 认证实现 |
| B2 | 是否存在超级管理员 | 06-后台 | 权限模型 |
| B3 | 是否需要多组织或多租户隔离 | 06-后台 | 数据隔离设计 |
| B4 | 仪表盘统计口径是实时聚合还是离线任务 | 06-后台 | 统计接口实现 |
| B5 | 数据导出是否受角色限制 | 06-后台 | 权限细化 |
| B6 | 系统设置是否只管理管理员与权限,还是还包含设备、订阅、公告等 | 06-后台, 需求缺口 | 后台功能范围 |
## 安全
| # | 问题 | 来源 | 阻塞 |
| --- | --- | --- | --- |
| S1 | 后台是否与小程序共用用户体系 | 07-安全 | 用户模型 |
| S2 | 是否需要设备侧应用层签名或加密 | 07-安全 | BLE 协议安全层 |
| S3 | 是否有合规或审计的特殊要求 | 07-安全 | 安全方案范围 |
## 数据库
| # | 问题 | 来源 | 阻塞 |
| --- | --- | --- | --- |
| DB1 | `users``devices` 绑定约束:一对一还是多对多 | 04-DB | bindings 表设计 |
| DB2 | `subscriptions` 归属用户、设备还是同时关联两者 | 04-DB | subscriptions 表设计 |
| DB3 | `sessions``treatment_records` 是一对一还是一对多 | 04-DB | 表关系设计 |
| DB4 | `pd_data` 的含义、数据来源、是否高频时序数据 | 04-DB, 需求缺口 | 存储方案选择 |
## 测试与验收
| # | 问题 | 来源 | 阻塞 |
| --- | --- | --- | --- |
| T1 | 小程序是否有最低微信版本要求 | 08-测试 | 兼容性测试范围 |
| T2 | 设备联调是否依赖特定手机机型 | 08-测试 | 测试设备准备 |
| T3 | 护理记录异步写入的最终一致性验收口径 | 08-测试 | 验收标准 |
| T4 | 后台导出是否属于第一阶段验收范围 | 08-测试 | MVP 范围 |
## 建议对齐优先级
以下问题同时阻塞多个模块,建议最先对齐:
1. **D2** 自动扫描定义 — 阻塞 BLE 命令 + 治疗参数 + 小程序 UI
2. **D4** 治疗记录上传主体 — 阻塞 API + 数据库 + MQTT + 小程序
3. **M1** 小程序是否直接 MQTT — 阻塞整体通信架构
4. **M9** 试用按用户还是按设备 — 阻塞订阅模型 + 数据库 + API
5. **DB4** pd_data 含义 — 阻塞存储方案
6. **I3** 设备注册调用方 — 阻塞注册流程 + API + 密钥管理
7. **A2** token 方案 — 阻塞认证架构
8. **D1** 佩戴确认判断方式 — 阻塞 BLE 命令 + UI
建议按此顺序逐一确认,每确认一项就同步更新对应的规格文档。
+265
查看文件
@@ -0,0 +1,265 @@
# 开发计划
基于全部已有资料整理,包括:
- `软件系统说明.docx`(根目录 + 开发资料目录两份一致)
- `通信协议_小程序与光子美容仪设备.docx` — BLE 协议完整定义
- `通信协议_小程序与腾讯云.docx` — HTTP API、MQTT 主题与消息格式、后台 API
- `小程序UI/` — 14 个页面 HTML 原型
- `管理后台UI/` — 10 个页面 HTML 原型
## 新资料解决了什么
对比之前的 `09-待确认决策清单.md`,以下问题已被新资料明确回答:
| 原待确认项 | 新资料结论 |
| --- | --- |
| D1 佩戴确认判断方式 | 设备自动状态上报(0x21),mode_state 含 SCANNING/ACTIVE 等 |
| D2 自动扫描定义 | 扫描面部(mode_state=0x01 SCANNING),PD 传感器采集各区光功率密度 |
| D3 治疗参数来源 | 小程序下发:区域掩码、波长、亮度、时长、模式(0x01 命令) |
| D4 治疗记录上传主体 | 小程序通过 HTTP API 同步(`POST /api/v1/treatment/sync`),设备通过 MQTT 上报遥测 |
| D6 设备连接认证/握手 | BLE 绑定使用服务器生成的 bind_token,写入 BondInfo characteristic |
| D7 设备绑定标识 | 扫码获取 device_id,后端验证后生成 bind_token |
| M1 小程序是否直接 MQTT | 是,小程序通过 MQTT 连接 `mqtt://iotcloud.tencent.com:8883` |
| A1 登录凭证 | 微信 code,后端返回 JWT Token |
| A2 token 方案 | JWT Token,有效期 7 天 |
| A3 token 续期 | `POST /api/v1/auth/refresh`,带 refresh_token |
| A4 绑定是否扫码 | 是,扫码获取 device_id |
| DB4 pd_data 含义 | PD 传感器光功率密度数据,分区域采集,含 avg_pd |
| I5 telemetry/event 边界 | telemetry 为周期遥测数据,event 为护理完成/设备异常等事件 |
| S2 设备侧应用层加密 | TLS 层加密,绑定使用 bind_token 验证 |
仍有少量未明确项,但不阻塞主链路开发:
- 订阅支付对接(微信支付流程细节)
- OTA 分片协议具体分包大小
- 管理后台管理员登录方式
- 管理后台多租户/角色矩阵细节
## 已有代码现状
仓库中已存在三个子系统的代码骨架:
- `miniprogram/` — 小程序基础结构,4 个 tabBar 页面,BLE 服务框架(命令字为占位)
- `cloud/` — 云函数 auth/device/subscription/record 四组函数(路由和字段为草案)
- `admin-console/` — uniapp + Vue 3 + Pinia 后台骨架,7 个页面(基础列表)
## 开发计划
### 阶段 1:基础设施与数据层
**目标:数据库建表、云函数 API 真实路由、统一中间件**
#### 1.1 数据库建表
根据 `04-数据库表结构设计.md` 和新协议资料,创建 DDL
- `users`openid、union_id、nickname、avatar_url、phone、status
- `devices`device_sn → 改为 device_id8 字节设备唯一 ID)、product_id、device_name、hw_version、fw_version、device_type、status、activated_at
- `bindings`user_id、device_id、bind_token、status、bound_at、unbound_at
- `subscriptions`user_id、device_id(可选)、type(试用/正式)、plan、status、started_at、expired_at、trial_used、source
- `sessions`user_id、device_id、session_id8 字节)、status、started_at、ended_at
- `treatment_records`session_id、user_id、device_id、regions、total_duration_ms、mode、avg_pd、sync_status
- `pd_data`session_id、device_id、region_name、pd_value、recorded_at
- `operation_logs`operator_type、operator_id、target_type、target_id、action、before_snapshot、after_snapshot、ip_address
#### 1.2 云函数统一框架
- 统一响应格式:`{ code, message, data }`,错误码与 `通信协议_小程序与腾讯云.docx` 对齐(1001-3001
- JWT Token 生成/验证中间件
- MySQL 连接池复用
- 请求日志记录
#### 1.3 认证接口
- `POST /api/v1/auth/login` — 微信 code 换 token
- `POST /api/v1/auth/refresh` — Token 续期
- JWT 签发,有效期 7 天
### 阶段 2BLE 通信层
**目标:小程序 BLE 服务完全对齐协议文档**
#### 2.1 重写 BLE 服务模块
基于 `通信协议_小程序与光子美容仪设备.docx`
- 帧构建/解析:header + length + type + payload + XOR 校验(校验结果为 0 表示通过)
- 服务 UUIDFFE0/FFE1/FFE2
- Characteristic UUIDFFE3DeviceInfo Read)、FFE4Command Write)、FFE5Status Read+Notify)、FFE6BondInfo Read+Write)、FFE7-FFE9OTA
- 命令字:0x01 设置参数、0x02 启动、0x03 停止、0x04 查询状态、0x05 绑定、0x06 解绑
- 状态字:0x21 状态上报、0x22 ACK、0x31 护理完成、0x32 异常、0x33 绑定成功
- 错误码:0x00-0x0C
- 区域掩码:bit0-6 对应左脸颊到右眼周,全脸 0x7F
- 波长:1=IR、2=R、3=UV、4=Y
#### 2.2 设备绑定流程实现
1. 扫码获取 device_id
2. 调用 `POST /api/v1/device/bind`,后端返回 bind_token
3. BLE 连接设备,写入 FFE6 BondInfo0x05 命令,含 user_id + bind_token + timestamp
4. 设备发送 0x33 绑定成功事件
5. 后端更新 bindings 表
#### 2.3 护理执行流程实现
1. BLE 连接,读取设备状态(0x04)
2. 设置护理参数(0x01):region_mask、wavelength、brightness、duration_ms、mode
3. 启动护理(0x02
4. 接收周期状态上报(0x21):mode_state、remaining_ms、battery、temperature 等
5. 接收护理完成事件(0x31):session_id、regions、total_duration_ms、avg_pd
### 阶段 3:云端 API 完整实现
**目标:所有接口对齐 `通信协议_小程序与腾讯云.docx`**
#### 3.1 设备接口
- `POST /api/v1/device/bind` — 绑定设备,生成 bind_token
- `POST /api/v1/device/unbind` — 解绑设备,BLE 发送 0x06 命令
- `GET /api/v1/device/list` — 用户绑定设备列表
- `GET /api/v1/device/{device_id}` — 设备详情
#### 3.2 订阅接口
- `GET /api/v1/subscription` — 当前订阅状态
- `POST /api/v1/subscription/purchase` — 购买订阅(含支付参数)
- `POST /api/v1/subscription/verify` — 验证支付
- 试用自动发放:绑定成功后自动创建 7 天试用
#### 3.3 护理记录接口
- `POST /api/v1/treatment/sync` — 同步护理记录(含 session_id、regions、total_duration_ms、avg_pd
- `GET /api/v1/treatment/history` — 分页查询历史记录
#### 3.4 用户接口
- `GET /api/v1/user/profile` — 获取用户信息
- `PUT /api/v1/user/profile` — 更新用户信息
### 阶段 4MQTT 消息处理
**目标:设备 MQTT 接入与云端消息处理**
#### 4.1 MQTT 主题实现
设备主题:
- `$iot/{product_id}/{device_name}/telemetry` — 遥测数据(QoS 0
- `$iot/{product_id}/{device_name}/status` — 状态上报(QoS 1
- `$iot/{product_id}/{device_name}/event` — 事件(护理完成、设备异常)(QoS 1)
- `$iot/{product_id}/{device_name}/control` — 下发控制指令(QoS 1
- `$iot/{product_id}/{device_name}/ota` — OTA 推送(QoS 1
用户主题:
- `users/{user_id}/subscription` — 订阅状态变更通知
- `users/{user_id}/devices` — 设备列表更新
- `users/{user_id}/notification` — 推送通知
#### 4.2 消息处理
- telemetry 消息:解析 JSON,写入 pd_data 表
- event 消息:护理完成写入 treatment_records,设备异常记日志
- control 下发:小程序或后台通过云端下发控制指令到设备
### 阶段 5:小程序 UI 完整实现
**目标:14 个页面对齐 UI 设计稿**
#### 5.1 页面清单(按 UI 原型)
| 页面 | UI 文件 | 关键功能 |
| --- | --- | --- |
| 授权登录 | 01_授权登录.html | 微信登录授权 |
| 扫码绑定 | 02_扫码绑定.html | 扫码获取 device_id |
| 蓝牙连接 | 03_蓝牙连接.html | BLE 扫描连接 |
| 绑定成功 | 04_绑定成功.html | 绑定完成 + 试用发放 |
| 确认佩戴 | 05_确认佩戴.html | 佩戴状态检测 |
| 首页 | 06_首页.html | 设备状态 + 护理入口 |
| 护理设置 | 06a_护理设置.html | 区域、波长、亮度、时长、模式设置 |
| 自动扫描 | 07_自动扫描.html | PD 传感器扫描 |
| 护理中 | 08_护理中.html | 实时状态、进度、剩余时间 |
| 护理完成 | 09_护理完成.html | 完成摘要 + 记录同步 |
| 订阅提示 | 10_订阅提示.html | 无订阅时引导 |
| 订阅套餐 | 11_订阅套餐.html | 套餐选择 + 购买 |
| 订阅成功 | 12_订阅成功.html | 购买完成确认 |
| 我的 | 13_我的.html | 用户信息、设备、订阅 |
| 护理记录 | 14_护理记录.html | 历史记录列表 |
#### 5.2 小程序 MQTT 集成
- 连接配置:`mqtt://iotcloud.tencent.com:8883`,ClientID `user_{user_id}`
- 订阅用户主题接收订阅状态变更和设备列表更新
- 接收实时遥测数据展示
### 阶段 6:管理后台完整实现
**目标:10 个页面对齐 UI 设计稿**
#### 6.1 页面清单
| 页面 | UI 文件 | 关键功能 |
| --- | --- | --- |
| 登录页 | 10_登录页.html | 管理员登录 |
| 仪表盘 | 01_仪表盘.html | 用户/设备/治疗/订阅统计 |
| 设备管理 | 02_设备管理.html | 设备列表、筛选、在线状态 |
| 设备详情 | 08_设备详情.html | 设备信息、绑定记录、远程控制 |
| 用户管理 | 03_用户管理.html | 用户列表 |
| 用户详情 | 09_用户详情.html | 用户信息、绑定、订阅、治疗记录 |
| 订阅管理 | 04_订阅管理.html | 订阅列表、创建、续期 |
| 护理记录 | 05_护理记录.html | 治疗记录查询、数据导出 |
| 操作日志 | 06_操作日志.html | 日志查询、筛选 |
| 系统设置 | 07_系统设置.html | 管理员管理、权限配置 |
#### 6.2 后台 API
对齐 `通信协议_小程序与腾讯云.docx` 第七章:
- `GET /api/v1/admin/devices` — 设备列表(分页)
- `GET /api/v1/admin/devices/{device_id}` — 设备详情
- `POST /api/v1/admin/devices/{device_id}/command` — 远程控制
- `GET /api/v1/admin/users` — 用户列表(分页)
- `GET /api/v1/admin/users/{user_id}` — 用户详情
- `GET /api/v1/admin/subscriptions` — 订阅列表(分页)
- `POST /api/v1/admin/subscriptions` — 创建订阅
- `GET /api/v1/admin/logs` — 操作日志(按类型、时间筛选)
### 阶段 7OTA 升级
**目标:固件升级完整链路**
- OTA 服务使用 FFE2FFE7(控制)、FFE8(数据)、FFE9(状态通知)
- 小程序检查新版本
- 分包传输固件
- 设备校验并重启
- 后台 OTA 管理入口
### 阶段 8:安全加固与测试
- 敏感数据加密存储
- API 防重放、限流
- 操作审计完善
- 端到端测试覆盖主链路
- BLE 联调测试
- MQTT 联调测试
- 后台功能测试
## 建议执行顺序
1. 阶段 1 — 数据库 + 云函数框架(1-2 天)
2. 阶段 2 — BLE 通信重写(2-3 天)
3. 阶段 3 — 云端 API 实现(2-3 天)
4. 阶段 5 — 小程序 UI 对齐设计稿(3-5 天)
5. 阶段 4 — MQTT 消息处理(1-2 天)
6. 阶段 6 — 管理后台 UI 对齐设计稿(2-3 天)
7. 阶段 7 — OTA1-2 天)
8. 阶段 8 — 安全与测试(2-3 天)
总计约 14-23 天。
## 需要立即更新的事项
新资料落地后,以下文件需要同步更新:
- `01-BLE通信协议明细.md` — 用真实命令字、UUID、payload 替换占位
- `03-云函数API接口清单.md` — 用真实路由和字段替换草案
- `04-数据库表结构设计.md` — 用 DDL 替换字段草案,增加 pd_data 详情
- `09-待确认决策清单.md` — 标记已解决的条目,更新剩余项
- `miniprogram/services/ble.js` — 用真实命令字和 UUID 重写
- `cloud/functions/*/index.js` — 用真实路由和字段重写
- `admin-console/src/pages/` — 对齐 UI 设计稿重写页面
@@ -0,0 +1,51 @@
# 剩余缺失信息清单
基于全部已有资料整理。以下问题在新开发资料中仍未明确,按阻塞程度排序。
## 阻塞主链路开发
| # | 问题 | 影响 | 建议处理方式 |
| --- | --- | --- | --- |
| C1 | DeviceSecret 签发流程:何时签发、由谁调用、是否可轮换 | 设备无法注册接入 IoT Hub | 先用腾讯云 IoT 控制台手动注册设备,后续再自动化 |
| C2 | 订阅支付对接:微信支付商户配置、payment_params 具体格式、支付回调地址 | 用户无法购买正式订阅 | 第一版只实现试用,购买功能后续对接微信支付 |
| C3 | refresh_token 机制:`/auth/refresh` 需要 refresh_token,但登录响应字段中只有 token | Token 续期无法实现 | 先用 token 直接续期,后续补 refresh_token 双 token 方案 |
## 阻塞部分功能
| # | 问题 | 影响 | 建议处理方式 |
| --- | --- | --- | --- |
| P1 | 一人多设备/一设备多用户规则:API 用 `device/list` 复数形式,但未明确限制 | 绑定逻辑不确定 | 先实现一对一,后续按需放开 |
| P2 | 试用按用户还是按设备发放:订阅消息含 `trial_used` 暗示按用户,但未明确 | 试用发放逻辑不确定 | 先按用户发放,trial_used 字段标记是否已用 |
| P3 | 试用到期后是否自动降级:设备错误码 0x06 ERR_NO_SUBSCRIPTION 暗示会校验 | 订阅校验逻辑不确定 | 先实现:到期后设备端返回无订阅错误,小程序引导购买 |
| P4 | OTA 分包策略:协议定义了 FFE7/FFE8/FFE9,但未给出具体分包大小和传输规则 | OTA 无法实现 | 先跳过 OTA,后续与固件团队对齐 |
| P5 | 后台管理员认证方式:有登录页 UI,但未定义用什么方式登录(账号密码/微信扫码/SSO) | 后台登录无法实现 | 先实现账号密码登录 |
| P6 | 后台权限矩阵:角色定义、菜单权限、API 权限均未定义 | 权限控制无法实现 | 先实现单角色无权限区分,后续补角色矩阵 |
| P7 | 小程序 MQTT 库选型:微信小程序使用 MQTT 需确认库 | 实时推送无法实现 | 调研 wx-mqtt 或通过 WebSocket 转 MQTT |
## 低阻塞可后续迭代
| # | 问题 | 影响 | 建议处理方式 |
| --- | --- | --- | --- |
| L1 | 护理历史"统计"是本地还是云端聚合 | API 设计 | 看 UI 原型 14_护理记录.html 推断 |
| L2 | 发现页内容来源:CMS 还是静态配置 | 后台功能范围 | UI 原型中未出现发现页,优先级最低 |
| L3 | 我的页面是否有售后、反馈、设置入口 | 页面结构 | 看 UI 原型 13_我的.html 推断 |
| L4 | 蓝牙授权是否需要定位权限 | 小程序权限声明 | iOS 需要,建议直接加上 |
| L5 | 绑定时是否校验设备在线状态 | 绑定逻辑 | 先不校验,后续加上 |
| L6 | 重复绑定/换绑限制 | 绑定逻辑 | 先实现基础逻辑 |
| L7 | 异步写入与接口返回关系 | 前端状态管理 | sync 接口同步返回 record_id |
| L8 | 固件版本管理和存储规则 | OTA 管理 | 后续定义 |
| L9 | 仪表盘统计口径:实时聚合还是离线任务 | 统计接口实现 | 先用 SQL 实时聚合,数据量大再改离线 |
| L10 | 数据导出是否受角色限制 | 权限细化 | 先不受限 |
| L11 | 系统设置范围:是否包含公告、字典、设备参数配置 | 后台功能范围 | 先只做管理员管理 |
| L12 | 多组织/多租户隔离 | 数据隔离 | 第一版不需要 |
| L13 | 是否有合规或审计特殊要求 | 安全方案 | 按通用标准实现 |
| L14 | 小程序最低微信版本要求 | 兼容性测试 | 使用基础库 2.25.0+ |
| L15 | 设备联调是否依赖特定手机机型 | 测试准备 | 联调时确认 |
## 总结
- 主链路阻塞项:3 条(C1-C3
- 部分功能阻塞项:7 条(P1-P7)
- 低阻塞可迭代项:15 条(L1-L15)
主链路开发已可启动,C1-C3 有临时替代方案。P1-P7 建议在对应阶段开始前确认。L1-L15 不阻塞任何阶段,可边做边补。
+124
查看文件
@@ -0,0 +1,124 @@
# Hox 光子美容仪项目 — 工作进度交接
## 项目概况
微信小程序 + 云开发后台 + uniapp 管理后台,产品是光子美容仪。
- 小程序 appid: `wxc4045074ef298510`
- 项目名: `hox-beauty`
- 部署: 微信云开发(免费 Tier)
- 主色: `#E6508C`(粉)、`#DCB982`(金)、`#52c41a`(绿)
## 目录结构
```
miniprogram/ # 微信小程序
app.js / app.json / app.wxss # 入口 + 全局样式 + tabBar
cloud-functions/ # 6 个云函数(auth/device/subscription/treatment/user/admin
pages/ # 15 个页面
services/ # ble.js + mqtt.js
utils/ # request.js(双模式:云函数/HTTP+ mock.js
admin-console/ # uniapp + Vue 3 管理后台
src/pages/ # 10 个页面
src/components/AdminLayout.vue # 侧边栏布局
src/utils/request.js # mock 模式(USE_MOCK=true
cloud/functions/ # 旧版 SCF 格式(已废弃,保留参考)
```
## 已完成的工作
### 基础架构
- 云开发初始化,6 个云函数部署完成
- 5 个数据库集合:users, bindings, subscriptions, treatment_records, operation_logs(权限:仅创建者可读写)
- request.js 双模式:`USE_CLOUD=true``wx.cloud.callFunction()`,false 走 HTTP
- 登录简化:云函数用 `cloud.getWXContext()` 自动获取 openid,无需手动 `wx.login()`
### 小程序页面(15 个)
- login(手机号登录)
- index(首页:设备状态 + 开始护理 + 设备管理)
- scan(扫码/手动输入绑定设备)
- bind-success(绑定成功 + 7天试用提示)
- ble-connectBLE 蓝牙连接,15秒超时)
- treatment-setup(护理参数设置)
- wear-check(佩戴检测)
- treating(护理进行中)
- treating-complete(护理完成)
- history(历史记录,从云端拉取)
- subscribe-plans(订阅方案选择)
- subscribe-prompt(订阅引导)
- subscribe-success(订阅成功)
- profile(个人中心 + 退出登录)
- device-info(设备信息详情)
### 设备管理
- 首页「设备管理」按钮:已绑定时弹出操作菜单(解绑)
- 解绑流程:断开 BLE → 调云函数 → 清空本地状态
- 手动输入绑定:绑定成功后直接跳 bind-success,不再跳 ble-connect
- 已绑定设备重复绑定时提示「已绑定设备」并返回
### 管理后台(10 个页面)
- login / dashboard / device / device-detail / user / user-detail / subscription / record / log / settings
- request.js 有 mock 模式(`USE_MOCK=true`),所有页面可用 mock 数据开发
- admin 云函数有 9 个 actiondashboard / devices / device_detail / device_unbind / users / user_detail / subscriptions / records / logs
### 已清理
- 删除了无用的 `miniprogram/pages/discover/``cloud/functions/record/`
## 本轮修复的问题
1. 手动输入设备号绑定后卡在 BLE 搜索 → 改为绑定成功直接跳 bind-success
2. ble-connect 页加 15 秒超时 + stopScan
3. ble.js 新增 `stopScan()` 方法
4. bind-success 页加「返回首页」按钮
5. subscribe-plans.js 字段名修正(plan → plan_type
6. history.js 兼容云函数返回的 created_at 字段
7. index.js 设备名兼容 name/device_id 字段
8. request.js 补 /api/v1/subscription 路由别名
9. admin 云函数从 1 个 action 扩展到 9 个
10. admin-console request.js 加 mock 模式
## 已验证的功能(真机测试)
- 登录正常
- 手动输入设备号绑定正常(自动发放 7 天试用订阅)
- 解绑正常
- 重复绑定提示正确
## 需要继续的工作
### 高优先级
1. **真机测试剩余流程**:订阅购买、订阅验证、历史记录查看
2. **BLE 真机调试**:需要真实硬件设备(devtools 无蓝牙)
- 扫描发现设备 → 连接 → 绑定 → 护理全流程
3. **管理后台连接真实后端**:当前 `USE_MOCK=true`,需要部署 HTTP 触发的云函数网关
### 中优先级
4. **Phase 7: OTA 升级**ble.js 里已有 OTA 相关 characteristicFFE2/FFE7/FFE8/FFE9),但 OTA 流程未实现
5. **管理后台 pages.json 配置 tabBar**:目前靠 AdminLayout 组件做导航,可考虑 uniapp 原生 tabBar
6. **operation_logs 集合**admin 云函数的 logs action 查这个集合,但各业务云函数尚未写入操作日志
### 低优先级
7. **Phase 8: 安全加固**:admin 云函数无鉴权,任何人都可调用
8. **数据导出功能**:管理后台各页面的「导出」按钮都是空操作
9. **清理 cloud/functions/ 目录**:旧版 SCF 格式已废弃
## 关键代码约定
- 云函数接收 `{ action, data }`,路由通过 action 字段
- `request.js``FUNC_MAP` 把 REST 路径映射到云函数调用,新接口必须加在这里
- `cloud.getWXContext()` 自动获取 openid,无需前端传
- tabBar 页面(index/history/profile)用原生导航栏;其他页面用自定义 header
- 动态岛适配:`style="padding-top: {{statusBarHeight + 24}}px;"` + app.globalData.statusBarHeight
- 小程序用 WXML/WXSS/JS(非 uniapp);管理后台用 uniapp + Vue 3
## BLE 协议备忘
- 帧格式:头 `0xAA 0x55` + 长度 + 类型 + 载荷 + XOR 校验
- 服务 UUIDFFE0(设备信息)/ FFE1(数据通信)/ FFE2OTA
- 设备广播名含 `HOX``LIGHTMASK`
- 护理区域位掩码:0x01 左脸颊 / 0x02 右脸颊 / 0x04 额头 / 0x08 下巴 / 0x10 鼻部 / 0x20 左眼周 / 0x40 右眼周
## 数据库集合
| 集合 | 关键字段 | 权限 |
|------|---------|------|
| users | openid, nickname, phone, created_at | 仅创建者可读写 |
| bindings | openid, device_id, status(active/inactive), bind_time | 仅创建者可读写 |
| subscriptions | openid, plan_type(trial/monthly/yearly), status, start_time, end_time, price | 仅创建者可读写 |
| treatment_records | openid, session_id, device_id, regions, total_duration_ms, mode, created_at | 仅创建者可读写 |
| operation_logs | action, detail, openid, created_at | 仅创建者可读写 |
+248
查看文件
@@ -0,0 +1,248 @@
# 需求缺口清单
基于 `软件系统说明.docx` 整理。本清单只记录两类内容:
- 文档中已经明确、可作为后续设计输入的事实
- 文档中缺失、会直接阻塞开发或联调的规格项
当前仓库没有源码、接口定义、数据库 schema、CI 或部署配置,因此本清单以产品说明为唯一依据,不补充未被文档证实的实现细节。
## 已确认事实
### 系统边界
- 系统由微信小程序、光子美容仪设备端、腾讯云 IoT/云服务、管理后台组成。
- 小程序与设备通过 `BLE 5.0 GATT` 通信。
- 小程序与云端通过 `HTTPS/MQTT` 通信。
- 设备通过 `MQTT over TLS` 连接腾讯云 IoT Hub。
- 管理后台是独立前端,技术栈为 `uniapp + Vue 3 + uView Plus`,部署到腾讯云静态网站托管。
- 小程序端是微信原生 `WXML / WXSS / JS`,不是 `uniapp`
### 小程序业务骨架
- 页面包括:首页、护理历史、发现、我的。
- 首次使用流程:扫码 -> 蓝牙授权 -> 设备绑定 -> 获得 7 天试用 -> 确认佩戴 -> 自动扫描 -> 开始治疗。
- 日常使用流程:打开小程序 -> 连接设备 -> 确认佩戴 -> 自动扫描 -> 开始治疗。
### BLE 已知协议事实
- 协议帧格式:帧头 `0xAA 0x55`,随后是长度、类型、数据、XOR 校验。
- 服务 UUID`FFE0` 设备信息服务,`FFE1` 数据通信服务,`FFE2` OTA 升级服务。
### 云端已知能力
- 云端基础设施包括:`Tencent Cloud IoT Hub``SCF``MySQL``Redis``CLS``CMQ`
- 环境划分为三套:开发环境 `IoT Hub + 云函数(测试)`,测试环境 `IoT Hub + 云函数 + MySQL`,生产环境 `IoT Hub + 云函数 + MySQL + Redis`
- 云函数职责:用户认证、设备绑定/解绑、订阅管理、护理记录同步、设备注册、试用订阅管理、数据统计。
### 数据模型已知名称
- `users`
- `devices`
- `bindings`
- `subscriptions`
- `sessions`
- `treatment_records`
- `pd_data`
- `operation_logs`
### MQTT 已知事实
- 设备上报主题:`$iot/{product_id}/{device_name}/telemetry`
- 设备事件主题:`$iot/{product_id}/{device_name}/event`
- 使用 `CMQ` 做异步处理。
- 护理记录存在异步写入路径。
### 安全已知事实
- 全链路使用 `TLS 1.2+`
- 设备认证依赖 `DeviceSecret`
- 用户认证是微信登录 + Token。
- Token 有效期为 7 天。
- 需要敏感数据加密存储、API 鉴权、角色权限、API 级别鉴权。
## 核心缺口
### 1. BLE 协议规格不完整
当前只有帧结构和服务 UUID,无法支持小程序、设备端和测试联调。
缺失项:
- `type` 命令字完整定义
- 请求/响应 payload 结构
- 各字段长度、编码、字节序
- 长度字段计算规则
- XOR 校验计算范围
- 错误码与 ACK/NACK 机制
- 超时、重试、幂等策略
- 主动上报与被动响应的区分
- characteristic UUID 清单
- MTU、分包、粘包处理规则
- 断连重连与会话恢复策略
- OTA 协议、分片、校验、回滚规则
- 佩戴确认规则
- 自动扫描的具体定义
- 治疗开始、暂停、结束、状态同步命令
### 2. 小程序状态机与业务规则不完整
当前文档只描述了高层流程,没有足够的页面行为和异常流程定义。
缺失项:
- 扫码内容定义:二维码中包含什么
- 绑定是否必须扫码
- 用户和设备的绑定约束:一对一、一对多、多对一
- 解绑规则与限制
- 试用订阅规则:按用户还是按设备发放,是否可重复领取
- 订阅有效性校验时机
- 设备未连接、蓝牙拒绝、治疗中断、同步失败等异常流
- 小程序本地缓存与重试机制
- 页面跳转关系与关键空态
- 治疗前、中、后的状态枚举
- 后台切换、来电、锁屏、断蓝牙时的处理规则
### 3. 云端 API 契约缺失
当前只有功能名,没有接口定义,前后端和测试都无法并行推进。
缺失项:
- API 列表和路由
- HTTP 方法
- 请求参数
- 返回结构
- 错误码
- 鉴权方式
- Token 刷新与吊销机制
- 微信登录换取身份的流程
- 绑定/解绑接口规则
- 订阅接口的查询、创建、续期、停用规则
- 护理记录同步接口格式
- 幂等、防重、防刷设计
### 4. 设备注册与 IoT 流程缺失
文档提到设备注册和 `DeviceSecret`,但没有写清注册与认证流程。
缺失项:
- 设备出厂、激活、绑定、上线的完整流程
- `DeviceSecret` 的签发时机和保存方式
- 小程序是否参与设备注册
- IoT 事件如何触发云函数
- 是否使用规则引擎或设备影子
- MQTT 上下行消息结构
- 设备控制指令的 topic 与 payload
- 设备离线、禁用、换绑时的状态管理
### 5. 数据库字段设计缺失
当前只有表名,无法开始建库、写接口或定义查询。
缺失项:
- 每张表的字段列表
- 主键、外键、唯一约束
- 状态枚举
- 时间字段和时区约定
- 审计字段
- 软删/硬删策略
- `sessions``treatment_records` 的边界
- `pd_data` 数据含义、采样频率、保留周期
- `operation_logs` 的记录范围和保留周期
### 6. 管理后台规格不完整
当前只有模块清单,还不足以支持页面设计和接口定义。
缺失项:
- 管理员登录方式
- 角色定义与权限矩阵
- 页面路由和菜单结构
- 列表页筛选项、排序项、导出格式
- 详情页字段清单
- 仪表盘统计指标口径
- 日志查询维度
- 是否支持设备远程控制
### 7. 安全设计缺实现细节
当前停留在原则层面,无法转为工程方案。
缺失项:
- Token 格式、签名算法、刷新策略
- `DeviceSecret` 存储和轮换方式
- 敏感字段加密范围
- API 防重放、防刷、限流策略
- 后台高权限操作的二次确认要求
- 审计日志保留和防篡改策略
- 隐私数据脱敏要求
### 8. 测试与运维方案缺失
缺少交付和验收所需的执行标准。
缺失项:
- BLE 联调测试方案
- 设备模拟方案
- API 测试样例
- MQTT 联调样例
- 真机测试范围
- 云函数发布流程
- 数据库迁移流程
- CLS 日志规范
- CMQ 重试和死信策略
- 告警、备份、恢复方案
- 验收标准与性能指标
## 歧义点
这些内容在文档中提到,但定义仍然模糊,后续需要先澄清再设计:
- 小程序与云端的 `MQTT` 是直接连接还是仅通过服务端转发。
- “自动扫描”到底指肤质检测、佩戴检测、设备自检,还是其他扫描动作。
- `pd_data``PD` 含义和数据来源。
- 护理记录“异步写入”是全量异步,还是仅明细异步。
- 管理后台中的“系统设置”是否只管理管理员与权限,还是还包含设备、订阅、公告等全局配置。
## 补规格优先级
建议按以下顺序补充规格,避免阻塞主链路开发:
1. BLE 通信协议明细
2. 小程序与云端 API 契约
3. 数据库表结构设计
4. 设备注册、绑定、订阅规则
5. MQTT 消息规范
6. 小程序状态机与异常流程
7. 管理后台权限与页面规格
8. 安全与运维方案
## 建议补充文档
建议在当前说明基础上继续补以下文档:
- `01-BLE通信协议明细.md`
- `02-小程序业务流程与状态机.md`
- `03-云函数API接口清单.md`
- `04-数据库表结构设计.md`
- `05-IoT设备注册与MQTT消息规范.md`
- `06-管理后台功能与权限设计.md`
- `07-安全与鉴权方案.md`
- `08-测试与验收标准.md`
## 当前结论
当前说明已经足够确定系统边界、主要技术选型和一阶段开发主线,但还不足以直接进入实现。最关键的四个缺口是:
- BLE 协议明细
- API 契约
- 数据库字段设计
- 业务状态机
在这四项没有补齐前,代码实现和联调都将高度依赖猜测,返工风险很高。
二进制文件未显示。
二进制文件未显示。
@@ -0,0 +1,150 @@
# 代码与设计文档对比分析
> 基于根目录 01~11 设计文档与当前代码实现(含本轮修改)的逐项对比。
> 日期:2026-04-24
---
## 一、超前实现(文档未规划,代码已实现)
### 1.1 架构层面
| 项目 | 说明 |
|------|------|
| 微信云开发模式 | 文档基于 SCF + MySQL + Redis + CMQ 架构;代码已迁移至微信云开发(cloud DB + cloud functions),无需 MySQL/Redis/CMQ |
| Mock 开发模式 | admin-console 的 request.js 内置完整 mock 数据,所有页面可脱离后端独立开发,文档未提及 |
| request.js 双模式 | 小程序 request.js 支持 `USE_CLOUD=true` 走云函数、`false` 走 HTTP,文档未规划此适配层 |
| FUNC_MAP 路由映射 | 小程序端将 REST 路径映射到云函数调用的字典,文档未涉及 |
| Pinia 状态管理 | admin-console 使用 pinia 管理 admin 登录状态,文档仅提到 Vue 3 |
### 1.2 功能层面
| 项目 | 说明 |
|------|------|
| 操作日志写入 | auth/device/subscription/treatment/user/admin 六个云函数均已写入 operation_logs,文档仅在 DB 表结构中定义了表,未要求业务层实现 |
| Admin Token 鉴权 | admin 云函数实现 login + verifyToken 校验(base64 编码),文档的「安全方案」仅列为待设计 |
| CSV 导出 | 5 个管理后台页面(设备/用户/记录/订阅/日志)均实现 CSV 导出下载,文档仅提到「数据导出」为空操作 |
| BLE 15秒超时 + stopScan | ble-connect 页面加 15 秒扫描超时自动停止,文档未定义扫描超时策略 |
| bind-success 独立页 | 绑定成功后展示 7 天试用提示的独立页面,文档流程图中无此独立步骤 |
| 灵动岛适配 | 所有自定义 header 页面适配 iPhone Dynamic IslandstatusBarHeight + 24px),文档未提及 |
| MQTT 客户端框架 | mqtt.js 已实现基于 WebSocket 的 MQTT 客户端框架(连接/订阅/心跳/重连),虽然未正式启用但框架完备 |
| 系统设置页面 | settings 页面含基础配置、订阅价格、功能开关(注册/绑定/免费模式/维护模式),文档的「系统设置」仅为占位 |
| Admin Login UI | 完整的登录页 + pinia store + token 持久化,文档仅列「admin 登录方法」为待确认 |
### 1.3 BLE 协议层
ble.js 已实现了文档 Phase 2 要求的大部分内容:
| 文档要求 | 代码状态 |
|----------|----------|
| 帧格式 0xAA 0x55 + len + type + payload + XOR checksum | 已实现(buildFrame/parseFrame |
| 服务 UUID FFE0/FFE1/FFE2 | 已定义 |
| 特征 UUID FFE3~FFE9 | 全部已定义 |
| 命令字节 0x01~0x06 | 全部已定义(SET_PARAMS/START/STOP/QUERY/BIND/UNBIND |
| 状态上报 0x21~0x33 | 全部已定义(STATUS_REPORT/ACK/TREATMENT_COMPLETE/EXCEPTION/BIND_SUCCESS |
| 错误码 0x00~0x0C | 全部已定义 |
| ACK/NACK + 序号 + 5秒超时 | 已实现(_pendingAcks + nextSeq |
| 区域位掩码 bit0-6, 全脸 0x7F | 已实现 |
| 波长值 IR=1/R=2/UV=3/Y=4 | 已实现 |
| 模式 NORMAL=0/SMART=1 | 已实现 |
| 设备信息读取(14字节解析) | 已实现(readDeviceInfo |
| 护理参数设置(region+wavelength+brightness+duration+mode | 已实现(setParams |
| 绑定/解绑(userId+token+timestamp | 已实现(bindDevice/unbindDevice |
---
## 二、文档规划但未实现
### 2.1 高优先级未实现(阻塞主链路)
| 编号 | 内容 | 来源 | 说明 |
|------|------|------|------|
| N1 | BLE 真机全流程调试 | 10-Phase2, 08-验收 | ble.js 协议层完整但未接入真实硬件验证,佩戴检测/护理/绑定全流程需真机测试 |
| N2 | MQTT 消息处理链路 | 05, 10-Phase4 | mqtt.js 有框架但未接入 IoT Hub;设备遥测/事件上报、异步写护理记录均未实现 |
| N3 | IoT 设备注册流程 | 05, 11-C1 | DeviceSecret 签发流程未实现;workaround: 手动在腾讯云控制台注册 |
| N3b | iot 云函数(register_device/issue_secret/get_status | 03 | 3 个 IoT API 均未创建 |
| N4 | 微信支付集成 | 11-C2 | subscription.purchase 目前是直接创建订阅,未接入微信支付;workaround: 仅试用版可用 |
| N5 | stats 云函数(4 个统计 API | 03 | user_overview/device_overview/treatment_overview/subscription_overview 未创建 |
| N6 | auto-scan 自动扫描页面 | 02, 10-Phase5 | treatment-setup 中智能模式跳转 auto-scan 页面,但该页面未创建 |
### 2.2 中优先级未实现
| 编号 | 内容 | 来源 | 说明 |
|------|------|------|------|
| M1 | devices 独立集合 | 04 | 文档规划 8 张表,代码只实现了 5 张;devices 表未独立创建(设备信息嵌在 bindings 中) |
| M2 | sessions 集合 | 04 | 护理会话表未创建;treatment_records 直接存储,无 1:N 会话-记录关系 |
| M3 | pd_data 集合 | 04, 11-DB4 | PD(光密度)数据表未创建;文档中此表定义也几乎为空 |
| M4 | OTA 升级流程 | 10-Phase7 | ble.js 有 FFE7/FFE8/FFE9 characteristic 定义,但 OTA 流程(分块传输、校验、重启)未实现 |
| M5 | JWT Token 体系 | 07, 10-Phase1 | 文档要求 JWT + 7天有效期 + refresh_token;代码使用简单 openid+timestamp 拼接,无 refresh_token |
| M6 | refresh_token 机制 | 11-C3 | 登录仅返回 token,无 refresh_token;workaround: auth.refresh 直接用 openid 生成新 token |
| M7 | 管理后台权限模型 | 06, 07 | 无角色/菜单/API/数据范围四级权限;当前所有登录管理员权限相同 |
| M8 | treatment-done 页同步记录 | 10-Phase5 | treatment-done 页存在但未调用 treatment.sync 云函数上传护理记录 |
### 2.3 低优先级未实现
| 编号 | 内容 | 来源 | 说明 |
|------|------|------|------|
| L1 | BLE 分帧(MTU 超长时) | 01 | 文档提到 payload 超 MTU 时需分帧 + 序号;代码未实现 |
| L2 | 重连后重新订阅 notify | 01, 02 | 文档要求 BLE 断连重连后需重新订阅 characteristic notify;代码未处理 |
| L3 | 统一错误码规范 | 03 | 文档规划统一错误码范围,代码各函数自行定义 code 值 |
| L4 | 幂等键 | 03 | 文档要求 record.sync 等接口支持幂等键防重复;代码未实现 |
| L5 | before/after 快照日志 | 04 | 文档规划 operation_logs 含 before_snapshot/after_snapshot/ip_address/user_agent;代码仅记录 action + detail |
| L6 | 软删除(deleted_at | 04 | 文档要求全局软删除,代码用 status 字段代替(功能等效但字段不一致) |
| L7 | 操作日志 ip_address | 04, 07 | 云函数无法直接获取客户端 IP;文档未考虑云开发环境的限制 |
| L8 | 管理后台远程控制指令 | 06 | 文档提到管理后台可下发控制指令到设备,完全未实现 |
| L9 | 数据导出权限限制 | 06, 11-L10 | 文档提到导出功能应有权限控制,当前所有管理员均可导出 |
| L10 | 测试用例与 CI/CD | 08 | 无任何测试基础设施,无 CI/CD 配置 |
---
## 三、文档与代码有差异(实现方式不同)
| 文档规划 | 代码实际 | 差异说明 |
|----------|----------|----------|
| MySQL 数据库,BIGINT 自增 PK | 微信云数据库,auto-generated _id | 数据模型保持一致但存储引擎完全不同 |
| 8 张表 | 5 张集合 | 缺少 devices、sessions、pd_data |
| JWT Token | openid + timestamp 拼接 | 安全性较低但简化了实现 |
| RESTful HTTP API | 云函数 action 路由 | 入口形式不同,功能等价 |
| 4 个 tabBar 页(首页/历史/发现/我的) | 3 个 tabBar 页(首页/历史/我的) | 删除了「发现」页面 |
| SCF + CMQ 异步处理 | 同步云函数 | 无异步队列,记录同步为同步操作 |
| admin 后台部署在腾讯云静态托管 | uniapp 项目(H5 模式) | 部署方式待定,当前为本地开发 |
| 多环境(dev/test/prod) | 单一云开发环境 | 未区分环境 |
| Redis 缓存 | 无缓存层 | 云开发免费 tier 无 Redis |
---
## 四、开发计划完成度(对照 10-开发计划)
| Phase | 内容 | 状态 | 完成度 |
|-------|------|------|--------|
| Phase 1 | 基础设施 & 数据层 | 部分完成 | 60% — 数据库 5/8 表,统一响应格式已有,JWT 未做 |
| Phase 2 | BLE 通信层 | 协议完成 | 85% — 协议层完整,缺真机验证和分帧 |
| Phase 3 | 云 API 全实现 | 基本完成 | 80% — 缺 IoT 3个 + Stats 4个 API |
| Phase 4 | MQTT 消息处理 | 未启动 | 10% — 仅有 mqtt.js 框架,未接入 |
| Phase 5 | 小程序 UI | 大部分完成 | 75% — 14/15 页面存在,缺 auto-scan 页,treatment-done 未同步记录 |
| Phase 6 | 管理后台 UI | 基本完成 | 90% — 10 个页面全部存在,含导出和设置 |
| Phase 7 | OTA 升级 | 未启动 | 5% — 仅有 characteristic 定义 |
| Phase 8 | 安全加固 & 测试 | 部分完成 | 25% — admin 鉴权已加,其余未做 |
**整体完成度约 55%,主链路功能框架已搭建完成,关键阻塞项为 BLE 真机调试、MQTT/IoT 接入和微信支付。**
---
## 五、建议优先级
### 立即可做(不需要外部依赖)
1. 创建 auto-scan 页面(智能模式自动扫描)
2. treatment-done 页面调用 treatment.sync 上传护理记录
3. 创建 stats 云函数(4 个统计 API,供 dashboard 使用)
4. 补充 admin 云函数的 settings action(设置页已存在但后端无处理)
### 需要硬件/外部配置
5. BLE 真机全流程调试(需要真实设备)
6. IoT 设备注册 + MQTT 接入(需要腾讯云 IoT Hub 配置)
7. 微信支付集成(需要商户号配置)
### 后续迭代
8. JWT Token 替换
9. OTA 升级流程
10. 权限模型完善
11. 测试用例编写