2026-05-01 00:10:45 +08:00
2026-04-30 22:45:57 +08:00
2026-05-01 00:10:45 +08:00
2026-05-01 11:35:44 +08:00
2026-05-01 10:35:54 +08:00
2026-05-01 11:35:44 +08:00
2026-05-01 10:35:54 +08:00
2026-05-01 11:35:44 +08:00
2026-05-01 10:43:27 +08:00

人脸识别考勤系统

基于 Qt 6 Quick/QML 开发的跨平台人脸识别考勤管理客户端,用于连接考勤服务端,完成签到记录查看、筛选导出、统计分析、签到时段配置、学生与班级名称映射、人脸照片与学号绑定等管理工作。

本项目是纪田野的个人毕业设计作品,主要用于人脸识别考勤场景的功能展示、系统联调和学习研究。

项目特点

  • 跨平台客户端:支持 Windows 桌面端和 Android 端构建。
  • 单窗口管理:考勤记录、统计分析、配置中心、人脸管理和系统说明集中在一个界面中。
  • 响应式界面:针对手机窄屏做了独立布局适配,避免控件重叠和文字遮挡。
  • 数据导出:支持将考勤记录和统计报表导出为 CSV 文件。
  • 本地配置缓存:服务端地址、签到时段、映射配置会保存到本地。
  • 自动重连:服务端不可达时自动重连,并使用简短状态提示。
  • Android 字体优化:Android 端使用原生文字渲染,并降低粗体权重,减少中文粗体重影。
  • Android 路径兼容:Gradle 配置已允许中文路径构建,并启用 AndroidX。

技术栈

分类 内容
开发语言 C++17、QML
UI 框架 Qt Quick / Qt Quick Controls 2
Qt 模块 Core、Gui、Qml、Quick、QuickControls2、Network
构建系统 CMake 3.16+
桌面编译器 MinGW / MSVC / Clang / GCC
Android 构建 Qt for Android、Android SDK、Android NDK、JDK
加密处理 AES-128-CBC,代码位于 src/CryptoUtils.cpp

目录结构

rewrite_qt/
├── android/                  # Android 打包补充资源和 Gradle 配置
│   ├── gradle.properties
│   └── res/mipmap-*/         # Android 启动图标
├── assets/                   # 桌面端图标资源
├── cmake/                    # 平台相关模板文件
├── qml/
│   └── Main.qml              # 主界面
├── src/
│   ├── ApiClient.*           # 服务端 API 客户端
│   ├── AppController.*       # QML 与业务逻辑中枢
│   ├── AttendanceTypes.h     # 考勤数据结构
│   ├── CryptoUtils.*         # AES 解密工具
│   ├── *ListModel.*          # 暴露给 QML 的列表模型
│   └── crypto/tiny_aes.hpp   # AES 底层实现
├── CMakeLists.txt
├── LICENSE
├── README.md
└── main.cpp

功能说明

考勤记录

考勤记录页用于查看和管理服务端同步下来的签到记录。

  • 查看总记录数、今日签到数、当前筛选结果数。
  • 按班级、学号、姓名关键字筛选记录。
  • 按全部时间、今天、最近 7 天、最近 30 天、指定日期筛选。
  • 刷新最新记录。
  • 导出当前筛选结果为 CSV。
  • 清空服务端全部考勤记录。

导出字段:

签到时间,班级编号,班级名称,学号,姓名,置信度,状态

统计分析

统计分析页基于当前加载的考勤记录在本地计算统计结果。

  • 支持今天、最近 7 天、最近 30 天、本月等快捷范围。
  • 支持手动指定开始日期和结束日期。
  • 展示统计学生数、统计记录数、统计范围。
  • 按学生汇总总签到次数、今日签到次数、最后签到时间和平均置信度。
  • 导出统计报表为 CSV。

导出字段:

学号,姓名,总签到次数,今日签到,最后签到时间,平均置信度

