"""文章服务""" from datetime import datetime from slugify import slugify from app import db from app.models import Article, Category, Tag class ArticleService: """文章业务逻辑""" @staticmethod def get_published_list(page=1, per_page=10, category_id=None, tag_id=None): """获取已发布文章列表""" query = Article.query.filter_by(is_published=True) if category_id: query = query.filter_by(category_id=category_id) if tag_id: query = query.join(Article.tags).filter(Tag.id == tag_id) return query.order_by(Article.published_at.desc()).paginate( page=page, per_page=per_page, error_out=False ) @staticmethod def get_by_slug(slug): """通过slug获取文章""" article = Article.query.filter_by(slug=slug, is_published=True).first() if article: # 增加浏览次数 article.view_count += 1 db.session.commit() return article @staticmethod def get_by_id(article_id): """通过ID获取文章""" return Article.query.get(article_id) @staticmethod def get_all_list(page=1, per_page=20, is_published=None): """获取所有文章列表(后台用)""" query = Article.query if is_published is not None: query = query.filter_by(is_published=is_published) return query.order_by(Article.updated_at.desc()).paginate( page=page, per_page=per_page, error_out=False ) @staticmethod def create(title, content, summary=None, author_id=None, category_id=None, tag_ids=None, cover_image=None, is_published=False): """创建文章""" # 生成唯一slug slug = slugify(title) count = Article.query.filter(Article.slug.like(f'{slug}%')).count() if count > 0: slug = f'{slug}-{count + 1}' article = Article( title=title, slug=slug, content=content, summary=summary or content[:200] + '...' if len(content) > 200 else content, author_id=author_id, category_id=category_id, cover_image=cover_image, is_published=is_published, published_at=datetime.utcnow() if is_published else None ) # 添加标签 if tag_ids: tags = Tag.query.filter(Tag.id.in_(tag_ids)).all() article.tags = tags db.session.add(article) db.session.commit() return article @staticmethod def update(article_id, **kwargs): """更新文章""" article = Article.query.get(article_id) if not article: return None # 处理发布状态变化 if 'is_published' in kwargs and kwargs['is_published'] and not article.is_published: kwargs['published_at'] = datetime.utcnow() # 处理标签 tag_ids = kwargs.pop('tag_ids', None) if tag_ids is not None: tags = Tag.query.filter(Tag.id.in_(tag_ids)).all() article.tags = tags # 更新其他字段 for key, value in kwargs.items(): if hasattr(article, key): setattr(article, key, value) db.session.commit() return article @staticmethod def delete(article_id): """删除文章""" article = Article.query.get(article_id) if article: db.session.delete(article) db.session.commit() return True return False @staticmethod def get_hot_articles(limit=5): """获取热门文章""" return Article.query.filter_by(is_published=True)\ .order_by(Article.view_count.desc())\ .limit(limit).all() @staticmethod def get_recent_articles(limit=5): """获取最新文章""" return Article.query.filter_by(is_published=True)\ .order_by(Article.published_at.desc())\ .limit(limit).all()