🤞 Sync 2026-09-27 22:16:29

This commit is contained in:
github-actions[bot] committed 2026-09-27 22:16:29 +08:00
1 parent 8ede4a8320
commit 618f51e9dc
459 files changed
+44817 -2191

No files matched your search

@@ -218,21 +218,32 @@ function action_node_save()
back_to_nodes(http)
end
-- 单节点删除
-- 节点删除:idx 支持单个(行内删除按钮)或逗号分隔多个(勾选批量删除)
function action_node_delete()
local http = require("luci.http")
local core = require("substore.core")
if post_ok() then
local id = http.formvalue("id") or ""
local idx = tonumber(http.formvalue("idx") or "")
local idx_param = http.formvalue("idx") or ""
if type(idx_param) == "table" then idx_param = table.concat(idx_param, ",") end
local nodes = core.read_nodes(id)
if idx and nodes[idx] then
table.remove(nodes, idx)
if core.write_nodes(id, nodes) then
core.save_meta(id, { node_count = #nodes })
core.refresh_combos(id)
local idxs = {}
for s in tostring(idx_param):gmatch("%d+") do
idxs[#idxs + 1] = tonumber(s)
end
-- 倒序删除,避免 table.remove 后下标偏移
table.sort(idxs, function(a, b) return a > b end)
local removed = false
for _, i in ipairs(idxs) do
if nodes[i] then
table.remove(nodes, i)
removed = true
end
end
if removed and core.write_nodes(id, nodes) then
core.save_meta(id, { node_count = #nodes })
core.refresh_combos(id)
end
end
back_to_nodes(http)
end
@@ -125,7 +125,7 @@ var NODEFORM_I18N = {
"defaultOpt": "<%:Default%>"
};
</script>
<script src="/luci-static/resources/substore/nodeform.js?v=2.1.3"></script>
<script src="/luci-static/resources/substore/nodeform.js?v=2.2.0"></script>
<script>
// 切换导入模式:仅切换显示/禁用,不提交表单
function substore_local_switch(mode) {
@@ -73,7 +73,7 @@ var NODEFORM_I18N = {
};
var NODE_EDIT_DATA = <%=js_node%>;
</script>
<script src="/luci-static/resources/substore/nodeform.js?v=2.1.3"></script>
<script src="/luci-static/resources/substore/nodeform.js?v=2.2.0"></script>
<script>
function node_edit_prepare() {
var arr = collectNodes();
@@ -57,7 +57,7 @@
<% end %>
</select>
</label>
<label><%:Keyword%>: <input type="text" name="keyword" value="<%=keyword%>"/></label>
<label><%:Keyword%>: <input type="text" name="keyword" size="12" value="<%=keyword%>"/></label>
<label><%:Sort by%>:
<select name="sort">
<option value="name" <%=sort_by=="name" and "selected" or ""%>>name</option>
@@ -69,14 +69,29 @@
</label>
<label style="margin-left:0.5em"><input type="checkbox" name="desc" value="1" <%=sort_desc and "checked" or ""%>/> <%:Desc%></label>
<input type="submit" class="cbi-button cbi-button-apply" value="<%:Filter%>"/>
<button type="button" class="cbi-button" onclick="location.reload()"><%:Refresh%></button>
<button type="button" class="cbi-button cbi-button-reset" onclick="substore_delete_selected()"><%:Delete%></button>
<button type="button" class="cbi-button" onclick="runProbe('ping')">Ping</button>
<button type="button" class="cbi-button" onclick="runProbe('tcping')">TCPing</button>
<button type="button" class="cbi-button" onclick="runProbe('url')"><%:URL Test%></button>
</div>
</form>
<!-- 勾选批量删除用的隐藏表单:JS 收集选中下标填入 idx(逗号分隔)后提交 -->
<form id="batch_delete_form" method="post" action="<%=luci.dispatcher.build_url('admin/services/substore/node_delete')%>" style="display:none">
<input type="hidden" name="token" value="<%=token%>"/>
<input type="hidden" name="id" value="<%=id%>"/>
<input type="hidden" name="idx" value=""/>
<input type="hidden" name="proto" value="<%=proto%>"/>
<input type="hidden" name="keyword" value="<%=keyword%>"/>
<input type="hidden" name="group" value="<%=group%>"/>
<input type="hidden" name="sort" value="<%=sort_by%>"/>
<% if sort_desc then %><input type="hidden" name="desc" value="1"/><% end %>
</form>
<table class="cbi-section-table">
<tr class="cbi-section-table-titles">
<th style="width:1em"><input type="checkbox" onclick="substore_toggle_all(this)"/></th>
<th><%:Name%></th>
<th><%:Group%></th>
<th><%:Protocol%></th>
@@ -87,6 +102,7 @@
</tr>
<% for _, n in ipairs(nodes) do %>
<tr class="cbi-section-table-row" data-server="<%=n.server or ""%>" data-port="<%=n.port or ""%>">
<td><input type="checkbox" class="node-check" value="<%=n.__idx%>"/></td>
<td><%=n.name or ""%></td>
<td>
<input type="text" class="group-input" style="width:8em" value="<%=luci.util.pcdata(n.group or "")%>"
@@ -114,7 +130,7 @@
</tr>
<% end %>
<% if #nodes == 0 then %>
<tr class="cbi-section-table-row"><td colspan="7" style="text-align:center;color:#808080"><%:No nodes found.%></td></tr>
<tr class="cbi-section-table-row"><td colspan="8" style="text-align:center;color:#808080"><%:No nodes found.%></td></tr>
<% end %>
</table>
<div id="probe_area" style="display:none;margin:0.5em 0">
@@ -149,6 +165,20 @@ function substore_set_group(el) {
+ '&group=' + encodeURIComponent(el.value)
+ '&token=' + encodeURIComponent('<%=token%>'));
}
function substore_toggle_all(el) {
var boxes = document.querySelectorAll('.node-check');
for (var i = 0; i < boxes.length; i++) boxes[i].checked = el.checked;
}
function substore_delete_selected() {
var boxes = document.querySelectorAll('.node-check:checked');
if (boxes.length === 0) { alert('<%:Please select nodes first%>'); return; }
if (!confirm('<%=luci.util.pcdata(luci.i18n.translate('Delete selected nodes?'))%>')) return;
var idxs = [];
for (var i = 0; i < boxes.length; i++) idxs.push(boxes[i].value);
var form = document.getElementById('batch_delete_form');
form.elements['idx'].value = idxs.join(',');
form.submit();
}
function runProbe(mode) {
var area = document.getElementById('probe_area');
var sum = document.getElementById('probe_summary');