系统更新增加客户端「全部更新」,依次远程更新所有启用实例。
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -211,20 +211,25 @@
|
||||
return v;
|
||||
}
|
||||
|
||||
async function runClientUpdate(row) {
|
||||
async function runClientUpdate(row, opts) {
|
||||
const options = opts || {};
|
||||
const iid = row.getAttribute("data-id");
|
||||
const name = row.getAttribute("data-name") || ("#" + iid);
|
||||
const btn = row.querySelector("[data-client-update]");
|
||||
const statusEl = row.querySelector("[data-client-status]");
|
||||
if (!iid || !btn) return;
|
||||
if (!iid || !btn) return { ok: false, name: name, msg: "无效行" };
|
||||
if (btn.disabled && !options.forceEnabled) {
|
||||
return { ok: false, name: name, msg: "未启用或忙碌中" };
|
||||
}
|
||||
if (
|
||||
!options.skipConfirm &&
|
||||
!window.confirm(
|
||||
"确认远程更新「" +
|
||||
name +
|
||||
"」?\n\n将执行 git pull + pm2 restart。\n有持仓时服务会短暂中断,请谨慎。"
|
||||
)
|
||||
) {
|
||||
return;
|
||||
return { ok: false, name: name, msg: "已取消" };
|
||||
}
|
||||
btn.disabled = true;
|
||||
setStatus(statusEl, "读取当前版本…", "pending");
|
||||
@@ -238,13 +243,11 @@
|
||||
});
|
||||
const data = res.data || {};
|
||||
if (!data.ok) {
|
||||
setStatus(
|
||||
statusEl,
|
||||
data.msg || (res.status ? "更新失败 HTTP " + res.status : "更新失败"),
|
||||
"err"
|
||||
);
|
||||
const msg =
|
||||
data.msg || (res.status ? "更新失败 HTTP " + res.status : "更新失败");
|
||||
setStatus(statusEl, msg, "err");
|
||||
btn.disabled = false;
|
||||
return;
|
||||
return { ok: false, name: name, msg: msg };
|
||||
}
|
||||
setStatus(statusEl, "已受理 → 等待上线…", "pending");
|
||||
try {
|
||||
@@ -255,11 +258,67 @@
|
||||
"更新完成"
|
||||
);
|
||||
await refreshClientRow(row);
|
||||
return { ok: true, name: name };
|
||||
} finally {
|
||||
btn.disabled = false;
|
||||
}
|
||||
}
|
||||
|
||||
async function runAllClientUpdates() {
|
||||
const allBtn = document.getElementById("client-update-all");
|
||||
const allStatus = document.getElementById("client-update-all-status");
|
||||
const rows = Array.prototype.slice
|
||||
.call(document.querySelectorAll(".client-update-row"))
|
||||
.filter(function (row) {
|
||||
const btn = row.querySelector("[data-client-update]");
|
||||
return btn && !btn.disabled;
|
||||
});
|
||||
if (!rows.length) {
|
||||
setStatus(allStatus, "没有可更新的启用实例", "err");
|
||||
return;
|
||||
}
|
||||
if (
|
||||
!window.confirm(
|
||||
"确认远程更新全部 " +
|
||||
rows.length +
|
||||
" 台启用实例?\n\n将依次执行 git pull + pm2 restart。\n有持仓时服务会短暂中断,请谨慎。"
|
||||
)
|
||||
) {
|
||||
return;
|
||||
}
|
||||
if (allBtn) allBtn.disabled = true;
|
||||
const refreshBtn = document.getElementById("client-update-refresh");
|
||||
if (refreshBtn) refreshBtn.disabled = true;
|
||||
let okCount = 0;
|
||||
let failCount = 0;
|
||||
try {
|
||||
for (let i = 0; i < rows.length; i++) {
|
||||
const row = rows[i];
|
||||
const name = row.getAttribute("data-name") || "#" + (i + 1);
|
||||
setStatus(
|
||||
allStatus,
|
||||
"全部更新中 " + (i + 1) + "/" + rows.length + " · " + name,
|
||||
"pending"
|
||||
);
|
||||
const result = await runClientUpdate(row, { skipConfirm: true });
|
||||
if (result && result.ok) okCount += 1;
|
||||
else failCount += 1;
|
||||
}
|
||||
if (failCount === 0) {
|
||||
setStatus(allStatus, "全部更新完成 · " + okCount + " 台", "ok");
|
||||
} else {
|
||||
setStatus(
|
||||
allStatus,
|
||||
"全部更新结束 · 成功 " + okCount + " · 失败 " + failCount,
|
||||
"err"
|
||||
);
|
||||
}
|
||||
} finally {
|
||||
if (allBtn) allBtn.disabled = false;
|
||||
if (refreshBtn) refreshBtn.disabled = false;
|
||||
}
|
||||
}
|
||||
|
||||
async function loadClients() {
|
||||
const body = document.getElementById("client-update-body");
|
||||
if (!body) return;
|
||||
@@ -328,9 +387,11 @@
|
||||
const hubBtn = document.getElementById("hub-update-btn");
|
||||
const hubRefresh = document.getElementById("hub-update-refresh");
|
||||
const clientsRefresh = document.getElementById("client-update-refresh");
|
||||
const clientsAll = document.getElementById("client-update-all");
|
||||
if (hubBtn) hubBtn.addEventListener("click", runHubUpdate);
|
||||
if (hubRefresh) hubRefresh.addEventListener("click", refreshHubVersion);
|
||||
if (clientsRefresh) clientsRefresh.addEventListener("click", loadClients);
|
||||
if (clientsAll) clientsAll.addEventListener("click", runAllClientUpdates);
|
||||
refreshHubVersion();
|
||||
loadClients();
|
||||
}
|
||||
|
||||
@@ -166,7 +166,9 @@
|
||||
<h3>客户端远程更新</h3>
|
||||
<p class="muted field-hint">经 Bridge 探测版本并下发更新;客户端需已具备 <code>/api/hub/update</code></p>
|
||||
<div class="settings-actions">
|
||||
<button type="button" class="settings-primary" id="client-update-all">全部更新</button>
|
||||
<button type="button" class="btn-secondary" id="client-update-refresh">刷新列表</button>
|
||||
<span class="update-status muted" id="client-update-all-status"></span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="table-wrap">
|
||||
@@ -183,7 +185,7 @@
|
||||
{% endblock %}
|
||||
{% block scripts %}
|
||||
<script src="{{ url_for('static', filename='settings_backup.js') }}?v=2"></script>
|
||||
<script src="{{ url_for('static', filename='settings_update.js') }}?v=4"></script>
|
||||
<script src="{{ url_for('static', filename='settings_update.js') }}?v=5"></script>
|
||||
<script>
|
||||
HubSettingsBackup.boot();
|
||||
HubSettingsUpdate.boot();
|
||||
|
||||
Reference in New Issue
Block a user