需求 #74 » 刷脸和刷卡接口文档(1).md
一、概述
设备与平台之间有两种交互通道,互为补充:
| 通道 | 方向 | 用途 | 适用场景 |
|---|---|---|---|
| MQTT | 平台 → 设备 | 人脸库下发(全量/增量) | 人脸库变更时批量推送、设备弱网/离线回传 |
| MQTT | 设备 → 平台 | 通行记录上报 | 设备离线后批量回传通行记录 |
| HTTP | 设备 → 平台 | 实时刷脸/刷卡通行 | 闸机类设备实时鉴权、落库 |
| HTTP | 设备 → 平台 | 人脸库查询 | 设备拉取指定设备的人脸信息 |
核心能力说明:
- 刷脸抓拍图
snapImage(base64):设备随通行记录上报,平台落库并上传 OSS/MinIO。 - 识别相似度
confidence(字符串):设备随通行记录上报,平台落库。 - 设备
passDirection通行方向(整型枚举:1=进,2=出),用于通行通知。 - 消费者
studentStatus在校状态(1=在校,0=离校),随第三方照片同步。 - 临时用户通行控制:
isRestricted/restrictionStartTimeStr/restrictionEndTimeStr/maxAllowedCalls/callsMade(限时 / 限次)。
二、MQTT 连接信息
设备需连接平台提供的 MQTT Broker(地址、用户名、密码由平台方下发,设备端按自有运行环境配置)。
设备需要关注的主题:
| 方向 | 主题 | 说明 |
|---|---|---|
| 平台 → 设备(订阅) | schoolFaceTopic/all:{设备sn} |
全量刷新指令 |
| 平台 → 设备(订阅) | schoolFaceTopic/add:{设备sn} |
人脸增量新增 |
| 平台 → 设备(订阅) | schoolFaceTopic/remove:{设备sn} |
人脸增量移除 |
| 设备 → 平台(发布) | schoolFaceTopic/accessRecord/{设备sn} |
通行记录上报 |
{设备sn}= 设备编码equipmentCode,即 HTTP 接口中的deviceID。
设备亦可订阅schoolFaceTopic/projectAddress/query响应以获取项目地址配置,本对接文档不展开。
三、平台 → 设备:人脸库下发(三个主题)
人脸库变更时,平台通过 MQTT 向设备推送增量(或全量刷新)。主题前缀固定为 schoolFaceTopic,后接动作与设备编码(用 : 连接)。
| 主题 | 触发时机 | 消息体 |
|---|---|---|
schoolFaceTopic/all:{设备sn} |
人脸库需要全量刷新(如设备首次接入、强制同步) | {"RefreshFaces":true} |
schoolFaceTopic/add:{设备sn} |
有新人脸加入该设备通行范围 | 新增的 FaceRecognition 对象数组 |
schoolFaceTopic/remove:{设备sn} |
有人脸移出该设备通行范围 | 移除的 FaceRecognition 对象数组 |
3.1 全量刷新(all)
平台向 schoolFaceTopic/all:{设备sn} 发布:
{"RefreshFaces":true}
设备收到后,应主动调用 /api/face/getFaceByEquipment(见第五章)按设备编码拉取完整人脸列表覆盖本地。
3.2 增量新增(add)
平台向 schoolFaceTopic/add:{设备sn} 发布 FaceRecognition 数组,示例:
[
{
"cardCode": "239C704D0100010101FFFFFFFFFFFFFF",
"equipmentId": 10831,
"faceUrl": "https://sharedlife-yhtschool.oss-cn-beijing.aliyuncs.com/2025/09/08/3af3209830854cd184a17d138258263e.jpg",
"id": 164,
"isTemp": false,
"loginName": "18849351456",
"userName": "马浩然"
}
]
3.3 增量移除(remove)
平台向 schoolFaceTopic/remove:{设备sn} 发布需删除的 FaceRecognition 数组,示例:
[
{
"cardCode": "239C704D0100010101FFFFFFFFFFFFFF",
"equipmentId": 10831,
"faceUrl": "http://sharedlife-yhtschool.oss-cn-beijing.aliyuncs.com/2024/11/14/a78dbff01e6b48b38b31e94252cdb594.png?Expires=999725285900&OSSAccessKeyId=LTAIBVqUQrV6kQax&Signature=ZSDB7MFRVIwvQZ1cSmxensgxvKY%3D",
"id": 53,
"isTemp": false,
"loginName": "18849351456",
"userName": "马浩然"
}
]
3.4 FaceRecognition 字段说明(下发与查询通用)
| 字段 | 类型 | 说明 |
|---|---|---|
id |
Long | 人脸记录主键 |
equipmentId |
Long | 设备 ID |
loginName |
String | 登录名(学号/手机号) |
userName |
String | 姓名 |
faceUrl |
String | 人脸照片地址(OSS) |
cardCode |
String | 卡号(刷卡识别用) |
isTemp |
Boolean | true=临时用户,false=正式用户 |
isRestricted |
Boolean | 是否限时/限次(临时用户) |
restrictionStartTimeStr / restrictionEndTimeStr |
String | 当日可通行时间段 |
maxAllowedCalls / callsMade |
Integer | 最大通行次数 / 已通行次数 |
四、设备 → 平台:通行(刷脸/刷卡)记录上报
4.1 方式 A:HTTP 实时接口
跨域已放开(@CrossOrigin(origins = "*")),设备可直接调用。
(1)刷脸使用 POST /api/face/useFace
请求体(Content-Type: application/json):
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
deviceID |
String | 是 | 设备编码 |
loginName |
String | 是 | 登录名(刷脸识别结果) |
isTemp |
Boolean | 否 | 是否临时用户,默认 false |
snapImage |
String | 是 | 抓拍人脸 base64(原文落库并上传 OSS/MinIO) |
confidence |
String | 是 | 识别相似度(如 "0.935" 或 "95.6") |
passTime |
String | 否 | 通行时间(设备端识别时间),格式 yyyy-MM-dd HH:mm:ss;不传则取服务器接收时间 |
正式用户示例:
{
"deviceID": "1c54e6124e8f",
"loginName": "18849351456",
"isTemp": false,
"snapImage": "data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD...",
"confidence": "0.935",
"passTime": "2026-07-23 10:40:00"
}
临时用户示例:
{
"deviceID": "1c54e6124e8f",
"loginName": "15210756478",
"isTemp": true,
"snapImage": "data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD...",
"confidence": "0.912",
"passTime": "2026-07-23 10:42:10"
}
说明:
useFace会做通行规则校验。正式用户需命中该设备的任意一条通行规则(消费者状态/学校/校区/院系/专业/班级/楼宇/楼层/房间/储物柜等),否则拒绝;临时用户需在其通行范围、时限、限次内。校验不通过不落库。
(2)刷卡使用刷脸设备 POST /api/face/useFaceByCardCode
通过卡编号在刷脸/通行设备上识别,平台按卡号解析出消费者后再走 useFace 逻辑。
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
deviceID |
String | 是 | 设备编码 |
cardCode |
String | 是 | 卡编号 |
{
"deviceID": "1c54e6124e8f",
"cardCode": "239C704D0100010101FFFFFFFFFFFFFF"
}
平台逻辑:按
cardCode查找消费者 → 设置loginName→ 复用useFace的通行规则校验与落库。找不到用户返回未找到用户。
4.2 方式 B:MQTT 通行记录上报
设备发布到主题 schoolFaceTopic/accessRecord/{设备sn},消息体为 JSON 字符串:
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
loginName |
String | 与 cardCode 二选一 |
登录名 |
isTemp |
Boolean | 否 | 是否临时用户 |
cardCode |
String | 与 loginName 二选一 |
卡号 |
snapImage |
String | 是 | 抓拍人脸 base64 |
confidence |
String | 是 | 识别相似度 |
passTime |
String | 否 | 通行时间(设备端识别时间),格式 yyyy-MM-dd HH:mm:ss;不传则取服务器接收时间 |
登录名方式:
{
"loginName": "20210001",
"isTemp": false,
"snapImage": "/9j/4AAQSkZJRgABAQAAAQABAAD...",
"confidence": "0.912",
"passTime": "2026-07-23 10:40:00"
}
卡号方式:
{
"cardCode": "100200300",
"snapImage": "data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD...",
"confidence": "95.6",
"passTime": "2026-07-23 10:41:30"
}
平台回调中:必须携带
loginName或cardCode之一,否则丢弃。记录通过saveAccessRecordFromMqtt直接落库(不做通行规则校验,仅做设备存在性、用户解析、抓拍图上传、安防平台推送)。
4.3 返回码对照(HTTP 方式)
| 返回 msg | 含义 |
|---|---|
保存成功! |
上报成功(可能携带已通行次数) |
未找到设备! |
deviceID 对应的设备不存在 |
未找到用户! |
loginName / cardCode 查不到人 |
未配置通行规则! |
该设备未配置通行规则,拒绝正式用户 |
用户不符合通行规则! |
正式用户未命中任何规则 |
临时用户不在通行范围内! |
临时用户未授权该设备 |
临时用户不在可通行时间内! |
临时用户超出限时窗口 |
临时用户超过通行次数! |
临时用户已达限次 |
卡编号不能为空 |
入参校验失败 |
五、平台 → 设备:人脸信息查询
5.1 按设备获取人脸信息 POST /api/face/getFaceByEquipment
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
deviceID |
String | 是 | 设备编码 |
isTemp |
Boolean | 否 | 不传=正式+临时;true=仅临时;false=仅正式 |
{ "deviceID": "1c54e6124e8f" }
返回 FaceRecognition 数组(字段见 3.4),用于设备端全量刷新本地人脸库。
5.2 增量轮询 GET /api/face/faceChange?code={设备编码}
返回增量集合,供未使用 MQTT 的设备轮询:
{
"add": [ ...FaceRecognition数组... ],
"remove": [ ...FaceRecognition数组... ]
}
5.3 查询 24 小时变动记录 GET /api/face/getFaceChangeRecords?deviceID={设备编码}
返回过去 24 小时该设备的 ADD / REMOVE 变动明细:
{
"addList": [ ... ],
"removeList": [ ... ]
}