资讯动态

基于人脸识别的考勤签到小程序设计:从选型到上线避坑指南

发布时间:2026/9/30 19:59:11 来源:尧图企业网站定制
简介一份基于人脸识别的考勤签到小程序毕业设计论文PDF面向高校学生、小程序开发者及教育信息化研究者用于解决传统手动点名与刷卡签到效率低、易被替代的痛点。内容从引言、国内外研究现状、需求分析到系统架构、技术实现、数据库管理与测试评估完整展示了基于微信小程序WXMLWXSSJavaScript与人脸识别CNN模型的设计方案并给出教师端/学生端双端业务流程、云端人脸接口对接、数据库设计方法及系统功能测试结果。资源共1个PDF文件约1.54MB结构清晰、章节完整已有473人学习。读者可参考其中人脸识别签到全流程的落地思路包括卷积神经网络选型、后台服务器设置、学生人脸数据比对等细节作为毕业设计、课程项目或实际考勤系统开发的直接蓝本也可为后续结合5G、多生物识别技术的研究提供起点。1. 基于人脸识别的考勤签到小程序设计一份设计稿如何变成每天早晨的真实打卡行政群里最常听到的一句话是“谁又忘打卡了”。如果换成小程序里的一个人脸识别签到流程员工打开微信、对准摄像头、一秒完成打卡管理员在后端能看到迟到、早退、缺卡这套东西从设计文档到可运行系统真正的难点并不在人脸识别算法本身而在“采集图像是否合格、活体检测有没有被绕过、打卡记录是否可靠”这三件事上。基于人脸识别的考勤签到小程序设计解决的正是企业或学校场景里“人、时间、地点”三要素的自动化核验问题。适合行政管理者、独立开发者和准备做企业内部工具的技术团队下面从选型开始完整拆一遍落地路径。2. 人脸识别链路选型先定识别在哪跑再谈打卡体验2.1 人脸识别三种主流行法端侧、云端 API 与端云协同很多项目第一版喜欢把“人脸识别”四个字当成一个黑匣子直接把 OpenCV 的 Haar 特征拿来做检测再用一个简单特征比对就上线。考勤签到这样涉及员工权益的场景这条路走不通。主流的可落地做法有三种区别在于模型跑在哪里、数据从哪里来。第一种是纯端侧方案典型硬件是固定点位的人脸识别门禁机或者像人脸识别 K10 行空板这类带摄像头和 NPU 的开发板。模型直接跑在设备上不依赖办公网络响应可以做到 200 毫秒以内。但小程序端很难复刻这种体验小程序包体有限制本地推理能力受手机性能影响很大而且前端直接加载模型会让首次启动时间变得不可接受。第二种是云端 API 方案也就是把“注册人脸”和“人脸搜索”两个能力交给云服务。小程序端只负责拍照和上传云端返回最相似的人以及相似度分数。这是考勤签到小程序最常见的做法集成成本低识别精度由服务方保证适合员工规模在几十到几千人的场景。代价是每次比对都需要网络请求而且会产生接口调用费用。第三种是端云协同端侧做人脸检测和活体动作引导云端做人脸比对。这一种兼顾了体验和安全性但开发量最大。对于大多数团队来说第一步先用云端 API 把流程跑通后续再根据成本逐步把活体检测或人脸质量判断挪到端侧是性价比最高的路径。我通常会在项目一开始就画一张选型表把团队真实约束摆出来而不是先选最酷的方案。维度端侧门禁机云端 API端云协同实时性毫秒级视网络约 0.5-2 秒0.3-1 秒离线可用可以不可以部分可以识别精度依赖硬件与模型服务方持续迭代较高综合较优实施成本硬件采购高按调用量计费开发成本高数据隐私数据不出设备原图与特征都在云端原图抽样上云适用场景固定闸机、单一出入口小程序签到、移动办公对安全要求高的企业2.2 人脸注册与 1:N 搜索小程序选型绕不开的基本功考勤签到里常用的是 1:N 搜索也就是在一个人脸库里找到“这个人是谁”。流程拆开只有两步员工首次录入时把一张正脸照片和员工编号绑定注册到人脸库每次签到时拍一张照片到同一个库里去搜拿到返回的 personId 和匹配分数。这里面有一个容易被忽略的点人脸注册和人脸搜索是两个独立接口但共用同一个人脸库。设计阶段就要想清楚人脸库的分组方式。小企业可以只建一个分组按 employeeNo 作为 userId大型企业按部门或办公地点建立多个分组签到时先根据当前位置选定分组再在分组里做 1:N 搜索能明显减少搜索时间并降低误识别概率。调用方式上我一般不会在前端直接对接人脸服务而是把调用封装成一个独立的云函数或后端服务。伪代码结构如下class FaceService { async register(userId, imageBase64, groupId) { // 调用人脸注册接口返回 personId // 常见参数userId、imageBase64、groupId } async search(imageBase64, groupId) { // 调用人脸搜索接口返回匹配到的人与相似度分数 // 常见参数imageBase64、groupId、qualityControl } }这里最关键的两个参数一个是图像质量控制一个是相似度阈值。很多识别失败问题不是算法问题而是上传的照片模糊、逆光或者人脸占比太小。人脸服务通常提供 qualityControl 参数建议设置为高宁可在录入阶段多让员工重拍几次也不要让低质量照片进入人脸库。相似度阈值不要用服务默认值默认值往往偏向易用性对考勤来说偏松具体阈值怎么定在第 6 章单独说。2.3 活体检测是考勤签到的第一条红线考勤签到最怕的不是识别不准而是照片冒签。一张打印照片放摄像头前很多基础人脸识别也能通过所以活体检测必须作为独立模块设计不能省略。常见的活体内核有两种。动作活体会让用户按照屏幕提示完成眨眼、张嘴、左右摇头等动作后端校验动作顺序和动作耗时静默活体则是一次拍照通过纹理、反光等特征判断是不是真人。小程序签到场景我更建议用动作活体用户拿手机操作并不排斥多花两三秒而且动作活体对低端机的兼容性更好。静默活体虽然体验好但需要较强的模型支撑服务成本也会更高。活体检测需要注意两个参数动作超时时间和重试次数。默认给 5 秒一个动作比较合适超过 5 秒判为超时一个动作最多重试两次连续失败后要求用户重拍。如果完全不设重试限制用户在光线不好的地方很容易卡在活体检测体验会很难看。2.4 隐私合规与用户授权上线前绕不开的审查项人脸信息属于敏感个人信息小程序在调用摄像头和人脸服务之前必须做明确授权。不能只在用户点击“签到”的时候弹一个系统授权框而是要在首次进入时展示单独的说明页写明“采集人脸信息用于考勤签到身份核验不用于其他用途”。录入阶段要区分两个授权一个是微信的摄像头授权一个是业务层面的人脸信息使用授权。业务授权需要用户主动勾选并点击同意这行记录要存到数据库里包括授权时间、版本号和用户 openid。后续如果用户离职管理员要能一键删除该用户的人脸特征并且在前端界面提供“注销人脸信息”入口。这里还要注意原图保存策略。人脸搜索完成后原图不应该长期保留在云存储里。常见做法是签到记录里只保存一个缩略图用于人工复核而且缩略图只保留固定周期比如 30 天到期后自动清理。人脸库里的特征数据则保留到员工离职当天。2.5 离线兜底与网络质量差的备案云端识别依赖网络办公室地下层、电梯间、会议室深部经常出现请求超时。签到这个动作又偏偏不允许“等会再试”。我在实际项目中会设计一个本地待提交队列用户点击签到后先把签到请求写入本地缓存状态为“待提交”然后立即提示用户“签到请求已记录正在确认身份”网络恢复后自动补提交并对比服务端的最终识别结果。如果人脸比对始终失败方案里还要有一个兜底动作允许员工通过输入工号加密码的方式临时签到但这条记录标记为“人工核验”管理员事后比对现场照片。全自动固然好但考勤产品最重要的是不让人“无路可走”。3. 从云开发到人脸识别录入最小可跑通的微信小程序签到闭环3.1 载体选型微信小程序、uni-app 还是 H5基于人脸识别的考勤签到小程序载体上最常见的选择是微信小程序。微信生态自带身份体系用户不需要注册账号获取 openid 后就能对应到员工编号免登录体验对考勤签到这种高频小动作非常重要。如果你的团队后续还要做 Android、iOS、鸿蒙版本那么就需要考虑 uni-app 开发微信小程序这一条路径。uni-app 能一套代码编译到多个端但人脸识别相关能力需要做平台适配摄像头调用和文件上传的差异要单独处理。纯 H5 方案最不建议浏览器对人脸识别权限的控制不一致部分安卓浏览器甚至拿不到清晰的前置摄像头画面。3.2 用云开发初始化项目环境与集合云开发最大优势是省掉自建服务器云函数、云数据库、云存储三件套对中小规模考勤系统足够用。新项目我一般这样初始化// app.js App({ onLaunch() { if (!wx.cloud) { console.error(请使用 2.2.3 或以上的基础库以使用云能力) } else { wx.cloud.init({ env: your-env-id, traceUser: true }) } } })env 填你自己的云环境 ID开通云开发后在控制台能看到。traceUser 设为 true 后云函数里通过 cloud.getWXContext() 可以直接拿到用户的 openid不需要前端手动传。接下来在云开发控制台创建三个集合users、face_registry、attendance_records。users 存员工基础信息face_registry 存人脸库关联关系attendance_records 存每天签到记录。集合权限建议全部设为“仅管理员可读写”所有业务操作都通过云函数完成避免前端越权。3.3 人脸录入流程拍照、上传与云端注册员工首次使用需要先录入人脸。前端流程是调用摄像头拍一张正脸照片上传到云存储再触发云函数完成注册。async function registerFace() { const res await wx.chooseMedia({ count: 1, mediaType: [image], sourceType: [camera], camera: front, sizeType: [compressed] }) const filePath res.tempFiles[0].tempFilePath const openid wx.getStorageSync(openid) const uploadRes await wx.cloud.uploadFile({ cloudPath: faces/${openid}_${Date.now()}.jpg, filePath }) await wx.cloud.callFunction({ name: registerFace, data: { fileID: uploadRes.fileID, employeeNo: E10001, name: 张伟 } }) }这里必须使用 sourceType: [camera]禁止从相册选择。相册里的照片可能是美化过的、翻拍的甚至不是本人会直接污染人脸库。sizeType 选 compressed 可以显著减少上传时间但压缩过度会影响云端识别精度如果后端返回图像质量分过低要在前端提示重新拍摄。云函数 registerFace 负责真正的人脸注册和落库const cloud require(wx-server-sdk) cloud.init({ env: cloud.DYNAMIC_CURRENT_ENV }) exports.main async (event) { const { OPENID } cloud.getWXContext() const { fileID, employeeNo, name } event const res await cloud.downloadFile({ fileID }) const imageBase64 res.fileContent.toString(base64) // 调用人脸注册服务groupId 对应企业 ID const faceResult await faceService.register({ userId: employeeNo, imageBase64, groupId: company_main }) const db cloud.database() await db.collection(users).add({ data: { openid: OPENID, employeeNo, name, faceStatus: registered, createTime: db.serverDate() } }) return { code: 0, personId: faceResult.personId } }OPENID 直接从云端上下文获取而不是前端传入这样防止有人伪造员工绑定关系。人脸注册的凭证绝不能写在小程序前端代码里否则等于公开了调用额度。云函数里调用云存储下载原图再转 base64比前端直接传 base64 更安全也不容易超出云函数请求体大小限制。3.4 每日签到识别照片、人脸搜索与防重复写入签到流程与录入流程类似但多了两个关键判断这个人是谁、今天是否已经打过卡。async function signIn() { const res await wx.chooseMedia({ count: 1, mediaType: [image], sourceType: [camera], camera: front, sizeType: [compressed] }) const filePath res.tempFiles[0].tempFilePath const uploadRes await wx.cloud.uploadFile({ cloudPath: signin/${Date.now()}.jpg, filePath }) const result await wx.cloud.callFunction({ name: signIn, data: { fileID: uploadRes.fileID } }) if (result.result.code 0) { wx.showToast({ title: 签到成功 }) } else { wx.showModal({ title: 签到失败, content: result.result.message }) } }云函数 signIn 的完整逻辑应该包含四步下载图片、人脸搜索、判断重复签到、写入记录。const cloud require(wx-server-sdk) cloud.init({ env: cloud.DYNAMIC_CURRENT_ENV }) exports.main async (event) { const { OPENID } cloud.getWXContext() const db cloud.database() const { fileID } event const fileRes await cloud.downloadFile({ fileID }) const imageBase64 fileRes.fileContent.toString(base64) // 第一步人脸搜索 const searchRes await faceService.search({ imageBase64, groupId: company_main }) if (searchRes.score 80) { return { code: 1001, message: 人脸匹配不通过请重试 } } const employeeNo searchRes.userId // 第二步查今天是否已签到 const today db.serverDate() const existRes await db.collection(attendance_records) .where({ employeeNo, date: today, type: signin }) .count() if (existRes.total 0) { return { code: 1002, message: 今日已签到请勿重复操作 } } // 第三步写入签到记录 await db.collection(attendance_records).add({ data: { employeeNo, date: today, type: signin, score: searchRes.score, photoFileID: fileID, createTime: db.serverDate() } }) return { code: 0, employeeNo, score: searchRes.score } }这里的 date 字段建议按本地时区格式化成年月日字符串比如“2026-05-20”不要直接存时间戳。云函数运行在云端默认时区是 UTC直接用 new Date().toISOString() 可能差 8 小时导致凌晨签到的记录被算到前一天。这个坑我踩过不止一次。3.5 小程序动态设置标题让签到页带上部门信息用户打开小程序后顶部标题如果只是“考勤签到”四个字管理员分不清每个页面在哪个环节。我一般会在页面加载后动态设置标题顺便把当前员工的部门或班次信息带进去wx.setNavigationBarTitle({ title: 考勤签到 - 研发部 })这里不只是为了好看。小程序的头部标题同时也决定了分享卡片和最近使用列表中的文案动态设置成“考勤签到 - 研发部”后员工从最近使用里进入时能确认自己没进错入口。多个班级或多个办公点的场景这个细节能减少大量误操作。在 uni-app 开发微信小程序的场景下动态标题用小程序的 wx.setNavigationBarTitle 仍然有效但要注意页面 onShow 里设置否则从一个页面跳转返回时标题会被重置成全局配置。4. 考勤签到业务设计防代签、防重复与关键参数4.1 从“打卡”到“考勤”的业务闭环人脸识别解决了“是谁”的问题但考勤系统还要回答“几点来、几点走、迟到多久、缺卡怎么补”。很多基于人脸识别的考勤签到小程序设计文档把重心全放在识别流程上上线后才发现连最简单的“上午 9 点上班”都没法配置。业务上要拆成三个层级打卡事件、考勤规则、考勤结果。打卡事件是员工的一次签到或签退记录考勤规则定义上班时间、下班时间、迟到判定边界、午休时长考勤结果每天凌晨由定时任务把原始记录对照规则计算出来生成正常、迟到、早退、缺卡、外勤等状态。这一层如果不用定时任务每天让管理员手工看记录就没有达到“考勤系统”的目的。云开发里可以设置定时触发器每天凌晨 1 点跑一次云函数统计前一天的打卡记录。4.2 防代签三件套定位、Wi-Fi 与 openid 配合人脸识别本身已经很强但人脸是可以被授权他人代签的。比如员工 A 委托员工 B 拿手机对着自己脸拍一张系统无法区分。为了降低这类风险需要叠加位置和网络环境信息。小程序里通过 wx.getLocation 可以拿到经纬度参数设置如下wx.getLocation({ type: gcj02, isHighAccuracy: true, highAccuracyExpireTime: 4000, success(res) { console.log(res.latitude, res.longitude) } })isHighAccuracy 开启后会调用高精度定位速度会慢一些但考勤签到可以接受 1 到 3 秒的等待。拿到定位后在云端计算与公司坐标的距离超过 300 米就标记为“位置异常”需要管理员人工确认。定位可以被模拟器伪造所以还要加入 Wi-Fi 信息。小程序里的 wx.getConnectedWifi 能拿到当前连接的 Wi-Fi 的 BSSID办公场景下固定几个 BSSID 可以作为强校验条件。如果员工连接的是公司 Wi-Fi即使定位数据异常也可以放行如果两者都异常直接拦截。openid 只是身份标识防不了“人借手机给同事”的问题但能防止手工篡改请求参数。三道校验合在一起代签成本会明显提高日常使用中也能起到威慑作用。4.3 防重复签到与补卡规则重复签到是另一个高频问题。员工可能点了一次没反应又点了一次结果生成两条记录。数据库层要做唯一约束云开发数据库支持给字段创建唯一索引。建议对 attendance_records 集合建立 employeeNo date type 的复合唯一索引type 区分 signin 和 signout。万一业务上允许补卡补卡记录不能和正常记录走同一个写入通道。补卡应该走申请审批流程员工提交补卡申请管理员审批通过后在后台以特殊类型写入一条记录状态标记为“补卡”原签到时间不参与迟到判定。这样可以避免员工为了掩盖迟到先签退再补卡。还有一种情况是员工早上打卡成功下午外出忘打卡。很多系统只判断“今天是否打过卡”这会导致签退通道被拦截。所以查询条件必须带上 type 字段signin 和 signout 分别判断而不是只查 date。4.4 数据库表设计员工、打卡记录与图像留痕云开发数据库是文档型数据库但设计时仍然要遵循一定的关系约束。三个核心集合的结构建议如下users 集合{ _id: auto, openid: oXXXX, employeeNo: E10001, name: 张伟, department: 研发部, faceStatus: registered, faceGroupId: company_main, authorization: { agreed: true, agreedAt: 2026-05-20 10:00:00, version: v1 }, status: active }attendance_records 集合{ _id: auto, employeeNo: E10001, date: 2026-05-20, type: signin, signTime: 09:01:23, score: 92.5, latitude: 31.2304, longitude: 121.4737, wifiBSSID: d8:xx:xx:xx:xx:xx, photoFileID: cloud://env/signin/xxx.jpg, status: normal, source: face }face_registry 集合{ _id: auto, employeeNo: E10001, personId: 人脸服务返回的唯一 ID, groupId: company_main, createTime: 2026-05-20 10:00:00 }photoFileID 必须保存因为识别分数再高最终也要有人工抽检余地万一闹纠纷一张现场照片比任何日志都有效。但照片保留时间要设上限定期清理降低隐私风险。4.5 考勤规则参数表上线前和业务方对齐考勤规则不要写成死代码要配置化。最直观方式是建一张参数表由管理员修改云函数读取。核心参数如下参数名示例值说明work_start09:00上班时间work_end18:00下班时间late_grace_minutes10迟到宽容分钟数early_leave_minutes10早退宽容分钟数signin_timezoneAsia/Shanghai签到时间时区location_radius300允许签到半径单位米wifi_requiredtrue是否必须连接指定 Wi-Fiface_score_threshold80人脸搜索最低相似度liveliness_threshold80活体检测最低分数photo_retention_days30签到原图保留天数这个表格必须在开发前找业务方签字确认否则开发完再改规则牵涉到历史数据回溯会非常痛苦。5. 避坑光线、遮挡、相似脸与过期授权5 条踩坑记录5.1 逆光打卡识别率暴跌图像质量检查不能只靠前端判断现象员工站在窗户边人脸背光严重活体检测通过后人脸搜索却返回相似度极低系统提示签到失败。同一个员工换个角度就能成功。原因人脸搜索前整个人脸区域处于阴影中特征提取后关键点信息不完整不是算法的错。解决在云函数里调人脸搜索前先调一次人脸质量检查。常见质量维度包括人脸角度偏转、遮挡比例、亮度、清晰度。质量分低于阈值就直接返回“请正对光源重新拍摄”而不是继续走搜索浪费时间和费用。前端文案可以写成“请正对光线避免逆光再拍一次”。5.2 相似脸误识别相似度阈值设置得太随意现象一个部门两名同事长相相似A 打卡时系统识别成了 B生成了错误的考勤记录。原因人脸服务默认相似度阈值通常在 70 到 75 之间这个值对安防场景够用但考勤场景里一旦阈值过低相似脸群体就会频繁互串。解决上线第一天不要用默认值。先用第 6 章的验证方法拿真实员工照片扫一遍阈值把阈值定到 80 以上。同时在云函数里增加二次校验人脸搜索返回 personId 后再取该员工的最近一张打卡照片做 1:1 比对分数同时超过阈值才放行。双次校验对双胞胎场景尤为有效。5.3 戴口罩后识别率断崖下跌不要只依赖下半张脸现象新冠疫情后员工习惯戴口罩识别率从 99% 掉到 60%大量员工卡在活体检测环节。原因人脸搜索模型依赖嘴巴、鼻子等区域的特征下半张脸被口罩遮住特征缺失。解决分两步。第一步在签到页加“是否佩戴口罩”的选项小程序端调整引导文案提示摘下口罩如果确实不能摘下后端切换到口罩识别模式口罩模式只比对眉骨、眼睛、额头区域相似度阈值可以适当放宽 3 到 5 分。第二步长期方案是做人脸底库更新要求员工在无口罩状态下录入两到三张不同角度的照片保证特征完整。5.4 打印照片绕过活体检测动作活体指令过于固定现象员工把一张清晰打印的照片放在摄像头前活体检测仍然通过系统被盗签。原因有些低端活体检测只做了“张嘴”“眨眼”动作识别没有校验动作顺序也没有限制动作完成时间录一段视频就能依次触发。解决动作活体必须使用随机动作序列每次签到从动作池里随机抽 2 到 3 个动作并且每个动作都有独立的时间戳校验。后端记录动作开始时间、结束时间、人脸框移动轨迹动作总耗时超过 15 秒直接失败。另外不要把活体检测分数作为唯一标准还要对人脸框区域做背景一致性检查识别到屏幕边缘反光或照片纸张纹理就直接拒绝。5.5 授权过期与版本更新后的兼容问题现象小程序更新版本后老用户首次打卡时摄像头无法唤起页面白屏或停留在“授权中”。管理员后台看日志发现很多老员工连续几天没有人脸授权记录。原因微信基础库升级后部分授权行为需要重新触发或云开发环境配置被更换前端请求的 env 还是旧环境 ID导致云函数调用失败。解决在 App 的 onLaunch 里校验云环境可用性并在签到页首次渲染时调用 wx.getSetting 检查摄像头授权状态。如果授权被拒绝不要只在回调里提示要主动弹出一个引导页说明人脸采集的目的。授权状态和云环境 ID 都要做版本检查新版本发布后强制清理本地缓存并重新初始化。5.6 云函数冷启动导致签到超时现象早上 8 点 50 分几百人同时打开小程序签到云函数大量返回超时前端提示“网络异常”。原因云函数在并发高峰期会冷启动冷启动耗时可能到 3 到 5 秒而小程序端默认请求超时时间只有 5 到 15 秒。解决把超时时间调到 20 秒同时在云函数控制台配置内存为 512 MB 或更高冷启动概率会明显下降。更稳妥的做法是设置定时触发器在每天签到高峰前自动调用一次云函数做预热。前端也要做重试逻辑一次失败后隔 1 秒重试最多重试 3 次。6. 上线前用留出集校准阈值FRR 与 FAR 怎么选要设人脸识别阈值必须先定义两个指标。FRR 是把一个本人识别成别人表现为员工本人屡次打卡失败FAR 是把一个他人识别成本人表现为代签或相似脸蒙混过关。考勤场景里 FAR 的代价远高于 FRR一次误识别就是一次考勤事故宁可让 FRR 高一点也不能让 FAR 失控。建议上线前从真实场景收集两组照片一组是 50 个员工各拍 3 张正脸作为“本人组”另一组是这些员工互相拍照形成的 30 张“冒签组”。然后把照片灌到人脸搜索接口里记录每组照片的相似度分数用 Python 快速扫一遍阈值import json with open(eval_scores.json, r) as f: data json.load(f) # data 结构示例 # {genuine: [{score: 92}, {score: 88}], # imposter: [{score: 70}, {score: 75}]} for threshold in range(65, 96): frr_count sum(1 for x in data[genuine] if x[score] threshold) far_count sum(1 for x in data[imposter] if x[score] threshold) frr frr_count / len(data[genuine]) far far_count / len(data[imposter]) print(fthreshold{threshold}, FRR{frr:.3f}, FAR{far:.3f})扫描结果会出现一个交叉点。如果 FAR 在 80 分左右已经降到 0FRR 在 2% 到 3% 之间就可以把生产阈值定在 80。如果 FAR 直到 90 分才归零但 FRR 已经到了 8%说明人脸库照片质量不过关这时候改阈值没有意义应该回头提升录入照片质量。上线后不要一次性放开全员先选一个 20 人到 50 人的部门灰度跑两周。这两周里每一次识别失败都由管理员人工复核现场照片并把失败原因记录下来。如果失败以逆光、遮挡为主调整引导文案如果失败集中在某两三个长相相似的同事身上单独提高他们的比对阈值。我自己的习惯是灰度期结束后保留最近 30 天的签到现场照片每次有考勤争议都先看图再查日志别只盯着分数判断对错。希望帮到你。本文还有配套的精品资源点击获取

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