前言
今天为作业批改系统增加了QQ机器人提醒功能,包括作业截止提醒、成绩不理想私聊提醒等。记录一下实现过程和遇到的问题。
功能需求
- 作业截止前群提醒 - 在截止前24小时和1小时发送群消息
- 成绩不理想私聊提醒 - 分数<60分时私聊学生
- 首次提交绑定QQ号 - 收集学生QQ号用于后续提醒
架构设计
1 2 3 4 5
| ┌─────────────┐ HTTP ┌─────────────┐ │ 后端服务 │◄────────────►│ Napcat │ │ (Spring │ OneBot协议 │ (QQ机器人) │ │ Boot) │ │ │ └─────────────┘ └─────────────┘
|
选择直接调用 Napcat HTTP 接口,而不是通过 OpenClaw Gateway,这样可以:
核心实现
1. OneBot HTTP 服务
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| @Service @RequiredArgsConstructor public class OneBotHttpService { private final OneBotProperties properties; private final WebClient webClient = WebClient.create(); public void sendPrivateMessage(String qqNumber, String message) { Map<String, Object> body = Map.of( "user_id", qqNumber, "message", message ); sendRequest("/send_private_msg", body); } public void sendGroupMessage(String groupId, String message) { Map<String, Object> body = Map.of( "group_id", groupId, "message", message ); sendRequest("/send_group_msg", body); } }
|
2. 学生名单自动收集
采用渐进式策略:
- 首次作业:学生提交时自动收集到
class_student 表
- 后续作业:可以提醒未交学生
1 2
| classStudentMapper.insertIgnore(classId, studentId, studentName, "auto");
|
3. 定时提醒调度
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| @Service public class TaskReminderScheduleService { public void scheduleReminderTasks(Long taskId) { HomeworkTask task = taskMapper.selectById(taskId); LocalDateTime remind24h = task.getDeadline().minusHours(24); scheduleTask(taskId, remind24h, 24); LocalDateTime remind1h = task.getDeadline().minusHours(1); scheduleTask(taskId, remind1h, 1); } }
|
数据库设计
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| CREATE TABLE student_qq_binding ( student_id VARCHAR(32) PRIMARY KEY, qq_number VARCHAR(32) NOT NULL, student_name VARCHAR(64), created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP );
CREATE TABLE class_student ( id BIGSERIAL PRIMARY KEY, class_id BIGINT NOT NULL, student_id VARCHAR(32) NOT NULL, student_name VARCHAR(64) NOT NULL, source VARCHAR(20) DEFAULT 'auto', created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, UNIQUE(class_id, student_id) );
|
前端交互
首次提交时弹出QQ绑定对话框:
1 2 3 4 5 6 7 8
| <div v-if="showQqBindDialog" class="dialog-overlay"> <div class="dialog-content"> <h3>🔔 首次提交,请绑定QQ号</h3> <p>绑定后,当作业成绩不理想时,我们会通过QQ私聊提醒你。</p> <input v-model="qqNumberInput" placeholder="请输入你的QQ号" /> <button @click="bindQq">绑定并提交</button> </div> </div>
|
遇到的问题
OneBot 请求失败
错误日志:
1
| OneBot请求失败: endpoint=/send_group_msg
|
排查方向:
- Napcat HTTP 服务是否启动
- Token 是否配置正确
- 后端能否访问 Napcat 地址
- 群号是否正确,机器人是否在群里
测试命令:
1 2 3 4
| curl -X POST http://127.0.0.1:3000/send_group_msg \ -H "Authorization: Bearer TOKEN" \ -H "Content-Type: application/json" \ -d '{"group_id":"群号","message":"测试"}'
|
总结
今天完成了:
- ✅ 游客提交次数统计(按学号)
- ✅ 成绩统计去重(只取最新)
- ✅ QQ机器人提醒功能(群提醒+私聊)
- ✅ 首次提交QQ绑定
- ✅ 班级学生自动收集
2026-05-10 于桂林