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

View File

@@ -0,0 +1,43 @@
{% extends "base.html" %}
{% block title %}创建管理员 - 管理面板{% endblock %}
{% block content %}
<div class="container admin-container">
<div class="page-header">
<h1>👤 创建新管理员</h1>
<a href="{{ url_for('admin.dashboard') }}" class="btn btn-secondary">返回面板</a>
</div>
<div class="auth-card" style="max-width: 600px; margin: 0 auto;">
<form method="POST" class="auth-form">
<div class="form-group">
<label for="username">用户名</label>
<input type="text" id="username" name="username" required placeholder="请输入用户名" class="form-control">
</div>
<div class="form-group">
<label for="email">邮箱</label>
<input type="email" id="email" name="email" required placeholder="请输入邮箱" class="form-control">
</div>
<div class="form-group">
<label for="password">密码</label>
<input type="password" id="password" name="password" required placeholder="至少6位" class="form-control">
</div>
<div class="form-group">
<label for="confirm_password">确认密码</label>
<input type="password" id="confirm_password" name="confirm_password" required placeholder="再次输入密码"
class="form-control">
</div>
<div class="info-box">
<p><strong>提示:</strong>新管理员将拥有完整的管理权限,包括审核用户、帖子和创建其他管理员。</p>
</div>
<button type="submit" class="btn btn-primary btn-block">创建管理员</button>
</form>
</div>
</div>
{% endblock %}

View File

@@ -0,0 +1,49 @@
{% extends "base.html" %}
{% block title %}管理面板 - 泸州高中摄影社论坛{% endblock %}
{% block content %}
<div class="container admin-container">
<div class="page-header">
<h1>🛡️ 管理面板</h1>
</div>
<div class="admin-stats">
<div class="stat-card">
<div class="stat-icon">👥</div>
<div class="stat-info">
<div class="stat-number">{{ pending_users }}</div>
<div class="stat-label">待审核用户</div>
</div>
<a href="{{ url_for('admin.users') }}" class="stat-link">查看</a>
</div>
<div class="stat-card">
<div class="stat-icon">📝</div>
<div class="stat-info">
<div class="stat-number">{{ pending_posts }}</div>
<div class="stat-label">待审核帖子</div>
</div>
<a href="{{ url_for('admin.posts') }}" class="stat-link">查看</a>
</div>
</div>
<div class="admin-quick-links">
<h2>快速链接</h2>
<div class="quick-links-grid">
<a href="{{ url_for('admin.users') }}" class="quick-link-card">
<span class="quick-link-icon">👤</span>
<span class="quick-link-text">用户审核</span>
</a>
<a href="{{ url_for('admin.posts') }}" class="quick-link-card">
<span class="quick-link-icon">📸</span>
<span class="quick-link-text">帖子审核</span>
</a>
<a href="{{ url_for('admin.create_admin') }}" class="quick-link-card">
<span class="quick-link-icon"></span>
<span class="quick-link-text">创建管理员</span>
</a>
</div>
</div>
</div>
{% endblock %}

View File

