diff --git a/app.py b/app.py index 3061c04..662f0a7 100644 --- a/app.py +++ b/app.py @@ -700,12 +700,43 @@ def api_add_friend(): friend_id = data.get('friend_id') if not friend_id or friend_id == user_id: return jsonify({'success': False, 'message': '无效的好友ID'}), 400 + + # 检查是否已经是好友或有待处理的请求 existing = Friend.query.filter( ((Friend.user_id == user_id) & (Friend.friend_id == friend_id)) | ((Friend.user_id == friend_id) & (Friend.friend_id == user_id)) ).first() + if existing: - return jsonify({'success': False, 'message': '已经是好友或已发送请求'}), 400 + # 如果已经是好友,不允许重复申请 + if existing.status == 'accepted': + return jsonify({'success': False, 'message': '已经是好友'}), 400 + + # 如果有待处理的请求,不允许重复发送 + if existing.status == 'pending': + return jsonify({'success': False, 'message': '已发送好友请求,请等待对方处理'}), 400 + + # 如果之前被拒绝,允许重新发送(更新状态为pending) + if existing.status == 'rejected': + # 确保是当前用户发起的请求才能更新 + if existing.user_id == user_id: + existing.status = 'pending' + existing.created_at = datetime.utcnow() + db.session.flush() + + # 重新发送通知给对方 + sender_name = session['user'].get('name', '未知用户') + notif = Notification(user_id=friend_id, type='friend_request', + content=f'{sender_name} 请求添加你为好友', + from_user=sender_name, post_id=existing.id) + db.session.add(notif) + db.session.commit() + return jsonify({'success': True, 'message': '好友请求已重新发送'}) + else: + # 如果是对方之前发起的请求被拒绝,当前用户可以创建新的请求 + pass + + # 创建新的好友请求 friend_req = Friend(user_id=user_id, friend_id=friend_id, status='pending') db.session.add(friend_req) db.session.flush() @@ -3052,7 +3083,8 @@ def api_unregister_contest(contest_id): def api_contest_posts(contest_id): """获取杯赛讨论区帖子列表""" contest = Contest.query.get_or_404(contest_id) - posts = Post.query.filter_by(contest_id=contest_id).order_by(Post.created_at.desc()).all() + # 置顶帖子在前,然后按创建时间倒序 + posts = Post.query.filter_by(contest_id=contest_id).order_by(Post.pinned.desc(), Post.created_at.desc()).all() user = get_current_user() uid = user['id'] if user else None data = [] @@ -3127,11 +3159,11 @@ def api_search_posts(): query = query.filter_by(tag=tag) if sort == 'hottest': - query = query.order_by(Post.likes.desc()) + query = query.order_by(Post.pinned.desc(), Post.likes.desc()) elif sort == 'most_replies': - query = query.order_by(Post.replies_count.desc()) + query = query.order_by(Post.pinned.desc(), Post.replies_count.desc()) else: - query = query.order_by(Post.created_at.desc()) + query = query.order_by(Post.pinned.desc(), Post.created_at.desc()) posts = query.all() user = session.get('user') @@ -3712,6 +3744,25 @@ def api_create_post_with_poll(): def api_share_post(post_id): return jsonify({'success': True}) +@app.route('/api/posts//pin', methods=['POST']) +@login_required +def api_pin_post(post_id): + """置顶/取消置顶帖子(仅管理员)""" + user = session.get('user') + if user.get('role') != 'admin': + return jsonify({'success': False, 'message': '只有管理员可以置顶帖子'}), 403 + + post = Post.query.get(post_id) + if not post: + return jsonify({'success': False, 'message': '帖子不存在'}), 404 + + # 切换置顶状态 + post.pinned = not post.pinned + db.session.commit() + + action = '置顶' if post.pinned else '取消置顶' + return jsonify({'success': True, 'message': f'帖子已{action}', 'pinned': post.pinned}) + # ========== 聊天系统页面 ========== @app.route('/chat') @login_required diff --git a/templates/forum.html b/templates/forum.html index 36fc51a..fd3a068 100644 --- a/templates/forum.html +++ b/templates/forum.html @@ -563,7 +563,7 @@ async function openPost(pid) { const p = data.data; const replies = data.replies || []; const isAuthor = CU && CU.id === p.author_id; - const isTeacher = CU && CU.role === 'teacher'; + const isTeacher = CU && (CU.role === 'teacher' || CU.role === 'admin'); const reactions = p.reactions || {}; let reactBtns = '';