feat: 添加强制更新Lua脚本的配置并优化前端更新按钮
新增配置API的force_update字段返回与保存支持,更新终端Lua脚本逻辑以支持强制更新标记,同时简化前端更新按钮,移除模拟进度条并动态切换按钮状态与显示文本。
This commit is contained in:
@@ -89,10 +89,9 @@ local speaker = peripheral.find("speaker")
|
|||||||
local inspection = peripheral.find("ticket_inspection_machine")
|
local inspection = peripheral.find("ticket_inspection_machine")
|
||||||
|
|
||||||
local serverConnected = nil
|
local serverConnected = nil
|
||||||
local serverLastChangeTs = 0
|
|
||||||
local expectedGateVersion = nil
|
|
||||||
local versionMismatch = nil
|
local versionMismatch = nil
|
||||||
local pendingGateUpdate = false
|
local pendingGateUpdate = false
|
||||||
|
local remoteForceUpdate = false
|
||||||
local isUpdating = false
|
local isUpdating = false
|
||||||
local gateBusyUntilTs = 0
|
local gateBusyUntilTs = 0
|
||||||
|
|
||||||
@@ -395,6 +394,7 @@ local function refreshRemoteLuaVersion(serverBase)
|
|||||||
local ok, parsed = getJSON(url)
|
local ok, parsed = getJSON(url)
|
||||||
if not ok or type(parsed) ~= "table" then return false end
|
if not ok or type(parsed) ~= "table" then return false end
|
||||||
local remote = normalizeVersionTag(type(parsed.lua_versions) == "table" and parsed.lua_versions.gate or nil)
|
local remote = normalizeVersionTag(type(parsed.lua_versions) == "table" and parsed.lua_versions.gate or nil)
|
||||||
|
remoteForceUpdate = (parsed.force_update == true)
|
||||||
if #remote == 0 then
|
if #remote == 0 then
|
||||||
expectedGateVersion = nil
|
expectedGateVersion = nil
|
||||||
versionMismatch = nil
|
versionMismatch = nil
|
||||||
@@ -1427,7 +1427,7 @@ while true do
|
|||||||
pcall(function()
|
pcall(function()
|
||||||
refreshRemoteLuaVersion(guessBaseFromStatusURL(serverURL))
|
refreshRemoteLuaVersion(guessBaseFromStatusURL(serverURL))
|
||||||
end)
|
end)
|
||||||
if type(cfg) == "table" and type(cfg.force_update) == "boolean" and cfg.force_update == true and versionMismatch == true then
|
if remoteForceUpdate and versionMismatch == true then
|
||||||
pendingGateUpdate = true
|
pendingGateUpdate = true
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -162,7 +162,8 @@ router.get('/config', (req, res) => {
|
|||||||
fares: DataService.getFares(),
|
fares: DataService.getFares(),
|
||||||
transfers: cfg.transfers || [],
|
transfers: cfg.transfers || [],
|
||||||
promotion: cfg.promotion || { name: '', discount: 1 },
|
promotion: cfg.promotion || { name: '', discount: 1 },
|
||||||
lua_versions: cfg.lua_versions || {}
|
lua_versions: cfg.lua_versions || {},
|
||||||
|
force_update: cfg.force_update === true
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -185,6 +186,9 @@ router.put('/config', async (req, res) => {
|
|||||||
...(incoming.lua_versions || {})
|
...(incoming.lua_versions || {})
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
if (typeof incoming.force_update === 'boolean') {
|
||||||
|
cfg.force_update = incoming.force_update;
|
||||||
|
}
|
||||||
await DataService.saveConfig(cfg);
|
await DataService.saveConfig(cfg);
|
||||||
appendReqLog(req, { category: 'admin', type: 'update_config_generic', detail: incoming });
|
appendReqLog(req, { category: 'admin', type: 'update_config_generic', detail: incoming });
|
||||||
io.emit('config:updated', cfg);
|
io.emit('config:updated', cfg);
|
||||||
|
|||||||
@@ -228,7 +228,8 @@ router.get('/config', (req, res) => {
|
|||||||
const cfg = DataService.getConfig();
|
const cfg = DataService.getConfig();
|
||||||
res.json({
|
res.json({
|
||||||
promotion: { name: cfg.promotion?.name || '', discount: cfg.promotion?.discount ?? 1 },
|
promotion: { name: cfg.promotion?.name || '', discount: cfg.promotion?.discount ?? 1 },
|
||||||
lua_versions: cfg.lua_versions || {}
|
lua_versions: cfg.lua_versions || {},
|
||||||
|
force_update: cfg.force_update === true
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -681,7 +681,7 @@ local function backgroundSyncTask()
|
|||||||
sleep(UPDATE_CHECK_INTERVAL)
|
sleep(UPDATE_CHECK_INTERVAL)
|
||||||
pcall(refreshConfigOnce)
|
pcall(refreshConfigOnce)
|
||||||
|
|
||||||
if type(cfg) == 'table' and type(cfg.force_update) == 'boolean' and cfg.force_update == true and versionMismatch == true then
|
if type(CFG) == 'table' and type(CFG.force_update) == 'boolean' and CFG.force_update == true and versionMismatch == true then
|
||||||
pendingMachineUpdate = true
|
pendingMachineUpdate = true
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
+4
-8
@@ -815,14 +815,10 @@
|
|||||||
<div>
|
<div>
|
||||||
<label style="display:block; margin-bottom:8px; font-weight:600;">Lua 脚本更新控制</label>
|
<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-direction: column; gap: 10px;">
|
||||||
<div v-if="!isPushingUpdate">
|
<div>
|
||||||
<button @click="pushLuaUpdate"><i class="fas fa-satellite-dish"></i> 手动推送更新</button>
|
<button @click="pushLuaUpdate" :disabled="isPushingUpdate">
|
||||||
</div>
|
<i class="fas fa-satellite-dish"></i> {{ isPushingUpdate ? '推送中...' : '手动推送更新' }}
|
||||||
<div v-else class="progress-container" style="width: 100%; max-width: 300px;">
|
</button>
|
||||||
<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>
|
||||||
<div class="text-muted" style="font-size: 0.9rem;">
|
<div class="text-muted" style="font-size: 0.9rem;">
|
||||||
点击按钮后,将向全服所有终端发送更新指令,并在 5 秒内生效。<br>终端将在业务空闲时静默下载更新并重启,未加载的机器在加载后也会第一时间更新。
|
点击按钮后,将向全服所有终端发送更新指令,并在 5 秒内生效。<br>终端将在业务空闲时静默下载更新并重启,未加载的机器在加载后也会第一时间更新。
|
||||||
|
|||||||
+1
-11
@@ -1477,13 +1477,11 @@ createApp({
|
|||||||
};
|
};
|
||||||
|
|
||||||
const isPushingUpdate = ref(false);
|
const isPushingUpdate = ref(false);
|
||||||
const updateProgress = ref(0);
|
|
||||||
|
|
||||||
const pushLuaUpdate = async () => {
|
const pushLuaUpdate = async () => {
|
||||||
if (!confirm('确定要向所有机器推送更新指令吗?这将会使空闲机器静默更新并重启。')) return;
|
if (!confirm('确定要向所有机器推送更新指令吗?这将会使空闲机器静默更新并重启。')) return;
|
||||||
|
|
||||||
isPushingUpdate.value = true;
|
isPushingUpdate.value = true;
|
||||||
updateProgress.value = 0;
|
|
||||||
|
|
||||||
// 自动提升版本号 & 开启 force_update
|
// 自动提升版本号 & 开启 force_update
|
||||||
if (!config.lua_versions.ticketmachine) config.lua_versions.ticketmachine = 'v1.0.0';
|
if (!config.lua_versions.ticketmachine) config.lua_versions.ticketmachine = 'v1.0.0';
|
||||||
@@ -1494,20 +1492,12 @@ createApp({
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
await requestJson('/api/config', { method: 'PUT', headers: {'Content-Type': 'application/json'}, body: JSON.stringify(config) }, { expectOk: true });
|
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');
|
toast('推送指令发送完毕,终端将陆续更新', 'success');
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error(err);
|
console.error(err);
|
||||||
toast('推送更新失败', 'error');
|
toast('推送更新失败', 'error');
|
||||||
} finally {
|
} finally {
|
||||||
isPushingUpdate.value = false;
|
isPushingUpdate.value = false;
|
||||||
updateProgress.value = 100;
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -1762,7 +1752,7 @@ createApp({
|
|||||||
|
|
||||||
saveCurrentFare, deleteCurrentFare, closeFareModal,
|
saveCurrentFare, deleteCurrentFare, closeFareModal,
|
||||||
|
|
||||||
saveConfig, isPushingUpdate, updateProgress, pushLuaUpdate, exportData, exportFareMap,
|
saveConfig, isPushingUpdate, pushLuaUpdate, exportData, exportFareMap,
|
||||||
formatTime, formatLogDetail, getStationName, getStationInfo, loadFareMap, fetchData, refreshData: fetchData,
|
formatTime, formatLogDetail, getStationName, getStationInfo, loadFareMap, fetchData, refreshData: fetchData,
|
||||||
fareMapScale, fareMapLoading, fareMapError, zoomFareMapIn, zoomFareMapOut, zoomFareMapReset,
|
fareMapScale, fareMapLoading, fareMapError, zoomFareMapIn, zoomFareMapOut, zoomFareMapReset,
|
||||||
isTransferStation, getTransferTitleSuffix, getTransferLineBadges
|
isTransferStation, getTransferTitleSuffix, getTransferLineBadges
|
||||||
|
|||||||
Reference in New Issue
Block a user