@@ -0,0 +1,84 @@
{% extends "base.html" %}
{% block title %}帖子审核 - 管理面板{% endblock %}
{% block content %}
<div class="container admin-container">
<div class="page-header">
<h1>📝 帖子审核</h1>
<a href="{{ url_for('admin.dashboard') }}" class="btn btn-secondary">返回面板</a>
</div>
<!-- Pending Posts -->
<section class="admin-section">
<h2 class="section-title">待审核帖子 ({{ pending_posts|length }})</h2>
{% if pending_posts %}
<div class="admin-posts-grid">
{% for post in pending_posts %}
<div class="admin-post-card">
<img src="{{ url_for('uploaded_file', filename=post.image_path) }}" alt="Post image"
class="admin-post-image">
<div class="admin-post-info">
<div class="admin-post-author">
<a href="{{ url_for('users.profile', username=post.author.username) }}">
{{ post.author.username }}
</a>
<span class="post-time">{{ post.created_at.strftime('%Y-%m-%d %H:%M') }}</span>
</div>
{% if post.description %}
<div class="admin-post-description">
{{ post.description }}
</div>
{% endif %}
<div class="admin-actions">
<form method="POST" action="{{ url_for('admin.approve_post', post_id=post.id) }}"
style="display: inline;">
<button type="submit" class="btn btn-success">✓ 批准</button>
</form>
<form method="POST" action="{{ url_for('admin.reject_post', post_id=post.id) }}"
style="display: inline;" onsubmit="return confirm('确定要拒绝该帖子吗?');">
<button type="submit" class="btn btn-danger">✗ 拒绝</button>
</form>
</div>
</div>
</div>
{% endfor %}
</div>
{% else %}
<div class="empty-state">
<p>暂无待审核帖子</p>
</div>
{% endif %}
</section>
<!-- Recently Approved Posts -->
<section class="admin-section">
<h2 class="section-title">最近批准的帖子</h2>
{% if approved_posts %}
<div class="posts-grid">
{% for post in approved_posts %}
<div class="post-card">
<a href="{{ url_for('posts.post_detail', post_id=post.id) }}" class="post-image-link">
<img src="{{ url_for('uploaded_file', filename=post.image_path) }}" alt="Post image"
class="post-image" loading="lazy">
</a>
<div class="post-footer">
<span>{{ post.author.username }}</span>
<span class="badge badge-success">已批准</span>
</div>
</div>
{% endfor %}
</div>
{% else %}
<div class="empty-state">
<p>暂无已批准帖子</p>
</div>
{% endif %}
</section>
</div>
{% endblock %}

View File

@@ -0,0 +1,85 @@
{% extends "base.html" %}
{% block title %}用户审核 - 管理面板{% endblock %}
{% block content %}
<div class="container admin-container">
<div class="page-header">
<h1>👥 用户审核</h1>
<a href="{{ url_for('admin.dashboard') }}" class="btn btn-secondary">返回面板</a>
</div>
<!-- Pending Users -->
<section class="admin-section">
<h2 class="section-title">待审核用户 ({{ pending_users|length }})</h2>
{% if pending_users %}
<div class="admin-list">
{% for user in pending_users %}
<div class="admin-item">
<div class="admin-item-header">
<div class="user-info">
<div class="user-avatar">{{ user.username[0].upper() }}</div>
<div>
<div class="username">{{ user.username }}</div>
<div class="user-email">{{ user.email }}</div>
<div class="user-time">注册于 {{ user.created_at.strftime('%Y-%m-%d %H:%M') }}</div>
</div>
</div>
</div>
<!-- Student ID Photo -->
<div class="student-id-preview">
<p><strong>学生证照片:</strong></p>
<img src="{{ url_for('uploaded_file', filename=user.student_id_photo) }}" alt="Student ID"
class="student-id-image">
</div>
<!-- Actions -->
<div class="admin-actions">
<form method="POST" action="{{ url_for('admin.approve_user', user_id=user.id) }}"
style="display: inline;">
<button type="submit" class="btn btn-success">✓ 批准</button>
</form>
<form method="POST" action="{{ url_for('admin.reject_user', user_id=user.id) }}"
style="display: inline;" onsubmit="return confirm('确定要拒绝该用户的注册吗?');">
<button type="submit" class="btn btn-danger">✗ 拒绝</button>
</form>
</div>
</div>
{% endfor %}
</div>
{% else %}
<div class="empty-state">
<p>暂无待审核用户</p>
</div>
{% endif %}
</section>
<!-- Recently Approved Users -->
<section class="admin-section">
<h2 class="section-title">最近批准的用户</h2>
{% if approved_users %}
<div class="users-list">
{% for user in approved_users %}
<div class="user-list-item">
<div class="user-avatar">{{ user.username[0].upper() }}</div>
<div class="user-list-info">
<a href="{{ url_for('users.profile', username=user.username) }}" class="username">
{{ user.username }}
</a>
<p class="user-stats">{{ user.email }} · 加入于 {{ user.created_at.strftime('%Y-%m-%d') }}</p>
</div>
<span class="badge badge-success">已批准</span>
</div>
{% endfor %}
</div>
{% else %}
<div class="empty-state">
<p>暂无已批准用户</p>
</div>
{% endif %}
</section>
</div>
{% endblock %}

