更新:models/routes/services/templates/docs

This commit is contained in:
hmo
2026-04-26 18:02:36 +08:00
parent f7a82ac48a
commit 6abdd49c04
31 changed files with 1480 additions and 676 deletions
+73 -12
View File
@@ -17,6 +17,7 @@ class User(db.Model):
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(50), unique=True, nullable=False)
name = db.Column(db.String(50), nullable=True) # 姓名
password_hash = db.Column(db.String(200), nullable=False)
role = db.Column(db.String(20), default="user") # admin / user
created_at = db.Column(db.DateTime, default=datetime.now)
@@ -54,6 +55,7 @@ class User(db.Model):
return {
"id": self.id,
"username": self.username,
"name": self.name,
"role": self.role,
"created_at": self.created_at.strftime("%Y-%m-%d %H:%M")
if self.created_at
@@ -69,10 +71,14 @@ class Class(db.Model):
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(100), nullable=False)
description = db.Column(db.Text)
teacher_id = db.Column(db.Integer, db.ForeignKey("users.id"), nullable=True) # 班主任/老师
level = db.Column(db.String(20), default="启蒙") # 班级级别:启蒙/入门/进阶/熟练/精通
active = db.Column(db.Boolean, default=True) # 进行中
created_at = db.Column(db.DateTime, default=datetime.now)
# 关联 - 在Student模型中定义backref
# 关联
teacher = db.relationship("User", foreign_keys=[teacher_id])
def to_dict(self):
# 直接查询学员数量,避免relationship问题
from app.models import Student
@@ -82,6 +88,9 @@ class Class(db.Model):
"id": self.id,
"name": self.name,
"description": self.description,
"teacher_id": self.teacher_id,
"level": self.level or "启蒙",
"teacher_name": self.teacher.name if self.teacher else None,
"active": self.active if self.active is not None else True,
"student_count": student_count,
"created_at": self.created_at.strftime("%Y-%m-%d %H:%M")
@@ -126,6 +135,10 @@ class Student(db.Model):
# 通过关联获取问题名称
problem_names = [p.problem.name if p.problem else p.problem_name for p in problems_list]
# 获取目标统计
goal_count = len(self.goal_records) if self.goal_records else 0
completed_goal_count = sum(1 for g in self.goal_records if g.achievement_date) if self.goal_records else 0
return {
"id": self.id,
"name": self.name,
@@ -141,6 +154,8 @@ class Student(db.Model):
"problem_count": self.problems.count(),
"problem_names": problem_names, # 问题名称列表(按严重程度排序)
"plan_count": self.plans.count(),
"goal_count": goal_count,
"completed_goal_count": completed_goal_count,
}
@@ -190,6 +205,7 @@ class StudentProblem(db.Model):
"problem_no": self.problem.no if self.problem else None,
"severity": self.severity,
"level": self.level,
"created_at": self.created_at.isoformat() if self.created_at else None,
}
@@ -236,42 +252,81 @@ class StudentGoal(db.Model):
student_id = db.Column(db.Integer, db.ForeignKey("students.id"), nullable=False)
goal_id = db.Column(db.Integer, db.ForeignKey("goals.id"), nullable=False)
start_date = db.Column(db.DateTime) # 开始日期
assessment_date = db.Column(db.DateTime) # 评估日期
mastery_level = db.Column(db.Integer, nullable=True) # 掌握程度 1-5(评估时填写)
achievement_date = db.Column(db.DateTime, nullable=True) # 达成日期
comment = db.Column(db.Text, nullable=True) # 评语
assessment_date = db.Column(db.DateTime) # 计划评估日期
status = db.Column(db.String(20), default="进行中") # 状态:未开始/进行中/已完成/已过期
mastery_level = db.Column(db.Integer, nullable=True) # 掌握程度(来自最新评估)
achievement_date = db.Column(db.DateTime, nullable=True) # 达成日期(来自最终评估)
comment = db.Column(db.Text, nullable=True) # 评语(来自最新评估)
created_at = db.Column(db.DateTime, default=datetime.now)
updated_at = db.Column(db.DateTime, default=datetime.now, onupdate=datetime.now)
student = db.relationship("Student", backref="goal_records")
goal = db.relationship("Goal")
def get_status(self):
"""根据日期动计算状态"""
def compute_status(self):
"""根据日期动计算状态"""
from datetime import datetime
now = datetime.now()
if self.start_date and now < self.start_date:
return "未开始"
elif self.achievement_date:
return "已完成"
elif self.assessment_date and now > self.assessment_date:
return "结束"
return "过期"
else:
return "进行中"
def sync_status(self):
"""同步状态到数据库"""
self.status = self.compute_status()
def to_dict(self):
status = self.get_status()
return {
"id": self.id,
"student_id": self.student_id,
"goal_id": self.goal_id,
"goal_name": self.goal.name if self.goal else None,
"goal_content": self.goal.content if self.goal else None,
"goal_level": self.goal.level if self.goal else None,
"goal_category": self.goal.category if self.goal else None,
"status": status,
"status": self.status,
"start_date": self.start_date.isoformat() if self.start_date else None,
"assessment_date": self.assessment_date.isoformat() if self.assessment_date else None,
"mastery_level": self.mastery_level,
"achievement_date": self.achievement_date.isoformat() if self.achievement_date else None,
"comment": self.comment,
"created_at": self.created_at.isoformat() if self.created_at else None,
"updated_at": self.updated_at.isoformat() if self.updated_at else None,
}
class StudentGoalEvaluation(db.Model):
"""学员目标评估记录表"""
__tablename__ = "student_goal_evaluations"
id = db.Column(db.Integer, primary_key=True)
student_goal_id = db.Column(db.Integer, db.ForeignKey("student_goals.id"), nullable=False)
evaluator_id = db.Column(db.Integer, nullable=True) # 评估人(暂时用 nullable
assessment_date = db.Column(db.DateTime, default=datetime.now) # 评估日期
mastery_level = db.Column(db.Integer, nullable=False) # 掌握程度 1-5
comment = db.Column(db.Text, nullable=True) # 评语
is_final = db.Column(db.Boolean, default=False) # 是否最终评估
created_at = db.Column(db.DateTime, default=datetime.now)
updated_at = db.Column(db.DateTime, default=datetime.now, onupdate=datetime.now)
student_goal = db.relationship("StudentGoal", backref="evaluations")
def to_dict(self):
return {
"id": self.id,
"student_goal_id": self.student_goal_id,
"evaluator_id": self.evaluator_id,
"assessment_date": self.assessment_date.isoformat() if self.assessment_date else None,
"mastery_level": self.mastery_level,
"comment": self.comment,
"is_final": self.is_final,
"created_at": self.created_at.isoformat() if self.created_at else None,
"updated_at": self.updated_at.isoformat() if self.updated_at else None,
}
@@ -298,9 +353,14 @@ class PracticePlan(db.Model):
except:
pass
# 从 content 中提取问题列表
# 从 content 中提取问题列表(含级别和严重程度)
# 兼容旧数据:旧数据用 problem_name,新数据用 name
problems = content_obj.get("problems", [])
problem_names = [p.get("name", "") for p in problems] if problems else []
problem_details = [
{"name": p.get("name") or p.get("problem_name", ""), "level": p.get("level", ""), "severity": p.get("severity", "中等")}
for p in problems
] if problems else []
problem_names = [p["name"] for p in problem_details]
# 获取模板名称
template_name = self.template.name if self.template else None
@@ -319,6 +379,7 @@ class PracticePlan(db.Model):
"template_name": template_name,
"is_typical": self.is_typical,
"problem_names": problem_names,
"problem_details": problem_details,
"created_at": self.created_at.strftime("%Y-%m-%d %H:%M")
if self.created_at
else None,