高中生如何使用OpenClaw开发 班级即时消息通知网站 以及经验总结
项目开源地址:https://github.com/tigerZZY/Classroom-Instant-Messaging-Notification-System
编写背景:
本人为成都某不知名高中的高三学生,上学期我们班主任看见其他班有一个消息通知系统,便让本牛马 编写一个我们班自己的通知系统,于是便有了这个程序的诞生。
所实现的功能:
目录
- 🚀 快速入门
- 👤 用户角色与权限
- 🔐 注册与登录
- 📨 消息通知系统
- ⏰ 上课/课间消息策略
- 🎙️ 语音消息
- 🎂 生日祝福系统
- 🌤️ 天气模块
- 📋 课表管理
- ⚙️ 系统设置
- 👥 用户管理(管理员)
- 💻 ClassIsland 桌面插件
- 📱 确认消息专用页面
- ❓ 常见问题 FAQ
🚀 快速入门
这是什么?
强基五班班级管理系统是一个专为班级打造的 Web 消息平台,帮助老师高效发送通知、叫人和公告。支持网页端 + ClassIsland 桌面插件,消息到达即时弹窗 + 语音播报,课间自动提醒未确认消息。
核心功能一览
| 功能 | 说明 |
|---|---|
| 📢 消息通知 | 三种类型(通知 / 叫人 / 公告),支持置顶、星标、附件 |
| 🎙️ 语音消息 | 网页端直接录音发送,课间自动语音播报 |
| 🔔 课间提醒 | 课间自动轮播未确认消息,弹窗 + TTS 语音 |
| 🎂 生日祝福 | 自动提醒当天生日同学,ClassIsland 插件实时显示 |
| 📋 课表管理 | 多课表轮换支持(单/双周),教室大屏轮播 |
| 💻 桌面插件 | ClassIsland 插件:状态栏实时显示消息和生日 |
👤 用户角色与权限
系统有三种角色,各司其职:
👑 管理员(Admin)
- 权限范围:
- ✅ 查看所有消息(不限发送者)
- ✅ 发布消息、置顶、星标
- ✅ 管理用户(激活、禁用、删除)
- ✅ 修改系统设置(上下学时间、课间时段等)
- ✅ 管理课表、生日数据
- ✅ 批量删除消息
- 🔇 不播放语音播报(管理员端静默接收)
👨🏫 教师(Teacher)
- 用户名格式:
teacher_xxx(如teacher_何建伟) - 权限范围:
- ✅ 发布消息到本班
- ✅ 查看自己发送的消息
- ❌ 不能查看其他教师的消息(保护隐私)
- ❌ 不能管理用户和系统设置
- 🔇 不播放语音播报
- ⚠️ 注册后需管理员激活
👩🎓 班级用户(Class)
- 用户名格式:
class_xxx(如class_5) - 权限范围:
- ✅ 接收所有通知(管理员 + 教师发出的)
- ✅ 可以发布消息(仅管理员可见,用于反馈)
- ✅ 确认消息(标记已读)
- 🔊 播放语音播报(非自己发的消息)
- ❌ 不能管理后台功能
权限速查表
| 操作 | Admin | Teacher | Class |
|---|---|---|---|
| 查看所有消息 | ✅ | ❌ 仅自己 | ✅ |
| 发布消息 | ✅ | ✅ | ✅ |
| 语音播报接收 | 🔇 | 🔇 | 🔊 |
| 管理用户 | ✅ | ❌ | ❌ |
| 修改系统设置 | ✅ | ❌ | ❌ |
| 确认消息 | ✅ | ❌ | ✅ |
| 批量操作 | ✅ | ❌ | ❌ |
🔐 注册与登录
注册流程
┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐
│ 填写信息 │ ──▶ │ 提交注册 │ ──▶ │ 等待审核 │ ──▶ │ 审核通过 │
│ │ │ │ │ (pending) │ │ (active) │
└──────────┘ └──────────┘ └──────────┘ └──────────┘
注册注意事项:
-
用户名格式要求:
- 教师:必须以
teacher_开头。例如teacher_张三✅ |张三❌ - 班级用户:必须以
class_开头。例如class_5✅ |5班❌
- 教师:必须以
-
必填信息:
- 用户名(格式见上)
- 密码(至少 6 位)
- 确认密码(必须与密码一致)
- 显示名称(会显示在消息列表中)
- 角色选择(教师 / 班级用户)
-
审核机制:注册成功后账号状态为"待激活(pending)",管理员审核通过后方可登录。这是为了防止无关人员随意注册。
📨 消息通知系统
三种消息类型
| 类型 | 图标 | 用途 | 课间表现 |
|---|---|---|---|
| 📢 通知 | 🔔 | 日常通知(作业、活动、安排等) | 弹窗 + TTS 语音播报 |
| 📞 叫人 | 📞 | 紧急召唤(叫某位同学来办公室等) | 弹窗 + 特殊提示音 |
| 📣 公告 | 📣 | 重要公告(全班须知事项) | 弹窗 + 公告提示音 |
发送消息
- 点击首页顶部"发布消息"按钮
- 填写消息内容:
- 标题:消息标题(必填)
- 内容:消息正文
- 类型:选择通知 / 叫人 / 公告
- 优先级:普通 / 紧急(紧急消息红色标记)
- 附件:支持图片、文档、音频(最多 10 个附件,单文件 ≤ 50MB)
- 置顶:勾选后消息始终排在列表最前面
- 点击"发布" → 系统自动创建回执并推送
消息接收与确认
- 教室端(Class 角色):收到消息 → 弹窗 + 语音播报
- 消息列表:未读消息有红色标记,已确认消息灰色标记
- 确认操作:点击消息旁的"确认"按钮 → 标记已读
- 待确认统计:首页统计卡片显示"待确认 X 条"
消息列表功能
| 功能 | 说明 |
|---|---|
| 📌 置顶 | 重要消息固定在列表顶部(管理员操作) |
| ⭐ 星标 | 收藏常用消息 |
| 🗑️ 删除 | 单条删除或批量勾选后删除 |
| ✅ 批量确认 | 勾选多条消息后一次性确认 |
| 📎 附件预览 | 点击附件图标预览/下载 |
| 🔊 语音播放 | 消息含语音附件可在线播放 |
消息列表横向滚动
首页消息区域采用横向卡片布局,最近 5 条消息一行展示:
- 📌 置顶消息红色边框
- 🔴 紧急消息红色标签
- 📞 叫人消息特殊图标
- 🔔 未读消息闪烁提醒
⏰ 上课/课间消息策略
系统会根据当前时间智能判断消息的推送方式,避免教学干扰
课间 = 上学时间内但不在上课时段中。例如 09:40-09:55、16:30-16:40 等。
不同时段的推送策略
│ 上课时段
│ 📨 新消息 → 缓存到 pending 队列 │
│ 💬 页面提示"当前为上课时段,消息将在课间时通知" │
│ 🔇 不弹窗、不播放 TTS
│ 课间时段 │
│ 📨 新消息 → 立即弹窗 + TTS 语音播报 │
│ 🔄 课间轮播:逐条播放所有未确认消息 │
│ 🔔 课间提醒弹窗 + 语音提示 │
│ ⏱️ 轮播冷却:播完一轮后等待 2 分钟再重播 │
│ 周末/假期 │
│ 📨 新消息 → 立即弹窗播报(不缓存) │
│ 🏠 课间轮播不启用
课间提醒机制
- 每分钟检测:后端 Cron 每分钟检测当前是否处于课间
- 弹出提醒:课间开始时 → 弹窗"🔔 课间提醒:您有 X 条未确认的通知"
- TTS 语音:提醒后 2 秒开始逐条语音播报
- 防重复:每个课间只完整播报一轮,2 分钟冷却
周末特殊处理
周末不触发课间轮播,但新消息立即播报(与工作日上课缓存策略不同)。
🎙️ 语音消息
网页端录音
- 点击发送消息面板的"🎤 录音"按钮
- 浏览器请求麦克风权限 → 允许
- 开始录音(最长 60 秒),再次点击停止
- 发送后,音频随消息一起推送
语音播报(TTS)
- 触发条件:Class 角色 + 课间/周末 + 非自己发出的消息
- 播报内容:“来自 XXX 的消息:标题…”
- 提示音区分:
- 📢 通知 → 标准提示音
- 📞 叫人 → 紧急提示音
- 📣 公告 → 公告提示音
- 管理端:不播报(静默接收)
音频附件播放
接收端点击消息中音频附件可在线播放,使用浏览器原生音频控件。
🎂 生日祝福系统
生日录入
管理员可在后台管理页面的「生日管理」中:
- 逐条添加:姓名 + 生日日期
- 批量导入:表格粘贴(推荐导入全班数据)
- 当前系统已有 40+ 条生日数据
生日提醒
- 每日 8:00:后端自动检测当天生日
- WebSocket 推送:教室端弹窗"🎂 今天是 XXX 的生日!祝生日快乐!"
- ClassIsland 插件:状态栏显示"🎂 祝XXX同学N岁生日快乐!"(红色文字)
- 无人过生日:显示"🎂 今日无寿星"
多人生日
如当天有多个同学生日,显示"🎂 祝张三、李四同学生日快乐!"
🌤️ 天气模块
- 数据来源:小米天气 API(后端代理,无跨域问题)
- 默认城市:成都 · 武侯区
- 预警系统:
- 🟥 红色预警 → 红色横幅 + 闪烁圆点
- 🟧 橙色预警 → 橙色横幅
- 🟨 黄色预警 → 黄色横幅
- 🟦 蓝色预警 → 蓝色横幅
- 预警弹窗:0.8 秒后自动弹出(仅弹一次)
- 教室大屏模式:首页大屏轮播中展示天气卡片
📋 课表管理
系统支持多课表轮换(例如单周/双周不同课表)。
课表操作(管理员)
- 添加/编辑每节课:星期几、节次、科目、教师、时间
- 批量导入课表
- 课表名称管理(如 default、单周、双周)
- 课表周次映射(指定第几周用哪个课表)
课表查看
- 网页端按星期筛选查看
- 教室大屏轮播展示当天课表
- ClassIsland 插件可同步课表数据
⚙️ 系统设置
管理员可在「系统设置」页面配置以下参数:
| 设置项 | 说明 | 默认值 |
|---|---|---|
| 学校名称 | 显示在学校标题处 | |
| 上学时间 | 早读/第一节课开始时间 | 07:30 |
| 放学时间 | 最后一节课结束时间 | 21:50 |
| 上课时段 | 所有上课时间段(逗号分隔) | 见上文列表 |
| 学期开始 | 学期起始日期 | 2026-03-01 |
| 学期周数 | 学期总周数 | 20 |
| 考试日期 | 考试倒计时目标日期 | 由管理员设置 |
| 语音播报 | 是否启用 TTS 语音 | 开启 |
| 课间提醒 | 是否启用课间提醒轮播 | 开启 |
| 提醒间隔 | 未确认消息检查间隔(分钟) | 5 |
⚠️ 重要提醒
break_times 字段存在历史命名问题:
- 字段名叫
break_times(课间),但实际存的是上课时段 - 修改时格式:
HH:MM-HH:MM,HH:MM-HH:MM,... - 课间 = 上学时间内但不在
break_times中的空档
👥 用户管理(管理员)
管理员登录后在「用户管理」页面可以:
用户列表
展示所有注册用户,包含:
- 用户名、显示名称、角色、所属班级
- 状态(pending 待激活 / active 已激活)
- 是否启用(is_active)
用户操作
| 操作 | 说明 |
|---|---|
| ✅ 激活 | pending → active,用户可登录 |
| ✏️ 编辑 | 修改用户信息(角色、科目、手机号等) |
| 🚫 禁用 | 暂禁止登录(可恢复) |
| 🗑️ 删除 | 彻底删除用户(⚠️ 管理员不可删除) |
待激活提醒
首页统计卡片实时显示"待激活 X 人",提醒管理员及时审核。
💻 ClassIsland 桌面插件
ClassIsland 是教室大屏使用的桌面课表软件。Qj5Notifier 插件为 ClassIsland 增加了班级消息推送能力。
插件功能
| 组件 | 功能 |
|---|---|
| 🔔 消息通知 | 状态栏单行显示:图标 + 最新消息标题 + 未读徽章 |
| 🎂 生日祝福 | 今天生日显示祝福;无人过生日显示"今日无寿星" |
| 🌐 WebSocket | 实时连接服务器,秒级接收到新消息 |
课间行为
- 上课时段:新消息缓存,不打扰课堂
- 课间来临:WebSocket 收到
break_start→ 立即弹窗 + TTS + 逐条播报缓存消息 - 防重复:每个课间只播一次(
_drainedThisBreak防护) - 缓存上限:最多 50 条消息
消息通知组件样式
🔔 📢 关于明天考试的通知… [2 条未确认] 🟢在线
- 标题白色加粗(13px)
- 未读数量红色徽章
- 在线状态绿点
- 一行紧凑布局,适配状态栏窄空间
📱 确认消息专用页面
专为教室端设计的未确认消息集中处理页:
- 访问路径:
/confirm或从首页"待确认"卡片跳转 - 自动语音:进入页面后自动语音播报每条未确认消息
- 逐条确认:点击"确认"按钮逐条标记已读
- 课间提醒:WebSocket 实时监听
break_start,课间自动弹窗提醒 - 轮询兜底:每 10 秒检查一次(防止 WebSocket 断连)
使用场景
教室电脑常驻打开此页面,上课时静默,课间自动弹出提醒 → 班长/值日生查看确认。
编写时的经验总结
从 2026-04-25 项目启动到 2026-08-06 审计完成,完整技术栈:Node.js + Express + SQLite + WebSocket + PM2 + Electron
一、编码损坏 — 最反复出现的硬伤
1.1 edit 工具破坏 UTF-8(3 次)
现象:对 app.js 使用 edit 工具后,中文字符被替换为 ??(U+FFFD),触发 JavaScript SyntaxError,页面按钮全无响应。
根因:edit 工具的文本替换未保持 UTF-8 多字节字符边界,在多字节序列中间插入/替换字节。
教训:
- 禁止对含中文的 JS/HTML 文件使用
edit工具。改用write整体写入,或写成 Python 脚本在服务器端做字符串替换。 - 每次修改前必须备份(
cp file.js file.js.bak_$(date +%Y%m%d_%H%M%S))。
1.2 PowerShell GBK 编码损坏(多次)
现象:通过 PowerShell SSH/scp 传输到服务器的文件,中文字节被替换为 ?(0x3F),Node.js 语法检查失败。
根因:PowerShell 终端默认 GBK 编码,SSH 命令中的 UTF-8 多字节序列被截断。
教训:
- 一律使用「本地写脚本 → scp 上传到 /tmp → ssh bash/python3 执行」工作流。
- 绕过 PowerShell 的引号解析,不在 PowerShell 命令行中写含中文/特殊字符的内联脚本。
- Python 脚本是安全的中间格式(UTF-8 天然兼容,scp 二进制传输)。
1.3 PowerShell heredoc 陷阱
现象:ssh root@host "cat > file.py << 'EOF' ... EOF" 被 PowerShell 解析为本地命令,引号层层崩解。
根因:PowerShell 先解析命令行再传递给 ssh,heredoc 的 << 被当作本地重定向。
教训:
- 永远不在 PowerShell 命令行中写 heredoc。
- 需要远程创建脚本时:
scp local_script.sh root@host:/tmp/ && ssh root@host "bash /tmp/script.sh"。
二、服务崩溃 — 根因诊断与止血
2.1 TDZ(Temporal Dead Zone)导致间歇性崩溃
现象:/api/schedule/break-now 始终返回 500 → 上课时段消息缓存逻辑全失效 → PM2 重启 48 次。
根因:schedule.js 第 148 行 inClass 箭头函数捕获 inSchoolHours,但 inSchoolHours 在第 156 行才用 const 声明。V8 的 TDZ 检查在闭包创建时就触发 ReferenceError。
教训:
- 箭头函数隐式闭包可能触发 TDZ,
const/let声明的位置非常敏感。 - 关键 API 必须加单元级烟雾测试:启动后
curl /api/schedule/break-now检查返回 200。 - 使用
var声明提升变量作为 TDZ 的快速绕过手段(语义上不优雅但有效)。
2.2 JSON 解析崩溃 — 未捕获异常直接崩进程
现象:PM2 日志频繁 SyntaxError: Bad escaped character in JSON → SIGKILL。
根因:接收到畸形 JSON 请求体时,Express 的 express.json() 中间件抛出异常未被捕获。外加缺少 uncaughtException/unhandledRejection 全局处理器,任何未捕获异常直接崩进程 → PM2 重启 → 内存 session 全部丢失 → 用户被踢回登录页。
教训:
server.js第一行就应加process.on('uncaughtException', ...)和process.on('unhandledRejection', ...),记录日志但不退出。- 所有异步路由内部必须 try-catch。
- PM2 重启计数是最重要的健康指标,应该定期监控(
pm2 info或pm2 monit)。
2.3 bcrypt 模块缺失 — 部署后依赖不完整
现象:/api/users/:id/reset-password 必 500,Cannot find module 'bcrypt'。
根因:package.json 有 bcrypt 但 node_modules 中没有。可能是某次部署时 npm install 被中断或跳过了。
教训:
- 每次部署后用
node -e "require('bcrypt')"验证关键 native 模块可加载。 pm2 restart不等于npm install。换服务器或清node_modules后必须重新npm install --production。
2.4 SESSION_SECRET 每次都变 — 全员掉登录
现象:每次 PM2 重启 / 进程崩溃恢复后所有用户被踢回登录页。
根因:server.js 里 secret: process.env.SESSION_SECRET || crypto.randomBytes(32).toString('hex'),环境变量未设,每次生成新密钥 → 旧 session cookie 全部失效。
教训:
- session 密钥必须固定。用
ecosystem.config.js写入 env 或直接硬编码生成一次的固定值。 - 绝对不要用随机值作为 fallback。
三、远程操作 — PowerShell 是最大的障碍
3.1 问题矩阵
| 操作 | PowerShell 直接执行 | 脚本化(scp → ssh 执行) |
|---|---|---|
| SSH 单行命令 | 引号嵌套易出错 | ✅ 安全 |
| SSH heredoc | ❌ 被本地解析 | ✅ bash 执行 |
| Python 修复脚本 | ❌ 中文被破坏 | ✅ scp 二进制传输 |
| node --check 校验 | ❌ 工作目录错误 | ✅ 脚本内 cd 到正确目录 |
| base64 编码 | ❌ 编码不完整 | ✅ Python 处理 |
| 文件 grep/搜索 | ❌ 通配符被 PowerShell 展开 | ✅ 写成 bash 脚本 |
3.2 标准操作流程
# 1. 本地创建脚本
# C:\Users\zengz\.qclaw\workspace-agent-d3b9cb40\tmp_fix_xxx.sh (或 .py)
# 2. scp 上传
scp tmp_fix_xxx.sh root@47.108.162.103:/tmp/
# 3. ssh 执行
ssh root@47.108.162.103 "bash /tmp/fix_xxx.sh"
# 4. (如果是前端修改) 手动升级缓存版本号
# index.html 中 v=YYYYMMDDvN → v=YYYYMMDDvN+1
3.3 SSH 连接不稳定
现象(2026-05-30):从助手环境 22 端口多次不通(ping 超时、SIGKILL),但用户本地可连。HTTPS 正常。
应对:备选方案 — 请用户手动 SSH 执行简单命令。
四、前端 JS — 纯 SPA 的坑
4.1 innerHTML = XSS 入口
app.js 中 20 处 innerHTML =,含通知标题/内容、生日名字等直接拼接服务器数据。若有人注册后发送 <script>alert(1)</script> 作为消息标题,会触发 XSS。
建议:对用户可控字段用 textContent,或用 DOMPurify 过滤。
4.2 setInterval 泄漏
23 个 setInterval,部分无对应 clearInterval。SPA 内多次切换页面不清理 → 定时器堆积 → 内存泄漏。
4.3 函数名不匹配(幽灵引用)
openModal()— 不存在,实际是openBirthdayModal()/openPublishModal()等具体函数statUsers— 不存在,引用它的代码会导致静默失败loadMyNotifs()— 已删除但调用未清理
教训:删除功能时,用 grep 全局搜索函数名确保没有残留引用。
4.4 HTML ID 不匹配
课间时段输入框的 HTML id 和 JS 中引用的 id 不一致 → 设置页保存功能静默失效。
4.5 缓存版本号机制
<script src="js/app.js?v=YYYYMMDDvN"> 手动递增版本号。
每次前端修改后必须升级版本号,否则浏览器缓存旧 JS → 新功能不生效。
五、数据库 — SQLite 的实践经验
5.1 WAL 模式注意点
- SQLite WAL 文件会持续增长,需定期
PRAGMA wal_checkpoint(TRUNCATE)。 - 出现过 4MB WAL 配 64KB 主库的情况 — 不影响功能,但影响启动速度。
5.2 UTC vs 本地时间
SQLite 的 CURRENT_TIMESTAMP 返回 UTC。需用 datetime('now','localtime') 才能拿到北京时间。历史数据需要手动 +8 小时修复。
5.3 参数化查询 100% 覆盖
21 处数据库操作全部参数化(db.run(sql, [params], ...)),零 SQL 注入。这是做得最好的部分。
5.4 数据库路径混淆
曾存在根目录 0 字节空文件 class_system.db 与 data/class_system.db 同时存在 → 排查困难。
六、部署与运维
6.1 跨平台部署铁律
Windows 编译的 sqlite3 不能在 Linux 上运行(invalid ELF header)。
→ 永远在目标服务器上执行 npm install。
6.2 PM2 重启计数
累计 89 次重启。每次非预期的重启都是 bug 信号。健康的服务不应频繁重启。
6.3 备份清单
class-system-backup-20260605_204832— 2026-06-05 全量audit_backup_20260802— 2026-08-02 全量 (注意:本地下载包排除了!)data/class_system.db.bak/.bak_utcfix— 数据库备份- 多次
app.js.bak_*、index.html.bak_*、style.css.bak_*单文件备份
6.4 npm 安全漏洞未修复
31 个漏洞(2 critical / 21 high / 5 moderate / 3 low),npm audit fix --force 有 breaking change 风险,需先 npm audit 看具体包再决定。
七、快速参考卡
| 场景 | ✅ 正确做法 | ❌ 错误做法 |
|---|---|---|
| 修改服务器文件 | 本地写 Python 脚本 → scp → ssh python3 | PowerShell SSH 内联代码 |
| 修改含中文的 JS | write 工具整体写入,或服务器端 Python |
edit 工具 |
| 部署到 Linux | 目标机器 npm install |
复制 Windows 的 node_modules |
| 前端修改后 | 升版本号 ?v=YYYYMMDDvN+1 + PM2 重启 |
直接覆盖不升版本 |
| Session 密钥 | 固定写入 ecosystem.config.js |
crypto.randomBytes() fallback |
| API 接口 | try-catch 包裹 + 错误脱敏 | 裸 async (req, res) |
| 删除函数 | grep 全局搜索引用 | 只删定义不管调用 |
| PM2 重启 | 用备份验证后再重启 | 无备份直接改 |
| SQLite 操作 | 参数化查询 db.run(sql, [p1, p2]) |
字符串拼接 SQL |
尾声:一行代码里的少年气
从四月暮春到八月流火,一百多个深夜的键盘敲击,把一个高三学生的“临时任务”,锻造成了一套真正跑在教室大屏上的系统。它不只是 冷冰冰的代码,更是为班级刻下的一段时光。
在这个系统里,消息不再是冰冷的数据包,而是老师的一声叮咛,是同学生日的烛光,是课间十分钟里准时响起的、属于我们的声音。它打破了空间的隔阂,最终让冰冷的机器学会了在恰当的时刻保持沉默,又在需要的瞬间大声说话。让老师在炎热的夏季能够坐在办公室中就将消息传达到位,而不用遭受高温的“炙烤”
编程的过程,像极了高三的备考。你会遇到解不开的 TDZ(暂时性死区),会遇到编码错乱的乱码(Bug),也会在 PM2 一次次重启中怀疑人生。但正如《黑客与画家》中所说:“软件正在吞噬世界,但首先,它在喂养那些创造它的人。” 每一次修复,都是对逻辑的重新梳理;每一次部署,都是对耐心的极限考验。
这不仅是一次技术的试炼,更是一次关于“责任”的预演。我守着服务器,就像守着我们班的秩序。哪怕只是为了让那条“祝某某同学生日快乐”的弹窗准点出现,所有的熬夜都变得值得。
最后,借用诗人里尔克在《给青年诗人的信》中的话作结:
“哪有什么胜利可言,挺住意味着一切。”
愿未来的某一天,当北二外成都附中高2024级5班的同学们回想起高三,除了试卷和分数,还能记得大屏上那个红色的未读徽章,记得那句准时响起的“祝生日快乐”。那是我们在数字世界里,共同度过的一段滚烫岁月。
更多推荐



所有评论(0)