feat: 问题数据迁移到数据库;学员详情页URL导航改造;侧边栏统一

- 问题从文件系统迁移到数据库 problems 表
- 移除 PROBLEMS_DIR 配置和文件读取逻辑
- student.html 完整重写:编辑/添加/删除问题,生成方案进度显示
- 学员详情页支持独立URL访问 (/student/<id>)
- 统一侧边栏到 base.html
- 更新文档:DEPLOYMENT_SOP, MODELS, STRUCTURE, FRONTEND_ARCH
- 部署到生产环境 v1.2.0
This commit is contained in:
hmo
2026-04-23 06:35:32 +08:00
parent fd593bddf4
commit 18351212e8
18 changed files with 857 additions and 488 deletions
+60 -44
View File
@@ -1,7 +1,7 @@
# 钢琴练习方案系统 - 部署 SOP
> 版本:v1.1
> 日期:2026-04-21
> 版本:v1.2
> 日期:2026-04-23
> 核心原则:**不删除,只备份后新增/替换**
---
@@ -46,11 +46,12 @@
| 类型 | 源 | 容器内 | 说明 |
|------|-----|--------|------|
| Bind Mount | `/opt/piano-plan/个性化方案` | `/app/个性化方案` | 问题文件(15个md |
| Volume | `piano-plan-data` | `/app/data` | SQLite 数据库 |
| Volume | `piano-plan-output` | `/app/output` | PDF 输出 |
| Bind Mount | `/opt/piano-plan/config` | `/app/config` | API 配置 |
> ⚠️ **已移除**`/opt/piano-plan/个性化方案` 挂载点(问题文件已迁移到数据库 `problems` 表)
---
## 三、部署步骤
@@ -81,22 +82,18 @@ docker save piano-plan:latest -o piano-plan.tar
scp -i ~/.ssh/id_rsa piano-plan.tar root@47.106.65.108:/opt/piano-plan/
```
### 3.3 服务器部署(使用脚本!)
### 3.3 服务器部署
```bash
# 7. SSH 到服务器
ssh -i ~/.ssh/id_rsa root@47.106.65.108
# 8. 使用自动化部署脚本(会自动完成所有步骤并验证)
bash /path/to/deploy.sh /opt/piano-plan/piano-plan.tar
# 8. 创建带时间戳的备份目录
mkdir -p /opt/piano-plan/backups/backup_$(date +%Y%m%d)
# 或者手动部署(不推荐):
# 8a. 确认当前容器挂载配置
docker inspect piano-plan --format '{{json .Mounts}}'
# 9. 创建备份
mkdir -p /opt/piano-plan/backups
docker cp piano-plan:/app/data/piano_plans.db /opt/piano-plan/backups/piano_plans.db.bak
# 9. 备份当前数据库和配置
docker cp piano-plan:/app/data/piano_plans.db /opt/piano-plan/backups/backup_$(date +%Y%m%d)/
cp /opt/piano-plan/config/api_config.json /opt/piano-plan/backups/backup_$(date +%Y%m%d)/
# 10. 停止旧容器
docker stop piano-plan
@@ -105,38 +102,52 @@ docker rm piano-plan
# 11. 加载新镜像
docker load -i /opt/piano-plan/piano-plan.tar
# 12. 启动新容器(挂载配置必须完全正确!)
# 12. 启动新容器(无个性化方案挂载!)
docker run -d \
--name piano-plan \
-p 5001:5001 \
--restart unless-stopped \
-e FLASK_ENV=production \
-v /opt/piano-plan/个性化方案:/app/个性化方案 \
-v piano-plan-data:/app/data \
-v piano-plan-output:/app/output \
-v /opt/piano-plan/config:/app/config \
piano-plan:latest
```
### 3.4 验证
### 3.4 数据同步(特殊情况下从开发环境覆盖生产数据库)
> ⚠️ **警告**:这是**特殊处理**,仅在开发环境和生产环境数据结构需要统一时执行。正常部署不应覆盖生产数据库。
```bash
# 13. 检查容器状态
# 13. 停止容器
docker stop piano-plan
# 14. 上传开发环境数据库到服务器(在本地执行)
scp -i ~/.ssh/id_rsa data/piano_plans.db root@47.106.65.108:/opt/piano-plan/backups/
# 15. 覆盖生产数据库
docker cp /opt/piano-plan/backups/piano_plans.db piano-plan:/app/data/piano_plans.db
# 16. 重启容器
docker start piano-plan
```
### 3.5 验证
```bash
# 17. 检查容器状态
docker ps --filter name=piano-plan
# 14. 检查日志
# 18. 检查日志
docker logs piano-plan --tail 20
# 15. 验证服务
# 19. 验证服务
curl -I http://localhost:5001/
# 16. 验证问题文件(应该看到15个md文件)
docker exec piano-plan ls /app/个性化方案/
# 20. 验证数据库表
docker exec piano-plan ls /app/data/
# 17. 验证数据库(应该看到 templates 表)
docker exec piano-plan python -c "import sqlite3; conn=sqlite3.connect('/app/data/piano_plans.db'); print([r[0] for r in conn.execute('SELECT name FROM sqlite_master WHERE type=\"table\"')])"
# 18. 验证 API 配置
# 21. 验证 API 配置
docker exec piano-plan cat /app/config/api_config.json
```
@@ -152,7 +163,7 @@ docker exec piano-plan cat /app/config/api_config.json
| 学员数据 | piano-plan-data:/app/data | students, student_problems 表 |
| 班级数据 | piano-plan-data:/app/data | classes 表 |
| 练习方案 | piano-plan-data:/app/data | practice_plans 表 |
| 问题文件 | /opt/piano-plan/个性化方案 | 15个md文件 |
| 问题数据 | piano-plan-data:/app/data | problems 表(已从文件迁移到数据库) |
### 4.2 新增/更新的数据
@@ -221,32 +232,40 @@ ssh -i ~/.ssh/id_rsa root@47.106.65.108 "docker cp /tmp/update_templates.py pian
## 五、回滚流程
### 5.1 快速回滚(推荐)
### 5.1 从备份恢复数据库
```bash
# 停止当前容器
# 停止容器
docker stop piano-plan
# 从备份目录恢复(替换日期)
docker cp /opt/piano-plan/backups/backup_20260423/piano_plans.db piano-plan:/app/data/piano_plans.db
# 重启容器
docker start piano-plan
```
### 5.2 完整回滚(恢复旧镜像+数据库)
```bash
# 停止并删除当前容器
docker stop piano-plan
docker rm piano-plan
# 使用旧镜像重新启动(如果镜像还在)
# 使用旧镜像重新启动(如果镜像还在本地
docker run -d \
--name piano-plan \
-p 5001:5001 \
--restart unless-stopped \
-e FLASK_ENV=production \
-v /opt/piano-plan/个性化方案:/app/个性化方案 \
-v piano-plan-data:/app/data \
-v piano-plan-output:/app/output \
-v /opt/piano-plan/config:/app/config \
piano-plan:latest
```
### 5.2 从备份恢复
```bash
# 恢复数据库
# 从备份恢复数据库
docker stop piano-plan
cp /opt/piano-plan/backups/piano_plans.db.bak /var/lib/docker/volumes/piano-plan-data/_data/piano_plans.db
docker cp /opt/piano-plan/backups/backup_YYYYMMDD/piano_plans.db piano-plan:/app/data/piano_plans.db
docker start piano-plan
```
@@ -275,9 +294,10 @@ docker start piano-plan
| 源 | 容器内路径 | 说明 |
|-----|------------|------|
| /opt/piano-plan/个性化方案 | /app/个性化方案 | 问题文件 |
| /opt/piano-plan/config | /app/config | API 配置 |
> ⚠️ **已移除**`/opt/piano-plan/个性化方案` 挂载(问题文件已迁移到数据库)
---
## 七、API 配置说明
@@ -300,9 +320,6 @@ docker start piano-plan
## 八、常见问题
### Q: 部署后问题文件看不到?
A: 检查挂载 `/opt/piano-plan/个性化方案:/app/个性化方案` 是否正确
### Q: 数据库是空的?
A: 检查 volume `piano-plan-data` 是否被错误覆盖,尝试从备份恢复
@@ -335,8 +352,7 @@ location /api/generate-plan {
```
[ ] 容器状态:running
[ ] 服务响应:HTTP 200/302
[ ] 问题文件数量:15个 md 文件
[ ] 数据库记录:users, students, classes, student_problems, practice_plans 完整
[ ] 数据库记录:users, students, classes, student_problems, practice_plans, problems 完整
[ ] templates 表存在且包含 AI提示词模板、报告导出模板
[ ] API 配置:provider, model, api_key 正确
[ ] 功能验证:能生成练习方案
@@ -344,5 +360,5 @@ location /api/generate-plan {
---
> **最后更新**2026-04-21
> **更新原因**更新部署流程,添加数据保护规范,明确挂载点配置;添加 SSE 问题排查
> **最后更新**2026-04-23
> **更新原因**v1.2 部署更新;移除个性化方案挂载(问题已迁移到数据库);更新备份和回滚流程