配置中心

配置中心用于维护客户端与服务端交互所需的配置。

  • 设置服务端地址。
  • 测试服务端连接状态。
  • 管理签到时段。
  • 从服务端同步签到时段。
  • 管理学号到姓名的映射。
  • 管理班级编号到班级名称的映射。
  • 保存配置并同步到服务端。

默认签到时段:

名称 开始时间 结束时间 默认状态
上午签到 08:00 09:30 启用
中午签退 12:00 13:00 启用
下午签到 14:00 15:00 启用
晚上签退 17:00 18:30 启用

人脸管理

人脸管理页用于维护 K210 上传的人脸照片记录与真实学号之间的映射关系。

  • 同步人脸照片 ID。
  • 同步服务端学生 ID。
  • 展示人脸照片或无照片状态。
  • 为人脸 ID 绑定真实学号。
  • 保存人脸 ID 与学号映射。
  • 删除指定人脸信息。
  • 可选择同时删除该学生相关考勤记录。

照片访问地址格式:

{serverUrl}/api/face_photo/{id}?ts={timestamp}

其中 ts 用于避免缓存导致照片不刷新。

服务端配置

默认服务端地址:

http://27.106.113.205:8082

应用启动后会从本地配置读取已保存的服务端地址。用户可在“配置中心”中修改并保存。

本地保存键名:

server/url

服务端 API

客户端会基于服务端地址拼接 /api 前缀访问接口。

方法 路径 用途
GET /api/records?limit={limit}&offset={offset} 获取考勤记录
GET /api/statistics 获取总数、今日数和服务端时间
POST /api/clear 清空全部记录
DELETE /api/record?timestamp={timestamp}&student_id={studentId} 删除单条记录
GET /api/timeslots 获取签到时段
POST /api/timeslots 保存签到时段
GET /api/mapping_config 获取学生和班级映射
POST /api/mapping_config 保存学生和班级映射
GET /api/face_id_mapping 获取人脸 ID 到学号映射
POST /api/face_id_mapping 保存人脸 ID 到学号映射
GET /api/face_photos 获取照片 ID 列表
GET /api/all_student_ids 获取所有学生 ID
GET /api/face_photo/{id} 获取人脸照片
DELETE /api/face/{studentId} 删除人脸信息
DELETE /api/face/{studentId}?delete_records=true 删除人脸信息并删除相关考勤记录
GET /api/health 健康检查

考勤记录格式

/api/records 解密后应返回 JSON 数组。单条记录示例:

{
  "timestamp": "2026-04-24 08:10:23",
  "student_id": "20240001",
  "name": "张三",
  "confidence": 0.9821,
  "status": "success",
  "class_id": "1"
}

统计数据格式

{
  "total": 120,
  "today": 8,
  "server_time": "2026-04-24 10:30:00"
}

签到时段格式

{
  "time_slots": [
    {
      "name": "上午签到",
      "start_time": "08:00",
      "end_time": "09:30",
      "enabled": true
    }
  ]
}

映射配置格式

{
  "student_name_map": {
    "20240001": "张三"
  },
  "class_name_map": {
    "1": "软件工程一班"
  }
}

人脸映射格式

{
  "mappings": {
    "face_001": "20240001"
  }
}

加密响应

客户端对 /api/records 和 /api/statistics 请求添加请求头:

X-Encrypted-Response: true

客户端期望服务端返回 Base64 编码的 AES-128-CBC 密文。

解密参数位于 src/CryptoUtils.cpp:

参数 值
算法 AES-128-CBC
Padding PKCS#7
Key 2b 7e 15 16 28 ae d2 a6 ab f7 15 88 09 cf 4f 3c
IV 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f

本地配置文件

应用使用 QSettings 和 QStandardPaths::AppDataLocation 保存本地状态。

配置 保存位置
服务端地址 QSettings,键名 server/url
学生和班级映射 mapping_config.json
签到时段配置 timeslot_config.json

