From f83769fa20884a7252dcf326f41e7c81536221b5 Mon Sep 17 00:00:00 2001 From: hmo Date: Thu, 23 Apr 2026 21:57:00 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E7=9B=AE=E6=A0=87=E5=92=8C=E9=97=AE?= =?UTF-8?q?=E9=A2=98=E7=BB=9F=E4=B8=80=E5=88=86=E7=B1=BB=E4=BD=93=E7=B3=BB?= =?UTF-8?q?(=E7=BB=BC=E5=90=88/=E4=B9=90=E7=90=86=E7=9B=B8=E5=85=B3/?= =?UTF-8?q?=E6=BC=94=E5=A5=8F=E8=83=BD=E5=8A=9B/=E5=85=B6=E4=BB=96)?= =?UTF-8?q?=EF=BC=8C=E6=B7=BB=E5=8A=A0=E6=95=B0=E6=8D=AE=E5=BA=93=E8=BF=81?= =?UTF-8?q?=E7=A7=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/__init__.py | 23 +++++++++++++++++++++++ app/models.py | 9 +++++++-- app/routes/goals.py | 5 ++++- app/templates/goals.html | 18 +++++++++++++++--- 4 files changed, 49 insertions(+), 6 deletions(-) diff --git a/app/__init__.py b/app/__init__.py index 832205a..10e84e9 100644 --- a/app/__init__.py +++ b/app/__init__.py @@ -131,6 +131,29 @@ def create_app(): if "level" not in goal_columns: db.session.execute(text("ALTER TABLE goals ADD COLUMN level VARCHAR(20) DEFAULT '入门'")) db.session.commit() + + # 检查goals表是否有category字段 + if "category" not in goal_columns: + db.session.execute(text("ALTER TABLE goals ADD COLUMN category VARCHAR(20) DEFAULT '综合'")) + db.session.commit() + + # 迁移problems表分类:旧分类 -> 新分类 + # 技术类/技术类(手型)/技术类(生理限制) -> 演奏能力 + # 识谱类 -> 乐理相关 + # 综合类 -> 综合类 (保持不变) + # 其他 -> 其他 (保持不变) + category_mapping = { + '技术类': '演奏能力', + '技术类(手型)': '演奏能力', + '技术类(生理限制)': '演奏能力', + '识谱类': '乐理相关', + } + for old_cat, new_cat in category_mapping.items(): + db.session.execute( + text("UPDATE problems SET category = :new_cat WHERE category = :old_cat"), + {"new_cat": new_cat, "old_cat": old_cat} + ) + db.session.commit() except Exception as e: print(f"数据库迁移: {e}") diff --git a/app/models.py b/app/models.py index ae655f1..19ad9ad 100644 --- a/app/models.py +++ b/app/models.py @@ -6,6 +6,9 @@ import re db = SQLAlchemy() +# 问题和目标的统一分类体系 +ITEM_CATEGORIES = ['综合', '乐理相关', '演奏能力', '其他'] + class User(db.Model): """管理员用户表""" @@ -149,7 +152,7 @@ class Problem(db.Model): 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="技术类") # 分类 + category = db.Column(db.String(20), 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) @@ -159,7 +162,7 @@ class Problem(db.Model): "id": self.id, "no": self.no, "name": self.name, - "category": self.category, + "category": self.category or "综合", } @@ -198,6 +201,7 @@ class Goal(db.Model): name = db.Column(db.String(100), nullable=False) content = db.Column(db.Text) level = db.Column(db.String(20), default="入门") # 启蒙/入门/进阶/熟练/精通 + category = db.Column(db.String(20), default="综合") # 分类:综合/乐理相关/演奏能力/其他 created_at = db.Column(db.DateTime, default=datetime.now) updated_at = db.Column(db.DateTime, default=datetime.now, onupdate=datetime.now) @@ -207,6 +211,7 @@ class Goal(db.Model): "name": self.name, "content": self.content, "level": self.level, + "category": self.category or "综合", "created_at": self.created_at.isoformat() if self.created_at else None, "updated_at": self.updated_at.isoformat() if self.updated_at else None, } diff --git a/app/routes/goals.py b/app/routes/goals.py index ffd93ca..bbdb416 100644 --- a/app/routes/goals.py +++ b/app/routes/goals.py @@ -25,7 +25,8 @@ def create_goal(): goal = Goal( name=data["name"], content=data.get("content", ""), - level=data.get("level", "入门") + level=data.get("level", "入门"), + category=data.get("category", "综合") ) db.session.add(goal) db.session.commit() @@ -48,6 +49,8 @@ def update_goal(goal_id): goal.content = data["content"] if "level" in data: goal.level = data["level"] + if "category" in data: + goal.category = data["category"] db.session.commit() return jsonify(goal.to_dict()) diff --git a/app/templates/goals.html b/app/templates/goals.html index 9713a31..dfa39e8 100644 --- a/app/templates/goals.html +++ b/app/templates/goals.html @@ -46,6 +46,15 @@ +
+ + +
@@ -111,6 +120,7 @@ async function loadGoals() { grid.innerHTML = goalsWithChildren.map(g => { const level = g.level || '入门'; + const category = g.category || '综合'; const childNames = g.children && g.children.length > 0 ? g.children.map(c => escapeHtml(c.name)).join(', ') : ''; @@ -120,6 +130,7 @@ async function loadGoals() {
${escapeHtml(g.name)}
+ ${category} ${level}
${childNames ? `
子目标: ${childNames}
` : ''} @@ -140,14 +151,14 @@ async function saveGoal() { const id = document.getElementById('goal-id').value; const name = document.getElementById('goal-name').value; const level = document.getElementById('goal-level').value; + const category = document.getElementById('goal-category').value; const content = document.getElementById('goal-content').value; if (!name) { alert('请输入目标名称'); return; } const method = id ? 'PUT' : 'POST'; const url = id ? `${API_BASE}/${id}` : API_BASE; - const payload = {name, level, content}; - console.log('Saving goal:', payload); + const payload = {name, level, category, content}; try { const res = await fetch(url, { @@ -174,10 +185,10 @@ function editGoal(id) { fetch(`${API_BASE}/${id}`) .then(r => r.json()) .then(g => { - console.log('Editing goal:', g); document.getElementById('goal-id').value = g.id; document.getElementById('goal-name').value = g.name; document.getElementById('goal-level').value = g.level || '入门'; + document.getElementById('goal-category').value = g.category || '综合'; document.getElementById('goal-content').value = g.content || ''; document.getElementById('goalModalTitle').textContent = '编辑目标'; new bootstrap.Modal(document.getElementById('goalModal')).show(); @@ -298,6 +309,7 @@ document.getElementById('goalModal').addEventListener('hidden.bs.modal', () => { document.getElementById('goal-id').value = ''; document.getElementById('goal-name').value = ''; document.getElementById('goal-level').value = '入门'; + document.getElementById('goal-category').value = '综合'; document.getElementById('goal-content').value = ''; document.getElementById('goalModalTitle').textContent = '新建目标'; });