{"ts":1788110988612,"ok":true,"data":[{"code":"E0001","category":"网络","desc":"连接中转服务失败","causes":["服务器未启动","域名解析失败","防火墙拦截","token 不正确"],"steps":["1. 浏览器访问 /api/health 是否能通","2. 确认 DNS：ping score.yourdomain.com","3. 检查学生端配置中转服务地址","4. 抓包确认 9090/443 端口可达"],"fix":"按 3+1 步排查，若无法恢复则切换回局域网 P2P 模式（teacherServerUrl 设为教师端 IP:9090）"},{"code":"E0002","category":"网络","desc":"连接教师端 WS 失败（P2P 模式）","causes":["教师端未启动","局域网不通","FRP 未启动"],"steps":["1. 教师端右下角托盘图标确认运行中","2. 同网段 ping 教师端 IP","3. 启动 FRP 客户端（内网穿透时）"],"fix":"优先使用中转服务，P2P 仅作为降级兜底"},{"code":"E0003","category":"网络","desc":"WebSocket 心跳超时离线","causes":["网络抖动","客户端进程被挂起","中转重启断连"],"steps":["1. 查看网络是否 30s 内有大波动","2. 检查资源管理器中 student.exe CPU","3. 重启客户端即可自动重连"],"fix":"学生端代码已内置指数退避重连（1s→2s→4s→最大 30s），无需人工干预"},{"code":"E0004","category":"网络","desc":"中转鉴权失败 (4001)","causes":["WS_TOKEN 与服务端不一致","连接 URL 未携带 token 参数"],"steps":["1. 对比学生端/教师端与服务器 .env 的 WS_TOKEN","2. 连接 URL 加 ?token=xxx 或 Sec-WebSocket-Protocol"],"fix":"统一 WS_TOKEN，或生产留空（不强制鉴权）"},{"code":"E0101","category":"语音","desc":"麦克风未授权","causes":["首次运行权限框点击拒绝","系统隐私设置禁用麦克风","硬件麦克风被禁用"],"steps":["1. Windows 设置 → 隐私和安全性 → 麦克风 → 允许应用访问","2. 学生端 → 设置 → 隐私 → 开启麦克风","3. 重启学生端"],"fix":"也可直接删除设备 ID（DB 中）重新注册一次触发授权弹框"},{"code":"E0102","category":"语音","desc":"VOSK 模型未找到","causes":["models/ 目录没放 tar.gz 模型","打包 extraResources 漏了","voskModelPath 配置错误"],"steps":["1. 检查 student.exe 同级 resources/models 下是否有 vosk-model-small-cn.tar.gz","2. 查看学生端控制台：[voice-ipc] VOSK 模型 URL: file:///xxx","3. 对比配置 voskModelPath 与实际路径"],"fix":"tar.gz 放 resources/models/，并确保 voskModelPath = models/vosk-model-small-cn（与默认一致）"},{"code":"E0103","category":"语音","desc":"云端 STT 超时","causes":["到 stt.api.cxsjmc.cn 的网络不通","5960 端口被学校防火墙拦截","STT 服务维护中"],"steps":["1. curl -I https://stt.api.cxsjmc.cn:5960 看返回","2. 检查 STT token 是否过期（后台续期）","3. 增大 cloudTimeoutMs（默认 30s）"],"fix":"超时自动降级为 VOSK 本地识别，无需担心，只是精度略低，等网络恢复即自愈"},{"code":"E0104","category":"语音","desc":"云端 STT 返回空字符串","causes":["录到的是纯静音/正弦波（硬件噪音）","音频音量太小","热词表不匹配"],"steps":["1. 测试学生端 test-stt-api.cjs 录制真实人声","2. 系统音量调大 + 麦克风增益","3. 在 STT 热词表中录入班级全部学生姓名拼音"],"fix":"非语音段返回空是正常行为，连续失败再联系维护"},{"code":"E0201","category":"防退出","desc":"注册表写入失败（禁用任务管理器）","causes":["学生端以普通用户运行，无 HKCU Policies 写权限","杀毒软件拦截注册表写入"],"steps":["1. 把 student.exe 加入杀毒白名单","2. 用管理员身份运行一次（生成注册表键后普通用户即可读）","3. 域策略下发注册表"],"fix":"写入失败不影响防退出的其他层（快捷键拦截等仍生效）"},{"code":"E0202","category":"防退出","desc":"部分快捷键无法拦截","causes":["被系统优先注册（Ctrl+Alt+Del 硬件级）","驱动级键盘过滤驱动冲突"],"steps":["1. Ctrl+Alt+Del 无法拦截属正常（改用注册表禁用菜单）","2. 关闭其他快捷键软件（如词典划词）"],"fix":"Ctrl+Alt+Del 的任务管理器/关机/锁屏等入口已通过注册表 HKCU\\...\\Policies 禁用，安全上完整闭环"},{"code":"E0203","category":"防退出","desc":"电源阻止失败","causes":["powerSaveBlocker 在部分 Windows 家庭版受限","系统组策略禁 sleep prevention"],"steps":["1. powercfg /requests 查看当前持有","2. 管理员组策略开启允许应用阻止睡眠"],"fix":"阻止失败不影响核心功能，仅设备更易进入睡眠"},{"code":"E0301","category":"存储","desc":"配置文件损坏","causes":["磁盘坏扇区","进程 crash 时半写入"],"steps":["1. 8 份备份自动恢复：删除损坏的 student-config.json，重启学生端","2. 若仍失败，复制一份同名 .bak 替换"],"fix":"学生端内置 8 份奇偶校验备份，99.9% 场景自恢复"},{"code":"E0302","category":"存储","desc":"分数存储失败","causes":["C 盘写满","被杀毒拦截文件写入"],"steps":["1. 清理 C 盘空间（至少 1GB）","2. 加入杀软白名单","3. 重设 %APPDATA% 存储目录权限"],"fix":"每次分数变更都会立即同步给教师端，教师端有副本，可后补回"},{"code":"E0303","category":"存储","desc":"备份文件丢失 (≥3 份失效)","causes":["清理软件误删","手动删除 AppData"],"steps":["1. 学生端启动时重新生成 8 份","2. 从教师端重新同步花名册和积分"],"fix":"不影响主存储，下一次写入时自动补齐丢失的备份"},{"code":"E0401","category":"学生端","desc":"设备 ID 冲突","causes":["整盘克隆虚拟机/母盘导致 UUID 一样","手动复制配置文件"],"steps":["1. Admin 后台 → 设备管理 → 删除冲突 ID 之一","2. 对应学生端删除配置 deviceId 字段重启（自动重新生成）"],"fix":"生成规则是 UUIDv4 + 机器特征哈希，克隆场景请 SysPrep 或执行 node scripts/reset-device-id.js 各机独立运行一次"},{"code":"E0402","category":"学生端","desc":"教师端未授权退出","causes":["非法尝试关闭学生端 EXE","触发防退出机制"],"steps":["1. 正常下课由教师端在后台/指令中心选择目标设备→执行 authorized_quit","2. 运维紧急退出：管理员后台对应设备 authorized_quit"],"fix":"任何绕过方法都属违规，合法路径只有一个：中转 → authorized_quit IPC"},{"code":"E0501","category":"系统","desc":"学生端进程异常退出","causes":["OOM 崩溃","显卡驱动崩溃","杀软误删"],"steps":["1. 查看 %APPDATA%/classroom/student/logs/crash.log","2. 任务管理器 15 分钟后还不起来 → 手动重启一次","3. 考虑加入 nssm 托管"],"fix":"生产环境可用 PM2/nssm 把 student.exe 注册为自动重启服务"},{"code":"E0502","category":"系统","desc":"Electron 主进程崩溃","causes":["DLL 冲突","杀毒注入","硬件驱动异常"],"steps":["1. crashpad 报告定位到 dump 文件","2. 以 --disable-gpu --in-process-gpu 启动参数测试"],"fix":"学生端安装包已签名（如未签名请自签），避免杀软误注入"},{"code":"E0601","category":"后台","desc":"管理员登录被锁定 30 分钟","causes":["连续密码错误超阈值"],"steps":["1. 等 30 分钟自然解锁","2. 超管自己也被锁 → 服务器执行 npm run reset:admin 重置密码","3. 或 DB 直接 UPDATE admins SET fail_count=0, locked_until=0 WHERE username='admin'"],"fix":"启用两步验证 + IP 白名单避免暴力破解"},{"code":"E0602","category":"后台","desc":"指令下发全超时","causes":["学生端未在线","消息体过大","防火墙拦截下行"],"steps":["1. Admin 设备管理看目标是否在线","2. 不要在 params 塞 >1MB 的二进制","3. 检查服务器 9090 出站网络"],"fix":"下线设备指令会暂存离线队列，下次上线自动重放"}]}