# Lead · 意向客户(Phase 3) > 自主问卷用户信息采集的统一入口,落到 `leads` 表,供管理后台跟进。 ## 接口表 | Method | Path | 鉴权 | 说明 | |---|---|---|---| | POST | `/api/v1/leads` | - | 提交(小程序自测问卷、首页落地等) | | GET | `/api/v1/leads/stats` | ✅ | 统计:总数 / 24h / 按 source 分组 | | GET | `/api/v1/admin/leads` | ✅ | 列表,支持 phone / source / keyword / 时间过滤 | | GET | `/api/v1/admin/leads/:id` | ✅ | 详情 | | PUT | `/api/v1/admin/leads/:id/remark` | ✅ | 修改备注 | | DELETE | `/api/v1/admin/leads/:id` | ✅ | 删除 | ## POST /api/v1/leads **请求体** ```json { "name": "张三", "phone": "13800138000", "symptom": "便血近 1 周,伴有肛门坠胀", "questionnaire": { "total": 5, "answers": { "0": "sometimes", "1": "no" }, "createdAt": "2026-06-14T08:30:00.000Z" }, "source": "self-test", "score": 5 } ``` **校验规则** - `name` 必填,1-20 字符 - `phone` 必填,匹配 `^1[3-9]\d{9}$` - `symptom` 可选,≤ 500 字 - `questionnaire` 必填,任意 JSON 对象 - `source` 可选,枚举 `self-test` / `home` / `appointment` / `other`,默认 `self-test` - `score` 可选,0-100 **响应** ```json { "code": 0, "message": "提交成功", "data": { "id": "lead-1781398800000", "createdAt": "2026-06-14 16:30:00" } } ``` **错误码** | HTTP | code | message | |---|---|---| | 400 | 1 | 姓名必填 / 姓名长度需在 1-20 字符 | | 400 | 1 | 手机号必填 / 手机号格式不正确 | | 400 | 1 | 症状描述不超过 500 字 | | 400 | 1 | 问卷答案 questionnaire 必填且为对象 | | 400 | 1 | source 仅支持:self-test / home / appointment / other | | 400 | 1 | 该手机号在同渠道已提交过,请勿重复 | | 500 | 500 | 服务器内部错误 | ## GET /api/v1/admin/leads **Query** - `phone` 手机号精确匹配 - `source` 渠道 - `keyword` 姓名模糊匹配 - `startDate` / `endDate` 时间范围(`YYYY-MM-DD`) - `limit` 默认 50,最大 200 - `offset` 默认 0 **响应** ```json { "code": 0, "message": "ok", "data": { "list": [ { "id": "lead-1781398800000", "name": "张三", "phone": "13800138000", "symptom": "便血近 1 周", "questionnaire": { "total": 5, "answers": {} }, "source": "self-test", "score": 5, "remark": "", "createdAt": "2026-06-14 16:30:00", "updatedAt": "2026-06-14 16:30:00" } ], "total": 1, "limit": 50, "offset": 0 } } ``` ## 数据表 ```sql CREATE TABLE leads ( id VARCHAR(32) PRIMARY KEY, name VARCHAR(50) NOT NULL, phone VARCHAR(20) NOT NULL, symptom TEXT, questionnaire JSON NOT NULL, source VARCHAR(20) NOT NULL DEFAULT 'self-test', score INT DEFAULT 0, remark VARCHAR(500), created_at DATETIME DEFAULT CURRENT_TIMESTAMP, updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, UNIQUE KEY uniq_phone_source (phone, source) ); ``` 唯一约束 `(phone, source)`:同手机号在同一渠道只保留一条。