Files
bishe-docs/04_Qt管理端文档.md
T
2026-05-05 00:16:39 +08:00

463 lines
13 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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: <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/<id>`。
3. 下载成功后保存到本地缓存目录:
```text
<AppDataLocation>/face_photos/<id>.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 日志 |