feat: restart button in settings via atexit+execv
This commit is contained in:
+9
-3
@@ -389,9 +389,6 @@ async def api_import_backup(file: UploadFile = File(...)):
|
|||||||
|
|
||||||
from config.settings import reload_config
|
from config.settings import reload_config
|
||||||
reload_config()
|
reload_config()
|
||||||
from models.dashboard import dashboard_manager
|
|
||||||
import importlib
|
|
||||||
importlib.reload(__import__('models.dashboard', fromlist=['dashboard_manager']))
|
|
||||||
from server.game_manager import game_plugin_manager
|
from server.game_manager import game_plugin_manager
|
||||||
game_plugin_manager.reload()
|
game_plugin_manager.reload()
|
||||||
|
|
||||||
@@ -400,6 +397,15 @@ async def api_import_backup(file: UploadFile = File(...)):
|
|||||||
return {"ok": False, "message": str(e)}
|
return {"ok": False, "message": str(e)}
|
||||||
|
|
||||||
|
|
||||||
|
# ---- Restart ----
|
||||||
|
@router.post("/restart")
|
||||||
|
async def api_restart():
|
||||||
|
import os, sys, atexit
|
||||||
|
logger.info("Restart requested via API")
|
||||||
|
atexit.register(lambda: os.execv(sys.executable, [sys.executable] + sys.argv))
|
||||||
|
sys.exit(0)
|
||||||
|
|
||||||
|
|
||||||
# ---- Data Forwarding ----
|
# ---- Data Forwarding ----
|
||||||
@router.get("/forward")
|
@router.get("/forward")
|
||||||
async def api_list_forward_targets():
|
async def api_list_forward_targets():
|
||||||
|
|||||||
@@ -111,6 +111,18 @@ const PageSettings = {
|
|||||||
}; input.click();
|
}; input.click();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
document.getElementById('btn-restart-server')?.addEventListener('click', async () => {
|
||||||
|
if (!confirm('确定重启 TurboSu 服务?')) return;
|
||||||
|
try {
|
||||||
|
await fetch('/api/restart', { method: 'POST' });
|
||||||
|
Toast.show('服务正在重启,3秒后自动刷新...', 'info');
|
||||||
|
setTimeout(() => location.reload(), 3000);
|
||||||
|
} catch (e) {
|
||||||
|
Toast.show('重启请求已发送,请手动刷新', 'info');
|
||||||
|
setTimeout(() => location.reload(), 3000);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
document.getElementById('settings-test-mode')?.addEventListener('change', async (e) => {
|
document.getElementById('settings-test-mode')?.addEventListener('change', async (e) => {
|
||||||
const on = e.target.checked;
|
const on = e.target.checked;
|
||||||
await API.updateConfig({ ui_test_mode: on });
|
await API.updateConfig({ ui_test_mode: on });
|
||||||
@@ -184,7 +196,9 @@ const PageSettings = {
|
|||||||
|
|
||||||
'<div class="settings-section"><h3>游戏插件管理</h3><div style="display:flex;gap:8px;margin-bottom:16px"><button id="btn-import-plugin" class="btn btn-secondary btn-sm">导入 .tsp</button><button id="btn-reload-plugins" class="btn btn-secondary btn-sm">重新加载</button></div><div id="settings-game-list">' + this._gamePluginListHtml(games) + '</div></div>' +
|
'<div class="settings-section"><h3>游戏插件管理</h3><div style="display:flex;gap:8px;margin-bottom:16px"><button id="btn-import-plugin" class="btn btn-secondary btn-sm">导入 .tsp</button><button id="btn-reload-plugins" class="btn btn-secondary btn-sm">重新加载</button></div><div id="settings-game-list">' + this._gamePluginListHtml(games) + '</div></div>' +
|
||||||
|
|
||||||
'<div class="settings-section"><h3>数据备份</h3><div class="settings-row"><div><div class="settings-label">导出全量备份</div><div class="settings-desc">打包仪表盘+场景+配置为 .tsb</div></div><div class="settings-control"><button id="btn-export-backup" class="btn btn-secondary btn-sm">下载 .tsb</button></div></div><div class="settings-row"><div><div class="settings-label">恢复备份</div><div class="settings-desc">从 .tsb 文件恢复,需重启</div></div><div class="settings-control"><button id="btn-import-backup" class="btn btn-secondary btn-sm">导入 .tsb</button></div></div></div>' +
|
'<div class="settings-section"><h3>数据备份</h3><div class="settings-row"><div><div class="settings-label">导出全量备份</div><div class="settings-desc">打包仪表盘+场景+配置为 .tsb</div></div><div class="settings-control"><button id="btn-export-backup" class="btn btn-secondary btn-sm">下载 .tsb</button></div></div><div class="settings-row"><div><div class="settings-label">恢复备份</div><div class="settings-desc">从 .tsb 文件恢复</div></div><div class="settings-control"><button id="btn-import-backup" class="btn btn-secondary btn-sm">导入 .tsb</button></div></div></div>' +
|
||||||
|
|
||||||
|
'<div class="settings-section"><h3>系统</h3><div class="settings-row"><div><div class="settings-label">重启 TurboSu</div><div class="settings-desc">重新加载所有代码和配置</div></div><div class="settings-control"><button id="btn-restart-server" class="btn btn-danger btn-sm">重启服务</button></div></div></div>' +
|
||||||
|
|
||||||
'<div class="settings-section"><h3>开发工具</h3><div class="settings-row"><div><div class="settings-label">UI 测试模式</div><div class="settings-desc">本地随机模拟遥测数据</div></div><div class="settings-control"><label class="switch-label"><input type="checkbox" id="settings-test-mode" ' + (cfg.ui_test_mode?'checked':'') + '><span class="switch-track"></span></label></div></div></div>' +
|
'<div class="settings-section"><h3>开发工具</h3><div class="settings-row"><div><div class="settings-label">UI 测试模式</div><div class="settings-desc">本地随机模拟遥测数据</div></div><div class="settings-control"><label class="switch-label"><input type="checkbox" id="settings-test-mode" ' + (cfg.ui_test_mode?'checked':'') + '><span class="switch-track"></span></label></div></div></div>' +
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user