feat: add dashboard restart action and improve text button contrast
This commit is contained in:
@@ -3,6 +3,7 @@ from .auth import login_required
|
|||||||
from loguru import logger
|
from loguru import logger
|
||||||
import os
|
import os
|
||||||
import time
|
import time
|
||||||
|
import subprocess
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
import platform
|
import platform
|
||||||
import psutil
|
import psutil
|
||||||
@@ -153,3 +154,32 @@ def get_current_user_info():
|
|||||||
dashboard_server = current_app.dashboard_server
|
dashboard_server = current_app.dashboard_server
|
||||||
result = dashboard_server.get_current_user_info()
|
result = dashboard_server.get_current_user_info()
|
||||||
return jsonify(result)
|
return jsonify(result)
|
||||||
|
|
||||||
|
|
||||||
|
@system_bp.route('/api/restart_service', methods=['POST'])
|
||||||
|
@login_required
|
||||||
|
def restart_service():
|
||||||
|
"""调用项目根目录下的 restart.sh 重启服务"""
|
||||||
|
try:
|
||||||
|
project_root = os.path.abspath(os.path.join(os.path.dirname(__file__), '..', '..', '..'))
|
||||||
|
script_path = os.path.join(project_root, 'restart.sh')
|
||||||
|
|
||||||
|
if not os.path.exists(script_path):
|
||||||
|
return jsonify({"success": False, "message": f"未找到脚本: {script_path}"}), 404
|
||||||
|
|
||||||
|
subprocess.Popen(
|
||||||
|
['bash', script_path],
|
||||||
|
cwd=project_root,
|
||||||
|
stdout=subprocess.DEVNULL,
|
||||||
|
stderr=subprocess.DEVNULL,
|
||||||
|
start_new_session=True
|
||||||
|
)
|
||||||
|
|
||||||
|
logger.warning(f"后台触发服务重启脚本: {script_path}")
|
||||||
|
return jsonify({
|
||||||
|
"success": True,
|
||||||
|
"message": "已触发重启脚本,服务将在短时间内重启"
|
||||||
|
})
|
||||||
|
except Exception as e:
|
||||||
|
logger.error(f"触发服务重启失败: {e}")
|
||||||
|
return jsonify({"success": False, "message": str(e)}), 500
|
||||||
|
|||||||
@@ -362,6 +362,26 @@
|
|||||||
background: rgba(255,255,255,0.96) !important;
|
background: rgba(255,255,255,0.96) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.el-button--text {
|
||||||
|
color: #334155 !important;
|
||||||
|
font-weight: 600 !important;
|
||||||
|
padding: 6px 10px !important;
|
||||||
|
border-radius: 10px !important;
|
||||||
|
background: rgba(248, 250, 252, 0.9) !important;
|
||||||
|
border: 1px solid rgba(148, 163, 184, 0.14) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.el-button--text:hover,
|
||||||
|
.el-button--text:focus {
|
||||||
|
color: var(--primary) !important;
|
||||||
|
background: rgba(99, 102, 241, 0.08) !important;
|
||||||
|
border-color: rgba(99, 102, 241, 0.18) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.el-button--text [class*="el-icon-"] {
|
||||||
|
color: inherit !important;
|
||||||
|
}
|
||||||
|
|
||||||
.el-button--success,
|
.el-button--success,
|
||||||
.el-button--warning,
|
.el-button--warning,
|
||||||
.el-button--danger,
|
.el-button--danger,
|
||||||
|
|||||||
@@ -13,6 +13,7 @@
|
|||||||
<div class="page-hero-actions">
|
<div class="page-hero-actions">
|
||||||
<el-button type="primary" plain @click="reloadIframe"><i class="el-icon-refresh"></i> 刷新面板</el-button>
|
<el-button type="primary" plain @click="reloadIframe"><i class="el-icon-refresh"></i> 刷新面板</el-button>
|
||||||
<el-button type="primary" @click="openInNewTab"><i class="el-icon-top-right"></i> 新窗口打开</el-button>
|
<el-button type="primary" @click="openInNewTab"><i class="el-icon-top-right"></i> 新窗口打开</el-button>
|
||||||
|
<el-button type="danger" @click="confirmRestart"><i class="el-icon-refresh-left"></i> 重启服务</el-button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -40,7 +41,8 @@
|
|||||||
return {
|
return {
|
||||||
currentView: '14',
|
currentView: '14',
|
||||||
showTimeRangeSelector: false,
|
showTimeRangeSelector: false,
|
||||||
frameUrl: '{{ src_url }}'
|
frameUrl: '{{ src_url }}',
|
||||||
|
restarting: false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
@@ -54,6 +56,31 @@
|
|||||||
},
|
},
|
||||||
openInNewTab() {
|
openInNewTab() {
|
||||||
window.open(this.frameUrl, '_blank');
|
window.open(this.frameUrl, '_blank');
|
||||||
|
},
|
||||||
|
confirmRestart() {
|
||||||
|
this.$confirm('确认执行 ./restart.sh 重启服务吗?这会中断当前服务几秒钟。', '重启确认', {
|
||||||
|
confirmButtonText: '确认重启',
|
||||||
|
cancelButtonText: '取消',
|
||||||
|
type: 'warning'
|
||||||
|
}).then(() => {
|
||||||
|
this.triggerRestart();
|
||||||
|
}).catch(() => {});
|
||||||
|
},
|
||||||
|
async triggerRestart() {
|
||||||
|
if (this.restarting) return;
|
||||||
|
this.restarting = true;
|
||||||
|
try {
|
||||||
|
const response = await axios.post('/api/restart_service');
|
||||||
|
if (response.data.success) {
|
||||||
|
this.$message.success(response.data.message || '已触发重启');
|
||||||
|
} else {
|
||||||
|
this.$message.error(response.data.message || '重启失败');
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
this.$message.error(error.response?.data?.message || '触发重启失败');
|
||||||
|
} finally {
|
||||||
|
this.restarting = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user