Complete project files including setup.sh

This commit is contained in:
2026-01-11 14:17:26 +08:00
commit 0bbe394cb5
29 changed files with 3060 additions and 0 deletions

126
routes/posts.py Normal file
View File

@@ -0,0 +1,126 @@
import os
from flask import Blueprint, render_template, request, redirect, url_for, flash, current_app
from flask_login import login_required, current_user
from werkzeug.utils import secure_filename
from models import db, Post, Comment
from config import Config
posts_bp = Blueprint('posts', __name__)
def allowed_file(filename):
"""检查文件扩展名是否允许"""
return '.' in filename and \
filename.rsplit('.', 1)[1].lower() in Config.ALLOWED_EXTENSIONS
@posts_bp.route('/')
def index():
"""首页 - 显示已审核的帖子流"""
page = request.args.get('page', 1, type=int)
# 只显示已审核的帖子
pagination = Post.query.filter_by(is_approved=True)\
.order_by(Post.created_at.desc())\
.paginate(page=page, per_page=current_app.config['POSTS_PER_PAGE'], error_out=False)
posts = pagination.items
return render_template('index.html', posts=posts, pagination=pagination)
@posts_bp.route('/post/create', methods=['GET', 'POST'])
@login_required
def create_post():
"""创建帖子"""
if not current_user.is_approved:
flash('您的账号尚未通过审核,无法发帖', 'error')
return redirect(url_for('posts.index'))
if request.method == 'POST':
description = request.form.get('description')
image = request.files.get('image')
if not image:
flash('请上传照片', 'error')
return render_template('create_post.html')
if not allowed_file(image.filename):
flash('请上传有效的图片文件(支持 PNG, JPG, JPEG, GIF, WEBP', 'error')
return render_template('create_post.html')
# 保存图片
filename = secure_filename(f"{current_user.username}_{image.filename}")
# 添加时间戳避免重名
from datetime import datetime
timestamp = datetime.now().strftime('%Y%m%d%H%M%S')
filename = f"{timestamp}_{filename}"
filepath = os.path.join(Config.UPLOAD_FOLDER, 'posts', filename)
image.save(filepath)
# 创建帖子
post = Post(
user_id=current_user.id,
image_path=f'posts/{filename}',
description=description,
is_approved=False # 需要审核
)
db.session.add(post)
db.session.commit()
flash('帖子已提交,等待管理员审核', 'success')
return redirect(url_for('posts.index'))
return render_template('create_post.html')
@posts_bp.route('/post/<int:post_id>')
def post_detail(post_id):
"""帖子详情页"""
post = Post.query.get_or_404(post_id)
# 如果帖子未审核,只有作者和管理员可以查看
if not post.is_approved:
if not current_user.is_authenticated or \
(current_user.id != post.user_id and not current_user.is_admin):
flash('该帖子正在审核中', 'warning')
return redirect(url_for('posts.index'))
# 获取评论
comments = post.comments.order_by(Comment.created_at.desc()).all()
return render_template('post_detail.html', post=post, comments=comments)
@posts_bp.route('/post/<int:post_id>/comment', methods=['POST'])
@login_required
def add_comment(post_id):
"""添加评论"""
if not current_user.is_approved:
flash('您的账号尚未通过审核,无法评论', 'error')
return redirect(url_for('posts.post_detail', post_id=post_id))
post = Post.query.get_or_404(post_id)
if not post.is_approved:
flash('该帖子正在审核中,无法评论', 'error')
return redirect(url_for('posts.index'))
content = request.form.get('content')
if not content or not content.strip():
flash('评论内容不能为空', 'error')
return redirect(url_for('posts.post_detail', post_id=post_id))
comment = Comment(
post_id=post_id,
user_id=current_user.id,
content=content.strip()
)
db.session.add(comment)
db.session.commit()
flash('评论发表成功', 'success')
return redirect(url_for('posts.post_detail', post_id=post_id))