67
templates/base.html Normal file
View File

@@ -0,0 +1,67 @@
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{% block title %}泸州高中摄影社论坛{% endblock %}</title>
<link rel="stylesheet" href="{{ url_for('static', filename='css/style.css') }}">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Noto+Sans+SC:wght@300;400;500;700&display=swap" rel="stylesheet">
</head>
<body>
<!-- 导航栏 -->
<nav class="navbar">
<div class="container">
<div class="nav-brand">
<a href="{{ url_for('posts.index') }}">📷 泸州高中摄影社</a>
</div>
<div class="nav-menu">
{% if current_user.is_authenticated %}
<a href="{{ url_for('posts.index') }}" class="nav-link">首页</a>
<a href="{{ url_for('posts.create_post') }}" class="nav-link">发帖</a>
<a href="{{ url_for('users.profile', username=current_user.username) }}" class="nav-link">我的主页</a>
{% if current_user.is_admin %}
<a href="{{ url_for('admin.dashboard') }}" class="nav-link admin">管理面板</a>
{% endif %}
<a href="{{ url_for('auth.logout') }}" class="nav-link">退出</a>
<span class="nav-user">@{{ current_user.username }}</span>
{% else %}
<a href="{{ url_for('posts.index') }}" class="nav-link">首页</a>
<a href="{{ url_for('auth.login') }}" class="nav-link">登录</a>
<a href="{{ url_for('auth.register') }}" class="nav-link btn-primary">注册</a>
{% endif %}
</div>
</div>
</nav>
<!-- Flash 消息 -->
{% with messages = get_flashed_messages(with_categories=true) %}
{% if messages %}
<div class="flash-container">
{% for category, message in messages %}
<div class="flash flash-{{ category }}">
{{ message }}
<button class="flash-close" onclick="this.parentElement.remove()">×</button>
</div>
{% endfor %}
</div>
{% endif %}
{% endwith %}
<!-- 主内容 -->
<main class="main-content">
{% block content %}{% endblock %}
</main>
<!-- 页脚 -->
<footer class="footer">
<div class="container">
<p>&copy; 2026 泸州高中摄影社 | 分享精彩瞬间</p>
</div>
</footer>
<script src="{{ url_for('static', filename='js/main.js') }}"></script>
</body>
</html>

View File

@@ -0,0 +1,40 @@
{% extends "base.html" %}
{% block title %}修改密码 - 泸州高中摄影社论坛{% endblock %}
{% block content %}
<div class="auth-container">
<div class="auth-card">
<div class="auth-header">
<h1>🔐 修改密码</h1>
{% if current_user.is_admin and not current_user.password_changed %}
<p style="color: var(--warning-color);">首次登录,请修改默认密码以确保账号安全</p>
{% else %}
<p>修改您的登录密码</p>
{% endif %}
</div>
<form method="POST" class="auth-form">
<div class="form-group">
<label for="current_password">当前密码</label>
<input type="password" id="current_password" name="current_password" required placeholder="请输入当前密码"
class="form-control" autofocus>
</div>
<div class="form-group">
<label for="new_password">新密码</label>
<input type="password" id="new_password" name="new_password" required placeholder="至少6位"
class="form-control">
</div>
<div class="form-group">
<label for="confirm_password">确认新密码</label>
<input type="password" id="confirm_password" name="confirm_password" required placeholder="再次输入新密码"
class="form-control">
</div>
<button type="submit" class="btn btn-primary btn-block">确认修改</button>
</form>
</div>
</div>
{% endblock %}

View File

