Files
xsk-education-management/app/README.md
T
2026-06-30 11:35:25 +08:00

251 lines
9.8 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 新时空教务管理系统
这是一个面向新时空教务业务的综合管理系统。迁移后 VPS 是正式业务数据主机,负责保存 SQLite 数据库 `/data/xsk_education.db`;本机只保留微信群聊天记录采集/识别,并把课程小结批量推送到 VPS。
## 目录
- `app/`:FastAPI 后端和内置前端页面。
- `MAINTENANCE.md`:日常检查、部署、数据保护和回滚流程。
- `Makefile`:常用维护命令入口。
- `scripts/deploy_to_vps.py`:部署新时空教务管理系统到 VPS。
- `scripts/migrate_text_to_sqlite.py`:一次性把旧纯文本、JSON、JSONL 和课程小结 Markdown 迁移进 SQLite。
- `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.education-management.sync.plist.template`LaunchAgent 模板。
## 维护入口
推荐在仓库根目录 `/root/新时空教务管理系统` 执行日常维护命令:
```bash
make check
make smoke
make deploy
```
根目录 `Makefile` 会自动转发到 `app/` 下的实际应用配置,避免在错误目录执行 `docker compose``make deploy`。需要直接运行 Docker Compose 时,使用:
```bash
docker compose -f app/docker-compose.yml <命令>
```
## 后端结构
- `app/main.py`:FastAPI 应用入口,只负责注册路由和全局异常处理。
- `app/routers/`:按业务入口拆分 API 和页面路由,包括登录页面、课程记录、学生档案、管理后台、课程小结推送和健康检查。
- `app/config.py`:路径、环境变量、Cookie 名称和进程内写锁。
- `app/auth.py`:网页登录、Basic Auth、管理后台和课程小结推送鉴权。
- `app/schemas.py`:请求体 Pydantic 模型。
- `app/api_utils.py`:API 层通用读取、文件元信息和请求体转换。
- `app/domain.py`:领域数据结构、学生/科目别名、状态和识别常量。
- `app/storage.py`:原子写入、权限继承和业务数据备份。
- `app/data.py`:业务数据解析、登记、审核、课程小结入库和查询逻辑。
## 首次部署
推荐先配置 SSH key。若临时使用密码,可通过环境变量传入,不要写入仓库文件。
```bash
cd /Users/yangdawei/Desktop/新时空业务源数据/tools/xsk-education-management
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。SQLite 数据库 `/data/xsk_education.db` 是唯一事实源;运行时生成的 `/data/runtime_text_cache/` 只是兼容旧业务逻辑的缓存。下面命令只保留给迁移前或灾难恢复时使用,日常新增课程小结应走 `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/xsk_education.db
```
## SQLite 迁移
首次迁移先 dry-run
```bash
cd /root/新时空教务管理系统
make migrate-sqlite-dry-run
```
确认严格校验通过后执行正式迁移:
```bash
make migrate-sqlite
```
正式迁移会生成:
```text
/root/新时空教务管理系统/data/xsk_education.db
/root/新时空教务管理系统/data/sqlite_migration_report_<时间>.json
/root/新时空教务管理系统/archives/text-source-before-sqlite-<时间>.tar.gz
/root/新时空教务管理系统/archives/text-source-before-sqlite-<时间>.tar.gz.sha256
```
学生表包含 `primary_entry_year` 字段,用于维护“小学一年级入学年份”。排课系统只读该字段并按课程日期动态推算年级。管理后台的学生档案编辑页可以维护该字段;运行时 `学生课时账户.md` 缓存会导出为 7 列格式,同时仍兼容旧 6 列缓存导入。
## 课程小结推送
VPS 接收接口:
```text
POST /api/ingest/course-summaries
Header: X-INGEST-TOKEN: <VPS .env 中的 INGEST_AUTH_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-education-management 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、课程小结自动入账或审核批准修改正式课时数据时,服务会以 SQLite 事务写入 `/data/xsk_education.db`。旧纯文本事实源已封存为归档包;运行时文本缓存位于:
```text
/root/新时空教务管理系统/data/runtime_text_cache/
```
备份目录位于:
```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-education-management/sync.log
~/Library/Logs/xsk-education-management/sync.err.log
```
查看任务:
```bash
launchctl list | grep com.xsk.education-management.sync
```
卸载任务:
```bash
launchctl unload ~/Library/LaunchAgents/com.xsk.education-management.sync.plist
rm ~/Library/LaunchAgents/com.xsk.education-management.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/students`:学生档案列表。
- `GET /api/students?q=王鑫鹏`:按学生姓名或学生ID筛选学生档案。
- `GET /api/students?status=欠费`:按档案状态筛选。
- `GET /api/students/王鑫鹏`:单个学生档案。
- `POST /api/admin/students`:管理后台新增学生档案。
- `PUT /api/admin/students/{student_id}`:管理后台修改学生档案。
- 学生档案的剩余课时由系统按缴费记录和上课记录自动计算,管理接口不会接受人工修改余额。
- `GET /api/admin/teachers`:管理后台读取老师档案。
- `POST /api/admin/teachers`:管理后台新增老师档案。
- `PUT /api/admin/teachers/{teacher_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`:管理后台读取小结接收、自动入账、审核批准和驳回记录。