English Documentation | 简体中文文档
基于 Cloudflare Pages + Pages Functions + 私有 R2 强一致性对象存储 构建的轻量级、企业级安全、全端自适应无服务器班级积分与学生评价管理系统。
- 4 核心文件,零外部运行时依赖:全站由恰好 4 个纯原生文件(
_worker.js、login.html、admin.html、teacher.html)组成。原生 ES2022 JavaScript + 现代语义化 HTML5 + CSS3 变量与响应式网格,无 Webpack/Vite 等繁复构建产物,无外部 CDN 脚本,加载毫秒级响应。 - 强一致性 R2 存储:完全基于 Cloudflare 私有 R2 Standard 对象存储,放弃最终一致性的 KV,依托对象 ETag 乐观锁保障多名教师高并发记分零覆盖。
- 极简极低运维成本:Cloudflare 后台仅需配置唯一加密密钥
ADMIN,存储绑定名固定为R2,零数据库实例,免费额度即可支持普通学校全年稳定运行。
- 超级管理员(admin):负责教师账号维护(建号、重置密码、归档/恢复、彻底删除)、班级目录维护、教师-班级多对多绑定配置、期次全局维护、全局密码策略设置与系统公告发布。
- 任课教师(Teacher):支持自主修改登录密码;管理所辖班级的学生、评分项目、小组与期次(增删改、排序、软归档与彻底删除、全班毕业清空),仅对授权绑定的班级拥有操作权限。
- 严格路径白名单与角色互斥:对外严格仅开放
/login、/admin、/teacher及/api/*,所有非法路径探测、隐藏文件和根路径强制 302 重定向到/login.html;教师禁入管理台,管理员禁入教师台,未登录统一拦截。
- 两周周期循环记分与自动结转:针对学校每两周召开班会点评积分的教学习惯,教师在班会结束后点击【+ 开启新期】,系统自动将上一期积分归档并锁定,新一期自动继承全部学生名单与评分项目,所有积分清空归零开始新一轮记分。
- 期次双向锁定与主动防误触(v1.7.1 全新):
- 顶部工具栏期次锁常驻联动:未锁定时展示
🔓 可编辑 (点击锁定),已锁定时展示🔒 已锁定 (点击解锁),点击即可双向切换; - 纠错补录后随时重新加锁:历史往期不仅支持一键解锁修正历史分数,纠错保存完成后教师可随时主动重新加锁,重新封存为只读防误触状态;
- 当前期次主动封存:某个周期点评结束但暂未开启新一期前,教师可随时主动锁定当前期次,防止日常误点修改;
- 未保存草稿智能防线:本地存在未保存草稿时主动拦截加锁,提示先保存再锁定,彻底杜绝数据意外丢失;
- 期次设置管理弹窗(⚙)快捷切换:期次设置弹窗内提供配套的锁定/解锁按钮,状态智能跟随联动;点击锁定单元格或按 Enter 键自动弹出解锁确认。
- 顶部工具栏期次锁常驻联动:未锁定时展示
- 期末总评双模式汇总视图:在期次下拉框中选择【📊 期末总评分汇总】,教师可自由切换两种点评对照模式,均支持单列排序与多级高级排序:
- 模式 A(按期次对照):表头展示各期次得分小计与全期累计总分(
姓名 | 第1期 | 第2期 | ... | 全期总分); - 模式 B(按评分项目累计):表头展示各自定义评分项目全期累加总和(
姓名 | 语文全期 | 数学全期 | ... | 全期总分)。
- 模式 A(按期次对照):表头展示各期次得分小计与全期累计总分(
- 平滑无缝向后兼容:旧版本班级数据自动平滑迁移为“第 1 期”,现有接口与数据结构无损升级,确保历史积分记录零丢失。
- 全实体彻底物理删除(永久清理):
- 支持学生、评分项目、小组、期次、教师账号及班级目录的彻底物理永久删除,满足学生毕业、转学、教师离职、撤班或清除临时测试数据的实际需求;
- 免归档直接物理删除:在使用中列表里,【删除】按钮直接摆放在【归档】按钮旁边,支持一键直接彻底移除;在已归档列表中同样提供【彻底删除】;
- 单次 R2 对象原子级联清理:删除学生/项目/小组时,单次请求内原子级联清理该实体在当前及所有历史期次中的全部打分单元格,解绑组员关联,杜绝脏数据孤岛与垃圾残留;物理删除班级时原子调用
R2.delete,彻底释放存储空间。
- 全班学生毕业清空(Graduation Purge)安全锁:
- 针对初三/高三学生毕业离校整班换届场景,在班级设置中提供【全班学生毕业清空】功能;
- 原子清空该班级全部学生名单及全期次个人历史积分,同时完整保留班级评分项目、期次与小组结构,供新一届学生无缝接续使用。
- 三重安全防误触防线:
- 严禁采用繁琐易错的手工输入全班姓名名单确认;
- 第一重防线:10 秒强制冷静等待,倒计时归零前输入框与提交按钮强制置灰禁用;
- 第二重防线:动态随机算式验证,前端生成趣味加减乘混合算式(如
23 + 19 = ?或7 × 8 = ?,支持换题),算对后方可点亮确认; - 第三重防线:浏览器原生终极确认,二次阻断误触可能。
- 教师端与管理员后台 100% 权限对齐:
- 管理员后台班级管理全面补齐【期次】Tab,支持新增期次、编辑期次、锁定/解锁切换、归档与直接删除;
- 教师可操作的所有直接删除与毕业清空,管理员在管理后台均可同等操作。
- 全局密码强度策略:管理员可在后台随时开启/关闭密码强度要求,支持按需组合:
- 最小长度(6–32 位自定义);
- 强制包含大写字母(A-Z);
- 强制包含小写字母(a-z);
- 强制包含阿拉伯数字(0-9);
- 强制包含特殊符号(标点符号)。
- 双轨免限机制:管理员创建教师或重置密码时直接遵循底层安全基线(6–128 位),不受自定义复杂策略限制,极大方便管理员批量分发简易初始口令;教师端自主改密时严格受全局策略限制。
- 初始密码状态精准跟踪:教师账号精准记录
initialPasswordChanged;新创建教师与管理员重置密码后自动标为【初始密码】,在管理员教师列表中以高对比度橙色徽章醒目提示。 - 教师登录改密弹窗与实时正反馈:未改密教师登录后自动弹出改密模态框;支持管理员配置【提醒模式(可跳过)】与【强制模式(禁关闭/Esc)】;新密码输入框下方动态渲染规则勾选清单(✓/○),提供直观正反馈。
- 一键全员改密应急操作:后台提供【
⚠️ 一键要求所有教师改密】操作(带二次防误触确认),一键批量置位所有有效教师,从容应对全校级安全合规升级。
- 纯前端零后端交互:完全在客户端内存与表格渲染计算流程中执行,零网络请求、零存储负担。
- 多级自定义优先级:教师可在工具栏打开【⚡ 高级排序】面板,自由增删多个优先级条件(个人总分、小组总分、各自定义评分项目),并独立指定升序或降序;支持通过【↑】【↓】一键调整优先级顺序。
- 强制汉字拼音 A-Z 升序保底:当所有设置的优先等级分值均相同时,系统自动执行汉字拼音(
Intl.Collator("zh-Hans-CN"))升序保底,确保排版次序绝对确定、无歧义。 - 彩色状态标记框与互斥联动:表格上方醒目展示高级排序生效状态卡片,支持一键
[×]清除;点击表头单列排序时自动优先让位;按账号和班级在本地隔离记忆,切换班级时自动重置为默认录入顺序。
- 公告与时间线双模块:管理员可在后台编辑面向全体教师的【置顶通知】(支持富文本排版)与【版本更新日志】卡片时间线(版本号、日期、详细更新说明)。
- 新公告发布与静默保存:支持一键发布新公告触发全员教师重新弹出;支持静默保存修正错别字而不打扰教师。
- 教师端原生模态框展示:教师登录后自动居中弹出原生
<dialog>窗口,支持勾选【无新公告时不再弹出】(基于教师账号隔离的本地 Cookie 记录);顶栏常驻【📢 公告】入口与未读小红点,方便教师随时调出复看。
-
自然语言混合记分智能解析:单元格支持混合输入文字注释与分值(如
[主动发言+2] 迟到-1$\rightarrow$ 小计+1);仅统计带显式+或-的数字,普通无符号数字(如日期20260901)不计分并给出友好黄色警示。 -
离线草稿暂存与防误关拦截:未提交修改即时保存在
sessionStorage,意外刷新或断网重连后无缝恢复;存在未保存修改时,自动激活浏览器原生beforeunload弹窗拦截,杜绝误关导致心血白费。 - 乐观并发冲突逐项仲裁:当多名教师并发修改同一学生的同一单元格时,弹出直观的版本差异对比面板,支持逐项选择保留服务器最新版或本地草稿版。
- 全端浅色 / 深色模式:默认自动跟随操作系统
prefers-color-scheme: dark,页面右上角提供独立的 ☀️/🌙/🌓 三态切换按钮,全站界面与弹窗均采用深度定制的高品质护眼配色。 - 桌面端(PC):冻结左侧姓名列、顶部表头与右侧总分列;支持键盘上下左右方向键无缝跳格快速录入;编辑弹窗正居中聚焦。
- 移动端(手机)防异常专属排版(v1.5.1):
- 44px 紧凑顶栏针对性隐藏长文本链接,杜绝顶栏折行撑破与横向滚动条,各操作按钮触控精准;
- 顶栏
[分] Cloud Score标志升级为可点击链接,移动端轻触直达 GitHub 仓库; - 主内容区顶部提供仅 20px 高的轻量流式指示行,在表格滚动记分时自然滑出视野,零挤占记分屏幕空间;
- 悬浮工具栏双行紧凑排布(~68px 高),单屏横向容纳 6 个以上评分项目,支持平滑横向滑动浏览全部项目;
- 记分编辑抽屉靠顶排布(
top: 12px),彻底避开手机虚拟软键盘遮挡。
- 纯数学计算题验证码:加减乘整数动态算式挑战,防机器人碰撞与暴力破解,彻底告别图形验证码加载失败与小屏扭曲问题。
- 防爆破临时 IP 封禁:密码连续错误 8 次自动触发 15 分钟临时 IP 封禁(哈希存储于 R2,不暴露原始 IP,隐私合规)。
- 严格 CSP 与安全 Cookie:全站启用严格 Content-Security-Policy 内联脚本 SHA-256 哈希校验,禁止内联动态拼接;Cookie 强制启用
HttpOnly; SameSite=Strict; Secure; Path=/(生产环境使用__Host-前缀)。
整个生产运行系统由恰好 4 个纯原生核心文件构成,无多余子目录,极简纯粹:
├── _worker.js # Cloudflare Pages Advanced Mode 聚合后端 API 路由与安全鉴权
├── login.html # 统一登录认证、深浅色切换与数学计算题验证码
├── admin.html # 管理员控制台(教师/班级管理、期次管理、密码策略与系统公告)
├── teacher.html # 教师积分台(高密度记分、期次加锁解锁、毕业清空、高级排序与改密)
├── LICENSE # MIT 开源协议许可文本
├── README.md # 详细中文说明文档
└── README.en.md # Detailed English Documentation
system/catalog.json # 教师账号、PBKDF2 哈希、班级目录、密码策略与初始密码标记
system/announcement.json # 系统公告置顶通知、版本更新日志与发布版本标识
classes/{classId}.json # 班级稳定结构、期次配置、个人/小组积分、修订版本号与变更回执
sessions/{tokenHash}.json # 不透明会话、角色权限、CSRF 凭证与固定过期时间
captchas/{id}.json # 一次性数学挑战哈希、IP 摘要与过期时间
guards/{ipHash}.json # 登录失败计数时间窗口与临时 IP 封禁记录
双模管理(软归档 vs 物理彻底删除):
- 软归档(Archive):暂时封存实体,随时可一键【恢复】,历史打分与组员关系完整保留;
- 物理彻底删除(Delete):物理抹除实体,单次写入内原子级联清除该实体在当前及所有期次中的全部积分,防止垃圾孤岛数据残留。
| 维度 | 建议指标 / 边界 | 说明 |
|---|---|---|
| 有效班级数量 | 最多 20 个班级 | 支持年级多班并行管理 |
| 教师账号数量 | 最多 100 个教师 | 支持多对多权限交叉绑定 |
| 每班学生容量 | 最多 100 名学生 | 满足超大班额教学需要 |
| 每班评分项目 | 最多 30 个项目 | 自定义德智体美劳等多维度考评 |
| 每班小组数量 | 最多 20 个小组 | 支持合作学习分组评价 |
| 班级期次数量 | 无严格限制(建议每学期 5–15 期) | 支持两周一期循环评比与期末总评 |
| 单单元格限制 | 最多 500 字符,分值绝对值最大 1,000,000 |
容纳翔实的日常评语备注 |
| 单批次保存 | 单次 API 请求最多提交 500 个单元格修改 | 满足整班批量保存打分需求 |
-
获取 4 文件发布包: 下载本项目 Releases 中最新发布的
Cloud-Score-upload.zip(或由本地执行npm run build:release自动生成的无目录 ZIP 包)。 (注:该 ZIP 内部直接包含_worker.js、login.html、admin.html、teacher.html4 个文件,绝无嵌套子目录) -
创建 Cloudflare Pages 项目:
- 登录 Cloudflare Dashboard;
- 进入 Workers & Pages
$\rightarrow$ Create Application$\rightarrow$ Pages$\rightarrow$ Direct Upload; - 输入项目名称(如
cloud-score),将Cloud-Score-upload.zip拖入上传并点击部署。
-
配置 R2 存储桶与管理员密钥(关键步骤):
- 在 Cloudflare 控制台左侧进入 R2,点击 Create bucket 创建一个私有存储桶(如
cloud-score-data,保持 Public Access 为关闭状态); - 回到 Pages 项目详情页
$\rightarrow$ Settings$\rightarrow$ Functions:-
R2 bucket bindings:点击 Add binding,Variable name 必须填大写
R2,选择刚才创建的 Bucket; -
Environment variables:点击 Add variable,选择 Type 为 Secret(加密),Variable name 必须填大写
ADMIN,Value 输入管理员初始强密码(建议 20 位以上包含字母与数字的随机口令);
-
R2 bucket bindings:点击 Add binding,Variable name 必须填大写
- 回到 Pages 项目主页,再次点击 Deploy a new version 重新拖入上传一次 ZIP,使环境变量与 R2 绑定正式生效。
- 在 Cloudflare 控制台左侧进入 R2,点击 Create bucket 创建一个私有存储桶(如
-
初始化登录:
- 访问你的 Pages 默认域名(
https://<project-name>.pages.dev)或绑定的自定义域名; - 系统将自动跳转至
/login.html; - 账号输入
admin,密码输入你在 Secret 中配置的ADMIN密码,计算数学题即可进入管理后台建班、添加教师、设置密码策略。
- 访问你的 Pages 默认域名(
- Fork 或导入 GitHub 仓库:
- 将本项目 Fork 到你自己的 GitHub 账号;
- 在 Cloudflare Pages 中点击 Connect to Git,选中你的仓库;
- 构建设置(Framework preset 选
None,Build command 与 Build output directory 全部留空)。
- 配置 R2 与 Secret 变量:
- 在项目设置的 Functions 中绑定 R2 存储桶(变量名
R2)与 Secret 密钥(变量名ADMIN); - 重新触发一次部署即可。
- 在项目设置的 Functions 中绑定 R2 存储桶(变量名
- 排查原因:Functions 运行时未正确读取到绑定的 R2 存储桶或加密 Secret。
-
解决方案:
- 检查 Pages 的 Settings
$\rightarrow$ Functions 中 R2 绑定的变量名是否为严格纯大写的R2(不能写成r2或其他名称); - 检查环境变量中是否配置了类型为 Secret 且变量名为严格纯大写的
ADMIN; - 配置变量后必须重新部署一次(上传 ZIP 或推送提交)才能让绑定生效。
- 检查 Pages 的 Settings
- 排查原因:系统内置防暴力破解机制,同一 IP 连续 8 次密码错误将触发 15 分钟临时 IP 封禁保护。
- 解决方案:等待 15 分钟后系统自动解封;或者管理员可在管理后台(
admin.html)一键为该教师重置密码。
- 排查原因:v1.5.0 起引入了初始密码状态跟踪机制。由管理员新创建的教师或被管理员重置密码的教师,账号会被自动标记为【初始密码】状态。
- 解决方案:教师根据界面实时规则指引设置一次个人新密码即可,改密成功后将自动进入工作台并不再弹出提示。管理员亦可在后台切换为“提醒模式”或直接关闭密码强度策略。
- 单个学生毕业/转学:在教师端【班级设置】或管理员后台【学生】列表中,点击该学生右侧的【删除】(或归档后的【彻底删除】),系统将彻底物理抹除该学生名单,并原子级联清理该学生在所有期次中的全部个人历史积分。
- 全班学生毕业离校换届:在【班级设置】底部点击【全班学生毕业清空】,经过 10 秒强制倒计时冷静与随机数学计算题安全验证后确认,即可一键清空全班学生名单及所有期次的个人积分,同时完好保留评分项目与期次配置供新一届学生直接使用。
- 班级撤销彻底删除:管理员可在管理后台班级详情顶部点击【删除班级】(或归档后【彻底删除】),系统将原子解绑所有任课教师并物理删除该班级对应的云端 R2 存储文件。
本项目遵循 MIT License 开源协议,个人与教育机构可免费商用、修改与私有部署。