init
This commit is contained in:
55
app/templates/admin/appeal_list.html
Normal file
55
app/templates/admin/appeal_list.html
Normal file
@@ -0,0 +1,55 @@
|
||||
{% extends "base.html" %}
|
||||
|
||||
{% block title %}申诉管理{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="card shadow-sm">
|
||||
<div class="card-header">
|
||||
<h2 class="mb-0">申诉管理</h2>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="table-responsive">
|
||||
<table class="table table-hover align-middle">
|
||||
<thead class="table-light">
|
||||
<tr>
|
||||
<th>#ID</th>
|
||||
<th>申诉人</th>
|
||||
<th>关联用户名</th>
|
||||
<th>状态</th>
|
||||
<th>最后更新</th>
|
||||
<th>操作</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for appeal in appeals.items %}
|
||||
<tr>
|
||||
<td>{{ appeal.id }}</td>
|
||||
<td>{{ appeal.appealer.username if appeal.appealer else '未知用户' }}</td>
|
||||
<td>{{ appeal.blacklist_entry.uid }}</td>
|
||||
<td>
|
||||
<span class="badge
|
||||
{% if 'closed' in appeal.status %} bg-secondary
|
||||
{% elif 'user' in appeal.status %} bg-warning text-dark
|
||||
{% else %} bg-info text-dark {% endif %}">
|
||||
{{ appeal.status }}
|
||||
</span>
|
||||
</td>
|
||||
<td>{{ appeal.updated_at.strftime('%Y-%m-%d %H:%M') }}</td>
|
||||
<td>
|
||||
<a href="{{ url_for('main.appeal_detail', appeal_id=appeal.id) }}" class="btn btn-sm btn-outline-primary">查看详情</a>
|
||||
</td>
|
||||
</tr>
|
||||
{% else %}
|
||||
<tr>
|
||||
<td colspan="6" class="text-center text-muted">暂无申诉记录。</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-footer">
|
||||
<!-- 分页逻辑 -->
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
71
app/templates/admin/manage_sites.html
Normal file
71
app/templates/admin/manage_sites.html
Normal file
@@ -0,0 +1,71 @@
|
||||
{% extends "base.html" %}
|
||||
|
||||
{% block title %}合作站点管理{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<h2 class="mb-4">合作站点管理</h2>
|
||||
|
||||
<div class="row">
|
||||
<!-- 添加新站点表单 -->
|
||||
<div class="col-md-4">
|
||||
<div class="card">
|
||||
<div class="card-header">添加新站点</div>
|
||||
<div class="card-body">
|
||||
<form method="POST" action="{{ url_for('main.manage_sites') }}" novalidate>
|
||||
{{ form.hidden_tag() }}
|
||||
<div class="mb-3">
|
||||
{{ form.name.label(class="form-label") }}
|
||||
{{ form.name(class="form-control") }}
|
||||
{% for error in form.name.errors %}
|
||||
<div class="text-danger small">{{ error }}</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
{{ form.url.label(class="form-label") }}
|
||||
{{ form.url(class="form-control", placeholder="https://example.com") }}
|
||||
{% for error in form.url.errors %}
|
||||
<div class="text-danger small">{{ error }}</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{{ form.submit(class="btn btn-primary") }}
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 站点列表 -->
|
||||
<div class="col-md-8">
|
||||
<div class="card">
|
||||
<div class="card-header">站点列表</div>
|
||||
<div class="list-group list-group-flush">
|
||||
{% if sites %}
|
||||
{% for site in sites %}
|
||||
<div class="list-group-item d-flex justify-content-between align-items-center">
|
||||
<div>
|
||||
<strong>{{ site.name }}</strong>
|
||||
{% if not site.is_active %}<span class="badge bg-secondary">已禁用</span>{% endif %}
|
||||
<br>
|
||||
<small class="text-muted">{{ site.url or '未提供 URL' }}</small>
|
||||
</div>
|
||||
<div class="btn-group">
|
||||
<!-- 切换启用/禁用状态的按钮 -->
|
||||
<form action="{{ url_for('main.toggle_site_active', site_id=site.id) }}" method="POST" class="d-inline">
|
||||
<button type="submit" class="btn btn-sm btn-{{ 'warning' if site.is_active else 'success' }}">
|
||||
{{ '禁用' if site.is_active else '启用' }}
|
||||
</button>
|
||||
</form>
|
||||
<!-- 删除按钮 -->
|
||||
<form action="{{ url_for('main.delete_site', site_id=site.id) }}" method="POST" class="d-inline ms-2">
|
||||
<button type="submit" class="btn btn-sm btn-danger" onclick="return confirm('确定要删除站点 {{ site.name }} 吗?此操作不可逆!');">删除</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
{% else %}
|
||||
<div class="list-group-item text-center text-muted">暂无合作站点。</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
72
app/templates/admin/manage_users.html
Normal file
72
app/templates/admin/manage_users.html
Normal file
@@ -0,0 +1,72 @@
|
||||
{% extends "base.html" %}
|
||||
|
||||
{% block title %}管理后台 - 用户管理{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="card shadow-sm">
|
||||
<div class="card-header">
|
||||
<h2 class="mb-0">用户管理</h2>
|
||||
<p class="text-muted mb-0">在这里您可以管理所有已注册用户的角色和状态。</p>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="table-responsive">
|
||||
<table class="table table-striped table-hover align-middle">
|
||||
<thead class="table-light">
|
||||
<tr>
|
||||
<th>ID</th>
|
||||
<th>用户名 / 邮箱</th>
|
||||
<th>注册站点 / UID</th>
|
||||
<th>注册时间</th>
|
||||
<th style="min-width: 200px;">角色与状态</th>
|
||||
<th style="min-width: 120px;">操作</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for user in users %}
|
||||
<tr>
|
||||
<td>{{ user.id }}</td>
|
||||
<td>
|
||||
<div><strong>{{ user.username }}</strong></div>
|
||||
<small class="text-muted">{{ user.email }}</small>
|
||||
</td>
|
||||
<td>{{ user.pt_site }} / {{ user.uid }}</td>
|
||||
<td>{{ user.created_at.strftime('%Y-%m-%d') }}</td>
|
||||
{% if user.id == 1 %}
|
||||
<td>
|
||||
<div>角色: <span class="badge bg-danger">{{ user.role }}</span></div>
|
||||
<div>状态: <span class="badge bg-success">{{ user.status }}</span></div>
|
||||
</td>
|
||||
<td>
|
||||
<button class="btn btn-sm btn-secondary" disabled>不可修改</button>
|
||||
</td>
|
||||
{% else %}
|
||||
<form action="{{ url_for('main.update_user', user_id=user.id) }}" method="POST">
|
||||
{% set form = forms[user.id] %}
|
||||
{{ form.hidden_tag() }}
|
||||
<td>
|
||||
<div class="input-group input-group-sm mb-2">
|
||||
<span class="input-group-text">角色</span>
|
||||
{{ form.role(class="form-select") }}
|
||||
</div>
|
||||
<div class="input-group input-group-sm">
|
||||
<span class="input-group-text">状态</span>
|
||||
{{ form.status(class="form-select") }}
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
{{ form.submit(class="btn btn-sm btn-primary") }}
|
||||
</td>
|
||||
</form>
|
||||
{% endif %}
|
||||
</tr>
|
||||
{% else %}
|
||||
<tr>
|
||||
<td colspan="6" class="text-center text-muted">没有已注册的用户。</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
50
app/templates/admin/pending_users.html
Normal file
50
app/templates/admin/pending_users.html
Normal file
@@ -0,0 +1,50 @@
|
||||
{% extends "base.html" %}
|
||||
|
||||
{% block title %}管理后台 - 用户审核{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="card shadow-sm">
|
||||
<div class="card-header">
|
||||
<h2 class="mb-0">待审核用户列表</h2>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="table-responsive">
|
||||
<table class="table table-hover align-middle">
|
||||
<thead class="table-light">
|
||||
<tr>
|
||||
<th>用户名</th>
|
||||
<th>邮箱</th>
|
||||
<th>所在站点</th>
|
||||
<th>UID</th>
|
||||
<th>申请时间</th>
|
||||
<th>操作</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for user in users %}
|
||||
<tr>
|
||||
<td>{{ user.username }}</td>
|
||||
<td>{{ user.email }}</td>
|
||||
<td>{{ user.pt_site }}</td>
|
||||
<td>{{ user.uid }}</td>
|
||||
<td>{{ user.created_at.strftime('%Y-%m-%d %H:%M') }}</td>
|
||||
<td>
|
||||
<form action="{{ url_for('main.approve_user', user_id=user.id) }}" method="POST" class="d-inline">
|
||||
<button type="submit" class="btn btn-sm btn-success">批准</button>
|
||||
</form>
|
||||
<form action="{{ url_for('main.reject_user', user_id=user.id) }}" method="POST" class="d-inline">
|
||||
<button type="submit" class="btn btn-sm btn-danger" onclick="return confirm('确定要拒绝并删除该用户吗?');">拒绝</button>
|
||||
</form>
|
||||
</td>
|
||||
</tr>
|
||||
{% else %}
|
||||
<tr>
|
||||
<td colspan="6" class="text-center text-muted">目前没有待审核的用户。</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
125
app/templates/admin/report_detail.html
Normal file
125
app/templates/admin/report_detail.html
Normal file
@@ -0,0 +1,125 @@
|
||||
{% extends "base.html" %}
|
||||
|
||||
{% block title %}举报详情 - #{{ report.id }}{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="row">
|
||||
<!-- 左侧信息栏 -->
|
||||
<div class="col-lg-5">
|
||||
<div class="card shadow-sm mb-4">
|
||||
<div class="card-header"><h4 class="mb-0">举报详情 #{{ report.id }}</h4></div>
|
||||
<div class="card-body">
|
||||
<ul class="list-group list-group-flush">
|
||||
<li class="list-group-item"><strong>被举报邮箱:</strong> {{ report.reported_email }}</li>
|
||||
<li class="list-group-item"><strong>被举报用户名:</strong> {{ report.reported_uid or 'N/A' }}</li>
|
||||
<li class="list-group-item"><strong>所属站点:</strong> {{ report.reported_pt_site }}</li>
|
||||
<li class="list-group-item"><strong>举报理由:</strong> {{ report.reason_category }}</li>
|
||||
<li class="list-group-item"><strong>举报人:</strong> {{ report.reporter.username }}</li>
|
||||
<li class="list-group-item"><strong>状态:</strong> <strong class="text-capitalize">{{ report.status }}</strong></li>
|
||||
<li class="list-group-item"><strong>详细描述:</strong><br><span style="white-space: pre-wrap;">{{ report.description }}</span></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card shadow-sm mb-4">
|
||||
<div class="card-header"><h5 class="mb-0">证据链接</h5></div>
|
||||
<div class="list-group list-group-flush">
|
||||
{% for evidence in report.evidences %}
|
||||
<a href="{{ evidence.file_url }}" target="_blank" class="list-group-item list-group-item-action">
|
||||
{{ evidence.file_url }}
|
||||
</a>
|
||||
{% else %}
|
||||
<div class="list-group-item text-muted">未提供证据链接。</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% if current_user.role == 'admin' %}
|
||||
<div class="card shadow-sm mb-4">
|
||||
<div class="card-header"><h5 class="mb-0">管理员操作</h5></div>
|
||||
<div class="card-body d-grid gap-2">
|
||||
{% if report.status == 'pending' or report.status == 'in_review' %}
|
||||
<form action="{{ url_for('main.process_report', report_id=report.id, action='confirm') }}" method="POST" class="d-grid">
|
||||
<button type="submit" class="btn btn-success">确认违规 (加入黑名单)</button>
|
||||
</form>
|
||||
<form action="{{ url_for('main.process_report', report_id=report.id, action='invalidate') }}" method="POST" class="d-grid">
|
||||
<button type="submit" class="btn btn-warning">举报无效</button>
|
||||
</form>
|
||||
{% elif report.status == 'approved' %}
|
||||
<button type="button" class="btn btn-danger" data-bs-toggle="modal" data-bs-target="#revokeModal">
|
||||
撤销批准并移出黑名单
|
||||
</button>
|
||||
{% else %}
|
||||
<p class="text-muted mb-0">该举报已处理完毕,无更多操作。</p>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
<!-- 右侧评论区 -->
|
||||
<div class="col-lg-7">
|
||||
<div class="card shadow-sm">
|
||||
<div class="card-header"><h5 class="mb-0">审核与讨论</h5></div>
|
||||
<div class="card-body" style="max-height: 500px; overflow-y: auto;">
|
||||
{% for comment in comments %}
|
||||
<div class="d-flex mb-3">
|
||||
<div class="flex-shrink-0"><span class="badge rounded-pill bg-secondary">{{ comment.author.username }}</span></div>
|
||||
<div class="flex-grow-1 ms-3">
|
||||
<div class="p-2 bg-light rounded">
|
||||
<p class="small mb-0">{{ comment.body | safe }}</p>
|
||||
</div>
|
||||
<small class="text-muted">{{ comment.timestamp.strftime('%Y-%m-%d %H:%M') }}</small>
|
||||
</div>
|
||||
</div>
|
||||
{% else %}
|
||||
<p class="text-muted">暂无审核建议。</p>
|
||||
{% endfor %}
|
||||
</div>
|
||||
|
||||
{% if report.status == 'pending' or report.status == 'in_review' %}
|
||||
<div class="card-footer">
|
||||
<form method="POST">
|
||||
{{ form.hidden_tag() }}
|
||||
<div class="input-group">
|
||||
{{ form.body(class="form-control", placeholder="提交审核建议...") }}
|
||||
{{ form.submit(class="btn btn-outline-secondary") }}
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
{% else %}
|
||||
<div class="card-footer text-center bg-light">
|
||||
<p class="mb-0 text-muted">举报已处理,评论已关闭。</p>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 撤销操作的 Modal -->
|
||||
<div class="modal fade" id="revokeModal" tabindex="-1" aria-labelledby="revokeModalLabel" aria-hidden="true">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title" id="revokeModalLabel">撤销举报批准</h5>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
||||
</div>
|
||||
<form action="{{ url_for('main.revoke_report', report_id=report.id) }}" method="POST">
|
||||
<div class="modal-body">
|
||||
{{ revoke_form.hidden_tag() }}
|
||||
<p>你确定要撤销对举报 #{{ report.id }} 的批准吗?这将把相关用户从黑名单中移除。</p>
|
||||
<div class="mb-3">
|
||||
{{ revoke_form.reason.label(class="form-label") }}
|
||||
{{ revoke_form.reason(class="form-control", rows=3) }}
|
||||
{% for error in revoke_form.reason.errors %}<div class="invalid-feedback d-block">{{ error }}</div>{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">取消</button>
|
||||
{{ revoke_form.submit(class="btn btn-danger") }}
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
58
app/templates/admin/report_list.html
Normal file
58
app/templates/admin/report_list.html
Normal file
@@ -0,0 +1,58 @@
|
||||
{% extends "base.html" %}
|
||||
|
||||
{% block title %}管理后台 - 举报列表{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="card shadow-sm">
|
||||
<div class="card-header">
|
||||
<h2 class="mb-0">举报列表</h2>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="table-responsive">
|
||||
<table class="table table-hover align-middle">
|
||||
<thead class="table-light">
|
||||
<tr>
|
||||
<th>#ID</th>
|
||||
<th>被举报邮箱 / 站点</th>
|
||||
<th>举报人</th>
|
||||
<th>状态</th>
|
||||
<th>提交时间</th>
|
||||
<th>操作</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for report in reports.items %}
|
||||
<tr>
|
||||
<td>{{ report.id }}</td>
|
||||
<td>
|
||||
<div><strong>{{ report.reported_email }}</strong></div>
|
||||
<small class="text-muted">{{ report.reported_pt_site }}</small>
|
||||
</td>
|
||||
<td>{{ report.reporter.username }}</td>
|
||||
<td><span class="badge bg-info text-dark">{{ report.status }}</span></td>
|
||||
<td>{{ report.created_at.strftime('%Y-%m-%d %H:%M') }}</td>
|
||||
<td><a href="{{ url_for('main.report_detail', report_id=report.id) }}" class="btn btn-sm btn-outline-primary">查看详情</a></td>
|
||||
</tr>
|
||||
{% else %}
|
||||
<tr>
|
||||
<td colspan="6" class="text-center text-muted">目前没有举报记录。</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-footer">
|
||||
{# 分页导航 #}
|
||||
<div class="pagination">
|
||||
{% if reports.has_prev %}
|
||||
<a href="{{ url_for('main.report_list', page=reports.prev_num) }}" class="btn btn-sm btn-outline-secondary">« 上一页</a>
|
||||
{% endif %}
|
||||
<span class="mx-2">Page {{ reports.page }} of {{ reports.pages }}.</span>
|
||||
{% if reports.has_next %}
|
||||
<a href="{{ url_for('main.report_list', page=reports.next_num) }}" class="btn btn-sm btn-outline-secondary">下一页 »</a>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
Reference in New Issue
Block a user