Track site-created 3x-ui clients and per-panel inbound whitelist for users
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -20,6 +20,10 @@
|
||||
<div class="flash flash-error">{{ flash[6:] }}</div>
|
||||
{% elif flash == 'client_created' %}
|
||||
<div class="flash">Клиент создан в 3x-ui</div>
|
||||
{% elif flash == 'inbounds_synced' %}
|
||||
<div class="flash">Inbound’ы синхронизированы с 3x-ui</div>
|
||||
{% elif flash == 'inbounds_saved' %}
|
||||
<div class="flash">Доступные пользователям inbound’ы сохранены</div>
|
||||
{% elif flash == 'ok' %}
|
||||
<div class="flash">Данные обновлены</div>
|
||||
{% endif %}
|
||||
@@ -65,6 +69,60 @@ PublicKey = {{ created.publicKey }}
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
<div class="panel">
|
||||
<div class="panel-head">
|
||||
<strong>Создано через сайт</strong>
|
||||
<span class="muted">только клиенты, которых вы создали в этой панели</span>
|
||||
</div>
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Email</th>
|
||||
<th>Протокол</th>
|
||||
<th>Inbound</th>
|
||||
<th>Срок</th>
|
||||
<th>Лимиты</th>
|
||||
<th>Ссылка / ключи</th>
|
||||
<th>Когда</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for c in site_clients %}
|
||||
<tr>
|
||||
<td>
|
||||
<strong>{{ c.email }}</strong>
|
||||
{% if c.comment %}<div class="muted">{{ c.comment }}</div>{% endif %}
|
||||
</td>
|
||||
<td><span class="badge badge-proto">{{ c.protocol }}</span></td>
|
||||
<td class="muted">#{{ c.inbound_id }} {% if c.inbound_remark %}{{ c.inbound_remark }}{% endif %}</td>
|
||||
<td class="muted">
|
||||
{% if c.expiry_days and c.expiry_days > 0 %}
|
||||
{{ c.expiry_days }} дн.
|
||||
{% if c.start_after_first_use %}<br><span class="badge badge-ok">после 1-го входа</span>{% endif %}
|
||||
{% else %}
|
||||
без срока
|
||||
{% endif %}
|
||||
</td>
|
||||
<td class="muted">
|
||||
{{ c.total_gb or 0 }} GB
|
||||
{% if c.limit_ip %}<br>IP ≤ {{ c.limit_ip }}{% endif %}
|
||||
</td>
|
||||
<td>
|
||||
{% if c.link %}
|
||||
<div class="link-box" style="margin:0;max-width:280px;font-size:.78rem;word-break:break-all;">{{ c.link }}</div>
|
||||
{% elif c.private_key %}
|
||||
<div class="muted" style="font-size:.78rem;word-break:break-all;">priv: {{ c.private_key[:24] }}…</div>
|
||||
{% else %}—{% endif %}
|
||||
</td>
|
||||
<td class="muted">{{ c.created_at }}</td>
|
||||
</tr>
|
||||
{% else %}
|
||||
<tr><td colspan="7" class="muted">Пока никого не создавали через сайт</td></tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
{% if data %}
|
||||
<div class="stats">
|
||||
<div class="stat">
|
||||
@@ -165,10 +223,55 @@ PublicKey = {{ created.publicKey }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
<div class="panel" style="margin-bottom:1rem">
|
||||
<div class="panel-head">
|
||||
<strong>Доступные inbound’ы (VLESS / WireGuard)</strong>
|
||||
<strong>Inbound’ы для пользователей</strong>
|
||||
<span class="muted">отметьте, какие будут доступны при создании клиентов</span>
|
||||
</div>
|
||||
<form method="post" action="/admin/xui/{{ panel.id }}/inbounds/users">
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Для пользователей</th>
|
||||
<th>ID</th>
|
||||
<th>Remark</th>
|
||||
<th>Protocol</th>
|
||||
<th>Port</th>
|
||||
<th>В 3x-ui</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for ib in panel_inbounds %}
|
||||
<tr>
|
||||
<td>
|
||||
<label class="check" style="margin:0">
|
||||
<input type="checkbox" name="inbound_ids" value="{{ ib.inbound_id }}" {% if ib.is_available_for_users %}checked{% endif %} />
|
||||
</label>
|
||||
</td>
|
||||
<td>{{ ib.inbound_id }}</td>
|
||||
<td>{{ ib.remark or '—' }}</td>
|
||||
<td><span class="badge badge-proto">{{ ib.protocol }}</span></td>
|
||||
<td>{{ ib.port or '—' }}</td>
|
||||
<td>{% if ib.enable %}<span class="badge badge-ok">on</span>{% else %}<span class="badge badge-off">off</span>{% endif %}</td>
|
||||
</tr>
|
||||
{% else %}
|
||||
<tr><td colspan="6" class="muted">Список пуст — нажмите «Синхронизировать inbound’ы»</td></tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
<div class="actions" style="padding:1rem;gap:.5rem;display:flex;flex-wrap:wrap">
|
||||
<button class="btn btn-accent" type="submit" {% if not panel_inbounds %}disabled{% endif %}>Сохранить для пользователей</button>
|
||||
<button class="btn btn-ghost" type="submit" formaction="/admin/xui/{{ panel.id }}/inbounds/sync" formmethod="post">Синхронизировать с 3x-ui</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
{% if data %}
|
||||
<div class="panel" style="margin-bottom:1rem">
|
||||
<div class="panel-head">
|
||||
<strong>Все inbound’ы из API (VLESS / WireGuard)</strong>
|
||||
<span class="muted" id="inbounds-status"></span>
|
||||
</div>
|
||||
<table>
|
||||
@@ -198,7 +301,10 @@ PublicKey = {{ created.publicKey }}
|
||||
</div>
|
||||
|
||||
<div class="panel">
|
||||
<div class="panel-head"><strong>Clients</strong></div>
|
||||
<div class="panel-head">
|
||||
<strong>Все клиенты 3x-ui</strong>
|
||||
<span class="muted">из API панели (включая созданных не через сайт)</span>
|
||||
</div>
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
|
||||
Reference in New Issue
Block a user