74 lines
4.2 KiB
HTML
74 lines
4.2 KiB
HTML
{% extends "base.html" %}
|
||
{% block title %}端口转发 - RustProxyAdmin{% endblock %}
|
||
{% block page_title %}端口转发{% endblock %}
|
||
{% block page_desc %}管理端口转发条目(TCP/UDP){% endblock %}
|
||
{% block content %}
|
||
<div class="toolbar">
|
||
<input id="f-q" placeholder="搜索名称 / IP / 备注" style="width:220px">
|
||
<span id="common-filters"></span>
|
||
<button class="btn" onclick="__entryPage.page=1;__entryPage.reload()">筛选</button>
|
||
<button class="btn btn-primary" onclick="__entryPage.openForm()">新建转发</button>
|
||
</div>
|
||
<table class="tbl"><thead><tr id="thead"></tr></thead><tbody id="tbody"></tbody></table>
|
||
<div id="pager"></div>
|
||
<div class="batchbar" id="batchbar" style="display:none"></div>
|
||
<script src="/static/js/entries.js"></script>
|
||
<script>
|
||
(async () => {
|
||
await loadGT();
|
||
document.getElementById('common-filters').innerHTML = commonFiltersHtml();
|
||
document.getElementById('batchbar').innerHTML = batchBarHtml();
|
||
const L = initEntryPage({
|
||
runtimeBadge: true,
|
||
api: '/api/forward', etype: 'forward',
|
||
columns: [
|
||
{ label: '名称', cell: r => `<b>${esc(r.name)}</b>${r.remark ? `<div class="muted">${esc(r.remark)}</div>` : ''}` },
|
||
{ label: '节点', cell: r => esc(r.node_name || r.node_id) },
|
||
{ label: '协议', cell: r => `<span class="badge">${esc(r.proto)}</span>` },
|
||
{ label: '监听', cell: r => `<span class="mono">${esc(r.listen_ip)}:${r.listen_port}</span>` },
|
||
{ label: '目标', cell: r => `<span class="mono">${esc(r.target_ip)}:${r.target_port}</span>` },
|
||
{ label: '分组', cell: r => groupChip(r.group) },
|
||
{ label: '标签', cell: r => tagChips(r.tags) },
|
||
{ label: '配额', cell: quotaCell },
|
||
{ label: '到期', cell: expireCell },
|
||
{ label: '状态', cell: r => badgeFor(r.enabled, r.disabled_reason) },
|
||
{ label: '运行', cell: r => `<span data-rt="forward:${r.id}">-</span>` },
|
||
],
|
||
formHtml(item, isNew) {
|
||
const v = k => item ? (item[k] ?? '') : '';
|
||
return `
|
||
<div class="form-grid">
|
||
<div class="form-row"><label>名称 *</label><input id="fm-name" value="${esc(v('name'))}"></div>
|
||
<div class="form-row"><label>节点 *</label>${nodeSelectHtml('fm-node', item ? item.node_id : 1)}</div>
|
||
<div class="form-row"><label>协议 *</label><select id="fm-proto">${['tcp','udp','tcp+udp'].map(p => `<option ${v('proto') === p ? 'selected' : ''}>${p}</option>`).join('')}</select></div>
|
||
<div class="form-row"><label>分组</label>${groupSelectHtml('fm-group', item ? item.group_id : null)}</div>
|
||
<div class="form-row"><label>监听 IP</label><input id="fm-lip" value="${esc(item ? v('listen_ip') : '0.0.0.0')}"></div>
|
||
<div class="form-row"><label>监听端口 *</label><input id="fm-lport" type="number" min="1" max="65535" value="${esc(v('listen_port')) || '8080'}"></div>
|
||
<div class="form-row"><label>目标 IP *</label><input id="fm-tip" value="${esc(v('target_ip'))}"></div>
|
||
<div class="form-row"><label>目标端口 *</label><input id="fm-tport" type="number" min="1" max="65535" value="${esc(v('target_port')) || '80'}"></div>
|
||
<div class="form-row"><label>有效期</label>${expirePresetHtml(isNew ? 'permanent' : null)}</div>
|
||
<div class="form-row"><label>备注</label><input id="fm-remark" value="${esc(v('remark'))}"></div>
|
||
</div>
|
||
<div class="form-row"><label>标签</label><div>${tagCheckHtml(item ? item.tags.map(t => t.id) : [])}</div></div>`;
|
||
},
|
||
formData() {
|
||
const val = id => document.getElementById(id).value.trim();
|
||
return {
|
||
name: val('fm-name'), node_id: +document.getElementById('fm-node').value,
|
||
proto: document.getElementById('fm-proto').value,
|
||
listen_ip: val('fm-lip') || '0.0.0.0',
|
||
listen_port: +document.getElementById('fm-lport').value,
|
||
target_ip: val('fm-tip'),
|
||
target_port: +document.getElementById('fm-tport').value,
|
||
remark: val('fm-remark') || null,
|
||
group_id: document.getElementById('fm-group').value ? +document.getElementById('fm-group').value : null,
|
||
expire_preset: document.getElementById('fm-preset').value,
|
||
tag_ids: readTagIds(),
|
||
};
|
||
},
|
||
});
|
||
L.reload().catch(e => toast(e.message, true));
|
||
})();
|
||
</script>
|
||
{% endblock %}
|