Files
ny-exam-platform/README.md
T
2026-09-08 12:28:22 +08:00

6.4 KiB
Raw Blame History

NY 问卷考试系统数据平台

基于 PHP 8 + 卷王问卷系统(SurveyKing)社区版开放 API 的实时数据统计平台。 选择某个问卷 / 考试后,自动拉取答卷 → 用「姓名」关联学号名单 → 按 学号、姓名、成绩、提交时间、考试时长 依次排列展示,并支持定时自动刷新。

功能

功能 说明
问卷/考试切换 下拉选择,实时显示该问卷的答卷数据
学号自动匹配 用答卷中的「姓名」题在学号名单中查找对应学号(自动识别姓名题,也可手动指定)
实时刷新 5 秒 / 10 秒 / 15 秒 / 30 秒 / 60 秒 / 2 分钟可选,数据变化的行会高亮闪烁;每次刷新后新增的提交以绿色底纹标出
统计卡片 名单总人数、已提交、缺考、提交率、平均分、合格率(≥60% 满分)、最高分、最低分、平均用时;选择班级后,全部卡片只统计该班级
最高/最低分获得者 最高分、最低分卡片下方显示是谁(👑 / 🔻 + 姓名);可在「设置」中关闭
缺考名单 名单中有、但未提交的人
未匹配答卷 提交了但姓名不在名单中的答卷,方便排查
名单导入 上传 .xlsx / .csv,自动识别「学号」「姓名」「班级」列(班级可选);支持覆盖 / 追加、手动增删改
导出 成绩明细 CSV(学号/姓名/班级/成绩/提交时间/考试时长)、缺考名单 CSV(学号/姓名/班级)
排序 / 班级 点击表头排序,成绩明细默认按提交时间降序;支持学号/姓名/班级/成绩/提交时间/时长排序;按班级下拉筛选
全屏 / 自适应 右上角「全屏」按钮进入全屏(布局自动铺满、表格更高);页面适配手机 / 平板 / 桌面三端

环境要求

  • PHP ≥ 8.0(需启用 curl、json、mbstring、openssl(可选,用于 RSA 加密密码);zip 可选,无 zip 扩展时会用内置解析器读 xlsx)
  • 无需数据库、无需 Composer 依赖,数据以 JSON 存放在 data/

部署

方式一:PHP 内置服务器(最快体验)

在本目录执行:

php -S 0.0.0.0:8080

浏览器打开 http://localhost:8080。

Windows 也可双击 启动平台.bat。

方式二:放到 PHP 站点目录

把整个 ny-exam-platform 目录复制到 Apache / Nginx + PHP-FPM 的站点目录下, 确保进程对 data/ 目录有写权限即可。

首次配置

打开页面 → 右上角 设置:

配置项 示例 说明
卷王系统地址 http://192.168.1.10:1991 卷王后台地址,结尾不要带 /
接口前缀 /api 社区版默认 /api;企业版可填 /admin-api
登录账号 admin 卷王后台管理员账号
登录密码 123456 卷王后台密码
姓名题关键词 姓名,名字,学生姓名 用于自动识别哪道题填的是姓名
默认刷新间隔 15 秒

填完点 测试连接,显示「连接成功」后点 保存。

登录流程(社区版 v1.13):GET /api/system 取 RSA 公钥 → 公钥加密密码 → POST /api/public/login 换取 JWT。 注意:v1.13 服务端的 JwtTokenFilter 只从 Cookie sk-token 读取令牌(不读 Authorization 头), 所以登录后程序会把 Set-Cookie 里的 sk-token 原样带在后续每个请求的 Cookie 头里(同时也带 Authorization 头以兼容旧版)。 程序已内置该流程与令牌缓存,并向下兼容 /system/auth/login、/admin-api/oauth2/token 两种登录方式。

关于 401 "Full authentication is required to access this resource" 若你用自己写的客户端对接卷王社区版 v1.13,即使登录成功、拿到了 JWT,调用 /project/list 等接口仍可能返回 401。 原因是 v1.13 服务端只认 Cookie 里的 sk-token,不认 Authorization 头。务必在登录响应里取 Set-Cookie: sk-token=..., 并在后续每个请求带上 Cookie: sk-token=<token>。本平台已处理此细节。

学号名单

  • 平台启动时不预设任何名单,请通过右上角 名单管理 上传你自己的名单(.xlsx / .csv)。
  • 名单文件可包含「学号」「姓名」两列,「班级」为可选列;含班级时,成绩明细会显示班级列并支持按班级筛选(一份考试涉及多个班级时很实用)。
  • 上传方式:名单管理 → 点击或拖拽文件 → 选择覆盖 / 追加 → 保存名单;也可手动增 / 删 / 改。
  • 名单数据保存在 data/roster.json。

目录结构

ny-exam-platform/
├─ index.php                  主页面
├─ api.php                    后端接口(代理卷王 API)
├─ bootstrap.php              配置 / 公共函数 / 自动加载
├─ lib/
│  ├─ SurveyKingClient.php    卷王 API 客户端(登录、令牌缓存、项目、答卷)
│  ├─ DataService.php         数据组装(姓名→学号匹配、统计、排序)
│  ├─ Roster.php              学号名单管理(xlsx/csv 导入与持久化)
│  └─ XlsxReader.php          零依赖 XLSX 读取器
├─ assets/                    前端样式与脚本
├─ data/                      配置、名单、令牌缓存(需可写)
└─ tools/                     开发辅助(PHP 语法校验脚本)

常见问题

1. 页面提示"无法连接卷王系统" 检查:地址端口是否正确、服务器防火墙是否放行、接口前缀是否为 /api、账号密码是否正确。 可直接在服务器本机执行 curl http://127.0.0.1:1991/api/system 验证。

2. 读到了答卷但学号为空 说明答卷里的姓名与名单不一致。处理:

  • 在「姓名字段」下拉里手动指定正确的题目;
  • 或到「设置」里补充姓名题关键词;
  • 未匹配的答卷会显示在「未匹配答卷」面板,可据此核对姓名是否写错(如多了空格)。

3. 成绩列全是 - 说明该问卷不是考试模式或没有开启自动评分,卷王未返回 examScore。

4. 考试时长显示 - 答卷的 metaInfo.answerInfo 中没有开始/结束时间(例如是后台手动录入的答卷)。

5. 想让同一学号只保留最新提交 设置里勾选「同一学号只保留最新一份答卷」(默认开启);取消勾选则保留全部提交记录。