# 新时空教务管家 这是一个面向新时空教务业务的综合管理系统。迁移后 VPS 是正式业务数据主机,负责保存 `classnotes.txt`、`学生课时账户.md`、课程小结库、审核任务和操作记录;本机只保留微信群聊天记录采集/识别,并把课程小结批量推送到 VPS。 ## 目录 - `app/`:FastAPI 后端和内置前端页面。 - `MAINTENANCE.md`:日常检查、部署、数据保护和回滚流程。 - `Makefile`:常用维护命令入口。 - `scripts/deploy_to_vps.py`:部署教务管家服务到 VPS。 - `scripts/import_course_summaries.py`:一次性导入历史课程小结 Markdown。 - `scripts/sync_to_vps.py`:旧版正式数据同步脚本,迁移后不要继续常驻运行。 - `scripts/smoke_test.js`:轻量前端行为烟测。 - `scripts/install_gitea_backup_hook.py`:安装提交后自动推送到 Gitea 的 Git hook。 - `scripts/install_launch_agent.py`:安装 Mac 开机常驻同步任务。 - `launchd/com.xsk.records.sync.plist.template`:LaunchAgent 模板。 ## 首次部署 推荐先配置 SSH key。若临时使用密码,可通过环境变量传入,不要写入仓库文件。 ```bash cd /Users/yangdawei/Desktop/新时空业务源数据/tools/xsk-records-web XSK_USE_SSHPASS=1 \ XSK_SSH_PASSWORD='填写SSH密码' \ XSK_WEB_PASSWORD='填写网页访问密码' \ python3 scripts/deploy_to_vps.py --use-sshpass ``` 默认访问地址: ```text http://121.199.172.246:18080/ ``` 默认网页用户名为 `wolfydw`。网页密码只写入 VPS 的 `/root/新时空数据/app/.env`,不会提交进 Git。 如果 VPS 无法访问 Docker Hub,部署脚本会默认使用 `swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/library/python:3.12-slim` 作为基础镜像。需要更换时设置: ```bash XSK_PYTHON_IMAGE='python:3.12-slim' ``` ## 手动同步数据 迁移完成后不要再用本机 `classnotes.txt` 和 `学生课时账户.md` 覆盖 VPS。下面命令只保留给迁移前或灾难恢复时使用,日常新增课程小结应走 `POST /api/ingest/course-summaries`。 ```bash XSK_USE_SSHPASS=1 \ XSK_SSH_PASSWORD='填写SSH密码' \ python3 scripts/sync_to_vps.py --once --use-sshpass ``` 同步文件: - `/Users/yangdawei/Desktop/新时空业务源数据/新时空课程记录与课时账户/classnotes.txt` - `/Users/yangdawei/Desktop/新时空业务源数据/新时空课程记录与课时账户/学生课时账户.md` 远端数据目录: ```text /root/新时空数据/data/ ``` ## 课程小结推送 VPS 接收接口: ```text POST /api/ingest/course-summaries Header: X-INGEST-TOKEN: ``` 本机采集脚本默认在 `--write` 时推送到该接口。建议在本机 shell 配置: ```bash export XSK_INGEST_URL='http://121.199.172.246:18080/api/ingest/course-summaries' export XSK_INGEST_TOKEN='填写VPS里的INGEST_AUTH_TOKEN' ``` 然后运行: ```bash python3 /Users/yangdawei/Desktop/新时空业务源数据/新时空课程记录与课时账户/课程小结采集/批量采集微信课程小结.py --write ``` 推送成功批次会归档到本机 `课程小结采集/推送归档/`,失败批次会进入 `课程小结采集/推送失败队列/`,可用 `--retry-failed` 重试。需要临时恢复旧流程时再加 `--local-write`。 ## 历史小结导入 把本机历史课程小结目录同步或上传到 VPS 后,可在容器内执行一次性导入。历史导入只重建小结库和状态;历史 `classnotes缺失.txt` 默认转为审核任务,不自动扣课时。 ```bash cd /root/新时空数据/app docker compose exec xsk-records-web python scripts/import_course_summaries.py \ --source /data/import/课程小结采集 \ --target /data/course_summaries \ --state /data/course_summary_state.json \ --tasks /data/admin_tasks.json \ --operation-logs /data/operation_logs.jsonl \ --missing-table /data/import/课程小结采集/classnotes缺失.txt ``` ## 数据备份 通过登记 API、课程小结自动入账或审核批准修改正式课时数据时,服务会在写入前自动备份本次会改动的业务文件。正式数据和辅助状态位于: ```text /root/新时空数据/data/classnotes.txt /root/新时空数据/data/学生课时账户.md /root/新时空数据/data/course_summaries/ /root/新时空数据/data/course_summary_state.json /root/新时空数据/data/operation_logs.jsonl ``` 备份目录位于: ```text /root/新时空数据/data/backups/ ``` 每次登记生成一个事务备份目录,目录内包含变更前的业务文件副本和 `metadata.json`。系统自动保留最近 50 次备份,超过后删除最旧备份。 查看备份: ```bash ls -lt /root/新时空数据/data/backups/ ``` 恢复某次备份时,先停止服务,再把对应备份目录里的文件复制回数据目录,最后重启服务: ```bash cd /root/新时空数据/app docker compose stop cp /root/新时空数据/data/backups/<备份目录>/classnotes.txt /root/新时空数据/data/classnotes.txt 2>/dev/null || true cp /root/新时空数据/data/backups/<备份目录>/学生课时账户.md /root/新时空数据/data/学生课时账户.md 2>/dev/null || true docker compose up -d ``` ## 安装自动同步 ```bash XSK_USE_SSHPASS=1 \ XSK_SSH_PASSWORD='填写SSH密码' \ python3 scripts/install_launch_agent.py --use-sshpass ``` 日志位置: ```text ~/Library/Logs/xsk-records-web/sync.log ~/Library/Logs/xsk-records-web/sync.err.log ``` 查看任务: ```bash launchctl list | grep com.xsk.records.sync ``` 卸载任务: ```bash launchctl unload ~/Library/LaunchAgents/com.xsk.records.sync.plist rm ~/Library/LaunchAgents/com.xsk.records.sync.plist ``` ## 更换网页访问密码 登录 VPS 后修改 `/root/新时空数据/app/.env` 中的 `BASIC_AUTH_PASSWORD`,然后重启: ```bash cd /root/新时空数据/app docker compose up -d ``` 管理后台使用 `ADMIN_AUTH_PASSWORD`。为兼容旧部署,如果未配置 `ADMIN_AUTH_PASSWORD`,系统会继续使用原 `ACCOUNTS_AUTH_PASSWORD` 或 `ACCOUNT_AUTH_PASSWORD`。 ## API - `GET /api/health`:数据状态。 - `GET /api/records?q=王鑫鹏5月数学课`:自然语言查询上课记录。 - `GET /api/accounts`:课时账户列表。 - `GET /api/accounts?q=王鑫鹏`:按学生筛选账户。 - `GET /api/accounts?status=欠费`:按账户状态筛选。 - `GET /api/accounts/王鑫鹏`:单个学生账户。 - `POST /api/admin/accounts`:管理后台新增课时账户。 - `PUT /api/admin/accounts/{student_id}`:管理后台修改课时账户。 - `POST /api/corrections`:课程记录页提交纠错审核。 - `GET /api/admin/tasks`:管理后台查看审核任务。 - `POST /api/admin/tasks/{task_id}/approve`:批准纠错并写入正式上课记录。 - `POST /api/admin/tasks/{task_id}/reject`:驳回纠错。 - `POST /api/ingest/course-summaries`:本机采集脚本批量推送课程小结,使用 `X-INGEST-TOKEN` 鉴权。 - `GET /api/admin/course-summaries`:管理后台只读查询正式课程小结库。 - `GET /api/admin/operation-logs`:管理后台读取小结接收、自动入账、审核批准和驳回记录。