feat(shared,server,web,client,plugin)!: 角色与权限重构 + 学期周次 + 课表方向反转(1.2.0)

学生、任课关系、周次口径三处长期靠约定维持的事情,改为由数据模型保证。

学生不是账号
- 拆出独立 Student 表,没有 passwordHash / role / 任何登录字段
- 「学生不能登录」由表结构保证,不再靠「登录前判 role 再 403」的代码分支
- 三张个人数据表外键 userId → studentId;删掉 Enrollment 与 ClassTeacher
- 学生一律称「学号」、教师一律称「工号」,「学生账号」这个概念消失

任课关系唯一来源 = Course(班级 + 科目 + 教师)
- 班主任 = Class.teacherId,科任 = Course.teacherId,同一人两处指向同一账号、不重复建号
- 作业与成绩按科目再收一道:挂科目只由该科任课老师改,没挂科目归班主任 / 管理员
- 新增「任课教师分配」与「班级教师批量导入」(带「使用工号匹配」开关)

成绩与名单
- 成绩等级:百分制 / 等级制 A·B·C·D / 自定义,支持单个与批量改等级
- 按学号查成绩明细(教师端 + 班级端 + 设备令牌),受按班开关控制
- 调班 / 转出(单个与批量)+ 可查历史;学号不变、历史作业成绩留原归属
- 毕业归档页(按年度记录毕业班级 / 毕业生 / 转出学生 / 该届通知与作业)
- 学年升级(未毕业不归档、数据沿用);班级称呼改为「2026级1班」

ClassHelper 班级端在线状态
- Web 端显示 班级 / 设备名 / 设备号 / 在线离线 / 最后在线 / 最后心跳
- lastHeartbeatAt 驱动 60 秒在线窗口,与只表示「带状态上报」的 lastSeenAt 分开

学期周次
- 新增 TermWeek(classId 空串 = 全校默认),管理员可用日期范围选择器逐周配置
- 一键按开学日期生成整学期;联网拉取调休建议(只给建议、不改数据,无外网失败属正常)
- 改周次后随课表下发给教室的 ClassHelper 班级端

课表方向反转
- 主方向改为「服务端 → 教室」自动下发;教室不再自动回传
- 取教室课表改为手动动作(点击前弹警告),插件按待办标记在下一次心跳补报

改名
- 班级小助手 → ClassHelper:界面、窗口标题、托盘、灵动岛、EXE、安装包、
  安装目录、systemd 描述、插件清单与设置页、官网、文档站、README

BREAKING CHANGE: 产品名与 EXE 名变更(班级小助手.exe → ClassHelper.exe),
安装目录随之改变,不支持覆盖安装,需先卸载旧版。
服务端首次启动会自动应用 6 个数据库迁移(学生行按 id 原样搬迁,历史数据不丢),
升级前请先备份。
This commit is contained in:
LoveChengke committed 2026-10-06 19:41:18 +08:00
1 parent 17f55864bf
commit 9d5ac7adf9
172 files changed
+8761 -1896

No files matched your search

