初始化技术博客项目

功能特性:
- 前端文章展示 (Markdown渲染、代码高亮)
- 后台管理系统 (文章、分类、标签、作者管理)
- 图片上传 (点击、拖拽、粘贴)
- 网站设置 (Logo、底部宣传图片上传)
- 访问统计 (IP记录、趋势图表)
- 参考来源、附件支持
- 单端口部署 (16012)

技术栈:
- Flask 3.0 + SQLAlchemy
- SQLite数据库
- marked.js + highlight.js (Markdown渲染)
- Chart.js (统计图表)
This commit is contained in:
2026-06-04 23:12:34 +08:00
commit e689fed71e
53 changed files with 6506 additions and 0 deletions

66
app/models/article.py Normal file
View File

@@ -0,0 +1,66 @@
"""文章模型"""
from datetime import datetime
from app import db
class Article(db.Model):
"""文章表"""
__tablename__ = 'articles'
id = db.Column(db.Integer, primary_key=True)
title = db.Column(db.String(200), nullable=False)
slug = db.Column(db.String(200), unique=True, nullable=False)
summary = db.Column(db.Text)
content = db.Column(db.Text, nullable=False)
cover_image = db.Column(db.String(500))
is_published = db.Column(db.Boolean, default=False)
view_count = db.Column(db.Integer, default=0)
# 作者关联
author_id = db.Column(db.Integer, db.ForeignKey('article_authors.id'))
author = db.relationship('ArticleAuthor', backref='articles')
# 分类关联
category_id = db.Column(db.Integer, db.ForeignKey('categories.id'))
category = db.relationship('Category', back_populates='articles')
# 标签关联(多对多)
tags = db.relationship('Tag', secondary='article_tags', back_populates='articles')
# 参考来源和附件在article_ext.py中定义
# references = db.relationship('Reference', backref='article')
# attachments = db.relationship('Attachment', backref='article')
# 时间戳
created_at = db.Column(db.DateTime, default=datetime.utcnow)
updated_at = db.Column(db.DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)
published_at = db.Column(db.DateTime)
def __repr__(self):
return f'<Article {self.title}>'
def to_dict(self):
"""转换为字典"""
return {
'id': self.id,
'title': self.title,
'slug': self.slug,
'summary': self.summary,
'content': self.content,
'cover_image': self.cover_image,
'is_published': self.is_published,
'view_count': self.view_count,
'author': self.author.name if self.author else None,
'category': self.category.name if self.category else None,
'tags': [tag.name for tag in self.tags],
'created_at': self.created_at.isoformat() if self.created_at else None,
'updated_at': self.updated_at.isoformat() if self.updated_at else None,
'published_at': self.published_at.isoformat() if self.published_at else None
}
# 文章-标签关联表
article_tags = db.Table('article_tags',
db.Column('article_id', db.Integer, db.ForeignKey('articles.id'), primary_key=True),
db.Column('tag_id', db.Integer, db.ForeignKey('tags.id'), primary_key=True)
)