Repository navigation
ClassHelper v1.3.0(权限组 · 客户端设备统一更新与远控 · 大模型助手)
ClassHelper v1.3.0
这一版做两件事:把「谁能做什么」从角色名改成权限键,并给每台教室机器一个身份。
于是「给某位老师单独开一个入口」不用再改代码,「这台教室机上装的是哪个版本」也终于看得见。
另外新增了一个大模型助手:一句话描述要做的事,它只负责解析成待确认的动作,落库仍走既有入口。
⚠️ 升级须知
服务端升级后会自动应用 1 个数据库迁移(权限组 3 表 / 全局设置 / 客户端设备·命令·安装包 /
大模型审计 /Notification.assignDate/User.careMode),历史通知按本地日期回填,不会留空。
升级前请先备份。
没有分组的账号按角色默认模板生效,行为与 1.2.0 一致 —— 这一版不会因为升级把谁关在门外。
教室机器要看到「客户端设备」页里的版本与远控,客户端需升到 1.3.0。
一、权限组:角色只是默认模板
原先「谁能做什么」写在路由的 requireRole('ADMIN', 'TEACHER') 上,想给某位老师单独放行一个入口
只能改代码。现在改成读权限键:
- 权限目录共 39 个键(键 / 中文名 / 分类 / 默认角色),三端共用同一份,不存在「Web 端说有、客户端说没有」;
- 管理员可以建权限组、勾权限、把账号分配进去(一个账号可以属多个组);
- 没有分组的账号按角色默认模板生效;一旦分组,生效集合就只由组的并集决定 ——
所以权限组既能授权,也能收权; - 生效权限每次请求实时算,改完立刻生效,不需要重启服务端;
- 管理员账号始终是全集,且「权限组管理」「系统设置」两项不可被剥夺(免得把自己锁在门外);
- 班级端(
CLASS_DEVICE)不受分组影响,权限固定为空集。
有一条边界是故意保留的:班级维度的科目规则(「这一科的作业与成绩只有这一科的老师能改」)
不可被权限组覆盖,否则「班主任布置别人科目作业」的老问题会从新路径长回来。
二、客户端设备:教室机器有了身份
- 每台客户端首次启动生成一个
deviceKey(UUID),服务端按它登记一台设备;
这个键不接受外部改写,退出登录也会保留(改了就等于换了一台机器); - 心跳 30 秒一次,在线窗口 90 秒;没有登录就不上报(静默跳过),收到 401/403 退避 5 分钟;
- Web 端新增「客户端设备」页:班级 / 设备名 / 版本 / 平台 / 是否自动更新 / 目标版本 / 最后心跳 / 在线离线;
- 上报走的是「数据库记状态 + 客户端定时拉」,服务端不推 —— 教室机断网、休眠、重启之后
一上线就能把状态与待办补上,不需要维护新的长连接。
三、统一更新与远控
一键推送更新:Web 端指定目标版本 → 客户端下一次心跳拿到 → 下载 → 校验 sha256 → 空闲时安装。
- 安装包由服务端下载并缓存到
data/client-releases/<版本>/——
教室机常常根本没有外网,浏览器侧也受 CSP 限制不能直连 GitHub; - 自动安装三条护栏:① 没有 sha256 就拒收;② 必须等到「非上课 且 主窗口隐藏满 5 分钟」;
③ 冒烟模式永不安装; - 自动更新默认开启,可以按机器关掉;关掉之后客户端的设置页仍会显示服务端下发的目标版本,由人工处理。
远控命令:关机 / 重启 / 注销 / 锁屏。
- 命令有效期 10 分钟(避免机器离线几天之后一开机就被昨天的命令关掉);
- 客户端弹的是**默认选中「取消」**的对话框,60 秒未确认按取消处理;
- 执行之后必须回执,重复回执幂等;同一台机器、同一条命令只弹一次;
- 权限键是
remote:control(默认只有管理员有)。
四、大模型助手:只解析,不落库
Web 端新增「助手」页:直接说一句「明天放学前交数学卷子」,解析成待确认的动作卡片,你点确认才落库。
- 支持的动作:布置作业 / 发通知 / 叫学生来 / 看不懂(看不懂时会原样说明原因,不会瞎猜);
- 落库走的是既有的那几个接口 —— 于是权限断言、上课时段紧急通知保护、ClassIsland 推送
全部自动复用,系统里不存在第二套写入路径; - 模型给的参数会用与手动入口同一份 zod 再校验一次(模型输出不可信);
- 可接任意 OpenAI 兼容接口(
baseUrl+model+apiKey);Key 用 AES-256-GCM 加密后存库,
只进不出 —— 接口只回答「有没有配」和尾 4 位; - 内置
mockprovider:离线确定性解析,自动化验收一律用它(不联网); - 每次解析写一条审计记录,其中不含密钥。
五、系统:开发者模式 · 运行诊断 · 开机自启
- 开发者模式(
system:manage):开启后 500 错误的响应里附带error.stack; - 运行诊断:版本 / 运行时 / 数据库 / 目录 / 迁移状态一眼看完,绝不回传任何密钥;
- 开机自启动运行期可改:Windows 写
HKCU\...\Run,Linux 走systemctl enable/disable——
装完之后不用回去重跑安装器; - 非安装形态(开发机 / 免安装目录 / 容器)返回
supported:false并说明原因,
不会往开发机的注册表里写自启项; - 安装器只负责默认值:Windows 是组件页上一个默认勾选的独立 Section,Linux 在
install.sh里。
六、通知与作业:按天归档 + 批量发布
- 通知与作业同口径按「所属日期」归档(本地日期,不带时区),并新增按天、按发布人归档的接口;
- 新增批量发布:勾多个班一次发完,单个班失败不影响整批,逐班回结果;
- 作业的科目名跨班按名匹配已有课程,匹配不到就整班记失败,绝不自动建课 ——
自动建课会把创建者写成任课老师,等于悄悄改了任教关系。
七、客户端与界面
- 崩溃自愈:渲染进程挂掉、或超过 10 秒无响应,先静默重建主窗口(10 分钟内最多 3 次);
未捕获异常只在「没在上课、没人看着」的时机才重启进程; - 离线补弹:重新上线时把离线期间没读到的通知补推给灵动岛,取最近 5 条按时间升序,同一次离线只弹一次;
- 关怀模式(Web 端):字号与控件整体放大,几何令牌一个都不动;
- 侧栏回缩:Web 端侧栏折叠改成纯 CSS 收拢(不再借用 Element Plus 的
:collapse重建 DOM),
折叠过程里不再有结构切换。
验收
| 门禁 | 结果 |
|---|---|
lint / typecheck / check:icons / docs:check |
全绿 |
verify:e2e / verify:classisland / verify:classisland-plugin / verify:web / verify:desktop |
本版发布时未重跑 |
运行时验收这一轮没有重跑(只跑了构建前的静态门禁)。要补齐按仓库
AGENTS.md§8 的命令序列跑一遍。
产物
| 产物 | 说明 |
|---|---|
ClassHelper-1.3.0-x64-client-setup.exe |
桌面客户端安装包(Windows x64) |
ClassHelper-1.3.0-x64-client-portable.exe |
桌面客户端免安装单文件 |
ClassHelper-1.3.0-x64-server-setup.exe |
服务端安装包(Windows x64,内置 Node 运行时) |
classhelper-server-linux-x64-1.3.0.tar.gz |
服务端 Linux 包(由 GitHub Actions 在 ubuntu-22.04 上构建) |
ClassHelper.ClassIslandPlugin.cipx |
ClassIsland 联动插件 |
SHA256SUMS-1.3.0.txt |
跨组件哈希清单(人读;classhelper upgrade 用的是同名 .sha256) |