feat(web): 添加全局Lua脚本批量推送更新

替换原有的单个设备版本升级功能,添加推送前的确认弹窗,自动提升售票机和检票机的补丁版本并开启强制更新,添加推送进度展示,更新前端UI与说明文案,新增推送结果提示与异常处理
This commit is contained in:
2026-07-10 23:08:32 +08:00
parent 0ef09239fd
commit 908fdc2af0
2 changed files with 42 additions and 17 deletions
+8 -12
View File
@@ -815,21 +815,17 @@
<div>
<label style="display:block; margin-bottom:8px; font-weight:600;">Lua 脚本更新控制</label>
<div class="flex" style="flex-direction: column; gap: 10px;">
<div class="flex" style="flex-wrap: wrap; gap: 10px; align-items: center;">
<span style="min-width: 70px;">售票机</span>
<input v-model="config.lua_versions.ticketmachine" placeholder="例如 v1.5.8" style="max-width: 180px;">
<button @click="bumpLuaVersion('ticketmachine')"><i class="fas fa-arrow-up"></i> 补丁 +1</button>
<div v-if="!isPushingUpdate">
<button @click="pushLuaUpdate"><i class="fas fa-satellite-dish"></i> 手动推送更新</button>
</div>
<div class="flex" style="flex-wrap: wrap; gap: 10px; align-items: center;">
<span style="min-width: 70px;">检票机</span>
<input v-model="config.lua_versions.gate" placeholder="例如 v1.5.8" style="max-width: 180px;">
<button @click="bumpLuaVersion('gate')"><i class="fas fa-arrow-up"></i> 补丁 +1</button>
<div v-else class="progress-container" style="width: 100%; max-width: 300px;">
<div style="margin-bottom: 5px; font-size: 0.9rem; color: #666;">推送中... {{ updateProgress }}%</div>
<div class="progress-bar" style="height: 10px; background: #eee; border-radius: 5px; overflow: hidden;">
<div class="progress-fill" :style="{ width: updateProgress + '%', height: '100%', background: '#4caf50', transition: 'width 0.1s' }"></div>
</div>
</div>
<div class="text-muted" style="font-size: 0.9rem;">
每次发布新的 Lua 脚本后,在这里手动提升一次版本号;设备检测到不一致时会在左上角版本号旁显示更新标记。
</div>
<div class="flex">
<button @click="saveConfig"><i class="fas fa-save"></i> 保存 Lua 版本</button>
点击按钮后,将向全服所有终端发送更新指令,并在 5 秒内生效。<br>终端将在业务空闲时静默下载更新并重启,未加载的机器在加载后也会第一时间更新。
</div>
</div>
</div>
+34 -5
View File
@@ -1476,10 +1476,39 @@ createApp({
}, { successMessage: '保存成功' });
};
const bumpLuaVersion = async (device) => {
if (!config.lua_versions[device]) config.lua_versions[device] = 'v1.0.0';
config.lua_versions[device] = bumpPatchVersion(config.lua_versions[device]);
await saveConfig();
const isPushingUpdate = ref(false);
const updateProgress = ref(0);
const pushLuaUpdate = async () => {
if (!confirm('确定要向所有机器推送更新指令吗?这将会使空闲机器静默更新并重启。')) return;
isPushingUpdate.value = true;
updateProgress.value = 0;
// 自动提升版本号 & 开启 force_update
if (!config.lua_versions.ticketmachine) config.lua_versions.ticketmachine = 'v1.0.0';
if (!config.lua_versions.gate) config.lua_versions.gate = 'v1.0.0';
config.lua_versions.ticketmachine = bumpPatchVersion(config.lua_versions.ticketmachine);
config.lua_versions.gate = bumpPatchVersion(config.lua_versions.gate);
config.force_update = true;
try {
await requestJson('/api/config', { method: 'PUT', headers: {'Content-Type': 'application/json'}, body: JSON.stringify(config) }, { expectOk: true });
// 模拟进度条,持续约 5 秒 (设备5秒轮询一次)
for (let i = 0; i <= 100; i += 2) {
updateProgress.value = i;
await new Promise(resolve => setTimeout(resolve, 100)); // 100ms * 50 = 5000ms
}
toast('推送指令发送完毕,终端将陆续更新', 'success');
} catch (err) {
console.error(err);
toast('推送更新失败', 'error');
} finally {
isPushingUpdate.value = false;
updateProgress.value = 100;
}
};
const exportData = () => {
@@ -1733,7 +1762,7 @@ createApp({
saveCurrentFare, deleteCurrentFare, closeFareModal,
saveConfig, bumpLuaVersion, exportData, exportFareMap,
saveConfig, isPushingUpdate, updateProgress, pushLuaUpdate, exportData, exportFareMap,
formatTime, formatLogDetail, getStationName, getStationInfo, loadFareMap, fetchData, refreshData: fetchData,
fareMapScale, fareMapLoading, fareMapError, zoomFareMapIn, zoomFareMapOut, zoomFareMapReset,
isTransferStation, getTransferTitleSuffix, getTransferLineBadges