feat: add web restart button

This commit is contained in:
ngfchl
2026-07-07 10:42:11 +08:00
parent b04fdfb130
commit a77d8b8b66
2 changed files with 40 additions and 0 deletions
+16
View File
@@ -154,6 +154,22 @@ async def api_logs(limit: int = Query(default=100, ge=1, le=300)):
return JSONResponse(_log_buffer[-limit:])
@app.post("/api/restart")
async def api_restart():
"""重启服务:返回响应后退出当前进程,由 Docker restart 策略拉起。"""
import os
import signal
logging.getLogger("spam_guard").warning("🔄 Web 管理端请求重启服务")
async def delayed_exit():
await asyncio.sleep(1)
os.kill(os.getpid(), signal.SIGTERM)
asyncio.create_task(delayed_exit())
return JSONResponse({"ok": True, "message": "服务正在重启"})
@app.post("/api/send")
async def api_send(request: Request):
import config
+24
View File
@@ -184,6 +184,7 @@
<div class="status">
<span class="sse-dot" :class="sseConnected ? 'on' : 'off'"></span>
{{ sseConnected ? '实时连接' : '连接中...' }}
<el-button size="mini" type="warning" plain :loading="restarting" @click="restartService">重启</el-button>
</div>
</div>
@@ -294,6 +295,7 @@ new Vue({
logs: [],
newMessage: '',
sending: false,
restarting: false,
stats: { today_bans: 0, total_bans: 0, active_bans: 0 },
}
},
@@ -375,6 +377,28 @@ new Vue({
async loadStats() {
try { this.stats = await (await fetch('/api/stats')).json() } catch (e) {}
},
async restartService() {
this.$confirm('确认重启 TG Spam Guard 服务?重启期间 Web 和 Bot 会短暂不可用。', '重启服务', {
confirmButtonText: '确认重启',
cancelButtonText: '取消',
type: 'warning'
}).then(async () => {
this.restarting = true
try {
const data = await (await fetch('/api/restart', { method: 'POST' })).json()
if (data.ok) {
this.$message.success('✅ 服务正在重启,请稍等刷新')
setTimeout(() => location.reload(), 8000)
} else {
this.$message.error(`❌ 重启失败: ${data.error || '未知错误'}`)
this.restarting = false
}
} catch (e) {
this.$message.warning('服务可能已开始重启,请稍等刷新')
setTimeout(() => location.reload(), 8000)
}
}).catch(() => {})
},
async loadLogs() {
try {
this.logs = await (await fetch('/api/logs')).json()