根因:主包 2MB 全量组件注入导致 DevTools 渲染引擎内存渐增, 叠加离线时固定 3s 抑制期后的请求洪泛。 修复: - app.config.ts 添加 lazyCodeLoading: requiredComponents 主包 2.0MB→766KB,taro.js 526→131KB,vendors.js 230→28KB - request.ts 离线抑制改为指数退避(3s→6s→12s→30s cap) 后端不可达时自动延长抑制,防止请求风暴 - SegmentTabs Tab 接口改为 readonly,修复 TS 编译错误 - AbortController polyfill 补齐小程序运行时缺失 - 健康首页/设备同步/健康档案/报告/设置页 UI 重构 - 文章页公开端点适配游客访问 - 健康首页 Swiper 间隔优化 4s→5s,动画 500→300ms
160 lines
6.9 KiB
Markdown
160 lines
6.9 KiB
Markdown
# API 端点深度测试报告
|
||
|
||
> 测试工具: curl/Bash | 环境: http://localhost:3000
|
||
> 测试账号: admin / Admin@2026 (完整权限) | 总用例: 69
|
||
|
||
## 1. 模块通过率汇总
|
||
|
||
| 模块 | 测试数 | 通过 | 失败 | 通过率 |
|
||
|------|--------|------|------|--------|
|
||
| 认证与权限 | 8 | 8 | 0 | **100%** |
|
||
| 患者 CRUD | 11 | 10 | 1 | **90.9%** |
|
||
| 患者分页/注入 | 7 | 5 | 2 | **71.4%** |
|
||
| 患者删除 | 2 | 2 | 0 | **100%** |
|
||
| 健康数据 | 5 | 1 | 4 | **20%** |
|
||
| 预约系统 | 7 | 7 | 0 | **100%** |
|
||
| 咨询管理 | 9 | 7 | 2 | **77.8%** |
|
||
| 内容管理 | 13 | 10 | 3 | **76.9%** |
|
||
| 通用/跨切面 | 7 | 7 | 0 | **100%** |
|
||
| **总计** | **69** | **57** | **12** | **82.6%** |
|
||
|
||
## 2. 认证与权限 — 100% PASS
|
||
|
||
| ID | 测试 | 结果 |
|
||
|----|------|------|
|
||
| AUTH-01 | 错误密码 | PASS — `message=未授权` |
|
||
| AUTH-02 | 不存在的用户 | PASS — `message=未授权` |
|
||
| AUTH-03 | 无 Token 访问 | PASS — HTTP 401 |
|
||
| AUTH-04 | 无效 Token | PASS — HTTP 401 |
|
||
| AUTH-05 | 空 body 登录 | PASS — 429 限流触发 |
|
||
| AUTH-06 | SQL 注入 (`' OR 1=1 --`) | PASS — 无数据泄漏 |
|
||
| AUTH-07 | 超长密码 (10000 字符) | PASS — 429 限流触发 |
|
||
| AUTH-08 | 有效 Token | PASS — 200 + data |
|
||
|
||
**亮点:** 限流机制有效,登录端点不泄漏信息(统一返回"未授权"),SQL 注入被正确处理。
|
||
|
||
## 3. 患者 CRUD — 90.9% PASS
|
||
|
||
| ID | 测试 | 结果 | 说明 |
|
||
|----|------|------|------|
|
||
| PATIENT-01 | 空名称创建 | PASS | `400: 患者姓名不能为空` |
|
||
| PATIENT-02 | 500 字符名称 | PASS | `400: 长度不能超过255` |
|
||
| PATIENT-03 | 未来出生日期 (2099) | PASS | `400: 出生日期不能是未来日期` |
|
||
| PATIENT-04 | XSS in name (`<script>`) | **FAIL** | HTTP 200, 存储原值 |
|
||
| PATIENT-05 | 无效 gender | PASS | `400: 不是有效值` |
|
||
| PATIENT-06 | 有效创建 | PASS | success, version=1 |
|
||
| PATIENT-14 | 按 ID 查询 | PASS | success |
|
||
| PATIENT-15 | 不存在的 ID | PASS | `404: 患者不存在` |
|
||
| PATIENT-16 | 有效更新 | PASS | version=2 |
|
||
| PATIENT-17 | 乐观锁冲突 | PASS | `409: 版本冲突` |
|
||
| PATIENT-18 | 未来日期更新 | PASS | `400: 出生日期不能是未来日期` |
|
||
|
||
### PATIENT-04: XSS 存储未消毒 (MEDIUM)
|
||
|
||
- `<script>alert(1)</script>` 直接存入 name 字段
|
||
- 前端 React 默认转义,但建议服务端也做消毒
|
||
- **修复:** 添加 HTML sanitize 或正则剥离标签
|
||
|
||
### 患者分页/注入测试
|
||
|
||
| ID | 测试 | 结果 |
|
||
|----|------|------|
|
||
| PATIENT-10 | limit=10000 | **FAIL (LOW)** — 无上限,可能导致性能问题 |
|
||
| PATIENT-12 | SQL 注入 in search | **FAIL (MEDIUM)** — 连接错误 (HTTP 000) |
|
||
|
||
## 4. 健康数据 — 20% PASS (最差模块)
|
||
|
||
| ID | 测试 | 结果 | 说明 |
|
||
|----|------|------|------|
|
||
| HEALTH-01 | 极端血压 (0/0) | **FAIL** | HTTP 200,值存为 null |
|
||
| HEALTH-02 | 极端心率 (999) | **FAIL** | HTTP 200,值存为 null |
|
||
| HEALTH-03 | 负值 (-10) | **FAIL** | HTTP 200,值存为 null |
|
||
| HEALTH-04 | 无效 UUID | PASS | `422: UUID parsing failed` |
|
||
| HEALTH-05 | 未来日期 (2099) | **FAIL** | HTTP 200,记录被创建 |
|
||
|
||
### H-06: 日常监测 DTO-Entity 映射断裂 (HIGH)
|
||
|
||
**这是本次测试发现的最严重的后端问题。**
|
||
|
||
- **现象:** API 接受 `indicator_type`、`value`、`systolic`、`diastolic` 等字段但静默忽略,创建的记录所有测量字段为 null
|
||
- **根因:** DTO 字段与 Entity 列名不匹配。DTO 使用 `systolic`/`diastolic`,Entity 期望 `morning_bp_systolic`/`morning_bp_diastolic`
|
||
- **影响:** 日常监测功能实质失效 — 小程序录入的体征数据无法正确存储
|
||
- **修复:** 重构 DTO 字段映射,或统一 DTO/Entity 字段命名
|
||
- **预计工时:** 4h
|
||
|
||
**同时发现:** 无值范围校验(血压 0、心率 999 被接受)、未来 record_date 无校验。
|
||
|
||
## 5. 预约系统 — 100% PASS
|
||
|
||
| ID | 测试 | 结果 |
|
||
|----|------|------|
|
||
| APPOINT-01 | 列表查询 | PASS |
|
||
| APPOINT-02 | 空 doctor_id | PASS — 422 |
|
||
| APPOINT-03 | 无效 UUID | PASS — 422 |
|
||
| APPOINT-04 | 不存在的预约 | PASS — 404 |
|
||
| APPOINT-05 | page=0 | PASS |
|
||
| APPOINT-11 | 排班已满 | PASS — `400: 排班已满` |
|
||
| APPOINT-12 | 重复预约 | PASS — `400: 排班已满` |
|
||
|
||
**亮点:** UUID 校验、容量检查、404 处理全部正确。
|
||
|
||
## 6. 咨询管理 — 77.8% PASS
|
||
|
||
| ID | 测试 | 结果 |
|
||
|----|------|------|
|
||
| CONSULT-02 | 空描述创建 | **FAIL (LOW)** — 接受空描述 |
|
||
| CONSULT-05 | XSS in description | **FAIL (MEDIUM)** — XSS 存储原值 |
|
||
| CONSULT-06~09 | 评分范围 1-5 | **PASS** — 校验完善 |
|
||
|
||
**亮点:** 评分校验优秀(1-5 范围 + 只能评已关闭会话)。
|
||
|
||
## 7. 内容管理 — 76.9% PASS
|
||
|
||
| ID | 测试 | 结果 |
|
||
|----|------|------|
|
||
| ARTICLE-04 | 500 字符标题 | **FAIL (HIGH)** — HTTP 500 内部错误 |
|
||
| CATEGORY-02 | 空分类名称 | **FAIL (MEDIUM)** — 接受空名称 |
|
||
| TAG-04 | 重复标签名 | **FAIL (LOW)** — 允许重复 |
|
||
|
||
### ARTICLE-04: 500 字符标题导致 500 错误 (HIGH)
|
||
|
||
- **现象:** 500 字符文章标题返回 HTTP 500 Internal Server Error
|
||
- **根因:** DTO 缺少 `#[validate(length(max=255))]`,数据库列长度约束违反导致未处理的 DB 错误
|
||
- **修复:** 添加 DTO 长度校验 + 全局 DB 错误映射
|
||
- **预计工时:** 30min
|
||
|
||
### CATEGORY-02: 空分类名称被接受 (MEDIUM)
|
||
|
||
- 文章标题有空校验,标签名称有空校验,但分类名称没有
|
||
- **修复:** 添加 `#[validate(length(min=1))]`
|
||
|
||
## 8. 通用/跨切面 — 100% PASS
|
||
|
||
| ID | 测试 | 结果 |
|
||
|----|------|------|
|
||
| GENERIC-01 | 3 个并发更新 | PASS — 1 成功 + 2 冲突 (409) |
|
||
| GENERIC-02 | 错误 JSON body | PASS — 400 |
|
||
| GENERIC-03 | 缺少 Content-Type | PASS — 415 |
|
||
| GENERIC-04 | GET 带 body | PASS — body 被忽略 |
|
||
| GENERIC-05 | 超大页码 | PASS — 空列表 |
|
||
| GENERIC-06 | 快速连续请求 | PASS — 全 200 |
|
||
| GENERIC-07 | 不存在的文章 ID | PASS — 404 |
|
||
|
||
**亮点:** 乐观锁在并发下表现完美(1 成功 + 2 冲突),HTTP 状态码使用规范。
|
||
|
||
## 9. 失败项汇总
|
||
|
||
| ID | 严重性 | 模块 | 问题 | 修复 | 工时 |
|
||
|----|--------|------|------|------|------|
|
||
| H-06 | HIGH | 健康数据 | DTO-Entity 映射断裂 | 重构字段映射 | 4h |
|
||
| H-07 | HIGH | 内容管理 | 500 字符标题 → HTTP 500 | 添加 DTO 校验 | 30min |
|
||
| M-08 | MEDIUM | 健康数据 | 极端值无校验 | 添加范围校验 | 2h |
|
||
| M-09 | MEDIUM | 健康数据 | 未来 record_date | 添加日期校验 | 30min |
|
||
| M-10 | MEDIUM | 咨询 | XSS 存储未消毒 | HTML sanitize | 1h |
|
||
| M-11 | MEDIUM | 内容管理 | 空分类名被接受 | 添加 validate | 30min |
|
||
| M-12 | MEDIUM | 患者 | SQL 注入导致连接错误 | 调查 URL 编码 | 2h |
|
||
| M-13 | MEDIUM | 患者 | XSS 存储未消毒 | HTML sanitize | 1h |
|
||
| L-04 | LOW | 患者 | limit 无上限 | 设 max=200 | 30min |
|
||
| L-05 | LOW | 咨询 | 空描述被接受 | validate 或文档 | 30min |
|
||
| L-06 | LOW | 内容管理 | 重复标签名 | 唯一约束 | 1h |
|