@@ -0,0 +1,44 @@
{% extends "base.html" %}
{% block title %}发布作品 - 泸州高中摄影社论坛{% endblock %}
{% block content %}
<div class="container create-post-container">
<div class="page-header">
<h1>📸 发布摄影作品</h1>
<p class="subtitle">分享你的精彩瞬间</p>
</div>
<div class="create-post-card">
<form method="POST" enctype="multipart/form-data" class="create-post-form">
<div class="form-group">
<label for="image">照片 <span class="required">*</span></label>
<div class="file-upload-area large" id="postImageUploadArea">
<input type="file" id="image" name="image" accept="image/*" required class="file-input">
<div class="file-upload-text">
<span class="upload-icon">🖼️</span>
<p>点击或拖拽上传照片</p>
<p class="file-hint">支持 PNG, JPG, JPEG, GIF, WEBP最大 16MB</p>
</div>
<img id="postImagePreview" class="image-preview large" style="display: none;">
</div>
</div>
<div class="form-group">
<label for="description">描述</label>
<textarea id="description" name="description" rows="5" placeholder="说说这张照片的故事..."
class="form-control"></textarea>
</div>
<div class="info-box">
<p><strong>提示:</strong>您的作品将在管理员审核通过后展示给所有用户。</p>
</div>
<div class="form-actions">
<a href="{{ url_for('posts.index') }}" class="btn btn-secondary">取消</a>
<button type="submit" class="btn btn-primary">发布作品</button>
</div>
</form>
</div>
</div>
{% endblock %}

15
templates/errors/404.html Normal file
View File

@@ -0,0 +1,15 @@
{% extends "base.html" %}
{% block title %}页面未找到 - 404{% endblock %}
{% block content %}
<div class="container">
<div class="empty-state">
<div class="empty-icon">🔍</div>
<h1 style="font-size: 3rem; margin-bottom: 1rem;">404</h1>
<h2>页面未找到</h2>
<p>抱歉,您访问的页面不存在。</p>
<a href="{{ url_for('posts.index') }}" class="btn btn-primary" style="margin-top: 2rem;">返回首页</a>
</div>
</div>
{% endblock %}

15
templates/errors/500.html Normal file
View File

@@ -0,0 +1,15 @@
{% extends "base.html" %}
{% block title %}服务器错误 - 500{% endblock %}
{% block content %}
<div class="container">
<div class="empty-state">
<div class="empty-icon">⚠️</div>
<h1 style="font-size: 3rem; margin-bottom: 1rem;">500</h1>
<h2>服务器内部错误</h2>
<p>抱歉,服务器遇到了一个错误。我们会尽快修复。</p>
<a href="{{ url_for('posts.index') }}" class="btn btn-primary" style="margin-top: 2rem;">返回首页</a>
</div>
</div>
{% endblock %}

34
templates/followers.html Normal file
View File

@@ -0,0 +1,34 @@
{% extends "base.html" %}
{% block title %}{{ user.username }} 的粉丝 - 泸州高中摄影社论坛{% endblock %}
{% block content %}
<div class="container">
<div class="page-header">
<h1>{{ user.username }} 的粉丝</h1>
<a href="{{ url_for('users.profile', username=user.username) }}" class="btn btn-secondary">返回主页</a>
</div>
{% if followers %}
<div class="users-list">
{% for follower in followers %}
<div class="user-list-item">
<a href="{{ url_for('users.profile', username=follower.username) }}" class="user-avatar">
{{ follower.username[0].upper() }}
</a>
<div class="user-list-info">
<a href="{{ url_for('users.profile', username=follower.username) }}" class="username">
{{ follower.username }}
</a>
<p class="user-stats">{{ follower.get_follower_count() }} 粉丝 · {{ follower.posts.count() }} 作品</p>
</div>
</div>
{% endfor %}
</div>
{% else %}
<div class="empty-state">
<p>还没有粉丝</p>
</div>
{% endif %}
</div>
{% endblock %}

35
templates/following.html Normal file
View File

