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:
+69
-4
@@ -114,6 +114,15 @@ class Student(db.Model):
|
||||
class_obj = db.relationship("Class", backref="students")
|
||||
|
||||
def to_dict(self):
|
||||
# 获取问题列表,按严重程度排序(严重 > 中等 > 轻微)
|
||||
severity_order = {"严重": 0, "中等": 1, "轻微": 2}
|
||||
problems_list = sorted(
|
||||
self.problems.all(),
|
||||
key=lambda p: (severity_order.get(p.severity, 1), p.created_at)
|
||||
)
|
||||
# 通过关联获取问题名称
|
||||
problem_names = [p.problem.name if p.problem else p.problem_name for p in problems_list]
|
||||
|
||||
return {
|
||||
"id": self.id,
|
||||
"name": self.name,
|
||||
@@ -127,10 +136,33 @@ class Student(db.Model):
|
||||
if self.created_at
|
||||
else None,
|
||||
"problem_count": self.problems.count(),
|
||||
"problem_names": problem_names, # 问题名称列表(按严重程度排序)
|
||||
"plan_count": self.plans.count(),
|
||||
}
|
||||
|
||||
|
||||
class Problem(db.Model):
|
||||
"""问题表"""
|
||||
|
||||
__tablename__ = "problems"
|
||||
|
||||
id = db.Column(db.Integer, primary_key=True)
|
||||
no = db.Column(db.String(10), unique=True, nullable=False) # 编号:01, 02...
|
||||
name = db.Column(db.String(100), nullable=False) # 问题名称
|
||||
category = db.Column(db.String(50), default="技术类") # 分类
|
||||
content = db.Column(db.Text) # 问题详细内容
|
||||
created_at = db.Column(db.DateTime, default=datetime.now)
|
||||
updated_at = db.Column(db.DateTime, default=datetime.now, onupdate=datetime.now)
|
||||
|
||||
def to_dict(self):
|
||||
return {
|
||||
"id": self.id,
|
||||
"no": self.no,
|
||||
"name": self.name,
|
||||
"category": self.category,
|
||||
}
|
||||
|
||||
|
||||
class StudentProblem(db.Model):
|
||||
"""学员问题记录表"""
|
||||
|
||||
@@ -138,17 +170,21 @@ class StudentProblem(db.Model):
|
||||
|
||||
id = db.Column(db.Integer, primary_key=True)
|
||||
student_id = db.Column(db.Integer, db.ForeignKey("students.id"), nullable=False)
|
||||
problem_id = db.Column(db.String(50), nullable=False) # 如 "01_手小"
|
||||
problem_name = db.Column(db.String(100), nullable=False) # 如 "手小"
|
||||
problem_id = db.Column(db.Integer, db.ForeignKey("problems.id"), nullable=False) # 外键
|
||||
severity = db.Column(db.String(10), nullable=False) # 轻微/中等/严重
|
||||
level = db.Column(db.String(20)) # 启蒙/入门/进阶/熟练/精通
|
||||
created_at = db.Column(db.DateTime, default=datetime.now)
|
||||
|
||||
# 关联到 Problem
|
||||
problem = db.relationship("Problem", foreign_keys=[problem_id])
|
||||
|
||||
def to_dict(self):
|
||||
return {
|
||||
"id": self.id,
|
||||
"problem_id": self.problem_id,
|
||||
"problem_name": self.problem_name,
|
||||
"student_id": self.student_id,
|
||||
"problem_id": self.problem_id, # 外键关联到 problems.id
|
||||
"problem_name": self.problem.name if self.problem else None,
|
||||
"problem_no": self.problem.no if self.problem else None,
|
||||
"severity": self.severity,
|
||||
"level": self.level,
|
||||
}
|
||||
@@ -161,14 +197,43 @@ class PracticePlan(db.Model):
|
||||
|
||||
id = db.Column(db.Integer, primary_key=True)
|
||||
student_id = db.Column(db.Integer, db.ForeignKey("students.id"), nullable=False)
|
||||
template_id = db.Column(db.Integer, db.ForeignKey("templates.id"), nullable=True) # 使用的AI提示词模板
|
||||
is_typical = db.Column(db.Boolean, default=False, nullable=False) # 是否为典型方案
|
||||
content = db.Column(db.Text, nullable=False) # JSON格式存储方案内容
|
||||
created_at = db.Column(db.DateTime, default=datetime.now)
|
||||
|
||||
# 关联
|
||||
template = db.relationship("Template", foreign_keys=[template_id])
|
||||
|
||||
def to_dict(self):
|
||||
import json as json_module
|
||||
content_obj = {}
|
||||
try:
|
||||
content_obj = json_module.loads(self.content) if self.content else {}
|
||||
except:
|
||||
pass
|
||||
|
||||
# 从 content 中提取问题列表
|
||||
problems = content_obj.get("problems", [])
|
||||
problem_names = [p.get("name", "") for p in problems] if problems else []
|
||||
|
||||
# 获取模板名称
|
||||
template_name = self.template.name if self.template else None
|
||||
|
||||
# 获取学员班级
|
||||
class_name = None
|
||||
if self.student and self.student.class_obj:
|
||||
class_name = self.student.class_obj.name
|
||||
|
||||
return {
|
||||
"id": self.id,
|
||||
"student_id": self.student_id,
|
||||
"student_name": self.student.name if self.student else "",
|
||||
"class_name": class_name,
|
||||
"template_id": self.template_id,
|
||||
"template_name": template_name,
|
||||
"is_typical": self.is_typical,
|
||||
"problem_names": problem_names,
|
||||
"created_at": self.created_at.strftime("%Y-%m-%d %H:%M")
|
||||
if self.created_at
|
||||
else None,
|
||||
|
||||
Reference in New Issue
Block a user