应用信息:

ApplicationName: 人脸识别考勤系统
ApplicationVersion: 3.0.0
OrganizationName: STM32 Face Recognition

构建环境

基础要求

  • Qt 6.2 或更高版本
  • CMake 3.16 或更高版本
  • 支持 C++17 的编译器

Windows 桌面端推荐使用 Qt 6.x MinGW 64-bit Kit。

Android 端需要额外配置:

  • Qt for Android
  • Android SDK
  • Android NDK
  • JDK
  • Android 平台版本,例如 android-35

使用 Qt Creator 构建

  1. 打开 Qt Creator。
  2. 选择项目根目录下的 CMakeLists.txt。
  3. 选择对应 Kit,例如 Desktop Qt 6.x 或 Qt for Android。
  4. 等待 CMake 配置完成。
  5. 构建目标 apprewrite_qt。
  6. 桌面端可直接运行;Android 端可部署到设备或模拟器。

命令行构建

Windows 示例:

cmake -S . -B build -DCMAKE_PREFIX_PATH=D:/Qt/6.10.0/mingw_64
cmake --build build --target apprewrite_qt

Linux 示例:

cmake -S . -B build -DCMAKE_PREFIX_PATH=/path/to/Qt/6.x/gcc_64
cmake --build build --target apprewrite_qt

安装到系统路径:

cmake --install build

Windows 独立运行

直接双击构建出来的 apprewrite_qt.exe 时,如果提示找不到 Qt6Gui.dll、Qt6Core.dll 等动态库,需要使用 windeployqt 收集运行时依赖。

示例:

D:\Qt\6.10.0\mingw_64\bin\windeployqt.exe "D:\path\to\build\Desktop_Qt_6_10_0_MinGW_64_bit-Debug\apprewrite_qt.exe"

如果项目路径包含中文导致部署工具输出异常,建议复制 exe 到纯英文路径后部署:

mkdir C:\tmp\rewrite_qt_release
copy "D:\path\to\apprewrite_qt.exe" C:\tmp\rewrite_qt_release\
D:\Qt\6.10.0\mingw_64\bin\windeployqt.exe C:\tmp\rewrite_qt_release\apprewrite_qt.exe

部署完成后,将整个发布目录一起复制到目标电脑运行。

Android 构建说明

Android 相关配置位于 CMakeLists.txt:

QT_ANDROID_PACKAGE_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/android"
QT_ANDROID_APP_NAME "${REWRITE_QT_DISPLAY_NAME}"
QT_ANDROID_APP_ICON "@mipmap/ic_launcher"

Android 补充配置位于 android/gradle.properties:

android.overridePathCheck=true
android.useAndroidX=true

说明:

  • android.overridePathCheck=true 用于绕过 Windows 下 Android Gradle 对中文路径的检查。
  • android.useAndroidX=true 用于启用 AndroidX,避免依赖检查失败。
  • Android 桌面显示名由 QT_ANDROID_APP_NAME 设置为“人脸识别考勤系统”。
  • Android 启动图标位于 android/res/mipmap-*。

如果 Android 构建目录已经生成过旧的 Gradle 工程,修改配置后建议清理对应构建目录或重新运行 CMake 配置。

图标资源

桌面端图标位于 assets/:

assets/favicon.ico
assets/favicon-16x16.png
assets/favicon-32x32.png
assets/favicon-48x48.png
assets/favicon-64x64.png
assets/favicon-128x128.png
assets/favicon-192x192.png
assets/favicon-256x256.png

Android 启动图标位于:

android/res/mipmap-mdpi/ic_launcher.png
android/res/mipmap-hdpi/ic_launcher.png
android/res/mipmap-xhdpi/ic_launcher.png
android/res/mipmap-xxhdpi/ic_launcher.png
android/res/mipmap-xxxhdpi/ic_launcher.png