@@ -0,0 +1,35 @@
{% extends "base.html" %}
{% block title %}{{ user.username }} 关注的人 - 泸州高中摄影社论坛{% endblock %}
{% block content %}
<div class="container">
<div class="page-header">
<h1>{{ user.username }} 关注的人</h1>
<a href="{{ url_for('users.profile', username=user.username) }}" class="btn btn-secondary">返回主页</a>
</div>
{% if following %}
<div class="users-list">
{% for followed_user in following %}
<div class="user-list-item">
<a href="{{ url_for('users.profile', username=followed_user.username) }}" class="user-avatar">
{{ followed_user.username[0].upper() }}
</a>
<div class="user-list-info">
<a href="{{ url_for('users.profile', username=followed_user.username) }}" class="username">
{{ followed_user.username }}
</a>
<p class="user-stats">{{ followed_user.get_follower_count() }} 粉丝 · {{ followed_user.posts.count() }} 作品
</p>
</div>
</div>
{% endfor %}
</div>
{% else %}
<div class="empty-state">
<p>还没有关注任何人</p>
</div>
{% endif %}
</div>
{% endblock %}

87
templates/index.html Normal file
View File

@@ -0,0 +1,87 @@
{% extends "base.html" %}
{% block title %}首页 - 泸州高中摄影社论坛{% endblock %}
{% block content %}
<div class="container">
<div class="page-header">
<h1>📸 摄影作品分享</h1>
<p class="subtitle">发现精彩瞬间</p>
</div>
{% if posts %}
<div class="posts-grid">
{% for post in posts %}
<div class="post-card">
<div class="post-header">
<div class="user-info">
<a href="{{ url_for('users.profile', username=post.author.username) }}" class="user-avatar">
{{ post.author.username[0].upper() }}
</a>
<div>
<a href="{{ url_for('users.profile', username=post.author.username) }}" class="username">
{{ post.author.username }}
</a>
<span class="post-time">{{ post.created_at.strftime('%Y-%m-%d %H:%M') }}</span>
</div>
</div>
</div>
<a href="{{ url_for('posts.post_detail', post_id=post.id) }}" class="post-image-link">
<img src="{{ url_for('uploaded_file', filename=post.image_path) }}" alt="Post image" class="post-image"
loading="lazy">
</a>
{% if post.description %}
<div class="post-description">
{{ post.description }}
</div>
{% endif %}
<div class="post-footer">
<a href="{{ url_for('posts.post_detail', post_id=post.id) }}" class="comment-count">
💬 {{ post.get_comment_count() }} 条评论
</a>
</div>
</div>
{% endfor %}
</div>
<!-- 分页 -->
{% if pagination.pages > 1 %}
<div class="pagination">
{% if pagination.has_prev %}
<a href="{{ url_for('posts.index', page=pagination.prev_num) }}" class="page-link">上一页</a>
{% endif %}
{% for page_num in pagination.iter_pages(left_edge=1, right_edge=1, left_current=2, right_current=2) %}
{% if page_num %}
{% if page_num == pagination.page %}
<span class="page-link active">{{ page_num }}</span>
{% else %}
<a href="{{ url_for('posts.index', page=page_num) }}" class="page-link">{{ page_num }}</a>
{% endif %}
{% else %}
<span class="page-link">...</span>
{% endif %}
{% endfor %}
{% if pagination.has_next %}
<a href="{{ url_for('posts.index', page=pagination.next_num) }}" class="page-link">下一页</a>
{% endif %}
</div>
{% endif %}
{% else %}
<div class="empty-state">
<div class="empty-icon">📷</div>
<h2>还没有帖子</h2>
<p>成为第一个分享摄影作品的人吧!</p>
{% if current_user.is_authenticated %}
<a href="{{ url_for('posts.create_post') }}" class="btn btn-primary">发布作品</a>
{% else %}
<a href="{{ url_for('auth.register') }}" class="btn btn-primary">立即注册</a>
{% endif %}
</div>
{% endif %}
</div>
{% endblock %}

38
templates/login.html Normal file
View File

