Files
luntan/app/blueprints/admin.py

138 lines
5.6 KiB
Python

from datetime import datetime
from flask import Blueprint, render_template, redirect, url_for, request, flash
from flask_login import login_required, current_user
from ..extensions import db
from ..models import User, UserStatus, Post, ReviewStatus, Activity, ActivityStatus, ActivitySubmission, ReviewLog
from ..services.notify import notify
bp = Blueprint("admin", __name__, url_prefix="/admin")
def is_admin():
return current_user.is_authenticated and current_user.role == "admin"
@bp.before_request
def guard():
if request.endpoint and request.endpoint.startswith("admin."):
if not is_admin():
return redirect(url_for("auth.login"))
@bp.route("/")
@login_required
def dashboard():
pending_users = User.query.filter_by(status=UserStatus.pending).count()
pending_posts = Post.query.filter_by(status=ReviewStatus.pending).count()
pending_subs = ActivitySubmission.query.filter_by(status=ReviewStatus.pending).count()
return render_template("admin/dashboard.html", pending_users=pending_users, pending_posts=pending_posts, pending_subs=pending_subs)
@bp.route("/reviews/users")
@login_required
def review_users():
users = User.query.filter_by(status=UserStatus.pending).all()
return render_template("admin/reviews_users.html", users=users)
@bp.route("/reviews/users/<int:user_id>/approve", methods=["POST"])
@login_required
def approve_user(user_id):
u = User.query.get_or_404(user_id)
u.status = UserStatus.approved
db.session.add(ReviewLog(target_type="user", target_id=u.id, admin_id=current_user.id, action="approve"))
notify(u.id, "user_approved")
db.session.commit()
return redirect(url_for("admin.review_users"))
@bp.route("/reviews/users/<int:user_id>/reject", methods=["POST"])
@login_required
def reject_user(user_id):
u = User.query.get_or_404(user_id)
u.status = UserStatus.rejected
db.session.add(ReviewLog(target_type="user", target_id=u.id, admin_id=current_user.id, action="reject"))
notify(u.id, "user_rejected")
db.session.commit()
return redirect(url_for("admin.review_users"))
@bp.route("/reviews/posts")
@login_required
def review_posts():
posts = Post.query.filter_by(status=ReviewStatus.pending).all()
return render_template("admin/reviews_posts.html", posts=posts)
@bp.route("/reviews/posts/<int:post_id>/approve", methods=["POST"])
@login_required
def approve_post(post_id):
p = Post.query.get_or_404(post_id)
p.status = ReviewStatus.approved
p.published_at = datetime.utcnow()
db.session.add(ReviewLog(target_type="post", target_id=p.id, admin_id=current_user.id, action="approve"))
notify(p.user_id, "post_approved")
db.session.commit()
return redirect(url_for("admin.review_posts"))
@bp.route("/reviews/posts/<int:post_id>/reject", methods=["POST"])
@login_required
def reject_post(post_id):
p = Post.query.get_or_404(post_id)
p.status = ReviewStatus.rejected
db.session.add(ReviewLog(target_type="post", target_id=p.id, admin_id=current_user.id, action="reject"))
notify(p.user_id, "post_rejected")
db.session.commit()
return redirect(url_for("admin.review_posts"))
@bp.route("/activities", methods=["GET", "POST"])
@login_required
def manage_activities():
if request.method == "POST":
title = request.form.get("title")
theme = request.form.get("theme")
description = request.form.get("description")
a = Activity(title=title, theme=theme, description=description)
db.session.add(a)
db.session.commit()
flash("活动已创建")
return redirect(url_for("admin.manage_activities"))
acts = Activity.query.order_by(Activity.created_at.desc()).all()
return render_template("admin/activities.html", activities=acts)
@bp.route("/activities/<int:act_id>/publish", methods=["POST"])
@login_required
def publish_activity(act_id):
a = Activity.query.get_or_404(act_id)
a.status = ActivityStatus.published
db.session.add(ReviewLog(target_type="activity", target_id=a.id, admin_id=current_user.id, action="publish"))
db.session.commit()
return redirect(url_for("admin.manage_activities"))
@bp.route("/activities/<int:act_id>/close", methods=["POST"])
@login_required
def close_activity(act_id):
a = Activity.query.get_or_404(act_id)
a.status = ActivityStatus.closed
db.session.add(ReviewLog(target_type="activity", target_id=a.id, admin_id=current_user.id, action="close"))
db.session.commit()
return redirect(url_for("admin.manage_activities"))
@bp.route("/reviews/submissions")
@login_required
def review_submissions():
subs = ActivitySubmission.query.filter_by(status=ReviewStatus.pending).all()
return render_template("admin/reviews_submissions.html", submissions=subs)
@bp.route("/reviews/submissions/<int:sub_id>/approve", methods=["POST"])
@login_required
def approve_submission(sub_id):
s = ActivitySubmission.query.get_or_404(sub_id)
s.status = ReviewStatus.approved
db.session.add(ReviewLog(target_type="submission", target_id=s.id, admin_id=current_user.id, action="approve"))
notify(s.user_id, "submission_approved")
db.session.commit()
return redirect(url_for("admin.review_submissions"))
@bp.route("/reviews/submissions/<int:sub_id>/reject", methods=["POST"])
@login_required
def reject_submission(sub_id):
s = ActivitySubmission.query.get_or_404(sub_id)
s.status = ReviewStatus.rejected
db.session.add(ReviewLog(target_type="submission", target_id=s.id, admin_id=current_user.id, action="reject"))
notify(s.user_id, "submission_rejected")
db.session.commit()
return redirect(url_for("admin.review_submissions"))