a
This commit is contained in:
parent
c01f681dec
commit
4da3e0bd48
|
|
@ -1151,3 +1151,37 @@ async def backend_restart(_admin: Dict[str, Any] = Depends(require_system_admin)
|
|||
"note": "重启期间接口可能短暂不可用,页面可等待 3-5 秒后刷新状态。",
|
||||
}
|
||||
|
||||
|
||||
@router.post("/backend/stop")
|
||||
async def backend_stop(_admin: Dict[str, Any] = Depends(require_system_admin)) -> Dict[str, Any]:
|
||||
"""
|
||||
停止后端服务(uvicorn)。
|
||||
警告:停止后 API 将不可用,必须手动登录服务器启动!
|
||||
"""
|
||||
backend_dir = Path(__file__).parent.parent.parent # backend/
|
||||
stop_script = backend_dir / "stop.sh"
|
||||
if not stop_script.exists():
|
||||
raise HTTPException(status_code=500, detail=f"找不到停止脚本: {stop_script}")
|
||||
|
||||
cur_pid = os.getpid()
|
||||
|
||||
# 后台执行:sleep 1 后再停止,保证当前请求可以返回
|
||||
cmd = ["bash", "-lc", f"sleep 1; '{stop_script}'"]
|
||||
try:
|
||||
subprocess.Popen(
|
||||
cmd,
|
||||
cwd=str(backend_dir),
|
||||
stdout=subprocess.DEVNULL,
|
||||
stderr=subprocess.DEVNULL,
|
||||
start_new_session=True,
|
||||
)
|
||||
except Exception as e:
|
||||
raise HTTPException(status_code=500, detail=f"启动停止脚本失败: {e}")
|
||||
|
||||
return {
|
||||
"message": "已发起后端停止(1s 后执行)",
|
||||
"pid_before": cur_pid,
|
||||
"script": str(stop_script),
|
||||
"warning": "后端服务停止后,Web 界面将无法访问,请手动在服务器启动!",
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -610,43 +610,16 @@ const GlobalConfig = () => {
|
|||
}
|
||||
}
|
||||
|
||||
const handleStartTrading = async () => {
|
||||
const handleStopBackend = async () => {
|
||||
if (!window.confirm('警告:确定要停止后端服务吗?\n\n停止后 Web 界面将立即无法访问!\n必须手动登录服务器执行 ./start.sh 才能恢复。')) return
|
||||
setSystemBusy(true)
|
||||
setMessage('')
|
||||
try {
|
||||
const res = await api.startTradingSystem()
|
||||
setMessage(res.message || '交易系统已启动')
|
||||
await loadSystemStatus()
|
||||
const res = await api.stopBackend()
|
||||
setMessage(res.message || '后端服务已停止')
|
||||
alert('后端服务已停止,页面将不再响应。请手动去服务器启动。')
|
||||
} catch (error) {
|
||||
setMessage('启动失败: ' + (error.message || '未知错误'))
|
||||
} finally {
|
||||
setSystemBusy(false)
|
||||
}
|
||||
}
|
||||
|
||||
const handleStopTrading = async () => {
|
||||
setSystemBusy(true)
|
||||
setMessage('')
|
||||
try {
|
||||
const res = await api.stopTradingSystem()
|
||||
setMessage(res.message || '交易系统已停止')
|
||||
await loadSystemStatus()
|
||||
} catch (error) {
|
||||
setMessage('停止失败: ' + (error.message || '未知错误'))
|
||||
} finally {
|
||||
setSystemBusy(false)
|
||||
}
|
||||
}
|
||||
|
||||
const handleRestartTrading = async () => {
|
||||
setSystemBusy(true)
|
||||
setMessage('')
|
||||
try {
|
||||
const res = await api.restartTradingSystem()
|
||||
setMessage(res.message || '交易系统已重启')
|
||||
await loadSystemStatus()
|
||||
} catch (error) {
|
||||
setMessage('重启失败: ' + (error.message || '未知错误'))
|
||||
setMessage('停止后端失败: ' + (error.message || '未知错误'))
|
||||
} finally {
|
||||
setSystemBusy(false)
|
||||
}
|
||||
|
|
@ -1203,6 +1176,15 @@ const GlobalConfig = () => {
|
|||
>
|
||||
重启后端服务
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
className="system-btn danger"
|
||||
onClick={handleStopBackend}
|
||||
disabled={systemBusy}
|
||||
title="停止后端服务(需要手动去服务器启动)"
|
||||
>
|
||||
停止后端服务
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
className="system-btn"
|
||||
|
|
@ -1218,24 +1200,6 @@ const GlobalConfig = () => {
|
|||
<div className="system-control-group" style={{ marginTop: '15px' }}>
|
||||
<h4 className="control-group-title" style={{ margin: '10px 0 8px', fontSize: '14px', color: '#666' }}>交易服务管理</h4>
|
||||
<div className="system-actions">
|
||||
<button
|
||||
type="button"
|
||||
className="system-btn"
|
||||
onClick={handleStartTrading}
|
||||
disabled={systemBusy || systemStatus?.running === true}
|
||||
title="通过 supervisorctl 启动交易系统"
|
||||
>
|
||||
启动
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
className="system-btn"
|
||||
onClick={handleStopTrading}
|
||||
disabled={systemBusy || systemStatus?.running === false}
|
||||
title="通过 supervisorctl 停止交易系统"
|
||||
>
|
||||
停止
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
className="system-btn primary"
|
||||
|
|
|
|||
|
|
@ -671,6 +671,18 @@ export const api = {
|
|||
return response.json();
|
||||
},
|
||||
|
||||
stopBackend: async () => {
|
||||
const response = await fetch(buildUrl('/api/system/backend/stop'), {
|
||||
method: 'POST',
|
||||
headers: withAccountHeaders({ 'Content-Type': 'application/json' }),
|
||||
});
|
||||
if (!response.ok) {
|
||||
const error = await response.json().catch(() => ({ detail: '停止后端失败' }));
|
||||
throw new Error(error.detail || '停止后端失败');
|
||||
}
|
||||
return response.json();
|
||||
},
|
||||
|
||||
// 日志监控(Redis List)
|
||||
getSystemLogs: async (params = {}) => {
|
||||
const query = new URLSearchParams(params).toString();
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user