@@ -0,0 +1,38 @@
{% extends "base.html" %}
{% block title %}登录 - 泸州高中摄影社论坛{% endblock %}
{% block content %}
<div class="auth-container">
<div class="auth-card">
<div class="auth-header">
<h1>🔐 欢迎回来</h1>
<p>登录查看更多精彩作品</p>
</div>
<form method="POST" class="auth-form">
<div class="form-group">
<label for="username">用户名</label>
<input type="text" id="username" name="username" required placeholder="请输入用户名" class="form-control"
autofocus>
</div>
<div class="form-group">
<label for="password">密码</label>
<input type="password" id="password" name="password" required placeholder="请输入密码" class="form-control">
</div>
<div class="form-check">
<input type="checkbox" id="remember" name="remember" class="form-checkbox">
<label for="remember">记住我</label>
</div>
<button type="submit" class="btn btn-primary btn-block">登录</button>
</form>
<div class="auth-footer">
<p>还没有账号?<a href="{{ url_for('auth.register') }}">立即注册</a></p>
</div>
</div>
</div>
{% endblock %}

View File

@@ -0,0 +1,81 @@
{% extends "base.html" %}
{% block title %}{{ post.author.username }} 的作品 - 泸州高中摄影社论坛{% endblock %}
{% block content %}
<div class="container post-detail-container">
<div class="post-detail-card">
<!-- Post Header -->
<div class="post-detail-header">
<a href="{{ url_for('users.profile', username=post.author.username) }}" class="user-info-large">
<div class="user-avatar-large">
{{ post.author.username[0].upper() }}
</div>
<div>
<div class="username-large">{{ post.author.username }}</div>
<div class="post-time">{{ post.created_at.strftime('%Y年%m月%d日 %H:%M') }}</div>
</div>
</a>
{% if not post.is_approved %}
<div class="badge badge-warning">等待审核</div>
{% endif %}
</div>
<!-- Post Image -->
<div class="post-detail-image">
<img src="{{ url_for('uploaded_file', filename=post.image_path) }}" alt="Post image" class="detail-image">
</div>
<!-- Post Description -->
{% if post.description %}
<div class="post-detail-description">
{{ post.description }}
</div>
{% endif %}
<!-- Comments Section -->
<div class="comments-section">
<h2 class="comments-title">💬 评论 ({{ comments|length }})</h2>
{% if current_user.is_authenticated and current_user.is_approved and post.is_approved %}
<form method="POST" action="{{ url_for('posts.add_comment', post_id=post.id) }}" class="comment-form">
<textarea name="content" placeholder="发表你的想法..." required class="comment-input"></textarea>
<button type="submit" class="btn btn-primary">发表评论</button>
</form>
{% elif not current_user.is_authenticated %}
<div class="info-box">
<p><a href="{{ url_for('auth.login') }}">登录</a> 后可以发表评论</p>
</div>
{% endif %}
<!-- Comments List -->
<div class="comments-list">
{% for comment in comments %}
<div class="comment-item">
<a href="{{ url_for('users.profile', username=comment.author.username) }}" class="comment-avatar">
{{ comment.author.username[0].upper() }}
</a>
<div class="comment-content">
<div class="comment-header">
<a href="{{ url_for('users.profile', username=comment.author.username) }}"
class="comment-username">
{{ comment.author.username }}
</a>
<span class="comment-time">{{ comment.created_at.strftime('%Y-%m-%d %H:%M') }}</span>
</div>
<div class="comment-text">{{ comment.content }}</div>
</div>
</div>
{% endfor %}
{% if not comments %}
<div class="empty-comments">
<p>还没有评论,快来抢沙发吧!</p>
</div>
{% endif %}
</div>
</div>
</div>
</div>
{% endblock %}

87
templates/profile.html Normal file
View File