图标尺寸:

目录 尺寸
mipmap-mdpi 48x48
mipmap-hdpi 72x72
mipmap-xhdpi 96x96
mipmap-xxhdpi 144x144
mipmap-xxxhdpi 192x192

界面与移动端适配

主界面位于 qml/Main.qml,采用 ApplicationWindow、StackLayout、GridLayout、ColumnLayout 等组件组织页面。

当前界面包含五个页面:

  • 考勤记录
  • 统计分析
  • 配置中心
  • 人脸管理
  • 关于

移动端适配要点:

  • phoneLayout 用于 560px 以下窄屏布局。
  • 顶部页签使用统一的 MobileNavTabButton 样式。
  • 考勤筛选区使用两列布局,按钮等宽排布。
  • 统计页前两张统计卡左右排布,统计范围独占一整行。
  • 表格在窄屏隐藏部分非关键列,避免横向溢出。
  • 空状态卡片会根据可用高度自动缩小。
  • Android 端使用 sans-serif 字体和 Font.Medium 加粗权重,减少粗体重影。

运行状态提示

客户端通过底部 Toast 展示状态信息。服务端不可达时,提示会被压缩为简短文案:

服务器未连接,稍后重试

重连过程中显示:

正在重连服务器

这样可以避免将底层网络错误、URL 和长异常文本直接展示给用户。

常见问题

Android 构建提示项目路径包含中文

项目已经在 android/gradle.properties 中配置:

android.overridePathCheck=true

如果仍然失败,清理 Android 构建目录后重新构建。

Android 构建提示 AndroidX 未启用

项目已经在 android/gradle.properties 中配置:

android.useAndroidX=true

如果旧构建目录仍然报错,删除生成的 android-build-* 目录后重新部署。

Android 端粗体文字重影

项目在 Android 端启用了原生文字渲染:

QQuickWindow::setTextRenderType(QQuickWindow::NativeTextRendering);

同时 QML 中将 Android 端粗体权重降为 Font.Medium,避免合成粗体产生重影。

Windows 双击 exe 提示缺少 Qt DLL

使用 windeployqt 部署依赖后再运行。部署时建议使用和构建 Kit 一致的 Qt 目录。

修改图标后没有变化

重新运行 CMake 配置并重新构建。Windows 资源管理器可能缓存 exe 图标,可尝试换构建目录、改输出文件名或重启资源管理器。

启动后没有数据

检查服务端地址是否正确,并在配置中心点击“测试连接”。如果服务端不可达,底部会显示简短连接失败提示。

姓名或班级显示不正确

在配置中心维护学生姓名映射和班级名称映射,保存后记录列表和统计结果会重新计算。

人脸照片不显示

检查 /api/face_photos 是否返回照片 ID,并确认 /api/face_photo/{id} 可以访问。

仓库与作者

仓库地址:

ssh://git@git.yzfh.eu.cc:2084/yzfh/qt.git

作者:

纪田野

关于页中也展示了仓库地址和查看账号信息。若项目公开发布,请避免在仓库中提交真实密码。

维护建议

  • 不要提交 build/、build-codex/ 等构建目录。
  • 修改 QML 后建议运行 qmlformat 保持格式一致。
  • 服务端记录量超过 1000 条时,需要扩展分页加载逻辑。
  • 服务端加密参数变化时,需要同步修改 src/CryptoUtils.cpp。
  • 发布桌面版本时,使用 Qt 部署工具收集运行时依赖。
  • 发布 Android 版本时,建议补充签名配置和 release 构建流程。
  • 如果需要修改历史提交作者,请在推送前完成,避免远程协作历史冲突。

开源协议

本项目采用 MIT License 开源,详见 LICENSE 文件。

S
Description
QML 重构后
Readme MIT 730 KiB
Languages
C++ 51.9%
QML 44.9%
CMake 1.5%
PowerShell 1.2%
C 0.5%