Files
tech-blog-dev/app/routes/admin/articles.py
T
hz4th_coder 503a9780b2 refactor: 拆分admin路由为模块化结构,端口改为16013
- 将 routes/admin.py (672行) 拆分为 routes/admin/ 包
- 按功能模块拆分:auth, dashboard, articles, categories, tags, settings, stats, upload, authors
- 端口从 16012 改为 16013
- 初始化数据库和管理员账户
2026-06-25 11:21:36 +08:00

167 lines
5.9 KiB
Python

"""文章管理路由"""
from flask import render_template, redirect, url_for, request, flash
import json
from app.routes.admin import admin_bp, login_required
from app.services import ArticleService, CategoryService, TagService, AuthorService, ReferenceService, AttachmentService
@admin_bp.route('/articles')
@login_required
def articles():
"""文章列表"""
page = request.args.get('page', 1, type=int)
is_published = request.args.get('status')
if is_published == 'published':
is_published_filter = True
elif is_published == 'draft':
is_published_filter = False
else:
is_published_filter = None
articles = ArticleService.get_all_list(
page=page,
per_page=20,
is_published=is_published_filter
)
categories = CategoryService.get_all()
tags = TagService.get_all()
return render_template('admin/articles.html',
articles=articles,
categories=categories,
tags=tags,
current_status=is_published)
@admin_bp.route('/articles/create', methods=['GET', 'POST'])
@login_required
def article_create():
"""创建文章"""
if request.method == 'POST':
title = request.form.get('title')
content = request.form.get('content')
summary = request.form.get('summary')
author_id = request.form.get('author_id', type=int)
category_id = request.form.get('category_id', type=int)
cover_image = request.form.get('cover_image')
is_published = request.form.get('is_published') == 'on'
tag_ids = request.form.getlist('tags')
tag_ids = [int(t) for t in tag_ids if t]
# 处理参考来源
references_json = request.form.get('references', '[]')
references_data = json.loads(references_json) if references_json else []
article = ArticleService.create(
title=title,
content=content,
summary=summary,
author_id=author_id,
category_id=category_id,
tag_ids=tag_ids,
cover_image=cover_image,
is_published=is_published
)
# 添加参考来源
for ref in references_data:
if ref.get('title'):
ReferenceService.add(article.id, ref['title'], ref.get('url'), ref.get('description'))
flash('文章创建成功', 'success')
return redirect(url_for('admin.article_edit', article_id=article.id))
categories = CategoryService.get_all()
tags = TagService.get_all()
authors = AuthorService.get_all()
return render_template('admin/article_form.html',
article=None,
categories=categories,
tags=tags,
authors=authors,
references=[],
attachments=[])
@admin_bp.route('/articles/<int:article_id>/edit', methods=['GET', 'POST'])
@login_required
def article_edit(article_id):
"""编辑文章"""
article = ArticleService.get_by_id(article_id)
if not article:
flash('文章不存在', 'danger')
return redirect(url_for('admin.articles'))
if request.method == 'POST':
title = request.form.get('title')
content = request.form.get('content')
summary = request.form.get('summary')
author_id = request.form.get('author_id', type=int)
category_id = request.form.get('category_id', type=int)
cover_image = request.form.get('cover_image')
is_published = request.form.get('is_published') == 'on'
tag_ids = request.form.getlist('tags')
tag_ids = [int(t) for t in tag_ids if t]
# 处理参考来源
references_json = request.form.get('references', '[]')
references_data = json.loads(references_json) if references_json else []
ArticleService.update(
article_id,
title=title,
content=content,
summary=summary,
author_id=author_id,
category_id=category_id,
cover_image=cover_image,
is_published=is_published,
tag_ids=tag_ids
)
# 更新参考来源
ReferenceService.update_article_references(article_id, references_data)
flash('文章更新成功', 'success')
return redirect(url_for('admin.article_edit', article_id=article_id))
categories = CategoryService.get_all()
tags = TagService.get_all()
authors = AuthorService.get_all()
references = ReferenceService.get_by_article(article_id)
attachments = AttachmentService.get_by_article(article_id)
return render_template('admin/article_form.html',
article=article,
categories=categories,
tags=tags,
authors=authors,
references=references,
attachments=attachments)
@admin_bp.route('/articles/<int:article_id>/delete', methods=['POST'])
@login_required
def article_delete(article_id):
"""删除文章"""
if ArticleService.delete(article_id):
flash('文章已删除', 'success')
else:
flash('删除失败', 'danger')
return redirect(url_for('admin.articles'))
@admin_bp.route('/articles/<int:article_id>/toggle-publish', methods=['POST'])
@login_required
def article_toggle_publish(article_id):
"""切换文章发布状态"""
article = ArticleService.get_by_id(article_id)
if article:
ArticleService.update(article_id, is_published=not article.is_published)
status = '发布' if not article.is_published else '取消发布'
flash(f'文章已{status}', 'success')
else:
flash('文章不存在', 'danger')
return redirect(url_for('admin.articles'))