feat(docs,scripts,build): 用 docfx 搭文档站并发布到 GitHub Pages,版本号收口成脚本迭代
文档站(`docs/` 就是 docfx 项目,发布在 https://lovechengke.github.io/ClassHelper/): - 四章 + 常见问题 + 完整参考,共 44 页:快速上手(8 页)/ 应用帮助(10 页)/ 管理运维(6 页)/ 开发文档(11 页)。信息架构照 ClassIsland 文档站来: 顶栏分章、左侧章节导航、右侧本页目录、上一页 / 下一页、站内搜索、深色主题跟随系统; - 自定义模板覆盖(`templates/classhelper/`):把 docfx modern 模板那套英文 UI 文案 (In this article / Improve this doc / Next…)换成中文,补 GitHub 入口与版本徽标, 并加一层只调排版与配色的 `public/main.css`(不动 DOM 结构); - 站点顶栏的版本徽标取自根 `package.json`(`docs/build.mjs` 用 `--metadata` 注入), 不在文档里写第二份 —— 否则一定漂; - 404 页单独生成:GitHub Pages 的项目页挂在 `/<仓库名>/` 子路径下,而浏览器是按**被请求的路径** 解析页面里的相对链接的,所以 `<base>` 必须钉到站点根,由 `build.mjs`(本地 `./`)与 workflow(CI 传 `/<仓库名>/`)分别注入; - 构建前清空 `_site`:docfx 只覆盖不清理,删掉或改名的页面会以旧文件留在目录里, 而 Pages 上传的是整个目录。 版本迭代(**每一次 releases,不是每一次提交**): - 新增 `scripts/version.mjs`。这个仓库里同一个版本号散在 **10 个文件**里(5 份 `package.json`、 `deploy/package.runtime.json`、两个 compose 的镜像 tag、插件 `manifest.yml`、以及插件 C# 里的 `PluginVersion` 常量),手工改必然漏一处,而漏掉的那处**不会报错**,只在某个不常走的分支上 表现为"版本号对不上"。现在收口成两条命令:`pnpm version:check`(逐处比对,不一致 exit 1) 与 `pnpm version:bump patch|minor|major`(一次改写全部 10 处,任何一处匹配不到或匹配到多处 就直接失败退出,不做尽力而为的部分改写); - `AGENTS.md` 新增 §4.4「版本迭代(每一次 releases,不是每一次提交)」:写清版本号落在哪 10 处、 完整发布命令序列(体检 → 验收 → `dist:all` → 哈希清单 → 推 master → `gh release create` → Linux 包由 CI 合并哈希行),以及"已发布的版本号不要复用"的理由。 其它: - `.github/workflows/docs.yml`:推 master(`docs/**` / `package.json` / workflow 自身有变)即构建并 部署到 Pages;构建带 `--check`,把 docfx 的警告当错误 —— 最常见的警告是"某个 `.md` 没被任何 `toc.yml` 引用",那种页面有内容但没有侧边栏,属于必须修掉的疏漏; - docs 目录重组后的引用同步:`production` / `mysql` / `linux-deploy` / `winisland-design-tokens` 移到新位置后,AGENTS.md、`deploy/`、`scripts/`、客户端源码注释里的路径引用一并更新; - 文档站只发布 `docs/` 这一棵树,页面里指向树外的相对链接(`../AGENTS.md` 等)改成 GitHub 绝对 URL, 否则上线全是 404; - 图标派生清单补上文档站模板里的 `logo.png` 与 `favicon.png`(`pnpm icons` 一并生成, 仍然只有一个图形源 `build/classhelper.{png,ico}`); - `docs/_site` 进 `.gitignore` / `.prettierignore` 与 ESLint ignores; - 根脚本补 `version:check` / `version:bump` / `docs:build` / `docs:serve` / `docs:check`。
This commit is contained in:
1 parent
5b002a4f0b
commit
19c2aa07b2
61 files changed
+4761
-12
No files matched your search
@@ -0,0 +1,120 @@
|
||||
---
|
||||
title: 接入 ClassIsland
|
||||
description: 把教室里的 ClassIsland 接上班级小助手:下课表上报、大屏提醒下发、课表镜像三个方向。
|
||||
---
|
||||
|
||||
# 接入 ClassIsland
|
||||
|
||||
课堂里真正"知道现在第几节、在上什么课"的是 [ClassIsland](https://classisland.tech)。
|
||||
它跟班级小助手管的事情不重叠,接起来之后两边各拿各的好处:
|
||||
|
||||
| 方向 | 做什么 | 老师在哪看 |
|
||||
| ------------------------------- | ----------------------------------------------------------------------------------- | ---------------------------------------- |
|
||||
| ClassIsland → 班级小助手 | 上报**课表 + 节次时间 + 上课状态**(现在上什么 / 下一节 / 本节起止),写进本班课表 | Web 端「ClassIsland 联动」的实时状态卡片 |
|
||||
| 班级小助手 → ClassIsland | 老师发一条**提醒** → 落库 → 教室插件取回 → ClassIsland 上**全屏弹出**(可语音朗读) | Web 端「ClassIsland 联动 → 下发提醒」 |
|
||||
| (可选)班级 → ClassIsland 镜像 | 把小助手这边排好的课表**镜像**回 ClassIsland,新建一份档案,不动老师原有的课表 | 同一页的「开镜像」开关 |
|
||||
|
||||
> 没接 ClassIsland 也能用班级小助手,只是教室里少一个大屏播报的出口。**这一步是可选的。**
|
||||
|
||||
## 前置:ClassIsland 装好了
|
||||
|
||||
本插件按 ClassIsland 插件 API 2.0 编写,ClassIsland 2.0.x 与 2.1.0.x 都能加载。
|
||||
先确认教室机器上 ClassIsland 本身能正常显示课表。
|
||||
|
||||
## 第一步:在 Web 端签发设备令牌
|
||||
|
||||
**ClassIsland 联动**页(管理员 / 本班班主任)→「接入新设备」→ 选班级 → 生成令牌。
|
||||
|
||||
令牌形如 `chci_xxxxxxxx…`,**明文只显示这一次**:服务端只存它的 sha256 与一个前缀提示
|
||||
(`chci_80fa1c…`),用来在设备列表里人眼区分。丢了就重置一个。
|
||||
|
||||
## 第二步:在教室机器上装插件并填令牌
|
||||
|
||||
### 装插件
|
||||
|
||||
从 [Releases](https://github.com/LoveChengke/classhelper/releases) 取
|
||||
`ClassHelper.ClassIslandPlugin.cipx`:
|
||||
|
||||
- **推荐**:在 ClassIsland 里直接安装这个 `.cipx`(插件页有「从文件安装」)。
|
||||
- 或者手工解压:把包里的 `ClassHelper.ClassIslandPlugin/` 目录整个丢进
|
||||
`<ClassIsland 数据目录>\Plugins\`,然后重启 ClassIsland。
|
||||
|
||||
> **ClassIsland 运行时会锁住 DLL**。要覆盖升级插件,必须先完全退出 ClassIsland 再覆盖,
|
||||
> 否则写入会被拒。插件配置在 `Config\Plugins\<插件 id>\Settings.json`,
|
||||
> 里面存着服务器地址与设备令牌 —— **升级时别覆盖这个文件**。
|
||||
> 另外改配置要在 ClassIsland 退出时改,运行中改会被内存里的副本回写覆盖。
|
||||
|
||||
### 填令牌
|
||||
|
||||
ClassIsland 的**设置 → 班级小助手联动**里填:
|
||||
|
||||
| 设置项 | 说明 |
|
||||
| ---------------------------- | --------------------------------------------------------------- |
|
||||
| 后端地址 | `http://<服务器IP>:4000` |
|
||||
| 设备令牌 | 上一步生成的 `chci_…` |
|
||||
| 上报课表到小助手 | 打开后才会把 ClassIsland 的课表同步过来 |
|
||||
| 接收小助手提醒 | 关掉就收不到老师发的提醒 |
|
||||
| 提醒轮询间隔 | 默认 10 秒(可调到 5 秒)。上报本身就是心跳,轮询只是顺带取提醒 |
|
||||
| 把班级课表镜像回 ClassIsland | 见下面「镜像」一节 |
|
||||
|
||||
填完点**「立即上报」**。
|
||||
|
||||
## 第三步:验证
|
||||
|
||||
回到 Web 端的「ClassIsland 联动」页,应该出现设备卡片和「在线」标记,实时状态卡上会显示这台机器
|
||||
现在上什么课。到这一步链路就通了。
|
||||
|
||||
如果一直离线:先看插件的日志,再看服务端能不能从教室机器访问到(**别让系统代理拦住内网地址** ——
|
||||
插件对本地 / 内网做了强制直连,但填错地址一样连不上)。
|
||||
|
||||
## 提醒弹在哪个端:由教室客户端自己选
|
||||
|
||||
教室机器的**客户端**「设置 → 提醒」里选,选择会同步到班级记录:
|
||||
|
||||
| 选择 | ClassHelper 客户端 | ClassIsland |
|
||||
| ----------------------------------------- | ------------------------------ | ----------- |
|
||||
| `ClassHelper 与 ClassIsland 都弹`(默认) | 弹窗 + 灵动岛 | 全屏提醒 |
|
||||
| `只在 ClassHelper 客户端弹` | 弹窗 + 灵动岛 | 不推送 |
|
||||
| `只在 ClassIsland 上弹` | 只进通知中心(不弹窗、不上岛) | 全屏提醒 |
|
||||
|
||||
规则只有一条,**任何入口都遵守**:通知发布页、叫人、联动页的「下发提醒」三个入口共用同一份推送实现,
|
||||
不存在"某个页面发的通知不联动"。
|
||||
|
||||
## 两个方向各需要哪些开关
|
||||
|
||||
| 要同步的内容 | 需要打开 |
|
||||
| -------------------------------- | ------------------------------------------------------------------------------- |
|
||||
| 服务端 → ClassIsland(镜像课表) | ① 插件设置「把班级课表镜像回 ClassIsland」+ ② Web 端该设备的「镜像课表」 |
|
||||
| ClassIsland → 服务端(上报课表) | 插件设置「上报课表到班级小助手」 |
|
||||
| 提醒下发 | ① 教室客户端的「通知显示位置」不是"只在 ClassHelper" + ② 插件「接收小助手提醒」 |
|
||||
|
||||
## 上课时段:两边同一套规则
|
||||
|
||||
老师在**上课时段**发通知时,教室里的两个端遵守同一条规则,否则会出现"学生在客户端看不到、
|
||||
却在 ClassIsland 上被打断"的怪事:
|
||||
|
||||
| 提醒类型 | 上课时段 | 下课 / 放学 |
|
||||
| ------------------------------------------------------ | ---------------------------- | ----------- |
|
||||
| 通知类(`kind=notification`:通知发布页 / 联动页下发) | **暂存不弹**(两边都先收着) | 自动补弹 |
|
||||
| 主动通知:**紧急提醒**、**叫人**(`kind=call`) | **立刻弹** | 立刻弹 |
|
||||
|
||||
ClassIsland 侧的暂存由插件实现:它订阅课程服务,下课后把暂存的提醒补弹出来;未弹出前不回执,
|
||||
所以服务端会一直保留着待提醒,教室机器断网也不丢。
|
||||
|
||||
## 上报课表是"双向对齐"的
|
||||
|
||||
插件每次全量上报时,服务端只清理**「来源是 ClassIsland 且这次没再上报」**的课表行。于是:
|
||||
|
||||
- 老师在 ClassIsland 里删掉 / 挪动一节 → 小助手这边跟着同步;
|
||||
- 老师在小助手这边手排的课 → 一律不删。
|
||||
|
||||
## 镜像:把小助手的课表写回 ClassIsland
|
||||
|
||||
开启后,插件会新建一份名为 `班级小助手-<班级名>` 的档案课表,**不动老师原有的课表**。
|
||||
|
||||
镜像时会连节次时间一起带过去,并且**每两节之间补一段课间、最后一节之后不补**(放学)。
|
||||
这一步不做的话,ClassIsland 的课表会整体错位 —— 表现为"看着有内容、每节课都对不上"。
|
||||
|
||||
细节与实现见[ClassIsland 插件](../dev/classisland-plugin.md)。
|
||||
|
||||
下一步:[发布第一条内容](first-content.md)。
|
||||
@@ -0,0 +1,89 @@
|
||||
---
|
||||
title: 装学生端
|
||||
description: 在教室机器上安装班级小助手桌面客户端,用班级码登录,并第一次跑通实时通知。
|
||||
---
|
||||
|
||||
# 装学生端
|
||||
|
||||
桌面客户端装在**教室的那台机器**上(教室大屏、讲台电脑)。它是学生看课表作业的地方,
|
||||
也是「消息到达的第一现场」—— 灵动岛就长在这一端。
|
||||
|
||||
## 1. 下载与安装
|
||||
|
||||
从 [Releases](https://github.com/LoveChengke/classhelper/releases) 取:
|
||||
|
||||
| 产物 | 用途 |
|
||||
| ------------------------------------ | ------------------------------------------ |
|
||||
| `班级小助手-<版本>-x64-setup.exe` | 安装包(约 98 MB),装到本机并建快捷方式 |
|
||||
| `班级小助手-<版本>-x64-portable.exe` | 单文件便携版,双击即用,适合不改动机房机器 |
|
||||
|
||||
要自己打:
|
||||
|
||||
```bash
|
||||
pnpm dist:win # 安装包 + 便携版;只要免安装目录用 pnpm dist:dir
|
||||
```
|
||||
|
||||
> **装不上 / 双击没反应 / 一闪就没**(报 `0x80000003`)通常不是产物坏了,而是交付物被打了
|
||||
> Low 完整性标签。打包脚本收尾已自动修正;从 Release 下载的包不受影响。
|
||||
> 另外:关窗是隐藏到托盘,进程还在,再双击会因单实例锁秒退 —— 先从托盘退出。
|
||||
|
||||
## 2. 登录
|
||||
|
||||
打开客户端 → 填三项:
|
||||
|
||||
| 字段 | 填什么 |
|
||||
| ---------- | ------------------------------------------------------------- |
|
||||
| 服务器地址 | `http://<服务器IP>:4000`(局域网用内网 IP,别用 `localhost`) |
|
||||
| 班级码 | 管理员在「班级管理」里给这个班设的码,例如 `G203` |
|
||||
| 班级密码 | 建班级时设的密码 |
|
||||
|
||||
旁边的「测试连接」可以先确认网络通。**已登录过但服务器暂时不可达时**,登录页会给一个「离线进入」——
|
||||
进去后看到的是上次缓存的课表 / 作业 / 通知(顶部会标「离线缓存」),网络恢复后自动刷新。
|
||||
|
||||
> 客户端**没有改密码入口**,这是刻意的:教室机器上误改班级密码会把别的机器锁在门外。
|
||||
> 班级密码由管理员在 Web 端「班级管理 → 修改班级账号」维护。
|
||||
|
||||
## 3. 首次启动的六步向导
|
||||
|
||||
第一次启动会在登录页上自动弹一个向导:欢迎 → 连接服务器 → 登录班级 → 登录之后(主界面与离线缓存)→
|
||||
灵动岛提醒 → 完成。走完或跳过都会记为已完成,之后不再自动弹。
|
||||
|
||||
想重看:登录页的**「查看使用引导」**,或进去之后 **设置 → 通用 → 使用引导**。
|
||||
|
||||
## 4. 认一认主界面
|
||||
|
||||
左侧是四个一级项(**课表 / 作业 / 通知 / 成绩**)加上一个可展开的**设置**分组,
|
||||
顶部汉堡按钮把整栏收成 64px 的图标导轨(折叠状态会记住)。「通知」项上有未读红点。
|
||||
|
||||
| 页面 | 一句话 |
|
||||
| ---- | -------------------------------------------------------------- |
|
||||
| 课表 | 周视图 + 「今天」时间轴(大时钟 / 正在上什么 / 下一节) |
|
||||
| 作业 | 看板模式(按科目卡片、可全屏)/ 列表模式;教室机器还能录入作业 |
|
||||
| 通知 | 未读红点、优先级标签、点开自动标为已读 |
|
||||
| 成绩 | 班级账号看到的是全班总览(表格 + 柱状图 + 等级分布) |
|
||||
| 设置 | 通用 / 外观 / 灵动岛 / 提醒 / 账号 / 关于,六个子页 |
|
||||
|
||||
细节见[应用帮助](../app/index.md)。
|
||||
|
||||
## 5. 在教室机器上把它调成"能看"的样子
|
||||
|
||||
教室大屏的观看距离和角度跟办公桌不一样,装完建议顺手做三件事:
|
||||
|
||||
1. **开全屏作业看板** —— 作业页「全屏看板」,按屏幕尺寸自动排版,整个屏幕刚好放得下、不用滚动。
|
||||
2. **调灵动岛** —— 设置 → 灵动岛:高度、宽度、字号、主题色、停靠位置、视觉风格。
|
||||
讲台机器上通常把字号调大一点、位置放到顶部居中。
|
||||
触摸屏(希沃白板等)走的是另一套命中逻辑,客户端会自动识别,不用手动开。
|
||||
3. **选提醒弹在哪端** —— 设置 → 提醒:`ClassHelper 与 ClassIsland 都弹` / 只在客户端 / 只在 ClassIsland。
|
||||
这个选择会同步到班级记录,服务端据此决定要不要推 ClassIsland。
|
||||
|
||||
## 6. 确认实时链路是通的
|
||||
|
||||
在 Web 管理端给这个班发一条普通通知,教室机器上应该几秒内出现灵动岛胶囊。如果没有:
|
||||
|
||||
- 客户端顶栏的实时通道状态是不是"已连接"?
|
||||
- 现在是上课时段吗?上课时段的普通通知**只进队列、下课才弹**,这是设计行为,不是故障。
|
||||
- 服务器与教室机器之间能互相 ping 通吗?防火墙放行 4000 了吗?
|
||||
|
||||
排查清单见[常见问题](../faq.md)。
|
||||
|
||||
下一步(可选):[接入 ClassIsland](classisland.md)。
|
||||
@@ -0,0 +1,78 @@
|
||||
---
|
||||
title: 发布第一条内容
|
||||
description: 发通知、布置作业、叫人、录成绩——把班级小助手真正用起来的第一轮操作。
|
||||
---
|
||||
|
||||
# 发布第一条内容
|
||||
|
||||
前面几步做完,系统就完整了。这一页走一遍四件最常用的事,每件都点出**它会不会弹、弹在哪个端**。
|
||||
|
||||
## 发一条通知
|
||||
|
||||
**通知发布** → 选班级 → 填标题和内容 → 选优先级 → 发布。
|
||||
|
||||
| 优先级 | 学生端表现 |
|
||||
| ------ | -------------------------------------------------------------------------- |
|
||||
| 普通 | 课间弹胶囊,点击展开;**上课时段只进队列**,下课自动补弹 |
|
||||
| 重要 | 同上,卡片上带优先级标签 |
|
||||
| 紧急 | **无论是否上课都立即展开**(卡片内部红色呼吸光晕 + 紧急角标),45 秒后收起 |
|
||||
|
||||
**上课时段发紧急通知会被拦一次。** 服务端返回 `409 URGENT_DURING_CLASS`,前端弹一个全屏二次确认,
|
||||
上面写着"现在为上课时间段……"、正在上的那节课,还有待发布的标题;确认按钮带 **3 秒倒计时**,
|
||||
倒计时结束前点不动。确认之后才真的发出去。
|
||||
|
||||
这个拦截是**服务端做的**,绕过界面直接调接口一样会被拦 —— 它是产品行为,不是前端提醒。
|
||||
|
||||
## 布置一份作业
|
||||
|
||||
**作业发布** → 选班级 / 科目 → 填标题与要求 → 选**所属日期** → 发布。
|
||||
|
||||
> 作业按**所属日期**归类,不是按录入时间。晚上 8 点留的作业算今天。
|
||||
> 老师可以给今天、明天甚至上周补录一份作业,客户端按日期查得到。
|
||||
|
||||
附件支持站内相对路径或 `http(s)://` 链接(其他 scheme 服务端会拒,避免被当成脚本执行)。
|
||||
|
||||
学生端那边默认是**看板模式**:按科目分卡片、每条作业完整显示要求、整个看板缩放到刚好铺满屏幕;
|
||||
老师也可以在教室机器上直接**录入作业**、勾选**未交名单**(教室机器用的是班级账号)。
|
||||
|
||||
## 叫一位同学
|
||||
|
||||
**通知发布 → 叫人**(或管理员在**学生管理 → 叫人**)→ 选学生 → 点一个快捷短语或自己写一句 → 发送。
|
||||
|
||||
| 级别 | 学生端 |
|
||||
| -------- | ------------------------------------------------------------------ |
|
||||
| 普通叫人 | 课间显示「叫人」胶囊,点击展开;**上课时段只进队列**,下课自动弹出 |
|
||||
| 紧急叫人 | **无视上课时段立即展开**,上课时被收起后仍保留胶囊、可再次点开 |
|
||||
|
||||
文案是「请 XXX 同学找 XXX 老师」,卡片上是「收到」按钮(复用通知的已读机制)。
|
||||
|
||||
> 学生管理页是管理员专属,但班主任与科任老师同样需要叫人,所以给老师留的入口在「通知发布 → 叫人」。
|
||||
|
||||
## 录一次成绩
|
||||
|
||||
**成绩录入** → 选班级与考试名称 → 单条录入 / 批量录入 / 导入表格。
|
||||
|
||||
- **科目**下拉同样是全校统一目录,选一个该班还没有的科目会自动建课。
|
||||
- 导入表格支持 `.xlsx / .xls / .csv / .tsv`,列名按同义词自动映射(「学号→学生用户名」「得分→分数」),
|
||||
也可以手动改。**文件上限 8MB**,超了会返回明确的 413 而不是一句英文的内部错误。
|
||||
- 导入结果会给逐行的错误与警告,`errors[].row` 是 **Excel 视角的行号**(含表头),改完可以再导。
|
||||
|
||||
学生端看到的是**全班总览**:表格(分数 / 得分率 / 等级)+ 柱状图 + 等级分布 + 最近更新。
|
||||
|
||||
## 在教室大屏上播一条提醒(需要 ClassIsland)
|
||||
|
||||
**ClassIsland 联动 → 下发提醒** → 选班级、填标题内容、设置显示时长与语音朗读 → 下发。
|
||||
|
||||
它会**落库**再推给教室。教室机器断网也不丢:插件重连后会拉取还没确认的那条,
|
||||
立刻弹出来,弹完回执,不会重复弹。
|
||||
|
||||
如果教室客户端把「通知显示位置」设成了"只在 ClassHelper 客户端显示",这一步会回一句
|
||||
「该班教室已设置为只在 ClassHelper 客户端显示」—— 那是设计行为,不是报错。
|
||||
|
||||
---
|
||||
|
||||
到这里你已经把整套系统跑通了。接下来:
|
||||
|
||||
- 每一项功能的完整行为 → [应用帮助](../app/index.md)
|
||||
- 服务器怎么维护 → [管理运维](../management/index.md)
|
||||
- 遇到问题 → [常见问题](../faq.md)
|
||||
@@ -0,0 +1,40 @@
|
||||
---
|
||||
title: 快速上手
|
||||
description: 从零把班级小助手跑起来:装服务端、认管理端、建班级排课、装学生端、接 ClassIsland、发第一条内容。
|
||||
---
|
||||
|
||||
# 快速上手
|
||||
|
||||
班级小助手不是一个单机软件,它由四部分组成,**必须先有服务端,其他三端才有内容可看**:
|
||||
|
||||
| 组成部分 | 装在哪 | 谁用 | 必须先装? |
|
||||
| ------------------------ | --------------------------------------- | -------------------------- | ---------------- |
|
||||
| **服务端** | 一台能一直开着的机器(服务器/办公电脑) | —(它同时托管 Web 管理端) | ✅ 是 |
|
||||
| **Web 管理端** | 不用装 —— 浏览器打开服务端地址即可 | 老师、班主任、管理员 | 跟着服务端一起有 |
|
||||
| **桌面客户端** | 教室的电脑 / 教室大屏 | 学生看课表作业、老师录作业 | 服务端就绪之后 |
|
||||
| **ClassIsland 联动插件** | 教室那台装了 ClassIsland 的机器 | 教室大屏播报 | 可选 |
|
||||
|
||||
按顺序走下面这几页就行,全程大约半小时(不含下载时间):
|
||||
|
||||
1. [系统要求](requirements.md) —— 先确认机器和网络够用
|
||||
2. [安装服务端](server.md) —— Windows 安装包 / Linux 一键脚本 / Docker / 源码跑
|
||||
3. [认识 Web 管理端](web-admin.md) —— 登录进去,认一认界面
|
||||
4. [建班级、排课表](setup-class.md) —— 这是后面所有功能的前提
|
||||
5. [装学生端](client.md) —— 教室机器用班级码登录
|
||||
6. [接入 ClassIsland](classisland.md) —— 让教室大屏也会弹提醒(可选)
|
||||
7. [发布第一条内容](first-content.md) —— 通知 / 作业 / 叫人 / 成绩
|
||||
|
||||
## 只想先看看它长什么样?
|
||||
|
||||
不用装任何东西也能看出来它在干什么:
|
||||
|
||||
- **看界面**:本页文档里各处嵌的都是实机截图,比如[灵动岛](../app/island.md)、[课表](../app/schedules.md)。
|
||||
- **本地跑一套演示数据**:装好 Node 20.19+ 与 pnpm 之后,
|
||||
`pnpm install && pnpm build:shared && pnpm db:seed && pnpm dev` 会在本机拉起一套带演示班级的后端与
|
||||
Web 管理端(详见[安装服务端](server.md#从源码跑开发模式))。
|
||||
|
||||
## 装完之后呢
|
||||
|
||||
- 日常怎么用 → [应用帮助](../app/index.md)
|
||||
- 服务器怎么维护(备份、换库、升级) → [管理运维](../management/index.md)
|
||||
- 出问题了 → [常见问题](../faq.md)
|
||||
@@ -0,0 +1,76 @@
|
||||
---
|
||||
title: 系统要求
|
||||
description: 班级小助手服务端、Web 管理端、桌面客户端的运行环境与网络要求。
|
||||
---
|
||||
|
||||
# 系统要求
|
||||
|
||||
## 服务端
|
||||
|
||||
服务端的安装包**自带 Node 运行时**,目标机器不需要另外装 Node.js,也不需要数据库软件
|
||||
(默认用内嵌的 SQLite)。
|
||||
|
||||
| 项目 | 要求 |
|
||||
| -------- | --------------------------------------------------------------------------- |
|
||||
| 操作系统 | Windows 10 / 11 / Server 2016+(x64);Linux(glibc 2.28+,见下);Docker |
|
||||
| 内存 | 512 MB 起步,2 GB 以上更稳(Node + SQLite 常驻约 120–200 MB) |
|
||||
| 磁盘 | 程序约 340 MB(免安装目录)/ 安装后约 400 MB;数据按班级量增长,通常几十 MB |
|
||||
| CPU | 任意 x64;不需要独显 |
|
||||
|
||||
**Linux 的 glibc 要求**:内置的 Node 官方 linux-x64 构建要求 glibc ≥ 2.28。
|
||||
CentOS 7 是 2.17,一键安装器会检测并自动换成 `-glibc-217` 变体(尽力而为,未做长期验证)。
|
||||
判据:
|
||||
|
||||
```bash
|
||||
ldd --version | head -1
|
||||
```
|
||||
|
||||
**外网**:服务端只在「检查更新」时访问 GitHub,且失败是设计内的结果(返回"查不到",不报错)。
|
||||
内网机器可以完全不连通外网。
|
||||
|
||||
## Web 管理端
|
||||
|
||||
不需要安装,用浏览器打开服务端地址即可。
|
||||
|
||||
| 项目 | 要求 |
|
||||
| -------- | --------------------------------------------------------------------------- |
|
||||
| 浏览器 | Chrome / Edge 100+、Firefox 100+、Safari 15+(要支持 CSS 容器查询) |
|
||||
| 屏幕 | 桌面 1280×720 以上;手机(≤768px)有一套独立的抽屉式布局,同样可用 |
|
||||
| 安装 PWA | 手机 / 桌面 Chrome 里「添加到主屏幕」可当 App 用(需要 HTTPS 或 localhost) |
|
||||
|
||||
## 桌面客户端(学生端 / 教室机器)
|
||||
|
||||
| 项目 | 要求 |
|
||||
| -------- | ---------------------------------------------------------------------------- |
|
||||
| 操作系统 | Windows 10 / 11(x64) |
|
||||
| 内存 | 4 GB 以上(Electron 常驻约 250–400 MB) |
|
||||
| 磁盘 | 安装后约 330 MB |
|
||||
| 显卡 | 有 D3D11 即可;希沃一体机、老显卡、虚拟机都做过兼容(没有裁剪 GPU 回退组件) |
|
||||
| 触摸屏 | 支持,会自动进入[触摸模式](../app/island.md)(希沃白板等) |
|
||||
|
||||
> 客户端**只有 Windows 版**。Linux / macOS 上目前只能用 Web 管理端。
|
||||
|
||||
## 网络
|
||||
|
||||
三端的通信都指向服务端的 **HTTP 端口(默认 4000)**,其中:
|
||||
|
||||
- REST 接口:`/api/*`
|
||||
- 实时推送(Socket.IO):`/socket.io/`
|
||||
- Web 管理端静态资源:`/`(由服务端托管)
|
||||
|
||||
| 场景 | 要做什么 |
|
||||
| ------------------------- | --------------------------------------------------------------------------------------- |
|
||||
| 只在服务器本机用 | 什么都不用做,`http://127.0.0.1:4000` |
|
||||
| 教室机器 / 老师电脑也要用 | 客户端与管理端填服务器的**局域网 IP**(如 `http://192.168.1.10:4000`),防火墙放行 4000 |
|
||||
| 公网访问 | 前面加 Nginx / Caddy 反代并启用 HTTPS,见[生产部署指南](../management/production.md) |
|
||||
|
||||
> **别用代理**。本机自测时用 `curl.exe --noproxy '*'`,PowerShell 用 `-NoProxy`;
|
||||
> 教室机器上如果开了系统代理,填服务端地址后可能拿到代理返回的 404。插件里对本地 / 内网地址做了强制直连,
|
||||
> 但浏览器与客户端本身不会绕过。
|
||||
|
||||
## 卸载 / 重置
|
||||
|
||||
- 服务端:开始菜单 → 卸载。卸载会保留数据库(`data` 目录改名为 `data.backup`)。
|
||||
- 客户端:从托盘退出后卸载;重置配置删 `%APPDATA%\class-helper`(或客户端「关于」页显示的数据目录)。
|
||||
|
||||
下一步:[安装服务端](server.md)。
|
||||
@@ -0,0 +1,139 @@
|
||||
---
|
||||
title: 安装服务端
|
||||
description: 用 Windows 安装包、Linux 一键脚本、Docker 或源码把班级小助手服务端跑起来。
|
||||
---
|
||||
|
||||
# 安装服务端
|
||||
|
||||
服务端是整个系统的中心:它存数据、发实时推送,**并且顺带托管 Web 管理端**(所以老师那一端不用单独装东西)。
|
||||
|
||||
四种装法按场景选,任选一种即可:
|
||||
|
||||
| 方式 | 适合 | 一句话 |
|
||||
| --------------------------------- | -------------------------------------- | ------------------------------- |
|
||||
| [Windows 安装包](#windows-安装包) | 学校机房、教师办公电脑、单机即完整系统 | 双击 exe,装完自动启动 |
|
||||
| [Linux 一键安装](#linux-一键安装) | 学校已有 Linux 服务器 | 一条命令,带 systemd 与运维命令 |
|
||||
| [Docker](#docker) | 云服务器、想跟别的服务共用一台机器 | `docker compose up -d` |
|
||||
| [源码跑](#从源码跑开发模式) | 想改代码、想先看看它长什么样 | `pnpm dev` |
|
||||
|
||||
## Windows 安装包
|
||||
|
||||
### 生成安装包
|
||||
|
||||
安装包不入库(体积大),从 [Releases](https://github.com/LoveChengke/classhelper/releases) 直接下载
|
||||
`班级小助手服务端-<版本>-x64-setup.exe` 即可。要自己打:
|
||||
|
||||
```bash
|
||||
pnpm dist:server # 首次会执行一次 npm install(约 2 分钟)
|
||||
pnpm dist:server -- --reuse-deps # 迭代打包:复用已装依赖,跳过 npm install
|
||||
```
|
||||
|
||||
产物:
|
||||
|
||||
| 路径 | 说明 |
|
||||
| --------------------------------------------------------------------- | ------------------------------------------- |
|
||||
| `releases/server/<版本>/安装包/班级小助手服务端-<版本>-x64-setup.exe` | 安装程序(约 62 MB,NSIS) |
|
||||
| `releases/server/<版本>/免安装/` | 免安装目录,拷到任意 Windows x64 机器即可跑 |
|
||||
|
||||
包内自带 Node 运行时、后端产物、Web 管理端产物、生产依赖、迁移 SQL、随机 `JWT_SECRET` 的 `.env`
|
||||
与启停脚本。目标机器**不需要预先安装 Node.js**。
|
||||
|
||||
### 安装与启动
|
||||
|
||||
双击安装程序即可,**不需要管理员权限**(当前用户级安装)。
|
||||
|
||||
- 安装目录:`%LOCALAPPDATA%\Programs\ClassHelperServer`
|
||||
- 静默安装:`"班级小助手服务端-<版本>-x64-setup.exe" /S`
|
||||
- 开始菜单:启动服务 / 停止服务 / 重启服务 / 打开管理端 / 使用说明 / 卸载
|
||||
- 自动加入当前用户开机自启
|
||||
|
||||
装完服务会自动启动并完成首次初始化:数据库为空则执行随包迁移建表 → 创建管理员账号 →
|
||||
`http://127.0.0.1:4000/` 就是 Web 管理端。
|
||||
|
||||
常用脚本(都在安装目录里):
|
||||
|
||||
```cmd
|
||||
start.cmd :: 启动并等待就绪(已在运行则直接返回)
|
||||
stop.cmd :: 按 PID 精确停止
|
||||
restart.cmd :: 重启
|
||||
status.cmd :: 查看状态与 HTTP 探针结果
|
||||
```
|
||||
|
||||
机房主机这种无人值守的机器,建议以**管理员身份**跑一次 `install-service.cmd`,
|
||||
把服务注册成开机启动的计划任务(比注册表 Run 更稳):
|
||||
|
||||
```cmd
|
||||
install-service.cmd :: schtasks /Create /SC ONSTART /RL HIGHEST
|
||||
uninstall-service.cmd :: 删除计划任务
|
||||
```
|
||||
|
||||
安装目录结构与配置见[生产部署指南](../management/production.md);
|
||||
安装程序里的默认管理员口令**第一次登录后必须改掉**。
|
||||
|
||||
## Linux 一键安装
|
||||
|
||||
从 Release 下载 `classhelper-server-linux-x64-<版本>.tar.gz`(以及旁边的 `.sha256`),连同
|
||||
`install.sh` 一起拷到服务器:
|
||||
|
||||
```bash
|
||||
scp releases/server/<版本>/linux-x64/classhelper-server-linux-x64-*.tar.gz \
|
||||
install.sh verify-linux.sh root@<主机>:/tmp/
|
||||
|
||||
ssh root@<主机> 'bash /tmp/install.sh --check' # 先体检,不改任何东西
|
||||
ssh root@<主机> "printf '%s\n' '<管理员密码>' | bash /tmp/install.sh --yes --admin-password-stdin \
|
||||
--package /tmp/classhelper-server-linux-x64-*.tar.gz"
|
||||
```
|
||||
|
||||
安装器会装好内置 Node、把程序放到 `/opt/classhelper`、写好 systemd 单元、
|
||||
把 `classhelper` 运维命令软链到 `/usr/local/bin/`。之后:
|
||||
|
||||
```bash
|
||||
classhelper status # 服务状态
|
||||
classhelper doctor # 一整套自检(配置软链、权限、依赖完整性…)
|
||||
classhelper backup # 立即备份
|
||||
classhelper upgrade # 升级到最新 Release(自动校验 sha256)
|
||||
```
|
||||
|
||||
完整的目录布局、配置项、升级回滚、反向代理与故障排查见 [Linux 部署与运维](../management/linux-deploy.md)。
|
||||
|
||||
## Docker
|
||||
|
||||
```bash
|
||||
cd deploy
|
||||
cp .env.example .env # 至少改 JWT_SECRET
|
||||
docker compose up -d # 默认 SQLite 单容器,数据卷挂在本机
|
||||
```
|
||||
|
||||
要 MySQL 就用 `docker-compose.yml`(带一个 MySQL 服务),只想要单容器 SQLite 用
|
||||
`docker-compose.sqlite.yml`。细节见[生产部署指南](../management/production.md)。
|
||||
|
||||
## 从源码跑(开发模式)
|
||||
|
||||
想改代码或只想先看看,用这条路。需要 **Node ≥ 20.19** 与 **pnpm 11**。
|
||||
|
||||
```bash
|
||||
pnpm install
|
||||
cp packages/server/.env.example packages/server/.env # 至少改 JWT_SECRET
|
||||
pnpm db:generate
|
||||
pnpm --filter @classhelper/server db:deploy # 应用数据库迁移
|
||||
pnpm build:shared # 必须先构建 shared,否则后面会 ERR_MODULE_NOT_FOUND
|
||||
pnpm db:seed # 写演示数据(会清空业务表)
|
||||
pnpm dev # 后端 4000 + Web 端 5173 一起起
|
||||
```
|
||||
|
||||
演示账号见 [README 的「默认账号与种子数据」](https://github.com/LoveChengke/classhelper#readme);
|
||||
**演示口令只用于本地开发,别带到真实环境**。
|
||||
|
||||
| 端口 | 用途 |
|
||||
| ---- | -------------------------------------------------------- |
|
||||
| 4000 | 后端 REST + Socket.IO + (构建后)Web 管理端静态托管 |
|
||||
| 5173 | Web 管理端开发服务器(`/api`、`/socket.io` 代理到 4000) |
|
||||
| 5174 | 桌面客户端渲染进程开发服务器 |
|
||||
|
||||
> 改动 `packages/shared` 之后必须 `pnpm build:shared`(或让它跑着 watch)——
|
||||
> 三端都从它的 `dist` 导入。
|
||||
|
||||
## 装完之后
|
||||
|
||||
打开 `http://<服务器地址>:4000/`,用管理员账号登录。下一页:
|
||||
[认识 Web 管理端](web-admin.md)。
|
||||
@@ -0,0 +1,71 @@
|
||||
---
|
||||
title: 建班级、排课表
|
||||
description: 建第一个班级、配班级账号、加学生与老师、排课表——后面所有功能的前提。
|
||||
---
|
||||
|
||||
# 建班级、排课表
|
||||
|
||||
后面所有功能(发通知、布置作业、录成绩、接 ClassIsland)都挂在**班级**上,所以先把班级建出来。
|
||||
|
||||
## 1. 建班级(仅管理员)
|
||||
|
||||
Web 管理端 → **班级管理** → 「新建班级」:
|
||||
|
||||
| 字段 | 说明 |
|
||||
| -------- | ----------------------------------------------------------------------- |
|
||||
| 班级名称 | 例如「高二(3)班」 |
|
||||
| 年级 | 用于分组与统计 |
|
||||
| 班主任 | 从教师账号里选,默认是自己;之后随时可在班级详情顶部「更换班主任」改 |
|
||||
| 学期周数 | 默认 20,**上限 30**。课表的周次选择与周次范围都以它为准 |
|
||||
| 班级码 | 保存时自动生成(字母数字 4–16 位,存大写),可以改成好记的,例如 `G203` |
|
||||
| 班级密码 | 新建班级时的初始密码就是它 —— 学生在教室机器上要用这个登录 |
|
||||
|
||||
> **班级码 + 班级密码 = 学生端的登录凭据。** 学生端没有个人账号,一台教室机器用班级账号登录后,
|
||||
> 那台机器上的「已读 / 完成」是**代全班**操作的。
|
||||
>
|
||||
> 学期周数只有管理员能改:它决定"现在是第几教学周",乱改会让课表的周次过滤和上课时段判定错位。
|
||||
|
||||
## 2. 加学生(仅管理员)
|
||||
|
||||
**学生管理** → 「新建」或「导入名单」:
|
||||
|
||||
- **单个新建**:填姓名即可,登录名会自动生成。
|
||||
- **导入名单**:下载模板(列只有 `用户名 / 姓名`,学生没有账号属性,**没有密码列**),填好上传。
|
||||
用户名要匹配 `^[A-Za-z0-9_.-]{3,32}$`;重复用户名在 `append` 模式下跳过、`upsert` 模式下更新姓名。
|
||||
用户名已经属于某个教师 / 管理员账号时,这一行会进错误列表,不会覆盖别人的账号。
|
||||
|
||||
学生的用途是:**成绩、未交名单、叫人、已读记录都按名单记录**。所以名单不全,这几项就不准。
|
||||
|
||||
## 3. 加科任老师
|
||||
|
||||
教师的**录入**只有管理员能做(**教师管理**页,支持单个录入与导入名单)。班级层面的**分配**在班级详情里:
|
||||
把老师加进「协作教师」,他就能看到这个班、给这个班发作业 / 通知 / 叫人。
|
||||
|
||||
角色与可见范围见[班级、学生与教师](../app/classes.md)与[角色与权限](../dev/permissions.md)。
|
||||
|
||||
## 4. 排课表
|
||||
|
||||
**课表管理** → 选中班级 → 「新增课表」:
|
||||
|
||||
- **科目**下拉直接列出全校统一的 18 科目录(语文 / 数学 / 英语 / 政治 / 历史 / 物理 / 化学 / 地理 /
|
||||
生物 / 信息技术 / 体育 / 美术 / 音乐 / 班会 / 早读 / 晚读 / 通用技术 / 听力)。
|
||||
选中一个该班还没有的科目时,前端会**自动为该班建同名课程**,不用先去把科目的建一遍。
|
||||
- 填星期、开始 / 结束时间、周次范围(第几周到第几周)、单双周(每周 / 单周 / 双周)。
|
||||
- 一节课**必须同时有开始时间和结束时间** —— 「上课时段」的判定就是拿这两个时间比对的。
|
||||
|
||||
排完在**课表管理**里能看到周视图(7 列),客户端那边则多一个「今天」时间轴视图。
|
||||
|
||||
### 从 ClassIsland 导入更省事
|
||||
|
||||
如果教室里已经在用 ClassIsland,直接导入它的档案 JSON 就行:课表、节次时间、单双周都会一起进来,
|
||||
不用排两遍。见[表格与课表导入](../app/imports.md)。
|
||||
|
||||
## 5. 确认「上课时段」判定是对的
|
||||
|
||||
班级小助手有一整套「上课时段策略」:普通通知在上课时段只进队列、下课自动补弹,紧急通知与叫人则立刻弹。
|
||||
这套判定完全基于课表,所以**课表排错,提醒就会在该弹的时候不弹**。
|
||||
|
||||
排完课之后建议立刻验一下:在**通知发布**页选这个班,随便发一条普通通知,
|
||||
看客户端是不是在课间弹出来、上课时是不是安静地收着。规则详见[通知与提醒](../app/notifications.md)。
|
||||
|
||||
下一步:[装学生端](client.md)。
|
||||
@@ -0,0 +1,16 @@
|
||||
- name: 快速上手
|
||||
href: index.md
|
||||
- name: 系统要求
|
||||
href: requirements.md
|
||||
- name: 安装服务端
|
||||
href: server.md
|
||||
- name: 认识 Web 管理端
|
||||
href: web-admin.md
|
||||
- name: 建班级、排课表
|
||||
href: setup-class.md
|
||||
- name: 装学生端
|
||||
href: client.md
|
||||
- name: 接入 ClassIsland
|
||||
href: classisland.md
|
||||
- name: 发布第一条内容
|
||||
href: first-content.md
|
||||
@@ -0,0 +1,58 @@
|
||||
---
|
||||
title: 认识 Web 管理端
|
||||
description: 登录班级小助手 Web 管理端,认一认 12 个页面、新手引导与手机端布局。
|
||||
---
|
||||
|
||||
# 认识 Web 管理端
|
||||
|
||||
Web 管理端不用装:服务端起来之后,浏览器打开 `http://<服务器地址>:4000/` 就是它。
|
||||
|
||||
## 登录
|
||||
|
||||
用**教师 / 管理员账号**登录(用户名 + 密码)。学生没有个人账号,学生那一端走
|
||||
[班级码 + 班级密码](client.md),见[班级、学生与教师](../app/classes.md)。
|
||||
|
||||
- 新装的服务端只有安装时创建的那一个管理员账号。**第一次登录后请立刻在顶栏头像菜单 → 修改密码里改掉它。**
|
||||
- 登录页**不含任何演示内容**(没有"点击填充示例账号"之类的按钮),也不会提示种子口令。
|
||||
- 连不上服务器时页面会直接失败,不会静默重试 —— 先确认服务端在跑、端口对、没走代理。
|
||||
|
||||
## 界面
|
||||
|
||||
布局沿用 1Panel 那一套:左边固定深色侧边栏,右边浅灰底 + 白色圆角卡片。
|
||||
|
||||
| 页面 | 干什么 | 谁能进 |
|
||||
| ---------------- | ---------------------------------------------- | ---------------------- |
|
||||
| 仪表盘 | 全校 / 本班的汇总数字与最近动态 | 所有登录用户 |
|
||||
| 课表管理 | 排课、导入 ClassIsland 课表、节次时间 | 管理员、本班班主任 |
|
||||
| 作业发布 | 发作业、按天查看、看未交名单 | 教师、管理员、班级账号 |
|
||||
| 通知发布 | 发通知、发叫人 | 教师、管理员 |
|
||||
| 成绩录入 | 单条 / 批量录成绩、导入表格、看统计 | 管理员、本班班主任 |
|
||||
| ClassIsland 联动 | 接入教室设备、下发提醒、看实时状态、开镜像 | 管理员、教师 |
|
||||
| 班级管理 | 建班级、换班主任、改班级账号 | **仅管理员** |
|
||||
| 学生管理 | 学生名单增删、导入 | **仅管理员** |
|
||||
| 教师管理 | 教师账号增删改、导入名单、重置密码 | **仅管理员** |
|
||||
| 数据库管理 | 备份 / 恢复、导出导入、一键切换 SQLite ⇄ MySQL | **仅管理员** |
|
||||
| 检查更新 | 顶栏头像菜单里,查 GitHub 上有没有新版本 | 所有登录用户 |
|
||||
|
||||
> **前端隐藏 ≠ 权限**。上面这张表只是"入口藏不藏",每一条写入请求服务端都会再判一次
|
||||
> (见[角色与权限](../dev/permissions.md))。直接输网址绕过菜单,一样会被挡回仪表盘。
|
||||
|
||||
## 第一次登录的引导
|
||||
|
||||
首次登录进入主布局后会自动弹一次聚焦式引导,依次指出:侧边菜单 → 实时通道状态 → 账号菜单 → 完成。
|
||||
走完或跳过(右上角 × 或 Esc)都记作"已看过",之后不再自动弹。
|
||||
|
||||
想重看:**右上角头像菜单 →「使用引导」**。
|
||||
|
||||
## 手机 / 平板
|
||||
|
||||
| 屏幕宽度 | 布局 |
|
||||
| --------- | ------------------------------------------------------ |
|
||||
| > 992px | 常驻 210px 深色侧边栏 + 顶栏显示连接状态与实时事件计数 |
|
||||
| 769–992px | 保留侧边栏,内容区内边距压缩 |
|
||||
| ≤ 768px | 侧边栏收进抽屉,顶栏汉堡按钮唤出;表格在卡片内横向滚动 |
|
||||
|
||||
手机上(与电脑同一局域网)用 `http://<主机IP>:4000` 打开,可以「添加到主屏幕」当 App 用(PWA)。
|
||||
做成 HTTPS 之后 PWA 才能完全离线化,见[生产部署指南](../management/production.md)。
|
||||
|
||||
下一步:[建班级、排课表](setup-class.md)。
|
||||
Reference in new issue
Block a user