+8 -8
View File
@@ -1,20 +1,20 @@
---
title: 接入 ClassIsland
description: 把教室里的 ClassIsland 接上班级小助手:下课表上报、大屏提醒下发、课表镜像三个方向。
description: 把教室里的 ClassIsland 接上 ClassHelper:下课表上报、大屏提醒下发、课表镜像三个方向。
---
# 接入 ClassIsland
课堂里真正"知道现在第几节、在上什么课"的是 [ClassIsland](https://classisland.tech)。
它跟班级小助手管的事情不重叠,接起来之后两边各拿各的好处:
它跟 ClassHelper管的事情不重叠,接起来之后两边各拿各的好处:
| 方向 | 做什么 | 老师在哪看 |
| ------------------------------- | ----------------------------------------------------------------------------------- | ---------------------------------------- |
| ClassIsland → 班级小助手 | 上报**课表 + 节次时间 + 上课状态**(现在上什么 / 下一节 / 本节起止),写进本班课表 | Web 端「ClassIsland 联动」的实时状态卡片 |
| 班级小助手 → ClassIsland | 老师发一条**提醒** → 落库 → 教室插件取回 → ClassIsland 上**全屏弹出**(可语音朗读) | Web 端「ClassIsland 联动 → 下发提醒」 |
| ClassIsland → ClassHelper | 上报**课表 + 节次时间 + 上课状态**(现在上什么 / 下一节 / 本节起止),写进本班课表 | Web 端「ClassIsland 联动」的实时状态卡片 |
| ClassHelper → ClassIsland | 老师发一条**提醒** → 落库 → 教室插件取回 → ClassIsland 上**全屏弹出**(可语音朗读) | Web 端「ClassIsland 联动 → 下发提醒」 |
| (可选)班级 → ClassIsland 镜像 | 把小助手这边排好的课表**镜像**回 ClassIsland,新建一份档案,不动老师原有的课表 | 同一页的「开镜像」开关 |
> 没接 ClassIsland 也能用班级小助手,只是教室里少一个大屏播报的出口。**这一步是可选的。**
> 没接 ClassIsland 也能用 ClassHelper,只是教室里少一个大屏播报的出口。**这一步是可选的。**
## 前置:ClassIsland 装好了
@@ -46,7 +46,7 @@ description: 把教室里的 ClassIsland 接上班级小助手:下课表上报
### 填令牌
ClassIsland 的**设置 → 班级小助手联动**里填:
ClassIsland 的**设置 → ClassHelper 联动**里填:
| 设置项 | 说明 |
| ---------------------------- | --------------------------------------------------------------- |
@@ -85,7 +85,7 @@ ClassIsland 的**设置 → 班级小助手联动**里填:
| 要同步的内容 | 需要打开 |
| -------------------------------- | ------------------------------------------------------------------------------- |
| 服务端 → ClassIsland(镜像课表) | ① 插件设置「把班级课表镜像回 ClassIsland」+ ② Web 端该设备的「镜像课表」 |
| ClassIsland → 服务端(上报课表) | 插件设置「上报课表到班级小助手」 |
| ClassIsland → 服务端(上报课表) | 插件设置「上报课表到 ClassHelper」 |
| 提醒下发 | ① 教室客户端的「通知显示位置」不是"只在 ClassHelper" + ② 插件「接收小助手提醒」 |
## 上课时段:两边同一套规则
@@ -110,7 +110,7 @@ ClassIsland 侧的暂存由插件实现:它订阅课程服务,下课后把
## 镜像:把小助手的课表写回 ClassIsland
开启后,插件会新建一份名为 `班级小助手-<班级名>` 的档案课表,**不动老师原有的课表**。
开启后,插件会新建一份名为 `ClassHelper-<班级名>` 的档案课表,**不动老师原有的课表**。
镜像时会连节次时间一起带过去,并且**每两节之间补一段课间、最后一节之后不补**(放学)。
这一步不做的话,ClassIsland 的课表会整体错位 —— 表现为"看着有内容、每节课都对不上"。
+5 -5
View File
@@ -1,9 +1,9 @@
---
title: 装学生端
description: 在教室机器上安装班级小助手桌面客户端,用班级码登录,并第一次跑通实时通知。
title: 装 ClassHelper 班级端
description: 在教室机器上安装 ClassHelper桌面客户端,用班级码登录,并第一次跑通实时通知。
---
# 装学生端
# 装 ClassHelper 班级端
桌面客户端装在**教室的那台机器**上(教室大屏、讲台电脑)。它是学生看课表作业的地方,
也是「消息到达的第一现场」—— 灵动岛就长在这一端。
@@ -14,8 +14,8 @@ description: 在教室机器上安装班级小助手桌面客户端,用班级
| 产物 | 用途 |
| ------------------------------------ | ------------------------------------------ |
| `班级小助手-<版本>-x64-setup.exe` | 安装包(约 98 MB),装到本机并建快捷方式 |
| `班级小助手-<版本>-x64-portable.exe` | 单文件便携版,双击即用,适合不改动机房机器 |
| `ClassHelper-<版本>-x64-setup.exe` | 安装包(约 98 MB),装到本机并建快捷方式 |
| `ClassHelper-<版本>-x64-portable.exe` | 单文件便携版,双击即用,适合不改动机房机器 |
要自己打:
+6 -6
View File
@@ -1,6 +1,6 @@
---
title: 发布第一条内容
description: 发通知、布置作业、叫人、录成绩——把班级小助手真正用起来的第一轮操作。
description: 发通知、布置作业、叫人、录成绩——把 ClassHelper真正用起来的第一轮操作。
---
# 发布第一条内容
@@ -11,7 +11,7 @@ description: 发通知、布置作业、叫人、录成绩——把班级小助
**通知发布** → 选班级 → 填标题和内容 → 选优先级 → 发布。
| 优先级 | 学生端表现 |
| 优先级 | ClassHelper 班级端表现 |
| ------ | -------------------------------------------------------------------------- |
| 普通 | 课间弹胶囊,点击展开;**上课时段只进队列**,下课自动补弹 |
| 重要 | 同上,卡片上带优先级标签 |
@@ -32,14 +32,14 @@ description: 发通知、布置作业、叫人、录成绩——把班级小助
附件支持站内相对路径或 `http(s)://` 链接(其他 scheme 服务端会拒,避免被当成脚本执行)。
学生端那边默认是**看板模式**:按科目分卡片、每条作业完整显示要求、整个看板缩放到刚好铺满屏幕;
ClassHelper 班级端那边默认是**看板模式**:按科目分卡片、每条作业完整显示要求、整个看板缩放到刚好铺满屏幕;
老师也可以在教室机器上直接**录入作业**、勾选**未交名单**(教室机器用的是班级账号)。
## 叫一位同学
**通知发布 → 叫人**(或管理员在**学生管理 → 叫人**)→ 选学生 → 点一个快捷短语或自己写一句 → 发送。
| 级别 | 学生端 |
| 级别 | ClassHelper 班级端 |
| -------- | ------------------------------------------------------------------ |
| 普通叫人 | 课间显示「叫人」胶囊,点击展开;**上课时段只进队列**,下课自动弹出 |
| 紧急叫人 | **无视上课时段立即展开**,上课时被收起后仍保留胶囊、可再次点开 |
@@ -53,11 +53,11 @@ description: 发通知、布置作业、叫人、录成绩——把班级小助
**成绩录入** → 选班级与考试名称 → 单条录入 / 批量录入 / 导入表格。
- **科目**下拉同样是全校统一目录,选一个该班还没有的科目会自动建课。
- 导入表格支持 `.xlsx / .xls / .csv / .tsv`,列名按同义词自动映射(「学号→学生用户名」「得分→分数」),
- 导入表格支持 `.xlsx / .xls / .csv / .tsv`,列名按同义词自动映射(「用户名→学号」「得分→分数」),
也可以手动改。**文件上限 8MB**,超了会返回明确的 413 而不是一句英文的内部错误。
- 导入结果会给逐行的错误与警告,`errors[].row` 是 **Excel 视角的行号**(含表头),改完可以再导。
学生端看到的是**全班总览**:表格(分数 / 得分率 / 等级)+ 柱状图 + 等级分布 + 最近更新。
ClassHelper 班级端看到的是**全班总览**:表格(分数 / 得分率 / 等级)+ 柱状图 + 等级分布 + 最近更新。
## 在教室大屏上播一条提醒(需要 ClassIsland)
+3 -3
View File
@@ -1,11 +1,11 @@
---
title: 快速上手
description: 从零把班级小助手跑起来:装服务端、认管理端、建班级排课、装学生端、接 ClassIsland、发第一条内容。
description: 从零把 ClassHelper跑起来:装服务端、认管理端、建班级排课、装 ClassHelper 班级端、接 ClassIsland、发第一条内容。
---
# 快速上手
班级小助手不是一个单机软件,它由四部分组成,**必须先有服务端,其他三端才有内容可看**:
ClassHelper不是一个单机软件,它由四部分组成,**必须先有服务端,其他三端才有内容可看**:
| 组成部分 | 装在哪 | 谁用 | 必须先装? |
| ------------------------ | --------------------------------------- | -------------------------- | ---------------- |
@@ -20,7 +20,7 @@ description: 从零把班级小助手跑起来:装服务端、认管理端、
2. [安装服务端](server.md) —— Windows 安装包 / Linux 一键脚本 / Docker / 源码跑
3. [认识 Web 管理端](web-admin.md) —— 登录进去,认一认界面
4. [建班级、排课表](setup-class.md) —— 这是后面所有功能的前提
5. [装学生端](client.md) —— 教室机器用班级码登录
5. [装 ClassHelper 班级端](client.md) —— 教室机器用班级码登录
6. [接入 ClassIsland](classisland.md) —— 让教室大屏也会弹提醒(可选)
7. [发布第一条内容](first-content.md) —— 通知 / 作业 / 叫人 / 成绩
+2 -2
View File
@@ -1,6 +1,6 @@
---
title: 系统要求
description: 班级小助手服务端、Web 管理端、桌面客户端的运行环境与网络要求。
description: ClassHelper 服务端、Web 管理端、桌面客户端的运行环境与网络要求。
---
# 系统要求
@@ -38,7 +38,7 @@ ldd --version | head -1
| 屏幕 | 桌面 1280×720 以上;手机(≤768px)有一套独立的抽屉式布局,同样可用 |
| 安装 PWA | 手机 / 桌面 Chrome 里「添加到主屏幕」可当 App 用(需要 HTTPS 或 localhost) |
## 桌面客户端(学生端 / 教室机器)
## 桌面客户端(ClassHelper 班级端 / 教室机器)
| 项目 | 要求 |
| -------- | ---------------------------------------------------------------------------- |
+4 -4
View File
@@ -1,6 +1,6 @@
---
title: 安装服务端
description: 用 Windows 安装包、Linux 一键脚本、Docker 或源码把班级小助手服务端跑起来。
description: 用 Windows 安装包、Linux 一键脚本、Docker 或源码把 ClassHelper 服务端跑起来。
---
# 安装服务端
@@ -21,7 +21,7 @@ description: 用 Windows 安装包、Linux 一键脚本、Docker 或源码把班
### 生成安装包
安装包不入库(体积大),从 [Releases](https://github.com/LoveChengke/classhelper/releases) 直接下载
`班级小助手服务端-<版本>-x64-setup.exe` 即可。要自己打:
`ClassHelper 服务端-<版本>-x64-setup.exe` 即可。要自己打:
```bash
pnpm dist:server # 首次会执行一次 npm install(约 2 分钟)
@@ -32,7 +32,7 @@ pnpm dist:server -- --reuse-deps # 迭代打包:复用已装依赖,跳过
| 路径 | 说明 |
| --------------------------------------------------------------------- | ------------------------------------------- |
| `releases/server/<版本>/安装包/班级小助手服务端-<版本>-x64-setup.exe` | 安装程序(约 62 MB,NSIS) |
| `releases/server/<版本>/安装包/ClassHelper 服务端-<版本>-x64-setup.exe` | 安装程序(约 62 MB,NSIS) |
| `releases/server/<版本>/免安装/` | 免安装目录,拷到任意 Windows x64 机器即可跑 |
包内自带 Node 运行时、后端产物、Web 管理端产物、生产依赖、迁移 SQL、随机 `JWT_SECRET` 的 `.env`
@@ -43,7 +43,7 @@ pnpm dist:server -- --reuse-deps # 迭代打包:复用已装依赖,跳过
双击安装程序即可,**不需要管理员权限**(当前用户级安装)。
- 安装目录:`%LOCALAPPDATA%\Programs\ClassHelperServer`
- 静默安装:`"班级小助手服务端-<版本>-x64-setup.exe" /S`
- 静默安装:`"ClassHelper 服务端-<版本>-x64-setup.exe" /S`
- 开始菜单:启动服务 / 停止服务 / 重启服务 / 打开管理端 / 使用说明 / 卸载
- 自动加入当前用户开机自启
+5 -5
View File
@@ -20,7 +20,7 @@ Web 管理端 → **班级管理** → 「新建班级」:
| 班级码 | 保存时自动生成(字母数字 4–16 位,存大写),可以改成好记的,例如 `G203` |
| 班级密码 | 新建班级时的初始密码就是它 —— 学生在教室机器上要用这个登录 |
> **班级码 + 班级密码 = 学生端的登录凭据。** 学生端没有个人账号,一台教室机器用班级账号登录后,
> **班级码 + 班级密码 = ClassHelper 班级端的登录凭据。** ClassHelper 班级端没有个人账号,一台教室机器用班级账号登录后,
> 那台机器上的「已读 / 完成」是**代全班**操作的。
>
> 学期周数只有管理员能改:它决定"现在是第几教学周",乱改会让课表的周次过滤和上课时段判定错位。
@@ -30,7 +30,7 @@ Web 管理端 → **班级管理** → 「新建班级」:
**学生管理** → 「新建」或「导入名单」:
- **单个新建**:填姓名即可,登录名会自动生成。
- **导入名单**:下载模板(列只有 `用户名 / 姓名`,学生没有账号属性,**没有密码列**),填好上传。
- **导入名单**:下载模板(列是 `学号 / 姓名 / 班级 / 性别 / 家长手机号`,学生**不是账号**,没有密码列),填好上传。
用户名要匹配 `^[A-Za-z0-9_.-]{3,32}$`;重复用户名在 `append` 模式下跳过、`upsert` 模式下更新姓名。
用户名已经属于某个教师 / 管理员账号时,这一行会进错误列表,不会覆盖别人的账号。
@@ -39,7 +39,7 @@ Web 管理端 → **班级管理** → 「新建班级」:
## 3. 加科任老师
教师的**录入**只有管理员能做(**教师管理**页,支持单个录入与导入名单)。班级层面的**分配**在班级详情里:
把老师加进「协作教师」,他就能看到这个班、给这个班发作业 / 通知 / 叫人。
在「班级详情 → 任课老师」里给某位老师配一门课,他就能看到这个班,并**只能改自己任教科目**的作业与成绩。
角色与可见范围见[班级、学生与教师](../app/classes.md)与[角色与权限](../dev/permissions.md)。
@@ -62,10 +62,10 @@ Web 管理端 → **班级管理** → 「新建班级」:
## 5. 确认「上课时段」判定是对的
班级小助手有一整套「上课时段策略」:普通通知在上课时段只进队列、下课自动补弹,紧急通知与叫人则立刻弹。
ClassHelper有一整套「上课时段策略」:普通通知在上课时段只进队列、下课自动补弹,紧急通知与叫人则立刻弹。
这套判定完全基于课表,所以**课表排错,提醒就会在该弹的时候不弹**。
排完课之后建议立刻验一下:在**通知发布**页选这个班,随便发一条普通通知,
看客户端是不是在课间弹出来、上课时是不是安静地收着。规则详见[通知与提醒](../app/notifications.md)。
下一步:[装学生端](client.md)。
下一步:[装 ClassHelper 班级端](client.md)。
+1 -1
View File
@@ -8,7 +8,7 @@
href: web-admin.md
- name: 建班级、排课表
href: setup-class.md
- name: 装学生端
- name: 装 ClassHelper 班级端
href: client.md
- name: 接入 ClassIsland
href: classisland.md
+1 -1
View File
@@ -1,6 +1,6 @@
---
title: 认识 Web 管理端
description: 登录班级小助手 Web 管理端,认一认 12 个页面、新手引导与手机端布局。
description: 登录 ClassHelper Web 管理端,认一认 12 个页面、新手引导与手机端布局。
---
# 认识 Web 管理端