@@ -0,0 +1,87 @@
{% extends "base.html" %}
{% block title %}{{ user.username }} - 泸州高中摄影社论坛{% endblock %}
{% block content %}
<div class="container profile-container">
<!-- Profile Header -->
<div class="profile-header">
<div class="profile-avatar-large">
{{ user.username[0].upper() }}
</div>
<div class="profile-info">
<h1 class="profile-username">{{ user.username }}</h1>
{% if not user.is_approved %}
<div class="badge badge-warning">等待审核</div>
{% endif %}
<div class="profile-stats">
<div class="stat-item">
<span class="stat-number">{{ posts|length }}</span>
<span class="stat-label">作品</span>
</div>
<div class="stat-item">
<a href="{{ url_for('users.followers', username=user.username) }}">
<span class="stat-number">{{ follower_count }}</span>
<span class="stat-label">粉丝</span>
</a>
</div>
<div class="stat-item">
<a href="{{ url_for('users.following', username=user.username) }}">
<span class="stat-number">{{ following_count }}</span>
<span class="stat-label">关注</span>
</a>
</div>
</div>
{% if user.bio %}
<p class="profile-bio">{{ user.bio }}</p>
{% endif %}
<!-- Follow Button -->
{% if current_user.is_authenticated and current_user.id != user.id %}
{% if is_following %}
<form method="POST" action="{{ url_for('users.unfollow', username=user.username) }}"
style="display: inline;">
<button type="submit" class="btn btn-secondary">已关注</button>
</form>
{% else %}
<form method="POST" action="{{ url_for('users.follow', username=user.username) }}" style="display: inline;">
<button type="submit" class="btn btn-primary">关注</button>
</form>
{% endif %}
{% endif %}
</div>
</div>
<!-- User Posts -->
<div class="profile-posts">
<h2 class="section-title">📸 作品集</h2>
{% if posts %}
<div class="posts-grid">
{% for post in posts %}
<div class="post-card">
<a href="{{ url_for('posts.post_detail', post_id=post.id) }}" class="post-image-link">
<img src="{{ url_for('uploaded_file', filename=post.image_path) }}" alt="Post image"
class="post-image" loading="lazy">
{% if not post.is_approved %}
<div class="badge badge-overlay">审核中</div>
{% endif %}
</a>
<div class="post-footer">
<span class="comment-count">💬 {{ post.get_comment_count() }}</span>
</div>
</div>
{% endfor %}
</div>
{% else %}
<div class="empty-state">
<div class="empty-icon">📷</div>
<p>该用户还没有发布作品</p>
</div>
{% endif %}
</div>
</div>
{% endblock %}

61
templates/register.html Normal file
View File

@@ -0,0 +1,61 @@
{% extends "base.html" %}
{% block title %}注册 - 泸州高中摄影社论坛{% endblock %}
{% block content %}
<div class="auth-container">
<div class="auth-card">
<div class="auth-header">
<h1>📷 加入摄影社</h1>
<p>分享你的摄影作品,发现更多精彩</p>
</div>
<form method="POST" enctype="multipart/form-data" class="auth-form">
<div class="form-group">
<label for="username">用户名</label>
<input type="text" id="username" name="username" required placeholder="请输入用户名" class="form-control">
</div>
<div class="form-group">
<label for="email">邮箱</label>
<input type="email" id="email" name="email" required placeholder="请输入邮箱" class="form-control">
</div>
<div class="form-group">
<label for="password">密码</label>
<input type="password" id="password" name="password" required placeholder="至少6位" class="form-control">
</div>
<div class="form-group">
<label for="confirm_password">确认密码</label>
<input type="password" id="confirm_password" name="confirm_password" required placeholder="再次输入密码"
class="form-control">
</div>
<div class="form-group">
<label for="student_id_photo">学生证照片 <span class="required">*</span></label>
<div class="file-upload-area" id="fileUploadArea">
<input type="file" id="student_id_photo" name="student_id_photo" accept="image/*" required
class="file-input">
<div class="file-upload-text">
<span class="upload-icon">📤</span>
<p>点击或拖拽上传学生证照片</p>
<p class="file-hint">支持 PNG, JPG, JPEG, GIF, WEBP</p>
</div>
<img id="imagePreview" class="image-preview" style="display: none;">
</div>
</div>
<div class="info-box">
<p><strong>注意:</strong>您上传的学生证照片将用于身份验证,管理员审核通过后才能使用论坛功能。</p>
</div>
<button type="submit" class="btn btn-primary btn-block">提交注册</button>
</form>
<div class="auth-footer">
<p>已有账号?<a href="{{ url_for('auth.login') }}">立即登录</a></p>
</div>
</div>
</div>
{% endblock %}