Files
socks-manager/templates/groups.html
T
Your Name aa8af6c2e0 feat: SOCKS5 代理管理系统 v1.0
Flask + SQLite + Bootstrap5 暗色主题
- 仪表盘: 在线/离线统计 + 最近代理 + 操作日志
- 代理 CRUD: 增删改 + 启用/禁用 + 单/批量健康检测(SOCKS5)
- 分组管理: 创建/删除/筛选
- 操作日志: 分页查询
- RESTful API + Web 界面
- 管理员登录认证 (SM_ADMIN_PASSWORD 环境变量)
2026-07-16 16:40:20 +08:00

78 lines
3.2 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
{% extends "base.html" %}
{% block title %}分组管理 · SOCK Manager{% endblock %}
{% block content %}
<div class="d-flex justify-content-between align-items-center mb-4">
<h4 class="mb-0"><i class="bi bi-collection"></i> 分组管理</h4>
<button class="btn btn-primary btn-sm" data-bs-toggle="modal" data-bs-target="#addGroupModal">
<i class="bi bi-plus-lg"></i> 添加分组</button>
</div>
<div class="row g-3">
{% for g in groups %}
<div class="col-md-4 col-lg-3">
<div class="card" style="border-left:4px solid {{ g.color }}">
<div class="card-body">
<h6 style="color:{{ g.color }}">{{ g.name }}</h6>
<p class="text-muted small mb-1">{{ g.description or '无描述' }}</p>
<div class="d-flex justify-content-between align-items-center">
<span class="badge bg-secondary">{{ g.proxies|length }} 个代理</span>
<button class="btn btn-outline-danger btn-sm" onclick="deleteGroup({{ g.id }}, '{{ g.name }}')">
<i class="bi bi-trash"></i></button>
</div>
</div>
</div>
</div>
{% endfor %}
</div>
{% if not groups %}
<div class="text-center py-5 text-muted">暂无分组</div>
{% endif %}
<!-- Add Group Modal -->
<div class="modal fade" id="addGroupModal">
<div class="modal-dialog modal-sm">
<div class="modal-content" style="background:#1a1d27;border-color:#2a2d3a">
<div class="modal-header" style="border-color:#2a2d3a">
<h6 class="modal-title">添加分组</h6>
<button type="button" class="btn-close btn-close-white" data-bs-dismiss="modal"></button>
</div>
<div class="modal-body">
<div class="mb-3"><label class="form-label">名称</label>
<input id="gName" class="form-control" required></div>
<div class="mb-3"><label class="form-label">颜色</label>
<input id="gColor" type="color" class="form-control form-control-color" value="#6366f1"></div>
<div class="mb-3"><label class="form-label">描述</label>
<input id="gDesc" class="form-control"></div>
</div>
<div class="modal-footer" style="border-color:#2a2d3a">
<button type="button" class="btn btn-sm btn-outline-secondary" data-bs-dismiss="modal">取消</button>
<button type="button" class="btn btn-sm btn-primary" onclick="addGroup()">添加</button>
</div>
</div>
</div>
</div>
{% endblock %}
{% block extra_script %}
<script>
async function addGroup() {
const name = document.getElementById('gName').value.trim();
if (!name) return;
try {
await fetch('/groups/add', {method:'POST', headers:{'Content-Type':'application/x-www-form-urlencoded'},
body:`name=${encodeURIComponent(name)}&color=${document.getElementById('gColor').value}&description=${encodeURIComponent(document.getElementById('gDesc').value)}`});
toast('分组已添加', 'success'); location.reload();
} catch(e) { toast('添加失败', 'danger'); }
}
async function deleteGroup(id, name) {
if (!confirm(`确认删除分组 "${name}"`)) return;
const r = await fetch(`/groups/${id}`, {method:'DELETE'});
const j = await r.json();
if (j.error) { toast(j.error, 'warning'); } else { toast('分组已删除', 'success'); location.reload(); }
}
</script>
{% endblock %}