feat: v4.0 - 添加 Skills 管理功能

- 新增 Skill 模型,支持手动添加和 GitHub 抓取
- 后台添加 Skills 管理界面
- 前台添加 /skills 列表页和 /skills/<slug> 详情页
- 首页增加 Skills Tab 入口
- 添加数据库迁移脚本

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Jowe
2026-03-25 22:39:50 +08:00
parent 76ae3cbb5a
commit 731f0d3822
7 changed files with 611 additions and 1 deletions

View File

@@ -311,3 +311,51 @@ class Collection(db.Model):
def __repr__(self):
return f'<Collection user={self.user_id} site={self.site_id}>'
class Skill(db.Model):
"""Skills 模型"""
__tablename__ = 'skills'
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(100), nullable=False, comment='Skill名称')
slug = db.Column(db.String(100), unique=True, nullable=False, comment='URL别名')
description = db.Column(db.Text, comment='详细介绍')
short_desc = db.Column(db.String(200), comment='简短描述')
logo = db.Column(db.String(500), comment='Logo图片路径')
github_url = db.Column(db.String(500), comment='GitHub 链接')
source_type = db.Column(db.String(20), default='manual', comment='来源类型: manual/github')
source_repo = db.Column(db.String(200), comment='来源仓库')
usage = db.Column(db.Text, comment='使用方法')
examples = db.Column(db.Text, comment='使用示例')
is_active = db.Column(db.Boolean, default=True, comment='是否启用')
is_featured = db.Column(db.Boolean, default=False, comment='是否推荐')
view_count = db.Column(db.Integer, default=0, comment='浏览次数')
sort_order = db.Column(db.Integer, default=0, comment='排序权重')
created_at = db.Column(db.DateTime, default=datetime.now, comment='创建时间')
updated_at = db.Column(db.DateTime, default=datetime.now, onupdate=datetime.now, comment='更新时间')
def __repr__(self):
return f'<Skill {self.name}>'
def to_dict(self):
"""转换为字典"""
return {
'id': self.id,
'name': self.name,
'slug': self.slug,
'description': self.description,
'short_desc': self.short_desc,
'logo': self.logo,
'github_url': self.github_url,
'source_type': self.source_type,
'source_repo': self.source_repo,
'usage': self.usage,
'examples': self.examples,
'is_active': self.is_active,
'is_featured': self.is_featured,
'view_count': self.view_count,
'sort_order': self.sort_order,
'created_at': self.created_at.strftime('%Y-%m-%d %H:%M:%S') if self.created_at else None,
'updated_at': self.updated_at.strftime('%Y-%m-%d %H:%M:%S') if self.updated_at else None
}