diff --git a/app/routes/goals.py b/app/routes/goals.py index 1863e68..14afb6d 100644 --- a/app/routes/goals.py +++ b/app/routes/goals.py @@ -1,9 +1,17 @@ -from flask import Blueprint, request, jsonify +from flask import Blueprint, request, jsonify, render_template from app.models import db, Goal -from app.routes.auth import login_required_json +from app.routes.auth import login_required_json, admin_required +from app.routes import main_bp goals_bp = Blueprint("goals", __name__) +# 目标管理页面路由 +@main_bp.route("/goals") +@admin_required +def goals_page(): + """目标管理页面""" + return render_template("goals.html", active_nav="goals") + @goals_bp.route("/api/goals", methods=["GET"]) @login_required_json def get_goals(): diff --git a/app/routes/student_goals.py b/app/routes/student_goals.py new file mode 100644 index 0000000..7f5ee92 --- /dev/null +++ b/app/routes/student_goals.py @@ -0,0 +1,64 @@ +from flask import Blueprint, request, jsonify +from app.models import db, StudentGoal, Goal +from app.routes.auth import login_required_json + +student_goals_bp = Blueprint("student_goals", __name__) + +@student_goals_bp.route("/api/students//goals", methods=["GET"]) +@login_required_json +def get_student_goals(student_id): + records = StudentGoal.query.filter_by(student_id=student_id).all() + return jsonify([r.to_dict() for r in records]) + +@student_goals_bp.route("/api/students//goals", methods=["POST"]) +@login_required_json +def assign_goal(student_id): + data = request.get_json() + + # 检查目标是否存在 + goal = Goal.query.get(data["goal_id"]) + if not goal: + return jsonify({"error": "目标不存在"}), 404 + + # 检查是否已分配 + existing = StudentGoal.query.filter_by(student_id=student_id, goal_id=data["goal_id"]).first() + if existing: + return jsonify({"error": "目标已分配"}), 400 + + record = StudentGoal( + student_id=student_id, + goal_id=data["goal_id"], + status=data.get("status", "未开始"), + mastery_level=data.get("mastery_level", 1), + deadline=data.get("deadline") + ) + db.session.add(record) + db.session.commit() + return jsonify(record.to_dict()), 201 + +@student_goals_bp.route("/api/students//goals/", methods=["PUT"]) +@login_required_json +def update_student_goal(student_id, goal_id): + record = StudentGoal.query.filter_by(student_id=student_id, goal_id=goal_id).first_or_404() + data = request.get_json() + + if "status" in data: + record.status = data["status"] + if data["status"] == "已完成" and not record.completed_at: + from datetime import datetime + record.completed_at = datetime.now() + if "mastery_level" in data: + record.mastery_level = data["mastery_level"] + if "deadline" in data: + record.deadline = data["deadline"] + + db.session.commit() + return jsonify(record.to_dict()) + +@student_goals_bp.route("/api/students//goals/", methods=["DELETE"]) +@login_required_json +def remove_student_goal(student_id, goal_id): + record = StudentGoal.query.filter_by(student_id=student_id, goal_id=goal_id).first_or_404() + db.session.delete(record) + db.session.commit() + return jsonify({"message": "移除成功"}) \ No newline at end of file diff --git a/app/templates/goals.html b/app/templates/goals.html new file mode 100644 index 0000000..7a6762c --- /dev/null +++ b/app/templates/goals.html @@ -0,0 +1,182 @@ +{% extends "base.html" %} + +{% block content %} +
+

🎯 目标管理

+ + +
+
+
+
+
目标库
+ +
+
+
+
+
+
+
+
+ + + + + + +{% endblock %} + +{% block scripts %} +{{ super() }} + +{% endblock %} \ No newline at end of file