AI人脸识别考勤签到系统
AI人脸识别考勤系统 - 技术架构文档
1. 架构设计
graph TB
subgraph "前端层"
Web["React管理界面<br>人员管理/考勤记录/设置"]
Client["React考勤客户端<br>摄像头扫描/实时识别"]
end
subgraph "后端层"
API["Express API服务器<br>RESTful API"]
FR["Python人脸识别服务<br>InsightFace/ArcFace"]
end
subgraph "数据层"
DB["SQLite数据库<br>员工信息/考勤记录"]
FS["文件存储<br>人脸照片/特征向量"]
end
Web --> API
Client --> API
Client -->|"视频帧上传"| FR
API -->|"特征提取/比对请求"| FR
API --> DB
API --> FS
FR --> FS
架构说明:
前端:React + TypeScript + Tailwind CSS,Vite构建
后端API:Express + TypeScript,处理业务逻辑和数据库操作
人脸识别服务:Python FastAPI,使用InsightFace进行人脸检测、特征提取和1:N比对
数据库:SQLite,轻量级无需额外安装,支持离线运行
通信:前端与Express通过RESTful API通信,Express与Python服务通过HTTP通信
2. 技术说明
前端:React@18 + TypeScript + Tailwind CSS@3 + Vite
初始化工具:vite-init (react-express-ts模板)
后端API:Express@4 + TypeScript (ESM)
人脸识别服务:Python 3.10+ / FastAPI / InsightFace (insightface + onnxruntime)
数据库:SQLite (better-sqlite3)
状态管理:Zustand
路由:react-router-dom
图标:lucide-react
文件上传:multer
Excel导出:exceljs
3. 路由定义
路由 | 用途 |
|---|---|
| 仪表盘 - 今日考勤概览 |
| 人员管理 - 员工列表 |
| 人员录入 - 新增员工 |
| 人员编辑 - 修改员工信息 |
| 考勤记录 - 打卡流水查询 |
| 考勤设置 - 规则与参数配置 |
| 考勤客户端 - 摄像头扫描打卡界面 |
4. API定义
4.1 员工管理
// 获取员工列表 GET /api/employees?page=1&pageSize=20&department=&keyword= Response: { data: Employee[], total: number, page: number } // 获取单个员工 GET /api/employees/:id Response: Employee // 创建员工(multipart/form-data,含照片) POST /api/employees Body: { emp_id: string, name: string, department: string, position: string, photo: File } Response: Employee // 更新员工 PUT /api/employees/:id Body: { name?: string, department?: string, position?: string, status?: "active"|"disabled", photo?: File } Response: Employee // 删除员工 DELETE /api/employees/:id Response: { success: boolean } // 批量导入 POST /api/employees/batch Body: FormData { file: File (zip包含照片+Excel) } Response: { success: number, failed: number, errors: string[] }4.2 考勤记录
// 获取考勤记录 GET /api/attendance?date=2026-06-07&department=&emp_id=&page=1&pageSize=20 Response: { data: AttendanceRecord[], total: number } // 创建打卡记录(由识别服务调用) POST /api/attendance Body: { emp_id: string, face_score: number, device_id: string } Response: AttendanceRecord // 导出考勤记录 GET /api/attendance/export?dateFrom=2026-06-01&dateTo=2026-06-07&department= Response: Blob (Excel文件) // 获取今日统计 GET /api/attendance/today-stats Response: { total: number, present: number, late: number, absent: number, recentRecords: AttendanceRecord[] }4.3 考勤设置
// 获取设置 GET /api/settings Response: AttendanceSettings // 更新设置 PUT /api/settings Body: AttendanceSettings Response: AttendanceSettings4.4 人脸识别服务API(Python FastAPI)
// 人脸特征提取(从上传图片) POST /fr/extract Body: FormData { image: File } Response: { success: boolean, feature: number[], bbox: [number,number,number,number], quality: number } // 人脸比对(1:N搜索) POST /fr/search Body: { feature: number[], threshold: number } Response: { matched: boolean, emp_id: string | null, score: number } // 从视频帧检测人脸并比对 POST /fr/detect-and-search Body: FormData { image: File, threshold: number } Response: { detected: boolean, faces: Array<{ bbox: number[], emp_id: string | null, score: number }> } // 健康检查 GET /fr/health Response: { status: "ok", model_loaded: boolean }4.5 数据类型定义
interface Employee { id: number; emp_id: string; // 工号 name: string; // 姓名 department: string; // 部门 position: string; // 职位 photo_path: string; // 照片路径 feature_path: string; // 特征向量文件路径 status: "active" | "disabled"; created_at: string; updated_at: string; } interface AttendanceRecord { id: number; emp_id: string; employee_name: string; capture_time: string; // 打卡时间 device_id: string; // 设备标识 type: "check_in" | "check_out"; // 上班/下班 face_score: number; // 人脸比对分数 status: "normal" | "late" | "early" | "absent"; created_at: string; } interface AttendanceSettings { check_in_time: string; // 上班时间 "09:00" check_out_time: string; // 下班时间 "18:00" check_in_start: string; // 上班打卡开始时间 "06:00" check_in_end: string; // 上班打卡截止时间 "10:00" check_out_start: string; // 下班打卡开始时间 "17:00" check_out_end: string; // 下班打卡截止时间 "23:59" late_threshold_min: number; // 迟到判定分钟数 cooldown_min: number; // 重复打卡冷却时间(分钟) face_threshold: number; // 人脸比对阈值 0-1 device_id: string; // 本设备标识 }5. 服务器架构图
graph LR Controller["Controller<br>路由与参数校验"] --> Service["Service<br>业务逻辑"] Service --> Repository["Repository<br>数据访问"] Repository --> Database["SQLite<br>数据存储"] Service --> FRClient["FRClient<br>人脸识别HTTP客户端"] FRClient --> FRService["Python FastAPI<br>人脸识别服务"] FRService --> InsightFace["InsightFace<br>人脸检测与特征提取"] FRService --> FeatureStore["特征文件存储<br>本地.npy文件"]6. 数据模型
6.1 数据模型定义
erDiagram "employee" { int id PK string emp_id UK "工号" string name "姓名" string department "部门" string position "职位" string photo_path "照片路径" string feature_path "特征向量路径" string status "状态: active/disabled" datetime created_at "创建时间" datetime updated_at "更新时间" } "attendance_record" { int id PK string emp_id FK "工号" datetime capture_time "打卡时间" string device_id "设备标识" string type "类型: check_in/check_out" float face_score "比对分数" string status "状态: normal/late/early/absent" datetime created_at "创建时间" } "settings" { int id PK string key UK "设置键" string value "设置值(JSON)" datetime updated_at "更新时间" } "sync_log" { int id PK string device_id "设备标识" string action "同步动作" string status "状态" datetime synced_at "同步时间" } "employee" ||--o{ "attendance_record" : "emp_id"6.2 数据定义语言
-- 员工信息表 CREATE TABLE IF NOT EXISTS employee ( id INTEGER PRIMARY KEY AUTOINCREMENT, emp_id TEXT NOT NULL UNIQUE, name TEXT NOT NULL, department TEXT NOT NULL DEFAULT '', position TEXT NOT NULL DEFAULT '', photo_path TEXT NOT NULL DEFAULT '', feature_path TEXT NOT NULL DEFAULT '', status TEXT NOT NULL DEFAULT 'active' CHECK(status IN ('active', 'disabled')), created_at TEXT NOT NULL DEFAULT (datetime('now', 'localtime')), updated_at TEXT NOT NULL DEFAULT (datetime('now', 'localtime')) ); -- 打卡记录表 CREATE TABLE IF NOT EXISTS attendance_record ( id INTEGER PRIMARY KEY AUTOINCREMENT, emp_id TEXT NOT NULL, capture_time TEXT NOT NULL, device_id TEXT NOT NULL DEFAULT 'default', type TEXT NOT NULL DEFAULT 'check_in' CHECK(type IN ('check_in', 'check_out')), face_score REAL NOT NULL DEFAULT 0, status TEXT NOT NULL DEFAULT 'normal' CHECK(status IN ('normal', 'late', 'early', 'absent')), created_at TEXT NOT NULL DEFAULT (datetime('now', 'localtime')), FOREIGN KEY (emp_id) REFERENCES employee(emp_id) ); -- 索引 CREATE INDEX IF NOT EXISTS idx_attendance_emp_id ON attendance_record(emp_id); CREATE INDEX IF NOT EXISTS idx_attendance_capture_time ON attendance_record(capture_time); CREATE INDEX IF NOT EXISTS idx_attendance_date ON attendance_record(date(capture_time)); CREATE INDEX IF NOT EXISTS idx_employee_department ON employee(department); CREATE INDEX IF NOT EXISTS idx_employee_status ON employee(status); -- 系统设置表 CREATE TABLE IF NOT EXISTS settings ( id INTEGER PRIMARY KEY AUTOINCREMENT, key TEXT NOT NULL UNIQUE, value TEXT NOT NULL DEFAULT '{}', updated_at TEXT NOT NULL DEFAULT (datetime('now', 'localtime')) ); -- 同步日志表 CREATE TABLE IF NOT EXISTS sync_log ( id INTEGER PRIMARY KEY AUTOINCREMENT, device_id TEXT NOT NULL, action TEXT NOT NULL, status TEXT NOT NULL DEFAULT 'pending', synced_at TEXT NOT NULL DEFAULT (datetime('now', 'localtime')) ); -- 默认设置 INSERT OR IGNORE INTO settings (key, value) VALUES ('attendance_rules', '{"check_in_time":"09:00","check_out_time":"18:00","check_in_start":"06:00","check_in_end":"10:00","check_out_start":"17:00","check_out_end":"23:59","late_threshold_min":0,"cooldown_min":5}'), ('face_recognition', '{"threshold":0.6,"device_id":"default"}');7. Python人脸识别服务设计
7.1 技术栈
框架:FastAPI + uvicorn
人脸检测与识别:InsightFace (buffalo_l模型) + onnxruntime
依赖:insightface, onnxruntime, opencv-python, numpy, pillow
7.2 服务端口
Express API服务器:
3001Python人脸识别服务:
3002Vite开发服务器:
5173
7.3 特征库管理
每个员工的人脸特征向量保存为
.npy文件,存储在data/features/目录服务启动时加载所有特征到内存,构建特征矩阵
新增/删除员工时,通过API通知特征库更新
1:N比对使用余弦相似度,阈值默认0.6
7.4 启动方式
# 安装Python依赖 pip install fastapi uvicorn insightface onnxruntime opencv-python numpy pillow # 启动人脸识别服务 cd face_recognition_service python main.py8. 项目目录结构
AI考勤/ ├── src/ # React前端代码 │ ├── components/ # 通用组件 │ ├── pages/ # 页面组件 │ │ ├── Dashboard.tsx # 仪表盘 │ │ ├── Employees.tsx # 人员管理 │ │ ├── Attendance.tsx # 考勤记录 │ │ ├── Settings.tsx # 考勤设置 │ │ └── Scanner.tsx # 考勤客户端 │ ├── hooks/ # 自定义Hooks │ ├── utils/ # 工具函数 │ ├── App.tsx # 应用入口 │ └── main.tsx # 渲染入口 ├── api/ # Express后端代码 │ ├── routes/ # API路由 │ ├── services/ # 业务逻辑 │ ├── repositories/ # 数据访问 │ ├── middleware/ # 中间件 │ ├── database.ts # 数据库初始化 │ └── index.ts # 服务器入口 ├── face_recognition_service/ # Python人脸识别服务 │ ├── main.py # FastAPI入口 │ ├── face_engine.py # 人脸识别引擎封装 │ ├── feature_store.py # 特征库管理 │ └── requirements.txt # Python依赖 ├── data/ # 数据目录 │ ├── database.sqlite # SQLite数据库 │ ├── photos/ # 员工照片 │ └── features/ # 特征向量文件 ├── migrations/ # 数据库迁移SQL ├── shared/ # 前后端共享类型 ├── package.json ├── tsconfig.json ├── vite.config.ts └── tailwind.config.js