feat: 用户被多次举报合并

This commit is contained in:
DengDai
2025-11-25 09:36:36 +08:00
parent 881188587d
commit 40feb92473
7 changed files with 120 additions and 44 deletions

View File

@@ -1,5 +1,6 @@
from flask import abort, Blueprint, render_template, request, flash, redirect, url_for, current_app
from sqlalchemy import or_
from sqlalchemy.orm.attributes import flag_modified
from flask_login import login_required, current_user
from app import db
from app.forms import SearchForm, ReportForm, UpdateUserForm, CommentForm, RevokeForm, AppealForm, AppealMessageForm, PartnerSiteForm
@@ -24,13 +25,12 @@ def index():
search_term = form.search_term.data
normalized_email = normalize_email(search_term)
search_result = Blacklist.query.join(Report).filter(
search_result = Blacklist.query.filter(
or_(
Blacklist.normalized_email == normalized_email,
Blacklist.username == search_term
),
Blacklist.status == 'active',
Report.status == 'approved'
Blacklist.status == 'active'
).first()
if search_result:
@@ -46,6 +46,9 @@ def index():
@login_required
def create_report():
"""创建新举报"""
if current_user.status != 'active':
flash('您的账户尚未激活,无法提交举报。请等待管理员审核。', 'warning')
return redirect(url_for('main.index'))
form = ReportForm()
active_sites = PartnerSite.query.filter_by(is_active=True).order_by(PartnerSite.name).all()
form.reported_pt_site.choices = [(site.name, site.name) for site in active_sites]
@@ -170,41 +173,60 @@ def process_report(report_id):
if action == 'confirm':
report.status = 'approved'
existing_blacklist = Blacklist.query.filter_by(report_id=report.id).first()
normalized = normalize_email(report.reported_email)
existing_blacklist = Blacklist.query.filter_by(normalized_email=normalized, status='active').first()
if not existing_blacklist:
new_blacklist_entry = Blacklist(
email=report.reported_email,
normalized_email=normalize_email(report.reported_email),
normalized_email=normalized,
pt_site=report.reported_pt_site,
uid=report.reported_username,
report_id=report.id,
report_ids=[report.id],
reason_categories=[report.reason_category],
username=report.reported_username or None
)
db.session.add(new_blacklist_entry)
other_pending = Report.query.filter(
Report.reported_email == report.reported_email,
Report.id != report.id,
Report.status == 'pending'
).all()
for other_report in other_pending:
other_report.status = 'approved'
comment = Comment(
body=f'该举报已自动批准(关联举报 #{report.id} 已确认违规)',
report=other_report,
author=current_user._get_current_object()
)
db.session.add(comment)
current_app.logger.info(f'举报批准: #{report.id} - {report.reported_email} by {current_user.username}')
if other_pending:
current_app.logger.info(f'自动批准关联举报: {len(other_pending)}')
flash(f'举报已批准,并已将相关信息添加到黑名单。同时自动处理了 {len(other_pending)} 个相关举报。', 'success')
else:
flash('举报已批准,并已将相关信息添加到黑名单。', 'success')
flash('举报已批准,并已将相关信息添加到黑名单。', 'success')
else:
flash('举报状态已更新为"批准"。该举报已在黑名单中,无需重复添加。', 'info')
if report.reason_category not in existing_blacklist.reason_categories:
existing_blacklist.reason_categories.append(report.reason_category)
existing_blacklist.report_ids.append(report.id)
flag_modified(existing_blacklist, 'reason_categories')
flag_modified(existing_blacklist, 'report_ids')
current_app.logger.info(f'举报合并: #{report.id} 合并到黑名单#{existing_blacklist.id} - 新增原因: {report.reason_category}')
flash(f'举报已批准并合并到现有黑名单记录(新增违规原因:{report.reason_category})。', 'success')
else:
current_app.logger.info(f'举报批准: #{report.id} - 相同原因已存在,不合并')
flash('举报已批准。该用户已有相同违规原因的记录,未进行合并。', 'info')
other_pending = Report.query.filter(
Report.reported_email == report.reported_email,
Report.id != report.id,
Report.status == 'pending'
).all()
merged_count = 0
for other_report in other_pending:
other_report.status = 'approved'
bl = existing_blacklist or new_blacklist_entry
if other_report.reason_category not in bl.reason_categories:
bl.reason_categories.append(other_report.reason_category)
bl.report_ids.append(other_report.id)
flag_modified(bl, 'reason_categories')
flag_modified(bl, 'report_ids')
merged_count += 1
comment = Comment(
body=f'该举报已自动批准(关联举报 #{report.id} 已确认违规)',
report=other_report,
author=current_user._get_current_object()
)
db.session.add(comment)
if other_pending:
current_app.logger.info(f'自动批准关联举报: {len(other_pending)}个,合并{merged_count}个不同原因')
flash(f'同时自动处理了 {len(other_pending)} 个相关举报(其中 {merged_count} 个不同原因已合并)。', 'info')
elif action == 'invalidate':
report.status = 'rejected'
current_app.logger.info(f'举报驳回: #{report.id} by {current_user.username}')
@@ -224,9 +246,23 @@ def revoke_report(report_id):
return redirect(url_for('main.report_detail', report_id=report.id))
form = RevokeForm()
if form.validate_on_submit():
blacklist_entry = Blacklist.query.filter_by(report_id=report.id).first()
if blacklist_entry:
db.session.delete(blacklist_entry)
normalized = normalize_email(report.reported_email)
blacklist_entry = Blacklist.query.filter_by(normalized_email=normalized, status='active').first()
if blacklist_entry and report.id in blacklist_entry.report_ids:
blacklist_entry.report_ids.remove(report.id)
if report.reason_category in blacklist_entry.reason_categories:
blacklist_entry.reason_categories.remove(report.reason_category)
flag_modified(blacklist_entry, 'report_ids')
flag_modified(blacklist_entry, 'reason_categories')
if len(blacklist_entry.report_ids) == 0:
db.session.delete(blacklist_entry)
current_app.logger.warning(f'举报撤销: #{report.id} - 黑名单记录已删除')
flash('举报已成功撤销,并已从黑名单中移除。', 'success')
else:
current_app.logger.warning(f'举报撤销: #{report.id} - 从黑名单中移除该举报')
flash(f'举报已成功撤销,已从黑名单中移除该违规原因(剩余 {len(blacklist_entry.report_ids)} 个举报)。', 'success')
report.status = 'revoked'
revocation_comment = Comment(
@@ -237,7 +273,6 @@ def revoke_report(report_id):
db.session.add(revocation_comment)
db.session.commit()
current_app.logger.warning(f'举报撤销: #{report.id} by {current_user.username} - 理由: {form.reason.data[:50]}')
flash('举报已成功撤销,并已从黑名单中移除。', 'success')
else:
flash('撤销失败:' + ' '.join(form.reason.errors), 'danger')
return redirect(url_for('main.report_detail', report_id=report.id))
@@ -398,9 +433,11 @@ def decide_appeal(appeal_id):
blacklist_entry = appeal.blacklist_entry
blacklist_entry.status = 'revoked'
appeal.status = 'approved'
if blacklist_entry.report:
blacklist_entry.report.status = 'overturned'
db.session.add(blacklist_entry.report)
for report_id in blacklist_entry.report_ids:
report = Report.query.get(report_id)
if report:
report.status = 'overturned'
db.session.add(report)
db.session.add(blacklist_entry)
db.session.add(appeal)
db.session.commit()