简洁美观的班级课表管理系统,支持课程编辑、周次管理、数据导入导出等功能。
- 📱 响应式设计 - 支持手机、平板、电脑访问
- 🎨 美观界面 - 现代化 UI,支持深色模式
- 📅 周次管理 - 自动计算当前周次,支持单双周课程
- ✏️ 在线编辑 - 无需后端知识,密码保护编辑权限
- 💾 数据持久 - 自动保存,支持导入导出
- 🐳 Docker 部署 - 一键部署,支持 Debian/CentOS
- 🔒 安全加固 - XSS 防护、路径遍历防护、输入验证
使用 GitHub Container Registry 预编译镜像,无需构建,秒级启动:
curl -fsSL https://raw.githubusercontent.com/yang12535/schedule-web/main/deploy/install-prebuilt.sh | bash或使用 Makefile:
make deploy-fast特点:
- ⚡ 秒级启动,无需等待构建
- 🔄 自动拉取最新镜像
- 🏗️ 支持 amd64/arm64 双架构
如需本地构建镜像:
curl -fsSL https://raw.githubusercontent.com/yang12535/schedule-web/main/deploy/install.sh | bash或使用 Makefile:
make deploy# 1. 克隆仓库
git clone https://github.com/yang12535/schedule-web.git
cd schedule-web
# 2. 配置环境变量
cp .env.example .env
# 编辑 .env 文件设置参数
# 3. 拉取并启动(使用预编译镜像)
make update-image
# 或: docker-compose pull && docker-compose up -d# 使用本地构建的镜像
docker-compose -f docker-compose.yml -f docker-compose.build.yml up -d --build# 安装依赖
make install-dev
# 启动服务
make dev| 变量名 | 说明 | 默认值 |
|---|---|---|
CLASS_NAME |
班级名称 | 我的课表 |
CLASS_DESC |
学期描述 | - |
SEMESTER_START |
学期开始日期 | 2024-03-01 |
EDIT_PASSWORD |
编辑密码(留空则无需密码) | - |
HOST_PORT |
服务端口 | 30080 |
# 查看所有命令
make help
# 常用操作
make start # 启动服务
make stop # 停止服务
make restart # 重启服务
make logs # 查看日志
make backup # 备份数据
make update-image # 更新到最新预编译镜像或使用管理脚本:
./deploy/manage.sh [command]
# 命令说明:
# start - 启动服务
# stop - 停止服务
# restart - 重启服务
# status - 查看状态
# logs - 查看实时日志
# password - 查看编辑密码
# backup - 备份数据
# restore - 恢复数据schedule-web/
├── src/ # 源代码
│ ├── server/ # 后端服务 (Node.js + Express)
│ └── public/ # 前端页面
├── deploy/ # 部署脚本
│ ├── install.sh # 一键安装脚本(本地构建)
│ ├── install-prebuilt.sh # 快速部署脚本(预编译镜像)⭐
│ └── manage.sh # 管理脚本
├── .github/workflows/ # GitHub Actions
│ └── docker.yml # 自动构建 Docker 镜像
├── data/ # 数据存储 (Docker 挂载)
├── logs/ # 日志文件 (Docker 挂载)
├── docker-compose.yml # Docker Compose 配置(预编译镜像)⭐
├── docker-compose.build.yml # Docker Compose 配置(本地构建)
├── Dockerfile # Docker 镜像构建
├── Makefile # 快捷命令
└── .env.example # 环境变量示例
点击页面上的 "📤 导出" 按钮,下载 JSON 格式的课表数据。
点击 "📥 导入" 按钮,选择之前导出的 JSON 文件。
兼容旧版本数据:支持自动迁移旧格式数据。
- 默认启用密码保护,首次启动会生成随机 6 位数字密码
- 可通过
EDIT_PASSWORD环境变量自定义密码 - 留空
EDIT_PASSWORD可关闭密码保护(不推荐用于生产环境) - 所有数据存储在本地
data/目录 - v1.0.2 安全加固:添加 XSS 防护、路径遍历防护、输入验证
现象:
- 页面标题显示正常,但课表数据一直显示"加载中..."
curl /api/schedule超时无响应docker stats显示容器 CPU 占用 300%+
根因:
Docker bind mount 绑定的是目录 inode,而非路径名。如果在容器运行期间,宿主机上删除并重建了挂载源目录(如 rm -rf data && mkdir data),bind mount 会指向一个已被标记为 (deleted) 的孤儿 inode,容器内看到的 /data 实际是空的。
验证方法:
# 宿主机上检查 mountinfo
CONTAINER_ID=$(docker-compose ps -q schedule)
cat /proc/$(docker inspect --format '{{.State.Pid}}' "$CONTAINER_ID")/mountinfo | grep '/data'
# 若输出中包含 "(deleted)"(或转义形式 "\040(deleted)"),即确认此问题修复:
# 停止并重建容器,让 Docker 重新建立挂载
make stop && make start
# 或手动:
docker-compose down
docker-compose up -d预防:
- 备份或更新数据时,不要删除
data/目录本身,只覆盖目录内的文件:# ✅ 正确:保留目录 inode cp backup/schedule.json data/schedule.json # ❌ 错误:会断开 bind mount rm -rf data/ mkdir data cp backup/schedule.json data/
- 若使用
rsync同步,加--inplace参数避免删除重建目录
在 .env 或 docker-compose.yml 中显式设置 EDIT_PASSWORD:
environment:
- EDIT_PASSWORD=你的密码EDIT_PASSWORD 的行为分为三种情况:
- 未设置 / 未传入容器环境变量:每次容器重启都会随机生成一个 6 位数字密码。
- 设置为空字符串:关闭密码保护。
- 设置为具体值:使用该值作为固定编辑密码。
- ✅ 新增弹窗公告(时段内生效)
- ✅ 新增单周补课模式
- ✅ 修复 9 项代码审查发现的问题(原子写入、API 404、跨周计算、时区等)
- ✅ 修复 20+ 个关键 Bug(详见 BUGFIX.md)
- ✅ XSS 漏洞修复
- ✅ Docker 部署稳定性提升
- ✅ 前端输入验证增强
- ✅ 后端错误处理完善
- ✅ 修复周末课程标记问题
- ✅ 优化下一节课卡片 UI
- ✅ 课程编辑功能
- ✅ 周次管理(单双周)
- ✅ 数据导入导出
- ✅ Docker 一键部署
- ✅ 兼容旧版本数据
欢迎提交 Issue 和 PR!
AGPL-3.0 © 2026 yang12535