ThinkPHP 访客预约系统人脸机对接:Outbox 解耦方案与录入删脸全链路(海康 + FS 实战)

张开发
2026/6/6 21:40:33 15 分钟阅读

分享文章

ThinkPHP 访客预约系统人脸机对接:Outbox 解耦方案与录入删脸全链路(海康 + FS 实战)
摘要国内园区、写字楼、工厂等场景下企业访客预约系统常需同时对接海康 ISAPI 与第三方 FS 人脸机。本文记录一套基于 ThinkPHP 的私有化访客管理项目在改造硬件层时的做法——通过 Outbox 发件箱模式把「员工录入、访客人脸上传、到期删脸」与多厂商协议解耦并补充飞书、钉钉通讯录同步与门禁下发的边界。文中架构与代码路径来自实际交付环境团队内部称为海之心访客预约系统供同类系统二次开发参考。关键词访客预约系统 · Outbox 模式 · ThinkPHP · 海康人脸机 · FS 人脸机 · 访客人脸下发 · 飞书钉钉同步 · 企业门禁对接 · 私有化部署一、背景园区访客场景里为什么不用「一种 face_type 走天下」在国内企业园区、机关单位、制造工厂等本地化部署的访客管理场景里门禁侧往往有三类刚性需求员工通行后台建档、PC 端录脸、改脸、离职删人人脸需同步到多台设备。访客预约线上填报、多级审核通过后按预约时段下发人脸与核销二维码到期自动从设备清除。多厂商并存现场通常已上线海康威视后续又增补 FS 等 HTTP 协议人脸机——不能因改一套 PHP 就废掉原有设备投资。笔者所在团队维护的这套访客预约产品海之心访客预约系统ThinkPHP MySQL支持宝塔/Linux 私有化部署早期与多数同类系统一样后台选一个face_type海康 / RV1109 / FS 内置所有协议堆进FaceHandler。随着某客户现场设备从「纯海康」变为「海康 四台 FS」问题逐渐暴露FS 协议与海康 ISAPI 差异大继续硬塞进 PHP 核心维护成本陡增。用 Python 独立进程对接 FS 更顺手协议升级、本机拉图、失败重试但业务事件仍必须从 PHP 业务层可靠产出。海康链路已靠计划任务 异步队列跑稳不宜为 FS 重写整条链路。最终方案海康走内置链路 Outbox 并行对接 FS——业务只「记一笔待同步事件」外部消费者负责真正调设备。下文按此展开读者可将思路迁移到自研或其它商用访客系统。二、总体架构┌─────────────────────────────────────────────────────────────────┐ │ 业务入口后台员工 / PC录脸 / 访客审核 / 到期删除 / 删员工 │ └────────────────────────────┬────────────────────────────────────┘ │ ┌─────────────────┴─────────────────┐ ▼ ▼ face_type 海康(2) face_outbox_enable 1 PHP FaceHandler FaceOutboxHandler 宝塔计划任务 写 registration_face_outbox │ │ ▼ ▼ 海康 ISAPIUserInfo 人脸 Python 消费者 pull → ack 现场海康设备 POST FS addface / delface 现场 FS 设备三条原则原则说明face_type与 Outbox独立主系统可以是海康Outbox 专门给 FS不要face_type4 又开 Outbox避免 PHP 内置 FS 与 Python 重复下发业务代码只enqueue不阻塞 HTTP审核接口先返回设备同步异步完成该架构在某客户内网机房 多台人脸机分区部署的环境中已稳定运行Web 与 Python 消费者同机或同网段设备仅访问内网地址符合国内园区常见网络隔离要求。三、Outbox 方案设计核心3.1 什么是 OutboxOutbox发件箱模式在微服务与集成领域并不新鲜业务事务成功时在同一系统内写入一条「待外发事件」由独立进程异步消费。在海之心访客预约系统当前的硬件改造里具体落地为表registration_face_outbox生产者PHPFaceOutboxHandler::enqueue*消费者scripts/face_outbox_fs_consumer.py可替换为 Java/Go只要实现 pull/ackAPI/resource/faceoutbox/pull|ack|stats这样 PHP 不必嵌入 FS 的addfaceJSON 细节只需描述「谁、什么操作、脸图在哪、有效期多久、核销卡号多少」——对任意访客预约类系统都具有参考价值。3.2 表结构与状态机-- 核心字段摘要actionupsert|deletebiz_type staff|visitor biz_id 员工 id 或 订单 id user_code 设备人员编号 HK000100/ORD00123 payload JSONface_url、valid_from、qrcode、ic… idempotency_key md5(action|biz_type|biz_id)status0待处理1处理中2成功3失败幂等同一员工/订单在「待处理/处理中」时再次 enqueue会更新原记录而不是插多条避免改脸一次产生几十条重复任务——这对高并发审核的访客系统尤为重要。3.3 开放 API接口作用GET /resource/faceoutbox/pull?tokenlimit20拉取 pending标记为 processingPOST /resource/faceoutbox/ack批量确认{id, success, message}GET /resource/faceoutbox/stats?token监控 pending/failed 数量鉴权face_outbox_secret支持 HeaderX-Face-Outbox-Token或参数token。3.4 后台开关管理后台系统设置 → 硬件设置本文所述系统与海之心访客预约系统配置项一致人脸机类型海康威视face_type2第三方人脸 Outbox开启Outbox 接口密钥与 Pythonface_outbox_config.json中token一致四、人员录入、人脸下发、删除——全链路说明下面按员工与访客分开并标明海康与 Outbox 各自做什么。这也是访客预约系统对接门禁时开发最常排查的几条路径。4.1 员工后台新增Base/addstafflist触发代码app/admin/controller/Base.php新增员工入库 → face_type0 时 FaceHandler::addtask海康/RV1109 人员任务 → FaceOutboxHandler::enqueueStaffUpsert($id, admin_add)步骤海康 (face_type2)Outbox → FS新增仅有姓名手机addtask 写人员信息无脸则跳过脸图无人脸不入队enqueue 要求 faceimg 非空新增时带了 faceimgaddtask → syncStaffToHikvision人员 Valid 至 2033pull 后 addface员工无有效期人脸真正上设备需后续改脸 / PC录脸触发 syncStaffFaceToHikvision有 faceimg 即 upsert人员编号registration_base_stafflistinfo.hkidno默认HK000{员工id}与海康、FS 的usrid一致。员工有效期海康syncStaffToHikvision()内写死2019-08-01~2033-08-01FS 员工不传times/timee长期白名单。4.2 员工PC 上传人脸Approve 录脸触发代码app/index/controller/Approve.php保存 faceimg 到 storage → face_type2: syncStaffFaceToHikvision入队 registration_hikvision_sync_log → face_type1/4: addtask → 任意开启 Outbox: enqueueStaffUpsert($uid, pc_upload)海康异步队列由计划任务/resource/task/syncHikvisionFaceQueue消费执行syncStaffToHikvision确保设备上有人员删除旧脸 → 上传新脸FDSetUpOutbox 侧 Pythonpull 事件本机public_root读图转base64避免 FS 拉不到外网 URL向每台 FS 发cmdaddfaceack 成功/失败国内很多园区访客系统的 PC 录脸页都走类似链路浏览器上传 → 业务库落盘 → 异步下发门禁避免接口超时。4.3 员工后台编辑 / 删除编辑Base/editstafflist海康仅faceimg 变化时syncStaffFaceToHikvision Outbox upsertRV1109/FS内置每次编辑 addtask Outbox upsert删除Base删员工FaceHandler::delstaff → 海康: removeStaffFromHikvision删人删脸 → Outbox: enqueueStaffDelete → Python delfaceOutbox delete 的 payload 只需user_codePython 构造{cmd:delface,body:{delall:0,usrids:[HK000100]}}4.4 访客审核通过触发代码app/handler/OrderHandler.php终审 status3FaceHandler::addtask(orderid) // 海康/FS内置 访客人脸队列 FaceOutboxHandler::enqueueVisitorUpsert($orderId, order_approve) shutdown: runVisitorFaceSyncWorker // 响应返回后再跑海康下发Outbox 访客 payload 要点字段来源FS exinfo 映射user_codeORD00{orderId}addface.usridvalid_from / valid_to订单 permission / 表单时间exinfo.times / timeeUnix 秒Asia/Shanghai 东八区face_url / face_path表单 validate15 人脸图img base64qrcode订单核销码入队前自动生成—icresolveFsIc(qrcode)exinfo.ic十进制卡号支持扫码/刷卡访客必须有人脸图才入队二维码在入队前若为空会调用OrderHandler::generateOrderQrcode()。时间戳统一按中国本地时区解析避免国内现场常见的「有效期偏 8 小时」问题。Python 侧 exinfo 示例FS 人脸机接口文档 V1.0.5 §4.2.1{req:uuid,cmd:addface,usrid:ORD00123,name:张三,img:base64,exinfo:{utype:0,times:1717372800,timee:1717459199,ic:50123456}}4.5 访客到期删除触发计划任务/resource/task/delHikvisionQrcode遍历 registration_hikvision_user 已到期记录 → FaceOutboxHandler::enqueueVisitorDelete(orderId, hkidno, visitor_expire) → 海康 processHikvisionVisitorDeleteRow 删设备用户Python 对 Outbox delete 事件执行delface与海康删人并行互不影响。访客预约系统若只做「下发不做清理」设备人员会无限膨胀——到期删除应与审核通过同等重要。五、Python 消费者实现要点目录scripts/文件职责face_outbox_fs_consumer.py轮询 pull、下发、ack支持--once给 cronfs_face_protocol.pyOutbox 事件 → FS 协议拉图 base64ic/时间戳解析face_outbox_config.jsonbase_url、token、fs_devices、public_root生产推荐国内宝塔面板 cron每分钟cd/www/wwwroot/你的站点/scripts\python3 face_outbox_fs_consumer.py--once/www/wwwlogs/fs-face-outbox.log21关键配置{base_url:http://127.0.0.1,token:与后台 Outbox 密钥一致,prefer_img_base64:true,public_root:/www/wwwroot/站点/public,fs_devices:[{ip:192.168.1.101,port:9000}]}prefer_img_base64true是现场踩坑总结不要让 FS 设备自己去拉 face_url内网设备往往访问不了公网域名会导致 Outbox status2 但设备无人脸。成功判定HTTP 200 且响应 JSONcode 0不能只看 HTTP 状态码。六、海康内置链路与 Outbox 并行Outbox不替代海康以下计划任务需继续保留任务频率作用addstaff1 分钟新员工人员信息上设备syncHikvisionFaceQueue1 分钟员工/访客人脸异步重试syncHikvisionUser1 分钟访客用户盒子/MQTT 场景syncHikvisionQrcode10~30 秒访客二维码/卡号delHikvisionQrcode1 分钟访客到期删除员工在海康上的 Valid 长期有效访客时间与 Outbox 共用resolveVisitorPermissionTimes()逻辑保证前台预约时段与设备一致。七、飞书 / 钉钉通讯录同步与人脸的关系国内中大型组织普遍用飞书、钉钉维护通讯录。海之心访客预约系统已接入二者部门/人员同步但需要明确边界重要结论飞书、钉钉同步只写员工库不会自动下发人脸。能力钉钉飞书入口后台addstafflistcztype2 / cronsyncDingtalkStaffcztype3 /syncFeishuStaff行为按部门拉人写入registration_base_stafflist同上webtype3人脸不触发addtask / Outbox不触发离职—removeOrphanStaff会调海康删人 delstaff可带 Outbox delete因此国内典型实施流程是定时同步飞书/钉钉组织架构员工首次通行前在PC 录脸页或后台上传人脸录脸成功后走第四节的海康 Outbox 双下发。若需要「同步通讯录即自动占位设备人员」要在DingTalkHandler/FeiShuHandler入库后主动调用enqueueStaffUpsert当前未做属于扩展点。做访客系统选型或二开时建议把「OA 同步」与「门禁下发」在方案阶段就分开评估避免客户误解「同步完就能刷脸」。八、端到端时序访客审核FS人脸机海康Python消费者计划任务face_outbox 表ThinkPHP审核员FS人脸机海康Python消费者计划任务face_outbox 表ThinkPHP审核员shutdown 触发海康下发审核通过generateOrderQrcodeenqueueVisitorUpsertaddtask 访客人脸返回成功syncHikvisionFaceQueuepulladdface exinfo(ic,times,timee)ack success九、部署检查清单执行scripts/face_outbox.sql建表后台face_type海康Outbox开启配置密钥人脸机管理只配海康设备FS IP 写在 Pythonfs_devices部署 Python 脚本与face_outbox_config.json配置 cron--once保留海康相关计划任务验证改一名员工人脸 → 查 Outbox 表 → 看 Python 日志 → FS 上 qureyfaceSQL 快速查看队列SELECTid,action,biz_type,user_code,status,error_msg,updatetimeFROMregistration_face_outboxORDERBYidDESCLIMIT10;十、常见问题现象原因处理Outbox 无记录未开启 / 员工无人脸 / 访客无人脸图查配置与 faceimgstatus2 但 FS 无人脸img_url 设备拉不到图prefer_img_base64 public_rootstatus1 卡住Python 崩溃未 ack改回 status0 或 ack 失败访客 FS 时间差 8 小时时间戳当时区 UTC已统一 Asia/Shanghai重复下发face_type4 且 Outbox 开改为 face_type2 Outbox飞书同步后设备无人同步不下发人脸PC 录脸或后台上传十一、扩展与演进新厂商人脸机实现新的消费者复用 pull/ack API解析同一套 payload 即可。按区域下发当前员工 FS 为配置内全量设备若要「食堂/办公楼层分设备」需在 payload 增加区域字段并在 Python 过滤fs_devices。纯数字核销码FSexinfo.ic要求十进制若需扫码内容与 ic 完全一致可将generateOrderQrcode改为纯数字策略。十二、相关代码索引便于二次开发app/handler/FaceOutboxHandler.php # 入队、pull、ack、访客时间、ic 解析 app/api/controller/FaceOutbox.php # HTTP API app/admin/controller/Base.php # 员工增删改 enqueue app/index/controller/Approve.php # PC 录脸 enqueue app/handler/OrderHandler.php # 访客审核 enqueue app/enterprise/handler/FaceHandler.php # 海康/FS 内置下发 scripts/face_outbox_fs_consumer.py # Python 消费者 scripts/fs_face_protocol.py # FS 协议与 exinfo 组装 docs/hardware/ # 项目内维护的架构文档结语Outbox 的价值在于业务系统只表达「发生了什么」新增脸、删脸、访客通过、访客过期设备怎么对接由消费者决定。在海康 FS 混合部署的访客场景里这套方案让 PHP 保持清晰、Python 专注协议、计划任务兜住海康异步重试三者并行而不互相拖累。本文实践来自海之心访客预约系统在 ThinkPHP 技术栈下的一次硬件层演进若你在做类似的多厂商门禁对接、企业访客管理系统二开或园区智能化集成文中 Outbox 表设计、pull/ack 约定与 FS exinfo 字段映射可直接借鉴。更细的字段说明见项目内docs/hardware/与scripts/FACE_OUTBOX_README.md。关于作者 / 项目说明海之心访客预约系统由成都海之心科技维护面向国内企事业单位提供访客登记、多级审核、人脸门禁与飞书钉钉通讯录等能力支持私有化部署。本文以技术复盘为主不代表特定厂商设备认证结论。建议 CSDN 标签访客预约系统OutboxThinkPHP海康威视人脸识别企业门禁飞书钉钉Python私有化部署文章版本2026-06含访客 exinfo.ic 核销卡号、base64 拉图、幂等 Outbox适配国内东八区与宝塔 cron 部署习惯。

更多文章