# Qt 管理端文档 ## 1. Qt 管理端是什么 Qt 管理端是整个系统的图形化后台。它支持 Windows 桌面端和 Android 端,主要用于: 1. 查看考勤记录。 2. 按班级、学号、姓名、日期筛选记录。 3. 导出记录 CSV。 4. 清空服务端考勤记录。 5. 查看统计分析。 6. 导出统计 CSV。 7. 配置服务端地址和 API Token。 8. 配置签到时间段。 9. 维护班级信息。 10. 查看 K210 上传的人脸照片。 11. 编辑 K210 face_id 对应的学号、姓名和班级。 12. 删除人脸信息,并可选择删除相关考勤记录。 ## 2. 相关文件 | 文件 | 作用 | | --- | --- | | `QT/main.cpp` | Qt 程序入口,设置应用信息、图标、QML 引擎 | | `QT/qml/Main.qml` | 主界面,包括所有页面和对话框 | | `QT/src/AppController.*` | QML 与 C++ 业务逻辑的中枢 | | `QT/src/ApiClient.*` | HTTP API 客户端 | | `QT/src/AttendanceTypes.h` | 考勤记录、统计、时间段结构体 | | `QT/src/CryptoUtils.*` | AES 加解密工具 | | `QT/src/RecordListModel.*` | 考勤记录模型 | | `QT/src/StatisticsListModel.*` | 统计模型 | | `QT/src/TimeSlotListModel.*` | 时间段模型 | | `QT/src/StudentProfileListModel.*` | 学生档案模型 | | `QT/src/MappingListModel.*` | 班级信息等键值模型 | | `QT/src/FaceListModel.*` | 人脸管理模型 | | `QT/CMakeLists.txt` | Qt/CMake 构建配置 | | `QT/clear_qt_cache.ps1` | 清理当前 Qt 项目的 Qt Creator/CMake 缓存 | | `QT/android/` | Android Gradle 配置和图标 | | `QT/assets/` | 桌面端图标 | ## 3. 技术栈 | 分类 | 内容 | | --- | --- | | 语言 | C++17、QML | | UI | Qt Quick、Qt Quick Controls 2 | | Qt 模块 | Core、Gui、Qml、Quick、QuickControls2、Network | | 构建系统 | CMake 3.16+ | | 样式 | `QQuickStyle::setStyle("Basic")` | | Android 文字渲染 | `NativeTextRendering` | | 本地配置 | `QSettings`、`QStandardPaths::AppDataLocation` | ## 4. 应用基础信息 位置:`QT/main.cpp` | 项 | 值 | | --- | --- | | ApplicationName | `人脸识别考勤系统` | | ApplicationVersion | `3.0.0` | | OrganizationName | `STM32 Face Recognition` | | 主 QML | `qrc:/qml/Main.qml` | | 默认窗口大小 | `1560 x 920` | | PC 最小窗口 | `900 x 620` | | Android 最小窗口 | `360 x 560` | ## 5. 页面结构 Qt 管理端是单窗口应用,共 5 个页面: | 页面 | 作用 | | --- | --- | | 考勤记录 | 查看、筛选、导出、清空记录 | | 统计分析 | 按时间范围统计学生签到情况 | | 配置中心 | 服务端地址、签到时间段、班级管理 | | 人脸管理 | 查看照片、编辑学号姓名班级、删除人脸 | | 关于 | 系统说明、版本和作者信息 | PC 宽屏显示左侧导航栏;窄屏和 Android 显示顶部/底部更紧凑的导航布局。 ## 6. 网络访问规则 Qt 端的服务端地址默认是: ```text http://127.0.0.1:8082 ``` 用户可在“配置中心”修改服务端地址和 API Token。保存后写入本地 `QSettings`: ```text server/url server/apiToken ``` `ApiClient::buildUrl` 会在地址后自动拼接 `/api`,例如: ```text 服务端地址: http://127.0.0.1:8082 传入 endpoint: /v1/system/health 实际请求: http://127.0.0.1:8082/api/v1/system/health ``` 所有请求都会带: ```text X-Api-Token: Accept: application/json ``` 除照片 JPEG 下载外,Qt 的业务 JSON 请求和响应统一使用 AES-128-CBC + PKCS#7 + Base64。GET/DELETE 请求要求服务端返回加密响应,POST JSON 会先加密请求体并携带 `X-Encrypted: AES128-CBC`;照片内容仍按 `image/jpeg` 原始二进制显示。 Qt 端没有在代码中写死默认 Token。启动后会优先读取本地 `QSettings` 的 `server/apiToken`,没有本地值时读取环境变量: ```powershell $env:ATTENDANCE_API_TOKEN="你的Token" ``` 网络超时: ```text 5000 ms ``` ## 7. 启动流程 Qt 启动后: 1. `main.cpp` 创建 `QGuiApplication`。 2. 设置应用图标、应用名、版本号、组织名。 3. Android 下启用原生文字渲染。 4. 创建 `AppController`。 5. `AppController` 读取本地服务端地址、API Token、学生档案缓存、班级缓存、人脸档案缓存和时间段配置。 6. `ApiClient` 设置当前服务端地址和 API Token。 7. 启动自动重连状态并执行健康检查。 8. QML 载入 `Main.qml`。 9. QML 通过上下文对象 `appController` 调用 C++。 ## 8. 自动重连 如果健康检查失败,`AppController` 会进入重连状态。 相关参数: ```text ReconnectIntervalMs = 5000 ``` 重连成功后,如果之前处于重连中,会调用: 1. `refreshAll()` 2. `refreshFaces()` 这样服务端恢复后,记录、配置、照片和映射会重新同步。 ## 9. 考勤记录页 功能: 1. 显示服务端记录。 2. 显示总记录数、今日记录数、当前筛选结果数。 3. 按班级筛选。 4. 按学号筛选。 5. 按姓名关键字筛选。 6. 按日期范围筛选。 7. 导出当前筛选结果。 8. 清空服务端所有记录。 记录加载默认请求: ```text GET /api/v1/attendance/records?limit=1000&offset=0 ``` 注意:当前 Qt 统计和筛选主要基于已加载的记录。如果服务端超过 1000 条,界面统计不一定覆盖全部历史记录。 ## 10. 筛选规则 筛选在 Qt 本地完成。 支持: | 筛选项 | 说明 | | --- | --- | | 班级 | `class_id` 匹配 | | 学号 | `student_id` 匹配 | | 姓名 | 学生档案姓名或原始 name 包含关键字 | | 日期 | 全部、今天、最近 7 天、最近 30 天、指定日期 | 姓名显示优先级: 1. 如果学生档案里有该学号,显示档案姓名。 2. 否则显示服务端记录中的 `name`。 3. 如果都没有,则显示原始学号。 班级显示优先级: 1. 如果班级信息里有该 `class_id`,显示班级名称。 2. 否则显示 `class_id`。 ## 11. 记录导出 导出 CSV 文件时会写入: ```text # 考勤记录导出 # 导出时间: yyyy-MM-dd HH:mm:ss # 记录总数: N 签到时间,班级编号,班级名称,学号,姓名,置信度,状态 ``` 字段会做 CSV 转义,包含逗号、双引号、换行时会自动加引号并转义。 ## 12. 统计分析页 统计页基于当前加载记录在本地计算。 支持时间范围: 1. 今天。 2. 最近 7 天。 3. 最近 30 天。 4. 本月。 5. 自定义开始和结束日期。 统计指标: | 指标 | 含义 | | --- | --- | | 统计学生数 | 当前范围内出现过的学生数量 | | 统计记录数 | 当前范围内记录数量 | | 总签到次数 | 每个学生在范围内的记录数量 | | 今日签到 | 每个学生今天的记录数量 | | 最后签到时间 | 每个学生最新一条记录时间 | | 平均置信度 | 每个学生记录的平均 confidence | 导出字段: ```text 考勤统计报表,<范围> 学号,姓名,总签到次数,今日签到,最后签到时间,平均置信度 ``` ## 13. 配置中心 配置中心包含三块: 1. 服务端地址和 API Token。 2. 时间段配置。 3. 班级管理。 ### 13.1 服务端配置 字段示例: ```text http://27.106.113.205:8082 ``` 按钮: | 按钮 | 作用 | | --- | --- | | 保存 | 同时保存服务端地址和 API Token 到 `QSettings`,并立即切换 `ApiClient` 配置 | | 测试连接 | 使用当前配置请求 `/api/v1/system/health` | ### 13.2 时间段配置 时间段格式: ```json { "name": "上午签到", "start_time": "08:00", "end_time": "09:30", "enabled": true } ``` 当前默认时间段为空。第一次使用时需要手动新增。 按钮: | 按钮 | 作用 | | --- | --- | | 展开/收起 | 展示或隐藏时间段列表 | | 新增时段 | 打开新增对话框 | | 清空时段 | 清空本地时间段并保存同步到服务端 | | 从服务器同步/同步 | 从服务端读取时间段;服务端为空数组时也会清空本地时间段 | | 保存时间段/保存 | 保存到本地并上传服务端 | 本地文件: ```text timeslot_config.json ``` 该文件只作为 Qt 管理端本地缓存;服务端当前以 SQLite 中的配置为准。 ### 13.3 班级管理 配置中心只负责班级新建、命名和删除,不再单独提供学生档案编辑页。学生学号、姓名和班级归属在人脸管理页的编辑弹窗中维护。班级信息通过独立接口维护: ```text GET /api/v1/classes POST /api/v1/classes ``` 请求体示例: ```json { "classes": [ { "class_id": "1", "class_name": "软件工程一班" } ] } ``` 记录列表、班级筛选和导出优先使用学生档案中的班级归属关系;没有配置时才显示设备上传记录中的原始班级编号。 删除班级前,管理端会先检查该班级下是否还有学生;服务端保存班级时也会进行同类校验。 本地文件: ```text profiles_cache.json ``` ## 14. 人脸管理页 人脸管理页把两类人脸数据合并展示: 1. 服务端照片列表。 2. 服务端人脸档案。 照片 ID 始终使用 K210 原始 `face_id`,例如 `faces/1.jpg`。Qt 通过 `/api/v1/face_profiles` 维护 `face_id -> 学号` 的绑定关系,并通过 `/api/v1/students` 保存学号、姓名和班级归属,不再把所有已有考勤学生 ID 当成“无照片人脸”展示。 用户可以: 1. 刷新人脸库。 2. 点击“编辑”打开弹窗,填写真实学号、姓名和班级。 3. 保存学生档案和人脸档案。 4. 删除人脸。 5. 修改已有学号前弹窗提示影响范围。 6. 删除人脸时选择是否同时删除该学生的考勤记录。 照片下载流程: 1. Qt 获取照片 ID 列表。 2. 对每个 ID 请求 `/api/v1/faces/photos/`。 3. 下载成功后保存到本地缓存目录: ```text /face_photos/.jpg ``` 4. QML 使用本地 file URL 显示图片。 ## 15. 关于页面 关于页显示: 1. 系统用途。 2. 功能范围。 3. 毕业设计说明。 4. 作者和版权信息。 5. 仓库地址。 6. 演示账号信息。 这些文本在 `QT/qml/Main.qml` 中。 ## 16. PC 和 Android 适配 当前 QML 中有这些布局断点: | 属性 | 条件 | 用途 | | --- | --- | --- | | `compactLayout` | `width < 1460` | PC 紧凑布局 | | `denseLayout` | `width < 1380` | 更密集显示 | | `narrowLayout` | `width < 1280` | 表格列裁剪 | | `slimLayout` | `width < 1040` | 隐藏侧边栏,使用移动导航 | | `phoneLayout` | PC 小于 560,Android 小于 640 | 手机布局 | Android 特殊处理: 1. 最小窗口宽度是 `360`。 2. 最小窗口高度是 `560`。 3. 字体使用 `sans-serif`。 4. 粗体权重降低为 `Font.Medium`。 5. 使用原生文字渲染,减少中文粗体重影。 配置页卡片现在使用内容自适应高度,避免按钮遮挡。 ## 17. 本地持久化 Qt 使用两类本地持久化。 ### 17.1 QSettings 保存服务端地址和 API Token: ```text server/url server/apiToken ``` ### 17.2 AppDataLocation 文件 | 文件 | 内容 | | --- | --- | | `timeslot_config.json` | 时间段配置 | | `profiles_cache.json` | 学生档案、班级信息和人脸档案的本地缓存 | | `face_photos/*.jpg` | 下载后的人脸照片缓存 | ## 18. 构建方式 ### 18.1 Qt Creator 1. 打开 Qt Creator。 2. 打开 `QT/CMakeLists.txt`。 3. 选择 Desktop Qt 6.x 或 Android Kit。 4. 等待 CMake 配置完成。 5. 构建 `apprewrite_qt`。 6. 桌面端直接运行;Android 端部署到设备或模拟器。 ### 18.2 命令行示例 Windows: ```powershell cd D:\University\graduation\thesis\code\QT cmake -S . -B build\Desktop -DCMAKE_PREFIX_PATH=D:\Qt\6.10.0\mingw_64 cmake --build build\Desktop ``` 实际路径要按本机 Qt 安装位置调整。 ### 18.3 迁移目录后清理缓存 如果项目移动到新目录后 Qt Creator 仍使用旧构建目录,或 CMake 报旧源码路径错误,可关闭 Qt Creator 后在 `QT/` 目录运行: ```powershell powershell -ExecutionPolicy Bypass -File .\clear_qt_cache.ps1 ``` 脚本只删除当前 Qt 项目目录内的 `.qtcreator`、`build`、`CMakeCache.txt`、`CMakeFiles`、`*.user` 等缓存,不清理 Qt Creator 全局配置。 ## 19. 常见问题 | 现象 | 可能原因 | 处理 | | --- | --- | --- | | 测试连接失败 | 服务端没启动、地址错、Token 不一致 | 检查服务端健康接口和 `ATTENDANCE_API_TOKEN` | | 迁移目录后 Qt Creator 报旧路径或构建目录不对 | 项目内 Qt Creator/CMake 缓存仍指向旧目录 | 关闭 Qt Creator,运行 `QT/clear_qt_cache.ps1` 后重新打开 `QT/CMakeLists.txt` | | 页面按钮重叠 | 窗口宽度过小或系统缩放异常 | 当前 QML 已做自适应布局,可适当放大窗口或降低缩放 | | Android 文字发虚/重影 | 字体渲染方式问题 | 当前 Android 使用原生渲染和中等粗体 | | 人脸照片不显示 | 下载失败、本地缓存路径无效、服务端无照片 | 刷新人脸库,看服务端 `faces/` | | 统计数量少于服务端总量 | Qt 默认只拉取 1000 条记录 | 增加分页或服务端统计接口 | | 时间段为空导致无法签到 | 当前默认就是空配置 | 在配置中心新增时间段并保存 | | 保存人脸档案后 K210 没变化 | K210 尚未同步或 WiFi 不通 | 等待同步或检查 K210 日志 |