题王 QKing · 局域网答题系统
面向局域网课堂的实时答题、整卷测验、表格操作题与编程题一体化系统: 单文件 exe,双击即用,断网也能跑。学生机在同一 WiFi 下打开网页就能答, 不需要公网、不需要装 Office、不需要老师机有网。
它想解决的三个问题
- 互动效率:口头点名、举手、传纸条,慢,而且不留数据。
- 判分负担:收上来一沓纸,只算分就占掉半节课。
- 零部署门槛:机房电脑老、没网、不许装东西——所以必须是单文件。
数字一览
| 项目 | 规模 |
|---|---|
| 功能模块 | 13 个(教学现场 / 题目与资源 / 数据与管理) |
| 题型 | 7 种(单选、多选、判断、填空、材料大题、编程题、Excel-WPS 操作题) |
| 数据表 | 26 张表、57 个索引 |
| 接口 | 162 条 HTTP 接口 + 14 条页面路由 |
| 自研代码 | 134 个文件 / 48,865 行 |
| 安装包 | 单文件 exe,约 23 MB |
| 运行环境 | Windows 7 SP1 / 10 / 11;浏览器 Chromium 内核 ≥ 109 |
三步开始用
1. 下载运行 — 取 lanquiz.exe 放到任意目录双击,控制台会打印本机与
局域网访问地址,数据落在同目录 quiz.db。
2. 建房开题 — 教师端登录后进入「房间与考试」创建房间,学生机在同一 WiFi 下打开地址、填姓名即可进入。6 位房间码就是班级凭证,换班上课时 切换房间即可,无需重启服务。
3. 出题与考试 — 题库支持批量导入;实时答题走大屏对战,整卷测验支持 限时、多卷与自动判分,Excel/WPS 操作题与编程题均在浏览器端判分。

功能盘点
| 模块 | 能干什么 |
|---|---|
| 实时答题 | 顺序 / 随机 / 抢答三种次序,选项乱序防抄,实时分布与排行榜,支持补答 |
| 整卷测验 | 6 位考试码进场,限时自动交卷、断线续答、自动判分并出报告 |
| 题库与组卷 | 7 种题型、分类标签、批量导入导出、题库包跨机迁移 |
| Excel/WPS 操作题 | 模板 + 考点 + 判分脚本三件套,浏览器端逐小题判分 |
| 编程题 | 浏览器内写 Python 并跑用例,Pyodide 免服务器编译环境 |
| 统计报告 | 概览、分布、排行、逐题分析,可导出 CSV 与打印 |
| 账号与升级 | CSV 批量导入学生、初始密码清单线下发号;后台一键升级 |

技术实现:三个关键选择
判分放在浏览器,服务端不碰学生代码。 编程题用 Pyodide(WebAssembly) 在学生机上跑用例;Excel/WPS 操作题用 ExcelJS + HyperFormula 在本地重算 公式。服务端只接收结果——不需要装 Office/WPS,也不消耗服务器算力。
数据就是 exe 同目录的一个 quiz.db。 SQLite 单文件库,WAL +
synchronous=NORMAL + busy_timeout=30s,26 张表 57 个索引;业务分库用
ATTACH 把题库域、考试域挂成独立文件,调用方 SQL 一行不用改(代价是跨
attached 库的事务不原子)。
升级靠三步替换。 先写 .new 并校验大小 / MD5 / MZ 头 → 旧 exe 改名
.old 当回退备份 → os.rename 原子就位。早期顺序是「先改名、再 copyfile
写回」,那 23 MB 的拷贝耗时里 exe 一直不存在,断电就再也打不开。

开发日志:翻过的车
- 入口瘦成组合根:
main.py从 6098 行、347 个顶层定义拆成纯装配文件, 顶部留着一张「旧行号 → 新模块」的拆分映射表;对外仍按main.X取用的 名字逐个显式 re-export(改这里 = 改对外契约)。 - 种子库把 519 个真实师生账号发出去了:打包时「要清空的表」是人工维护
的白名单,漏登记的表会原样随包发出去;后来新增
login_sessions又漏一次, 而 token 随包等于拿到包的人不用密码就能冒充管理员。改成「只保留白名单里 的表,其余一律清空」,打包前自检不过直接拒绝打包。 - 单文件 exe 的资源住在
%TEMP%:PyInstaller 运行时把 static/templates 全解到系统临时目录,会被 Windows 磁盘清理在运行期间删掉——表现是/static/*全 404、页面 500,而/healthz照样返回 ok,老师只能从学生 浏览器发现。修法:启动时把资源搬到可写的_res/,再补一个看门狗。 - WebSocket 广播被静默丢弃:主循环没注入、跨线程投递抛异常,调用方 都以为「已经推了」,学生端却一动不动,日志里一个字都没有。历史上 「整场不更新、切题卡住」的真因就是这个。
- 回归必须隔离:自研轻量测试基座(不依赖 pytest),37 个套件各跑独立 子进程 + 隔离临时 SQLite,形态开关钉死在默认值,避免「单独跑全过、 一起跑就失败」。
- 索引坏过一次:机房现场
PRAGMA quick_check报索引条目数对不上,/api/join一律 500,全班进不了房——但表数据一条没丢,手工一句REINDEX就救回来了。

已知限制(先说清楚)
- 表格操作题采「可信局域网 / 练习环境」模型,服务端不重算分数。
- 编程题依赖学生机浏览器(Chromium 内核 ≥ 109),Win7 机器需装 Firefox ESR 115 或 Chrome 109,IE 不支持。
- 表格题作答文件与明细只增不删,需要人工清理
excelstore/。 - 数据不加密(2026-09-21 移除整库加密),数据库是教师自持文件。
- 仓库里同时存在两代实现:老架构(FastAPI + Jinja2 + 原生 JS)与新架构
newhugo-Qking(Hugo 静态前端 + FastAPI 后端,17 个测试套件 1055 项全绿)。
文档、下载与源码
