feat: v1.4.0 - 典型方案采纳、推荐方案列表、审计字段、导航优化

- 添加典型方案采纳功能 (POST /api/plans/<id>/adopt)
- 添加推荐方案列表 (GET /api/students/<id>/recommended-plans)
- PracticePlan 新增 created_by/updated_by/updated_at 审计字段
- 方案编辑/详情页导航优化 (bfcache 处理、pageshow 事件)
- 方案列表支持删除功能
- 学员列表'暂无方案/问题'样式统一
- 更新文档:问题文件已废弃(迁移到数据库)
- 更新部署脚本和验证清单
This commit is contained in:
hmo
2026-04-27 02:01:22 +08:00
parent 6abdd49c04
commit e50a9207b4
20 changed files with 873 additions and 88 deletions
+9 -24
View File
@@ -1,14 +1,5 @@
#!/bin/bash
# 钢琴练习方案系统 - 自动化部署脚本
# 使用方法: ./deploy.sh <image-tar-path>
set -e # 任何命令失败就停止
if [ -z "$1" ]; then
echo "用法: $0 <image-tar-path>"
echo "示例: $0 /path/to/piano-plan.tar"
exit 1
fi
set -e
IMAGE_TAR="$1"
CONTAINER_NAME="piano-plan"
@@ -20,34 +11,30 @@ echo "=========================================="
echo "钢琴练习方案系统 - 部署脚本"
echo "=========================================="
# 1. 检查镜像文件是否存在
# 1. 检查镜像文件
if [ ! -f "$IMAGE_TAR" ]; then
echo "错误: 镜像文件不存在: $IMAGE_TAR"
exit 1
fi
# 2. 检查容器是否存在
if docker ps -a --format '{{.Names}}' | grep -q "^${CONTAINER_NAME}$"; then
echo "[2/7] 停止并删除旧容器..."
docker stop $CONTAINER_NAME > /dev/null 2>&1 || true
docker rm $CONTAINER_NAME > /dev/null 2>&1 || true
else
echo "[2/7] 容器不存在,跳过停止/删除"
fi
# 2. 停止并删除旧容器
echo "[2/7] 停止并删除旧容器..."
docker stop $CONTAINER_NAME > /dev/null 2>&1 || true
docker rm $CONTAINER_NAME > /dev/null 2>&1 || true
# 3. 加载新镜像
echo "[3/7] 加载镜像..."
docker load -i "$IMAGE_TAR" > /dev/null
echo "镜像加载完成"
# 4. 创建备份
# 4. 备份数据库(从旧容器)
echo "[4/7] 备份数据库..."
mkdir -p "$BACKUP_DIR"
TIMESTAMP=$(date +%Y%m%d_%H%M%S)
docker cp ${CONTAINER_NAME}:/app/data/piano_plans.db ${BACKUP_DIR}/piano_plans.db.bak.${TIMESTAMP} 2>/dev/null || true
echo "备份完成: ${BACKUP_DIR}/piano_plans.db.bak.${TIMESTAMP}"
# 5. 启动新容器(使用正确的挂载配置!)
# 5. 启动新容器
echo "[5/7] 启动新容器..."
docker run -d \
--name $CONTAINER_NAME \
@@ -60,7 +47,7 @@ docker run -d \
-v /opt/piano-plan/config:/app/config \
piano-plan:latest
# 6. 等待容器启动
# 6. 等待启动
echo "[6/7] 等待容器启动..."
sleep 3
@@ -75,11 +62,9 @@ else
exit 1
fi
# 验证问题文件
PROBLEM_COUNT=$(docker exec $CONTAINER_NAME ls /app/个性化方案/*.md 2>/dev/null | wc -l)
echo "✓ 问题文件数量: $PROBLEM_COUNT"
# 验证数据库
DB_TABLES=$(docker exec $CONTAINER_NAME python -c "import sqlite3; conn=sqlite3.connect('/app/data/piano_plans.db'); print(len(conn.execute('SELECT name FROM sqlite_master WHERE type=\"table\"').fetchall()))" 2>/dev/null || echo "0")
echo "✓ 数据库表数量: $DB_TABLES"