共享棋牌室智能门禁系统设计与实践:从密码锁到人脸识别的技术演进
一、项目背景
去年接手了一个共享棋牌室的智能化改造项目。客户有8个包间,希望实现24小时无人值守运营。最初使用的是远程密码锁,但在实际运营中暴露出一系列问题。
本文从技术角度记录整个系统的设计思路、选型过程、架构实现及落地经验,希望对从事物联网、智能硬件或共享经济相关开发的同行有所参考。
二、原有系统痛点分析
2.1 密码锁的技术缺陷
原有密码锁本质是一个“静态凭证验证系统”。核心逻辑如下:
用户预订 → 系统生成密码 → 用户输入密码 → 锁具验证 → 开门
这种设计存在几个根本性问题:
1. 身份与凭证解耦
密码作为凭证,与用户身份没有任何绑定关系。只要密码有效,任何知晓密码的人都能开门。这导致密码被随意转发、多人共享,逃单率居高不下。
2. 无行为追溯能力
系统只记录“哪个密码在什么时间被使用”,不记录“谁使用了密码”。发生安全事故时,无法提供有效的审计线索。
3. 缺乏持续控制能力
用户进入后,系统失去对用户行为的控制能力。超时占用、夜间滞留等问题无法自动处理,需要人工干预。
4. 运维成本高
客户每天需要处理大量售后问题:密码失效、忘记密码、超时纠纷等,实际上充当了24小时客服。
2.2 技术层面的局限性
从系统架构角度看,密码锁方案存在以下技术局限:
-
无用户态管理:无法建立用户身份体系
-
权限模型简单:仅有“有效/无效”两种状态,无法支持精细化权限控制(如时段限制、次数限制)
-
数据孤岛:通行数据无法与业务系统(订单、会员、财务)打通
-
离线能力弱:依赖网络下发密码,断网时无法处理新订单
三、需求分析与技术选型
3.1 核心需求
经过与客户多轮沟通,梳理出以下核心需求:
| 需求类别 | 具体描述 |
|---|---|
| 身份识别 | 明确知道“谁”进了门,而非“哪个密码”进了门 |
| 行为追溯 | 完整记录进出时间,支持按用户、时间、设备多维度查询 |
| 权限自动化 | 会员到期自动失效,续费自动恢复;临时用户限时自动回收 |
| 多业态支持 | 不仅支持棋牌室,还要能扩展到景区、自习室等场景 |
| 集中管理 | 一个后台管理所有门店,支持多租户隔离 |
| 离线可用 | 网络中断时门禁仍能正常工作,数据本地缓存 |
3.2 技术方案选型
3.2.1 身份识别技术对比
| 技术方案 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|
| 密码 | 成本低、部署简单 | 无身份绑定、易泄露 | 低安全要求场景 |
| IC卡 | 成本适中 | 需发卡、易丢失、无生物特征 | 企业内部场景 |
| 二维码 | 灵活、成本低 | 依赖手机、需网络、可截图分享 | 临时访客场景 |
| 蓝牙 | 体验较好 | 需APP、配对复杂 | 社区门禁场景 |
| 人脸识别 | 体验好、不可伪造、无接触 | 成本相对高、受环境影响 | 共享空间、高安全场景 |
考虑到棋牌室对安全性和用户体验的要求,选择人脸识别作为主认证方式,同时保留身份证和二维码作为备选。
3.2.2 人脸识别算法选型
对比了市面上主流的人脸识别方案:
| 方案 | 识别速度 | 活体检测 | 离线支持 | 成本 |
|---|---|---|---|---|
| 虹软ArcFace | <0.3s | 支持 | 支持 | 中 |
| 商汤SenseTime | <0.2s | 支持 | 需联网 | 高 |
| 百度AI | <0.3s | 支持 | 需联网 | 中 |
| 海康自研 | <0.5s | 支持 | 支持 | 中 |
综合考虑成本、离线能力和部署灵活性,选择了虹软ArcFace SDK作为人脸识别引擎。
3.2.3 硬件选型
硬件层面主要考虑:
-
处理器:RK3399/RK3568,性能足够,功耗适中
-
摄像头:双目摄像头,支持红外活体检测
-
屏幕:5寸/7寸IPS屏,户外场景需高亮屏
-
通信:4G+WiFi双模,适应不同网络环境
-
存储:8GB eMMC,可缓存5000+条通行记录
3.2.4 平台架构选型
-
后端:Spring Boot + MyBatis Plus,MySQL主从 + Redis缓存
-
前端管理端:Vue3 + Element Plus
-
用户端:微信小程序
-
设备通信:MQTT协议 + HTTP API双通道
-
部署:阿里云ECS + RDS + OSS
3.3 供应商选择
对比了3家供应商后,最终选择了中优云联的方案。主要原因:
-
完整的SaaS平台:支持多门店、多设备集中管理
-
断网离线存储:满足棋牌室地下室网络不稳定的需求
-
人证核验能力:符合后续扩展需求
-
开放API:支持与现有业务系统对接
四、系统架构设计
4.1 整体架构
系统采用典型的三层架构:
┌─────────────────────────────────────────────────┐ │ 应用层 │ │ ┌──────────┐ ┌──────────┐ ┌──────────┐ │ │ │用户小程序│ │管理后台 │ │数据大屏 │ │ │ └──────────┘ └──────────┘ └──────────┘ │ ├─────────────────────────────────────────────────┤ │ 平台层 │ │ ┌──────────────────────────────────────┐ │ │ │ SaaS管理平台 │ │ │ │ 设备管理│用户管理│权限管理│数据统计 │ │ │ └──────────────────────────────────────┘ │ │ ┌──────────────────────────────────────┐ │ │ │ 设备接入层 │ │ │ │ MQTT Broker │ HTTP API │ 数据同步 │ │ │ └──────────────────────────────────────┘ │ ├─────────────────────────────────────────────────┤ │ 设备层 │ │ ┌──────────┐ ┌──────────┐ ┌──────────┐ │ │ │人脸识别终端│ │身份证阅读器│ │二维码扫描器│ │ │ └──────────┘ └──────────┘ └──────────┘ │ └─────────────────────────────────────────────────┘
4.2 核心模块设计
4.2.1 设备端架构
设备端采用分层设计:
┌─────────────────────────────────────┐ │ 应用层 │ │ ┌─────────────┐ ┌─────────────┐ │ │ │ 识别逻辑 │ │ 权限校验 │ │ │ └─────────────┘ └─────────────┘ │ ├─────────────────────────────────────┤ │ 服务层 │ │ ┌─────────────┐ ┌─────────────┐ │ │ │ 人脸SDK封装 │ │ 通信模块 │ │ │ └─────────────┘ └─────────────┘ │ ├─────────────────────────────────────┤ │ 数据层 │ │ ┌─────────────┐ ┌─────────────┐ │ │ │ SQLite │ │ 本地文件系统│ │ │ └─────────────┘ └─────────────┘ │ ├─────────────────────────────────────┤ │ 硬件层 │ │ │ 摄像头 │ 屏幕 │ 继电器 │ 4G模块│ │ └─────────────────────────────────────┘
4.2.2 权限模型设计
权限模型支持灵活的权限策略配置:
| 权限类型 | 说明 | 有效期 | 使用限制 |
|---|---|---|---|
| 会员权限 | 月卡/季卡用户 | 固定时间段 | 不限次 |
| 访客权限 | 临时体验用户 | 指定时长 | 单次有效 |
| 预约权限 | 景区预约用户 | 指定时段 | 时段内有效 |
| 管理员权限 | 运营管理人员 | 永久/临时 | 不限 |
权限表结构设计:
CREATE TABLE `device_permission` ( `id` bigint(20) NOT NULL AUTO_INCREMENT, `user_id` varchar(64) NOT NULL COMMENT '用户ID', `device_id` varchar(64) DEFAULT NULL COMMENT '设备ID,空表示全部门店', `permission_type` tinyint(4) NOT NULL COMMENT '1-会员 2-访客 3-预约 4-管理员', `start_time` datetime NOT NULL COMMENT '生效时间', `end_time` datetime NOT NULL COMMENT '失效时间', `max_uses` int(11) DEFAULT NULL COMMENT '最大使用次数,NULL表示不限', `used_count` int(11) DEFAULT '0' COMMENT '已使用次数', `status` tinyint(4) DEFAULT '0' COMMENT '0-有效 1-失效', `created_at` datetime DEFAULT CURRENT_TIMESTAMP, `updated_at` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY (`id`), KEY `idx_user_id` (`user_id`), KEY `idx_device_id` (`device_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
4.2.3 通行记录表设计
CREATE TABLE `access_record` ( `id` bigint(20) NOT NULL AUTO_INCREMENT, `device_id` varchar(64) NOT NULL COMMENT '设备ID', `user_id` varchar(64) NOT NULL COMMENT '用户ID', `verify_type` tinyint(4) NOT NULL COMMENT '1-人脸 2-身份证 3-二维码', `verify_result` tinyint(4) NOT NULL COMMENT '1-通过 0-不通过', `face_image_url` varchar(512) DEFAULT NULL COMMENT '抓拍人脸照片URL', `idcard_info` json DEFAULT NULL COMMENT '身份证信息', `entry_time` datetime NOT NULL COMMENT '进门时间', `exit_time` datetime DEFAULT NULL COMMENT '出门时间', `duration_minutes` int(11) DEFAULT NULL COMMENT '停留时长(分钟)', `sync_status` tinyint(4) DEFAULT '0' COMMENT '0-未同步 1-已同步', `created_at` datetime DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`id`), KEY `idx_user_id` (`user_id`), KEY `idx_device_id` (`device_id`), KEY `idx_entry_time` (`entry_time`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
4.3 断网离线存储方案
这是系统设计中的一个关键点。棋牌室多位于地下室,网络信号不稳定。我们设计了以下离线存储机制:
4.3.1 数据同步策略
┌─────────────────────────────────────────────────┐
│ 云端平台 │
└─────────────────────────────────────────────────┘
↑↓
┌───────────────────┐
│ 同步服务 │
│ (增量同步) │
└───────────────────┘
↑↓
┌─────────────────────────────────────────────────┐
│ 设备本地 │
│ ┌─────────────┐ ┌─────────────┐ │
│ │ 权限表(本地)│ │ 记录表(本地)│ │
│ │ (SQLite) │ │ (SQLite) │ │
│ └─────────────┘ └─────────────┘ │
└─────────────────────────────────────────────────┘
4.3.2 离线识别流程
用户刷脸
↓
本地人脸识别
↓
查询本地权限表
↓
┌─────────────────────────────────────┐
│ 判断权限是否有效 │
│ - 是否在有效期内 │
│ - 是否超过使用次数 │
└─────────────────────────────────────┘
↓
通过 → 开门 + 记录本地
不通过 → 拒绝开门
4.3.3 数据缓存策略
-
权限数据:设备启动时同步全量权限,之后每5分钟增量同步
-
通行记录:本地最多缓存5000条,超过后覆盖最旧记录
-
同步机制:网络恢复后,批量上传本地记录,上传成功后删除本地记录
五、关键技术实现
5.1 人脸识别SDK集成
基于虹软ArcFace SDK的实现要点:
// 人脸识别服务封装
public class FaceRecognitionService {
private FaceEngine faceEngine;
// 初始化引擎
public void init() {
faceEngine = new FaceEngine();
faceEngine.activeOnline(context, appId, sdkKey);
faceEngine.setFaceLiveType(FaceEngine.FACE_LIVE_TYPE_RGB_IR);
}
// 1:1人脸比对
public float compare(byte[] face1, byte[] face2) {
FaceFeature feature1 = faceEngine.extractFaceFeature(face1);
FaceFeature feature2 = faceEngine.extractFaceFeature(face2);
return faceEngine.compareFaceFeature(feature1, feature2);
}
// 活体检测
public boolean livenessCheck(byte[] rgbImage, byte[] irImage) {
return faceEngine.checkLive(rgbImage, irImage) > 0;
}
}
5.2 设备通信协议
采用MQTT + HTTP双通道设计:
-
MQTT:用于实时指令下发(如远程开门、权限同步)
-
HTTP:用于批量数据上报(如通行记录同步)
// MQTT消息格式
{
"topic": "/device/{deviceId}/command",
"payload": {
"cmd": "sync_permission",
"data": {
"permissions": [...],
"timestamp": 1700000000
}
}
}
5.3 人证核验实现
人证核验流程:
1. 用户刷身份证 → 读取身份证信息(姓名、证件号、照片) 2. 现场抓拍人脸 3. 调用1:1比对算法,比对现场人脸与身份证照片 4. 比对通过 → 记录身份证信息,开门 比对不通过 → 拒绝开门
身份证信息读取使用公安部认证的二代身份证阅读器模组,通过串口通信。
5.4 SaaS平台多租户设计
// 多租户数据隔离 - MyBatis拦截器实现
@Intercepts({@Signature(type = StatementHandler.class, method = "prepare", args = {Connection.class, Integer.class})})
public class TenantInterceptor implements Interceptor {
@Override
public Object intercept(Invocation invocation) throws Throwable {
StatementHandler statementHandler = (StatementHandler) invocation.getTarget();
MetaObject metaObject = SystemMetaObject.forObject(statementHandler);
MappedStatement mappedStatement = (MappedStatement) metaObject.getValue("delegate.mappedStatement");
// 获取当前租户ID
String tenantId = TenantContext.getCurrentTenant();
// 动态拼接SQL,添加租户过滤条件
String originalSql = statementHandler.getBoundSql().getSql();
if (shouldAddTenantCondition(mappedStatement)) {
String newSql = addTenantCondition(originalSql, tenantId);
metaObject.setValue("delegate.boundSql.sql", newSql);
}
return invocation.proceed();
}
}
六、系统部署与落地
6.1 部署架构
┌─────────────────────────────────────────────────┐
│ 阿里云ECS │
│ ┌─────────────┐ ┌─────────────┐ │
│ │ 应用服务器 │ │ 应用服务器 │ (多节点) │
│ └─────────────┘ └─────────────┘ │
│ ┌─────────────┐ ┌─────────────┐ │
│ │ MySQL │ │ Redis │ (主从) │
│ └─────────────┘ └─────────────┘ │
│ ┌─────────────┐ ┌─────────────┐ │
│ │ OSS │ │ MQTT Broker│ │
│ └─────────────┘ └─────────────┘ │
└─────────────────────────────────────────────────┘
↑
┌───┴───┐
│ 4G │
└───┬───┘
┌───────────────┼───────────────┐
↓ ↓ ↓
┌─────────┐ ┌─────────┐ ┌─────────┐
│ 门店1 │ │ 门店2 │ │ 门店3 │
│ 8个设备 │ │ 6个设备 │ │ 10个设备│
└─────────┘ └─────────┘ └─────────┘
6.2 实施步骤
-
硬件安装:替换原有密码锁,安装人脸识别终端,约30分钟/门
-
网络配置:设备配置WiFi或4G网络,确保云端连通
-
权限导入:导入现有会员数据,同步权限
-
灰度测试:先开放1-2个包间测试,稳定后全量切换
-
用户培训:现场指导用户使用,张贴使用说明
6.3 落地效果
系统上线3个月后的数据:
| 指标 | 改造前 | 改造后 | 变化 |
|---|---|---|---|
| 前台人力成本 | 48000元/年 | 0 | -100% |
| 逃单损失 | ~8000元/年 | 0 | -100% |
| 客诉处理时间 | 2小时/天 | 0.2小时/天 | -90% |
| 超时纠纷 | 5-10次/月 | 0 | -100% |
| 通行数据可追溯率 | 0% | 100% | - |
七、技术总结与展望
7.1 经验总结
1. 离线能力是共享场景的刚需
很多开发者容易忽略这一点,认为现在网络覆盖很好。但实际上地下室、电梯间等场景网络不稳定是常态。设备必须具备本地存储和本地判断能力。
2. 权限模型设计要足够灵活
不同业态对权限的要求差异很大。棋牌室需要按小时计费,景区需要按时段预约,自习室需要按次计费。设计一个通用的权限模型非常重要。
3. 人证核验不只是“刷脸+刷证”
实际使用中,老年人刷脸通过率低、光线影响大等问题都需要考虑。需要设计降级方案,比如允许管理员远程开门。
4. 数据同步要处理好冲突
断网期间产生的本地记录,恢复网络后可能遇到数据冲突(如用户权限已变更)。需要设计合理的冲突解决策略。
7.2 下一步规划
-
智能调度:基于包间使用数据,动态调整价格和促销策略
-
异常预警:超时未出、夜间异常进入等场景自动报警
-
客流分析:基于进出数据,分析用户行为,优化运营策略
-
边缘计算:在设备端实现更多本地计算,减少云端依赖
八、参考资料
-
虹软ArcFace人脸识别SDK开发文档
-
《人脸识别技术在门禁系统中的应用研究》
-
MQTT协议规范v5.0
-
Spring Boot多租户架构设计实践
本文首发于CSDN,欢迎技术交流。
标签:#人脸识别 #门禁系统 #物联网 #共享经济 #系统架构
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐

所有评论(0)