340 lines
22 KiB
Markdown
340 lines
22 KiB
Markdown
# 数学学习系统(前后端分离版)
|
||
|
||
把原单文件静态页 `math_learning_dashboard_v3.html` 重构为可运行的前后端分离系统,
|
||
前端采用 Ant Design,包含用户体系与标准 RBAC。
|
||
页面结构、题库与学习流程在此基础上重设计:知识点以“初等/高等数学知识图谱”
|
||
为全局地基,章节与题目通过关系表挂到图谱节点,不再使用文本标签匹配。
|
||
学习状态从浏览器 localStorage 改为 SQLite 持久化;教材目录以
|
||
《盖尔范德中学生数学思维丛书》为基础,并支持大模型配置与按章节生成题目。
|
||
|
||
## 技术栈
|
||
|
||
- 后端:FastAPI + SQLAlchemy + SQLite
|
||
- 前端:React + TypeScript + Vite + Ant Design
|
||
- 公式渲染:KaTeX(支持 `$...$` / `$$...$$` 与 Markdown 插图)
|
||
- 认证:JWT(HS256)+ PBKDF2 密码散列
|
||
- RBAC:user / role / user_role / permission / role_permission
|
||
- 部署:支持本机直接运行或 `docker compose`
|
||
|
||
## 目录结构
|
||
|
||
```text
|
||
nex_math/
|
||
├── backend/ # FastAPI 应用
|
||
│ ├── main.py # 入口(CORS、路由注册)
|
||
│ ├── database.py # SQLite 连接与默认库路径
|
||
│ ├── models/ # ORM:教材 / 章节 / 知识点 / 题目 / 记录 / 错题 / 模型配置
|
||
│ ├── schemas/ # Pydantic 请求响应模型
|
||
│ ├── routers/ # overview / practice / data / analytics / archive / catalog / question-bank / llm
|
||
│ ├── services/ # llm_client / question_generator / ai_teacher / question_engine / mastery_engine / recommendation
|
||
│ ├── seed/ # 目录与题库种子数据
|
||
│ └── dbtool.py # 数据库备份 / 恢复 / 内容快照(python -m dbtool)
|
||
├── frontend/ # Vite + React 前端
|
||
│ └── src/
|
||
│ ├── pages/ # 学习端 9 个页面 + 管理端页面 + 登录 / 电子书阅读器
|
||
│ ├── components/ # SplitView / Pane(分屏工作台)、Paper(答题卡·题块·解析)、
|
||
│ │ # PaperReview(整卷回看)、useApi、ui.tsx 等
|
||
│ ├── api/ # API 客户端
|
||
│ ├── theme.ts # 设计令牌:标签色 / 状态色 / 掌握度色
|
||
│ ├── i18n.ts # 中英双语文案(新增键必须 zh、en 同时补)
|
||
│ └── types/
|
||
├── data/ # math.db(本机库,被 gitignore)
|
||
│ ├── ebooks/ # 教材电子书(随仓库提交)
|
||
│ ├── backups/ # db.sh backup 生成的时间戳备份(gitignore)
|
||
│ └── dump/ # catalog.sql:内容快照,提交进仓库=远端存了一份库
|
||
└── scripts/ # init.sh(建环境)/ start.sh(起服务)/ db.sh(备份与恢复)
|
||
```
|
||
|
||
## 界面与导航
|
||
|
||
- 左侧菜单栏支持**展开 / 收拢**两种模式:底部“收拢菜单”按钮或顶栏折叠按钮
|
||
一键切换,偏好写入 localStorage 下次进入自动恢复;收拢态只显示图标,
|
||
悬停出现文字提示,功能分组以分隔线保留。
|
||
- 窄屏(<768px)自动切换为覆盖式抽屉导航,顶栏汉堡按钮开合,不再挤压内容区。
|
||
- 顶栏统一展示“分区 · 页面说明”、角色标识与头像菜单(设置 / 退出登录),
|
||
与侧栏底部用户卡片入口一致。
|
||
- 全站样式与控件收敛到三层:**theme.ts(设计令牌)→ ui.tsx(Page / Panel /
|
||
Toolbar / DataTable / RowActions / MetricGrid / CountTag / EmptyState 等)
|
||
→ 页面**,新页面只组合统一控件,不各写一套尺寸与颜色。
|
||
- **题库管理 / 练习记录 / 错题本 / 章节测试采用「清单 + 试卷」分屏工作台**
|
||
(`components/SplitView.tsx` + `Pane`):一栏是可搜索的清单,另一栏按真实试卷版式
|
||
排题目;两栏各自独立滚动,清单不会把试卷顶走,整页不再是一条长滚动条。
|
||
- 题库管理:左「教材→章节」树 + 搜索/难度/来源/使用状态筛选,右栏题目预览卷;
|
||
侧栏首行显示题库总数,并提示还有多少题没挂到章节(计数来自 `/api/question-bank/summary`)。
|
||
- 练习记录:左练习清单(得分进度条 + 错题数徽标),右该次练习的完整试卷回看,
|
||
顶部答题卡按题号标色(正确 / 错误 / 未答),点题号跳题,可切「全部 / 只看错题」与「展开全部解析」。
|
||
- 错题本:左错题清单(按知识点筛选、搜索题干),右错题精讲,逐题对照
|
||
我的作答 / 正确答案 / 解析,底部上一题、下一题翻页。
|
||
- 章节测试:试卷在左,答题卡与本次小结在右,答题中随时点题号跳题、查看已答未答;
|
||
交卷后同一套布局直接变成判卷结果。
|
||
- 中缝可拖拽调节清单栏宽度(248–560px),偏好写入 localStorage
|
||
(`nex_math.split.<bank|records|errors|test>.aside`);窄屏(<992px)自动改为上下堆叠。
|
||
- 章节测试按章节组卷,前置条件是**教材有章节目录、章节下挂了题目**。缺任何一步都只给
|
||
引导空态,不会变成红色报错,也不会写出 0 题的记录:
|
||
- 教材还没有章节 → 提示请管理员在「教材管理」中添加教材、整理章节目录;
|
||
- 选了还没挂题的章节 → 组出的是空卷,试卷位置显示「请管理员在题库管理里把题目关联到
|
||
本章」,答题卡提示本章暂无题目,提交按钮禁用;
|
||
- 章节题量不足 5 题时,组卷条件那行挂黄色徽标提示实际题量。
|
||
|
||
## 快速开始(本机)
|
||
|
||
要求:
|
||
|
||
- Python 3.10+。macOS 自带的 `python3` 往往是 3.9,`init.sh` 会自动改找
|
||
`python3.13 / 3.12 / 3.11 / 3.10`;最省事的做法是先装
|
||
[uv](https://docs.astral.sh/uv/)(脚本会在 `PATH`、`~/.local/bin`、`~/.cargo/bin` 里找它,
|
||
并用它拉一个 CPython 3.12),或 `brew install python@3.12`。
|
||
- Node.js 20.19+ / 22.12+(Vite 8 的要求;本机 `node -v` 低于 20 时脚本会给出提示)。
|
||
|
||
```bash
|
||
./scripts/init.sh # 创建虚拟环境、安装依赖、写入种子数据
|
||
./scripts/start.sh # 同时启动后端 :8000 与前端 :5173
|
||
```
|
||
|
||
打开 http://localhost:5173。
|
||
|
||
- `init.sh` 可重复执行:虚拟环境已存在就复用,已有 `data/math.db` 就不重写种子数据。
|
||
- 依赖装不上时会自动改用国内镜像重试(pip → 清华源,npm → npmmirror);
|
||
也可以显式指定:`PIP_INDEX_URL=… NPM_REGISTRY=… ./scripts/init.sh`;
|
||
只想准备后端环境用 `./scripts/init.sh --no-web`。
|
||
- `start.sh` 启动前会检查 8000 / 5173 是否被占用并直接告诉你是哪个进程,
|
||
换端口:`BACKEND_PORT=8010 FRONTEND_PORT=5180 ./scripts/start.sh`。
|
||
|
||
默认账号:
|
||
|
||
| 账号 | 密码 | 角色 | 说明 |
|
||
| --- | --- | --- | --- |
|
||
| admin | admin123 | 管理员 | 用户、模型、教材课程、题库管理 |
|
||
| student | student123 | 普通用户 | 学习总览、练习、错题、分析等 |
|
||
|
||
首次登录后请通过左侧栏底部用户卡片的“个人设置”修改默认密码,
|
||
并在生产环境设置 JWT_SECRET(环境变量)。管理员可在“模型配置”维护多通道模型。
|
||
管理员是纯管理账号:不创建学习档案,学习总览/知识地图等学习功能不展示,
|
||
学习类接口对管理员返回无权限。
|
||
|
||
## 快速开始(Docker)
|
||
|
||
```bash
|
||
docker compose up --build
|
||
```
|
||
|
||
前端 http://localhost:5173,后端文档 http://localhost:8000/docs。
|
||
数据库会以卷形式挂载在宿主机的 `./data/math.db`。
|
||
|
||
## 热加载
|
||
|
||
- 前端:Vite 开发服务器自带 HMR,保存代码页面即时更新;
|
||
- 后端:`./scripts/start.sh` 与 `docker compose` 均以
|
||
`uvicorn --reload` 启动,Python 代码变更自动重载。
|
||
|
||
## 功能对照
|
||
|
||
| 静态版模块 | 新系统位置 | 说明 |
|
||
| --- | --- | --- |
|
||
| 学习总览 | `/` 学习总览 | 指标卡 + 掌握度 + 推荐计划 |
|
||
| 知识地图 | 知识地图 | 知识点掌握度;点击卡片查看定义、掌握度、相关知识点,以及讲了它的教材章节与视频课程(可一键进入本章测试) |
|
||
| 章节测试 | 章节测试 | 选书→选章→按掌握度动态抽取 5 题,可“换一套”;唯一的组卷与练习入口。试卷 + 右侧答题卡分屏,需要教材已有章节目录 |
|
||
| 错题本 | 错题本 | 左清单 + 右错题精讲分屏:逐题对照我的作答、正确答案与解析,可按知识点筛选 |
|
||
| 练习记录 | 练习记录 | 左清单 + 右整卷回看:答题卡跳题、只看错题、展开全部解析 |
|
||
| 今日任务 | 今日任务 | 推荐今日章节 → 做章节测试 → 对章节提交掌握反馈 |
|
||
| 学习分析 | 学习分析 | 正确率、错题、诊断排序 |
|
||
| 导出 / 导入档案 | 个人设置 → 学习档案 | `/api/archive/export`、`/api/archive/import` |
|
||
| 教材 / 课程 | 教材 / 课程 | 盖尔范德丛书书目(ISBN)+ 在线课程链接 |
|
||
| 教材详情 | 点击教材卡片 | 查看章节目录、每章知识点、题目数量并直接开始本章测试 |
|
||
| 题库管理 | 题库管理 | 左章节树 + 筛选、右题目预览卷的分屏;编辑删除题目,按教材章节调用模型生成 |
|
||
| 模型配置 | 模型配置 | 多通道模型配置、通道命名、默认通道与连通测试 |
|
||
| 用户管理 | 用户管理(管理员) | 创建用户、启停账号、切换角色、重置密码 |
|
||
| 个人设置 | 左侧栏底部用户卡片 → 个人设置(主内容区整页) | 修改昵称/密码,导出与导入学习档案 |
|
||
| 教材课程管理 | 教材课程管理(管理员) | 教材/课程维护;章节可新增/编辑/删除,也可按教材 AI 自动生成目录,章节可直接跳转到对应题库 |
|
||
| 题库生成 | 题库管理 | 先选教材,再选章节与数量,按章节调用大模型生成新题 |
|
||
|
||
学习数据(掌握度、练习记录、错题、每日完成)按用户隔离,同一账号的数据互相独立。
|
||
练习提交时会保存每题题目快照与作答(错误选项、正确答案、解析),因此题库后续
|
||
删题也不影响错题本与练习记录的逐题回看;所有明细均归属当前用户,用户之间不可见。
|
||
|
||
## RBAC 权限
|
||
|
||
| 权限码 | 说明 | 管理员 | 普通用户 |
|
||
| --- | --- | --- | --- |
|
||
| learning:use | 学习总览/练习/错题/分析/档案 | ✘ | ✔ |
|
||
| users:manage | 用户管理 | ✔ | ✘ |
|
||
| llm:manage | 模型配置 | ✔ | ✘ |
|
||
| catalog:manage | 教材/课程管理 | ✔ | ✘ |
|
||
| question-bank:manage | 题库管理与生成 | ✔ | ✘ |
|
||
| knowledge:manage | 知识图谱管理 | ✔ | ✘ |
|
||
|
||
除登录、健康检查外,所有 `/api/*` 接口都要求 `Authorization: Bearer <token>`;
|
||
管理接口在后端通过权限依赖二次校验(`backend/dependencies.py`)。
|
||
|
||
知识点状态由掌握度自动计算:`≥85 已掌握`、`75–84 基本掌握`、`60–74 待加强`、`<60 重点`。
|
||
|
||
## 教材目录
|
||
|
||
当前教材基线为《盖尔范德中学生数学思维丛书》(中国科学技术大学出版社):
|
||
|
||
| 分册 | ISBN |
|
||
| --- | --- |
|
||
| 函数和图像(主教材,已上传 PDF 电子书) | 978-7-312-05005-3 |
|
||
| 代数 | 978-7-312-04893-7 |
|
||
| 三角函数(已上传 PDF) | 978-7-312-04695-7 |
|
||
| 坐标方法 | 978-7-312-05006-0 |
|
||
| 几何 | 978-7-312-05779-3 |
|
||
|
||
**有正式目录的书,章节由种子预置**:`seed/catalog.py` 里 `OFFICIAL_*_CHAPTERS`
|
||
是核对过原书的正式目录,按 ISBN 绑到 `CATALOG[*].chapters`,`python -m seed`
|
||
与后端启动都会幂等地补齐章节,并按 `KNOWLEDGE_CHAPTER_MAP` /
|
||
`DEFAULT_CHAPTER_KNOWLEDGE` 把演示题与知识点挂上去(只补空,不覆盖人工改动)。
|
||
目前已落地:函数和图像 8 章、三角函数 10 章、坐标方法 7 章、几何 4 章。
|
||
|
||
**没有正式目录的书不由种子编造**(代数、普林斯顿微积分读本、柯西-施瓦茨大师课)。
|
||
管理员在「教材 / 课程」打开某本教材的章节面板后,有三种方式:
|
||
|
||
1. 「添加章节」手动逐条录入名称与内容提示;
|
||
2. 「AI 整理章节」:把书的目录原文(版权页/目录页文字,或在别处查到的正式目录)粘进
|
||
「目录参考数据」,任务在后台解析目录并为每章挂上知识图谱节点;模型只做整理,
|
||
不新增、不补造素材里没有的章节;
|
||
3. 纯接口方式 `POST /api/textbooks/{id}/chapters/generate`:先按 ISBN 查 Open Library /
|
||
Google Books 的正式目录,再让模型按正式目录还原,查不到且模型没把握时直接拒绝写入。
|
||
|
||
确认无误的正式目录也可以回填到 `backend/seed/catalog.py` 的
|
||
`OFFICIAL_*_CHAPTERS` / `CATALOG[*].chapters`,再执行
|
||
`cd backend && .venv/bin/python -m seed`(幂等:只补缺,不覆盖界面上的修改,也不清空学习记录),
|
||
这样换机器或库丢了都能一并重建。
|
||
|
||
> 种子题库的 18 道演示题会按知识点自动挂到《函数和图像》的章节下(当前:引言 3 题、
|
||
> 第6章 幂函数 15 题),所以「章节测试」开箱就能组卷;管理员手工改过的章节归属不会被覆盖。
|
||
|
||
## 模型配置与题目生成
|
||
|
||
1. 打开“模型配置”→“新增通道”,选择 OpenAI / DeepSeek / 阿里千问(百炼)/
|
||
OpenAI 兼容;通道名称建议按“服务商 · 模型”填写(例如“阿里千问 · qwen-plus”),
|
||
系统会随服务商选择自动带出默认 Base URL 与模型名。
|
||
2. 填写 API Key 并点击该通道的“测试”;Key 仅保存在本地 `data/math.db`,
|
||
回显只显示末四位。可新增多个通道并用“设为默认”指定生成题目时使用的通道。
|
||
3. 打开“题库管理”,选择教材、章节、数量、难度、该章节知识点(可多选)与
|
||
生成使用的模型通道(默认取“默认通道”),
|
||
点击“开始生成”。返回结果会做 JSON 结构校验(4 个选项、唯一答案、非空题干)后
|
||
入库并挂到所选教材章节下,可在该章“章节测试”中直接使用;题库页支持筛选与删除。
|
||
|
||
大模型调用统一走 OpenAI Chat Completions 协议(`services/llm_client.py`),
|
||
不需要额外 SDK;生成的题若带新知识点,首次作答会自动建立该知识点并参与掌握度计算。
|
||
生成提示词要求模型把数学公式写成 LaTeX(`$...$` 或 `$$...$$`)、插图写成
|
||
``;题库、练习、错题本与练习记录中的题目内容均由前端 KaTeX
|
||
渲染公式并展示图片。
|
||
|
||
### 教材章节目录的整理与题库跳转
|
||
|
||
在「教材 / 课程」中打开某本教材的章节面板后:
|
||
|
||
1. 「添加章节」逐个录入名称与内容提示;
|
||
2. 面板右上角的「AI 整理章节」:选模型通道,把该书目录原文粘进「目录参考数据」,
|
||
点「开始整理」。任务在后台执行并显示进度,模型只整理素材里真实出现的目录条目
|
||
(不新增、不凭印象补造),同时为每章从知识图谱挑选知识点;与已有章节同名的条目自动跳过,
|
||
入库后仍可编辑或删除;
|
||
3. 每个章节行都有「题库」入口,点击后跳转到题库管理并自动筛选该书与章节,
|
||
可以在那里直接按章节生成新题,或把已有的未挂章节题目编辑到该章下。
|
||
|
||
题库管理每道题会标注“使用状态”(已使用次数 / 未使用)。使用过的题目和被
|
||
章节挂载的题目不允许删除,只能编辑;题目编辑会保留历史答题快照。
|
||
|
||
### AI 出题配图机制(自动生成,不使用图库/上传)
|
||
|
||
生成新题弹窗中有一个“需要配图(AI 根据题目自动生成图像)”开关:
|
||
|
||
- 不勾选:题目正常生成,不携带图像;
|
||
- 勾选后:提示词要求模型为这道题生成与题目语义一致的原创 SVG(函数图/几何示意图,
|
||
含坐标轴与关键标注),模型把它放在 JSON 的 `image_svg` 字段;
|
||
- 后端把每张 SVG 独立保存为 `/api/question-images/generated_*.svg` 并自动写入题干,
|
||
因此每道题都有自己独立的图,互不共享。
|
||
|
||
### 知识点与章节、多知识点
|
||
|
||
- 每个章节可维护多个“本章知识点”(教材课程管理 → 章节 → 编辑);
|
||
- 生成新题先选教材和章节后,知识点下拉自动展示该章节的知识点,可多选;
|
||
- 题目支持多个知识点:列表、练习记录、错题、掌握度与推荐都会按全部知识点统计;
|
||
- 练习提交时如果出现未见过的新知识点,会自动为用户建立并参与掌握度计算。
|
||
|
||
## 主要 API
|
||
|
||
所有接口前缀 `/api`,交互文档见 http://localhost:8000/docs。
|
||
|
||
| 方法 | 路径 | 说明 |
|
||
| --- | --- | --- |
|
||
| GET | `/overview` | 学习总览指标与推荐计划 |
|
||
| GET | `/knowledge` | 知识点掌握度 |
|
||
| GET | `/knowledge/detail/{id}` | 知识点详情:定义、相关知识点、关联章节与视频资源 |
|
||
| POST/DELETE | `/knowledge/nodes/{id}/resources`、`/knowledge/resources/{id}` | 知识点关联视频/课程(管理员) |
|
||
| GET | `/practice/chapter/{id}` | 章节测试组卷(不含答案) |
|
||
| POST | `/practice/submit` | 提交答案并判分、更新掌握度与错题 |
|
||
| GET/POST | `/daily`、`/daily/complete` | 今日完成状态 |
|
||
| GET | `/errors`、`/records`、`/records/{id}`、`/analytics` | 错题(含逐题详情)、记录、记录详情、分析 |
|
||
| GET/POST | `/archive/export`、`/archive/import` | 学习档案导出 / 恢复 |
|
||
| GET | `/textbooks` | 教材/课程目录(含章节,登录可用) |
|
||
| POST/PUT/DELETE | `/textbooks` 与 `/textbooks/{id}` | 教材/课程增删改(管理员) |
|
||
| POST/PUT/DELETE | `/textbooks/.../chapters` | 章节管理(管理员) |
|
||
| POST | `/textbooks/{id}/chapters/generate` | 按教材 AI 生成章节(管理员) |
|
||
| GET | `/question-bank/summary` | 题库侧栏计数:总数 / 未挂章节 / AI 生成 / 已使用(管理员) |
|
||
| GET/POST/PUT/DELETE | `/question-bank/questions`、`…/generate` | 题库管理:列表/生成/编辑/删除(管理员),已使用题禁止删除 |
|
||
| GET | `/llm/settings` | 模型通道列表与服务商预设(管理员) |
|
||
| POST/PUT/DELETE | `/llm/channels` 与 `/llm/channels/{id}` | 模型通道增删改(管理员) |
|
||
| PUT | `/llm/channels/{id}/default` | 设置默认通道(管理员) |
|
||
| POST | `/llm/channels/{id}/test`、`/llm/test` | 通道连通测试(管理员) |
|
||
| PUT | `/auth/profile` | 修改自己的用户昵称 |
|
||
| POST | `/auth/login`、`/auth/change-password` | 登录、修改自己的密码 |
|
||
| GET | `/auth/me` | 当前用户与角色 |
|
||
| GET/POST/PUT | `/users`、`/users/{id}`、`/users/roles` | 用户管理(管理员) |
|
||
|
||
## 配置
|
||
|
||
复制 `.env.example` 并按需修改(本机直接运行时使用环境变量):
|
||
|
||
- `DATABASE_URL`:留空默认使用 `<项目根>/data/math.db`
|
||
- `CORS_ORIGINS`:允许访问的前端地址
|
||
- `OPENAI_API_KEY`:可选。数据库还没有任何模型通道时,启动会自动创建
|
||
“OpenAI · gpt-4o-mini”默认通道并使用该 Key;
|
||
`ai_teacher.py` 的逐题讲解仍为本地规则实现
|
||
- `JWT_SECRET`:JWT 签名密钥,生产环境必须设置
|
||
|
||
## 重置演示数据
|
||
|
||
```bash
|
||
cd backend
|
||
.venv/bin/python -m seed --force
|
||
```
|
||
|
||
会清空全部用户的学习数据与题库(含 AI 生成题)并重新写入种子数据;
|
||
用户、角色、教材目录与模型配置保留。演示账号的学习历史(练习记录、错题本)
|
||
现在包含逐题明细,可直接展开查看每题作答。
|
||
|
||
`--force` 执行前会自动把当前库备份到 `data/backups/`(打印路径),误操作可用
|
||
`./scripts/db.sh restore` 回退。
|
||
|
||
## 数据备份与恢复
|
||
|
||
`data/*.db` 在 `.gitignore` 里,仓库只有代码和电子书,**数据库文件从来没有进过远端**:
|
||
库一旦被重置,章节、题目这些内容就跟着没了。为此有两层保险:
|
||
|
||
```bash
|
||
./scripts/db.sh path # 数据库文件位置
|
||
./scripts/db.sh backup 升级前 # 时间戳备份(用 SQLite backup API,服务在写也安全)
|
||
./scripts/db.sh list # 本机备份列表(默认保留最近 20 份)
|
||
./scripts/db.sh restore [文件|latest] # 回滚;覆盖前先把当前库再备份一份
|
||
./scripts/db.sh dump # 导出 data/dump/catalog.sql(内容快照,建议随改动提交)
|
||
./scripts/db.sh load # 把 data/dump/catalog.sql 灌回当前库
|
||
./scripts/db.sh dump data/dump/full.sql --full # 整库快照(含账号/答题记录)提交进仓库
|
||
./scripts/db.sh load data/dump/full.sql # 新机器上整库还原
|
||
```
|
||
|
||
* `dump` 只导**内容**:教材、章节、知识点与关联、课程、题库。
|
||
这份文本提交进 git,远端仓库里就始终有一份可恢复的数据库快照。
|
||
* 默认 `dump` 不含账号与学习数据。希望远端也能整库还原时,显式给输出路径,把全量快照
|
||
提交进仓库:`./scripts/db.sh dump data/dump/full.sql --full`(含密码散列、答题记录、
|
||
错题本;**不含 `llm_settings`,API Key 不会进 git**)。不想让个人数据上远端就删掉这份文件。
|
||
不带输出路径的 `dump --full` 只写本机 `data/backups/math.full.sql`。
|
||
* 新机器上的恢复顺序:`./scripts/init.sh`(建库 + 种子)→ `./scripts/db.sh load`(内容)
|
||
或 `./scripts/db.sh load data/dump/full.sql`(整库)→ 重启后端。
|
||
* 想确认远端有没有库快照:`git log --oneline -- data/dump` 有记录才说明推上去了。
|
||
* 电子书与库分离:`data/ebooks/` 随仓库提交,库只存文件名。
|
||
若库丢了,`seed/ebooks.py` 会按「大小 + SHA-256」认领磁盘上的已知电子书
|
||
(`KNOWN_EBOOKS`),重建教材条目并把文件挪回该书目录,不必重新上传。
|