# Visitor 联系人信息上报 API 文档 ## 1. 概述 Visitor 接口用于第三方系统向本平台上报联系人信息(姓名、手机、邮箱)。平台通过请求的 `Referer` 头自动匹配对应监控域名,将联系人信息存储到该域名下,并向传入的手机号发送短信验证码。 **基础 URL**:`http://:`(开发环境默认 `http://localhost:8000`) --- ## 2. 接口详情 ### 2.1 上报联系人信息 ``` POST /api/public/visitor Content-Type: application/json ``` **请求头**: | 头 | 类型 | 必填 | 说明 | |------|------|------|------| | `Referer` | string | 是 | 请求来源页面的完整 URL,用于提取域名匹配 | **请求体**: | 字段 | 类型 | 必填 | 说明 | |------|------|------|------| | `name` | string | 否 | 联系人姓名 | | `phone` | string | 否 | 联系电话(传入后会收到验证码短信) | | `email` | string | 否 | 电子邮箱 | **处理流程**: ``` POST /api/public/visitor → 从 Referer 头提取域名 → 在 monitored_domains 表中匹配 domain(需 is_active=true) → 获取该记录的 domain_id → 在 visitor_info 表中 upsert 联系人信息(同 domain_id 则更新,否则新建) → 生成 6 位数字验证码,通过阿里云短信发送至传入的 phone → 返回保存结果及验证码 ``` **curl 示例**: ```bash curl -X POST "http://localhost:8000/api/public/visitor" \ -H "Content-Type: application/json" \ -H "Referer: https://example.com/dashboard" \ -d '{ "name": "张三", "phone": "13800138000", "email": "zhangsan@example.com" }' ``` ### 2.2 响应 #### 保存成功 ```json { "success": true, "message": "联系人信息已保存", "domain": "example.com", "code": "843291" } ``` > 返回的 `code` 为 6 位数字验证码。如未传入 `phone` 字段,则 `code` 为 `null`。 #### 缺少或无效 Referer ```json { "success": false, "message": "缺少或无效的 Referer 头" } ``` #### 未找到匹配的域名 ```json { "success": false, "message": "未找到匹配的域名" } ``` ### 2.3 调用示例 **前端(浏览器自动携带 Referer)**: ```javascript const res = await fetch('/api/public/visitor', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ name: '张三', phone: '13800138000', email: 'zhangsan@example.com', }), }); const data = await res.json(); console.log(`验证码: ${data.code}`); ``` **Python 后端**: ```python import requests resp = requests.post( "https://license-server.example.com/api/public/visitor", headers={"Referer": "https://example.com/dashboard"}, json={ "name": "张三", "phone": "13800138000", "email": "zhangsan@example.com", }, ) print(resp.json()) ``` **Node.js**: ```javascript const resp = await fetch("https://license-server.example.com/api/public/visitor", { method: "POST", headers: { "Referer": "https://example.com/dashboard", "Content-Type": "application/json" }, body: JSON.stringify({ name: "张三", phone: "13800138000", email: "zhangsan@example.com" }), }); console.log(await resp.json()); ``` **curl**: ```bash curl -X POST \ -H "Referer: https://example.com/dashboard" \ -H "Content-Type: application/json" \ -d '{"name":"张三","phone":"13800138000","email":"zhangsan@example.com"}' \ "https://license-server.example.com/api/public/visitor" ``` --- ## 3. 数据表 ### visitor_info 联系人信息表,与 `monitored_domains` 一对一关联。同一域名多次请求会覆盖更新已有记录。 | 字段 | 类型 | 说明 | |------|------|------| | `id` | SERIAL PK | 主键 | | `domain_id` | INT (UNIQUE) | 关联的域名 ID | | `name` | VARCHAR(100) | 联系人姓名 | | `phone` | VARCHAR(50) | 联系电话 | | `email` | VARCHAR(200) | 电子邮箱 | | `created_at` | TIMESTAMPTZ | 创建时间 | | `updated_at` | TIMESTAMPTZ | 更新时间 | --- ## 4. 常见问题 **Q: 同一域名多次请求会怎样?** A: 覆盖更新已有联系人信息,不会新增记录。`domain_id` 有唯一约束保证不会重复。 **Q: 需要认证吗?** A: 不需要。`POST /api/public/visitor` 是公开接口,第三方系统可直接调用。 **Q: 不传手机号会发短信吗?** A: 不会。仅当 `phone` 字段有值时才发送短信验证码,但联系人信息仍会正常保存。 **Q: 验证码是什么用途?** A: 验证码通过短信发送到联系人手机,同时在响应中返回给调用方,方便第三方系统做二次校验。 **Q: 域名匹配支持哪些格式?** A: 支持纯域名(`example.com`)、带端口(`example.com:8080`)、带协议(`http://example.com` / `https://example.com`)。