182 lines
7.0 KiB
Python
182 lines
7.0 KiB
Python
from flask import Blueprint, request, jsonify, session
|
|
from app.models import db, StudentGoal, StudentGoalEvaluation, Goal
|
|
from app.routes.auth import login_required_json
|
|
from datetime import datetime, timedelta
|
|
|
|
student_goals_bp = Blueprint("student_goals", __name__)
|
|
|
|
@student_goals_bp.route("/api/students/<int:student_id>/goals", methods=["GET"])
|
|
@login_required_json
|
|
def get_student_goals(student_id):
|
|
records = StudentGoal.query.filter_by(student_id=student_id).all()
|
|
|
|
# 同步状态并排序
|
|
for r in records:
|
|
r.sync_status()
|
|
|
|
def sort_key(r):
|
|
status_order = {"进行中": 1, "未开始": 2, "已过期": 3, "已完成": 4}
|
|
order = status_order.get(r.status, 5)
|
|
assessment = r.assessment_date if r.assessment_date else datetime.min
|
|
return (order, -assessment.timestamp() if assessment else 0)
|
|
|
|
records.sort(key=sort_key)
|
|
return jsonify([r.to_dict() for r in records])
|
|
|
|
@student_goals_bp.route("/api/students/<int:student_id>/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
|
|
|
|
# 处理评估日期
|
|
assessment_date = None
|
|
if data.get("assessment_date"):
|
|
# 直接指定日期
|
|
assessment_date = datetime.fromisoformat(data["assessment_date"])
|
|
elif data.get("assessment_days"):
|
|
# 指定天数后
|
|
assessment_date = datetime.now() + timedelta(days=int(data["assessment_days"]))
|
|
|
|
# 处理开始日期
|
|
start_date = None
|
|
if data.get("start_date"):
|
|
start_date = datetime.fromisoformat(data["start_date"])
|
|
# 如果没有指定开始日期,默认为当前时间
|
|
elif data.get("start_now"):
|
|
start_date = datetime.now()
|
|
|
|
record = StudentGoal(
|
|
student_id=student_id,
|
|
goal_id=data["goal_id"],
|
|
start_date=start_date,
|
|
assessment_date=assessment_date
|
|
)
|
|
db.session.add(record)
|
|
db.session.commit()
|
|
return jsonify(record.to_dict()), 201
|
|
|
|
@student_goals_bp.route("/api/students/<int:student_id>/goals/<int:goal_id>", 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 "mastery_level" in data or "comment" in data:
|
|
is_final = data.get("is_final", False)
|
|
assessment_date = datetime.now()
|
|
if data.get("assessment_date"):
|
|
assessment_date = datetime.fromisoformat(data["assessment_date"])
|
|
|
|
# 如果提供了 evaluation_id,则是更新现有评估记录
|
|
if data.get("evaluation_id"):
|
|
evaluation = StudentGoalEvaluation.query.get(data["evaluation_id"])
|
|
if evaluation and evaluation.student_goal_id == record.id:
|
|
evaluation.mastery_level = data["mastery_level"]
|
|
evaluation.comment = data.get("comment")
|
|
evaluation.is_final = is_final
|
|
evaluation.updated_at = datetime.now()
|
|
# 如果是最终评估,同步到 StudentGoal
|
|
if is_final:
|
|
record.achievement_date = assessment_date
|
|
record.mastery_level = data["mastery_level"]
|
|
record.comment = data.get("comment")
|
|
record.sync_status()
|
|
else:
|
|
# 创建新评估记录
|
|
evaluation = StudentGoalEvaluation(
|
|
student_goal_id=record.id,
|
|
evaluator_id=None,
|
|
assessment_date=assessment_date,
|
|
mastery_level=data["mastery_level"],
|
|
comment=data.get("comment"),
|
|
is_final=is_final
|
|
)
|
|
db.session.add(evaluation)
|
|
|
|
# 如果是最终评估,同步到 StudentGoal
|
|
if is_final:
|
|
record.achievement_date = assessment_date
|
|
record.mastery_level = data["mastery_level"]
|
|
record.comment = data.get("comment")
|
|
record.sync_status()
|
|
else:
|
|
# 调整操作:只更新日期
|
|
if "start_date" in data:
|
|
if data["start_date"]:
|
|
record.start_date = datetime.fromisoformat(data["start_date"])
|
|
else:
|
|
record.start_date = None
|
|
if "assessment_date" in data:
|
|
if data["assessment_date"]:
|
|
record.assessment_date = datetime.fromisoformat(data["assessment_date"])
|
|
else:
|
|
record.assessment_date = None
|
|
record.sync_status()
|
|
|
|
db.session.commit()
|
|
return jsonify(record.to_dict())
|
|
|
|
@student_goals_bp.route("/api/students/<int:student_id>/goals/<int:goal_id>", methods=["DELETE"])
|
|
@login_required_json
|
|
def remove_student_goal(student_id, goal_id):
|
|
"""移除学员的目标分配(仅管理员)"""
|
|
from app.models import User
|
|
user = User.query.get(session.get("user_id"))
|
|
if not user or user.role != "admin":
|
|
return jsonify({"error": "权限不足,仅管理员可操作"}), 403
|
|
|
|
record = StudentGoal.query.filter_by(student_id=student_id, goal_id=goal_id).first_or_404()
|
|
|
|
# 先删除关联的评估记录
|
|
StudentGoalEvaluation.query.filter_by(student_goal_id=record.id).delete()
|
|
|
|
db.session.delete(record)
|
|
db.session.commit()
|
|
return jsonify({"message": "移除成功"})
|
|
|
|
@student_goals_bp.route("/api/evaluations/<int:evaluation_id>", methods=["DELETE"])
|
|
@login_required_json
|
|
def delete_evaluation(evaluation_id):
|
|
"""删除评估记录"""
|
|
evaluation = StudentGoalEvaluation.query.get_or_404(evaluation_id)
|
|
db.session.delete(evaluation)
|
|
db.session.commit()
|
|
return jsonify({"message": "删除成功"})
|
|
|
|
|
|
@student_goals_bp.route("/api/students/<int:student_id>/evaluations", methods=["GET"])
|
|
@login_required_json
|
|
def get_student_evaluations(student_id):
|
|
"""获取学员所有目标的所有评估记录"""
|
|
evaluations = StudentGoalEvaluation.query.join(StudentGoal).filter(
|
|
StudentGoal.student_id == student_id
|
|
).order_by(StudentGoalEvaluation.assessment_date.desc()).all()
|
|
|
|
# 补充目标信息
|
|
result = []
|
|
for e in evaluations:
|
|
d = e.to_dict()
|
|
# 获取关联的目标信息
|
|
sg = StudentGoal.query.get(e.student_goal_id)
|
|
if sg:
|
|
d["goal_name"] = sg.goal.name if sg.goal else None
|
|
d["goal_level"] = sg.goal.level if sg.goal else None
|
|
d["student_goal_id"] = sg.id
|
|
d["student_goal_goal_id"] = sg.goal_id
|
|
d["goal_start_date"] = sg.start_date.isoformat() if sg.start_date else None
|
|
d["goal_assessment_date"] = sg.assessment_date.isoformat() if sg.assessment_date else None
|
|
result.append(d)
|
|
|
|
return jsonify(result)
|