- IMAP 推送:imapBackend 实现 backend.BackendUpdater,SMTP 本地投递 与 Web 写信投递成功后 NotifyNewMessage,挂起 IDLE 的客户端即时收到 新邮件 FETCH 通知(按用户名+INBOX 过滤广播,通道满非阻塞丢弃) - 当前连接:新增 internal/connhub 连接注册中心,SMTP/IMAP/POP3 三协议 注册/注销/用户名/TLS/活跃时间追踪;后台新增「当前连接」页 (/admin/connections,统计卡片+连接表格,每 5 秒自动刷新) - 新增测试:connhub 并发安全、推送内容/非阻塞/nil 安全、 后台页面渲染;全量 -race 通过
90 lines
4.7 KiB
HTML
90 lines
4.7 KiB
HTML
{{define "admin_bans"}}
|
|
<!DOCTYPE html>
|
|
<html lang="zh-CN">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover">
|
|
<title>IP黑名单 - MailGo</title>
|
|
{{template "styles" .}}
|
|
</head>
|
|
<body>
|
|
{{template "navbar" .}}
|
|
<div class="container">
|
|
<div class="clearfix">
|
|
<div class="sidebar">
|
|
<a href="/inbox">返回邮箱</a>
|
|
<a href="/admin" {{if eq .activeFolder "admin"}}class="active"{{end}}>控制面板</a>
|
|
<a href="/admin/domains" {{if eq .activeFolder "domains"}}class="active"{{end}}>域名管理</a>
|
|
<a href="/admin/users" {{if eq .activeFolder "users"}}class="active"{{end}}>用户管理</a>
|
|
<a href="/admin/mails" {{if eq .activeFolder "mails"}}class="active"{{end}}>所有邮件</a>
|
|
<a href="/admin/outbound" {{if eq .activeFolder "outbound"}}class="active"{{end}}>外发队列</a>
|
|
<a href="/admin/protocol-logs" {{if eq .activeFolder "protocol-logs"}}class="active"{{end}}>协议日志</a>
|
|
<a href="/admin/connections" {{if eq .activeFolder "connections"}}class="active"{{end}}>当前连接</a>
|
|
<a href="/admin/bans" {{if eq .activeFolder "bans"}}class="active"{{end}}>IP黑名单</a>
|
|
</div>
|
|
<div class="content">
|
|
<div class="card">
|
|
<div style="display:flex;justify-content:space-between;align-items:center;margin-bottom:16px;">
|
|
<h2>IP 黑名单</h2>
|
|
<span style="color:#7f8c8d;font-size:13px;">阶段性封禁:第 4 次触发起封禁,30分钟 → 3小时 → 3个月 → 半年(上限)</span>
|
|
</div>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>IP 地址</th>
|
|
<th>状态</th>
|
|
<th>封禁次数</th>
|
|
<th>失败次数</th>
|
|
<th>原因</th>
|
|
<th>到期时间</th>
|
|
<th>操作</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
{{range .rows}}
|
|
<tr>
|
|
<td>{{.IPAddress}}</td>
|
|
<td>
|
|
{{if .Active}}<span class="badge" style="background:#e74c3c;color:#fff;">封禁中</span>
|
|
{{else}}<span class="badge" style="background:#95a5a6;color:#fff;">已过期</span>{{end}}
|
|
</td>
|
|
<td>
|
|
{{if .BanCount}}
|
|
{{if gt .BanCount 3}}第{{sub .BanCount 3}}次封禁{{else}}仅计数{{end}}
|
|
{{else}}—{{end}}
|
|
</td>
|
|
<td>{{.FailCount}}</td>
|
|
<td>{{if .Reason}}{{.Reason}}{{else}}—{{end}}</td>
|
|
<td>{{.ExpiresAt.Format "2006-01-02 15:04:05"}}{{if not .Active}}(已过期){{end}}</td>
|
|
<td>
|
|
<form method="POST" action="/admin/bans/{{.ID}}/unban" style="display:inline;"
|
|
onsubmit="return confirm('确定要解封 IP {{.IPAddress}} 吗?解封后该 IP 的封禁档位将清零。');">
|
|
<button type="submit" class="btn btn-primary btn-sm">解封</button>
|
|
</form>
|
|
</td>
|
|
</tr>
|
|
{{end}}
|
|
</tbody>
|
|
</table>
|
|
{{if not .rows}}
|
|
<p style="color:#7f8c8d;text-align:center;padding:40px 0;">暂无封禁记录</p>
|
|
{{end}}
|
|
</div>
|
|
{{if .totalPages}}
|
|
<div class="pagination">
|
|
{{if gt .page 1}}
|
|
<a href="/admin/bans?page={{sub .page 1}}">上一页</a>
|
|
{{end}}
|
|
<span>第 {{.page}} / {{.totalPages}} 页(共 {{.total}} 条)</span>
|
|
{{if lt .page .totalPages}}
|
|
<a href="/admin/bans?page={{add .page 1}}">下一页</a>
|
|
{{end}}
|
|
</div>
|
|
{{end}}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</body>
|
|
</html>
|
|
{{end}}
|