mirror of
https://github.com/1Panel-dev/1Panel.git
synced 2025-03-14 01:34:47 +08:00
parent
e9eea9c795
commit
3ff09c8b7a
@ -56,6 +56,28 @@ func (b *BaseApi) LoadDashboardCurrentInfo(c *gin.Context) {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, errors.New("error netOption in path"))
|
||||
return
|
||||
}
|
||||
|
||||
data := dashboardService.LoadCurrentInfo(ioOption, netOption)
|
||||
helper.SuccessWithData(c, data)
|
||||
}
|
||||
|
||||
// @Tags Dashboard
|
||||
// @Summary System restart
|
||||
// @Description 重启服务器/面板
|
||||
// @Accept json
|
||||
// @Param operation path string true "request"
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /dashboard/system/restart/:operation [post]
|
||||
func (b *BaseApi) SystemRestart(c *gin.Context) {
|
||||
operation, ok := c.Params.Get("operation")
|
||||
if !ok {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, errors.New("error operation in path"))
|
||||
return
|
||||
}
|
||||
if err := dashboardService.Restart(operation); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
}
|
||||
helper.SuccessWithData(c, nil)
|
||||
}
|
||||
|
@ -2,10 +2,12 @@ package service
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/1Panel-dev/1Panel/backend/app/dto"
|
||||
"github.com/1Panel-dev/1Panel/backend/global"
|
||||
"github.com/1Panel-dev/1Panel/backend/utils/cmd"
|
||||
"github.com/shirou/gopsutil/v3/cpu"
|
||||
"github.com/shirou/gopsutil/v3/disk"
|
||||
@ -20,11 +22,31 @@ type DashboardService struct{}
|
||||
type IDashboardService interface {
|
||||
LoadBaseInfo(ioOption string, netOption string) (*dto.DashboardBase, error)
|
||||
LoadCurrentInfo(ioOption string, netOption string) *dto.DashboardCurrent
|
||||
|
||||
Restart(operation string) error
|
||||
}
|
||||
|
||||
func NewIDashboardService() IDashboardService {
|
||||
return &DashboardService{}
|
||||
}
|
||||
|
||||
func (u *DashboardService) Restart(operation string) error {
|
||||
if operation != "1panel" && operation != "system" {
|
||||
return fmt.Errorf("handle restart operation %s failed, err: nonsupport such operation", operation)
|
||||
}
|
||||
itemCmd := fmt.Sprintf("%s 1pctl restart", cmd.SudoHandleCmd())
|
||||
if operation == "system" {
|
||||
itemCmd = fmt.Sprintf("%s reboot", cmd.SudoHandleCmd())
|
||||
}
|
||||
go func() {
|
||||
stdout, err := cmd.Exec(itemCmd)
|
||||
if err != nil {
|
||||
global.LOG.Errorf("handle %s failed, err: %v", itemCmd, stdout)
|
||||
}
|
||||
}()
|
||||
return nil
|
||||
}
|
||||
|
||||
func (u *DashboardService) LoadBaseInfo(ioOption string, netOption string) (*dto.DashboardBase, error) {
|
||||
var baseInfo dto.DashboardBase
|
||||
hostInfo, err := host.Info()
|
||||
|
@ -18,5 +18,6 @@ func (s *CronjobRouter) InitDashboardRouter(Router *gin.RouterGroup) {
|
||||
{
|
||||
cmdRouter.GET("/base/:ioOption/:netOption", baseApi.LoadDashboardBaseInfo)
|
||||
cmdRouter.GET("/current/:ioOption/:netOption", baseApi.LoadDashboardCurrentInfo)
|
||||
cmdRouter.POST("/system/restart/:operation", baseApi.SystemRestart)
|
||||
}
|
||||
}
|
||||
|
@ -3718,6 +3718,37 @@ const docTemplate = `{
|
||||
}
|
||||
}
|
||||
},
|
||||
"/dashboard/system/restart/:operation": {
|
||||
"post": {
|
||||
"security": [
|
||||
{
|
||||
"ApiKeyAuth": []
|
||||
}
|
||||
],
|
||||
"description": "重启服务器/面板",
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"Dashboard"
|
||||
],
|
||||
"summary": "System restart",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "string",
|
||||
"description": "request",
|
||||
"name": "operation",
|
||||
"in": "path",
|
||||
"required": true
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/databases": {
|
||||
"post": {
|
||||
"security": [
|
||||
|
@ -3711,6 +3711,37 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"/dashboard/system/restart/:operation": {
|
||||
"post": {
|
||||
"security": [
|
||||
{
|
||||
"ApiKeyAuth": []
|
||||
}
|
||||
],
|
||||
"description": "重启服务器/面板",
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"Dashboard"
|
||||
],
|
||||
"summary": "System restart",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "string",
|
||||
"description": "request",
|
||||
"name": "operation",
|
||||
"in": "path",
|
||||
"required": true
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/databases": {
|
||||
"post": {
|
||||
"security": [
|
||||
|
@ -6536,6 +6536,25 @@ paths:
|
||||
summary: Load dashboard current info
|
||||
tags:
|
||||
- Dashboard
|
||||
/dashboard/system/restart/:operation:
|
||||
post:
|
||||
consumes:
|
||||
- application/json
|
||||
description: 重启服务器/面板
|
||||
parameters:
|
||||
- description: request
|
||||
in: path
|
||||
name: operation
|
||||
required: true
|
||||
type: string
|
||||
responses:
|
||||
"200":
|
||||
description: OK
|
||||
security:
|
||||
- ApiKeyAuth: []
|
||||
summary: System restart
|
||||
tags:
|
||||
- Dashboard
|
||||
/databases:
|
||||
post:
|
||||
consumes:
|
||||
|
@ -8,3 +8,7 @@ export const loadBaseInfo = (ioOption: string, netOption: string) => {
|
||||
export const loadCurrentInfo = (ioOption: string, netOption: string) => {
|
||||
return http.get<Dashboard.CurrentInfo>(`/dashboard/current/${ioOption}/${netOption}`);
|
||||
};
|
||||
|
||||
export const systemRestart = (operation: string) => {
|
||||
return http.post(`/dashboard/system/restart/${operation}`);
|
||||
};
|
||||
|
@ -13,6 +13,7 @@
|
||||
</el-badge>
|
||||
</el-radio-button>
|
||||
</el-radio-group>
|
||||
<slot name="route-button"></slot>
|
||||
</el-card>
|
||||
</template>
|
||||
|
||||
|
@ -277,6 +277,11 @@ const message = {
|
||||
supervisor: 'Supervisor',
|
||||
},
|
||||
home: {
|
||||
restart_1panel: 'Restart Panel',
|
||||
restart_system: 'Restart Server',
|
||||
restartHelper:
|
||||
'Do you want to perform the operation [{0}] on this machine? This action will temporarily disable the service. Do you want to continue?',
|
||||
operationSuccess: 'Operation successful! Restarting, please wait...',
|
||||
overview: 'Overview',
|
||||
entranceHelper:
|
||||
'Enabling a secure entrance can help improve system security. If necessary, go to the Control Panel settings, select Security, and enable the secure entrance.',
|
||||
|
@ -275,6 +275,10 @@ const message = {
|
||||
supervisor: '進程守護',
|
||||
},
|
||||
home: {
|
||||
restart_1panel: '重啟面板',
|
||||
restart_system: '重啟伺服器',
|
||||
restartHelper: '您是否要對這台機器執行 [{0}] 操作?此操作將導致服務暫時無法使用。您要繼續嗎?',
|
||||
operationSuccess: '操作成功!正在重啟,請稍候...',
|
||||
overview: '概覽',
|
||||
entranceHelper: '設置安全入口有利於提高系統的安全性,如有需要,前往 面板設置-安全 中,啟用安全入口',
|
||||
appInstalled: '已安裝應用',
|
||||
|
@ -275,6 +275,10 @@ const message = {
|
||||
supervisor: '进程守护',
|
||||
},
|
||||
home: {
|
||||
restart_1panel: '重启面板',
|
||||
restart_system: '重启服务器',
|
||||
restartHelper: '是否对该机器进行 [{0}] 操作,该操作将导致服务暂时不可用,是否继续?',
|
||||
operationSuccess: '操作成功!正在重启,请稍候...',
|
||||
overview: '概览',
|
||||
entranceHelper: '设置安全入口有利于提高系统的安全性,如有需要,前往 面板设置-安全 中,启用安全入口',
|
||||
appInstalled: '已安装应用',
|
||||
|
@ -376,4 +376,10 @@ html {
|
||||
.limit-height-popover {
|
||||
max-height: 300px;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.router-button {
|
||||
margin-top: 12px;
|
||||
float: right;
|
||||
margin-right: 50px;
|
||||
}
|
@ -7,7 +7,19 @@
|
||||
path: '/',
|
||||
},
|
||||
]"
|
||||
/>
|
||||
>
|
||||
<template #route-button>
|
||||
<div class="router-button">
|
||||
<el-button link type="primary" @click="restart('1panel')">
|
||||
{{ $t('home.restart_1panel') }}
|
||||
</el-button>
|
||||
<el-divider direction="vertical" />
|
||||
<el-button link type="primary" @click="restart('system')">
|
||||
{{ $t('home.restart_system') }}
|
||||
</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</RouterButton>
|
||||
<el-alert
|
||||
v-if="!isSafety && globalStore.showEntranceWarn"
|
||||
style="margin-top: 20px"
|
||||
@ -231,10 +243,11 @@ import i18n from '@/lang';
|
||||
import { Dashboard } from '@/api/interface/dashboard';
|
||||
import { dateFormatForSecond, computeSize } from '@/utils/util';
|
||||
import { useRouter } from 'vue-router';
|
||||
import { loadBaseInfo, loadCurrentInfo } from '@/api/modules/dashboard';
|
||||
import { loadBaseInfo, loadCurrentInfo, systemRestart } from '@/api/modules/dashboard';
|
||||
import { getIOOptions, getNetworkOptions } from '@/api/modules/monitor';
|
||||
import { getSettingInfo, loadUpgradeInfo } from '@/api/modules/setting';
|
||||
import { GlobalStore } from '@/store';
|
||||
import { MsgSuccess } from '@/utils/message';
|
||||
const router = useRouter();
|
||||
const globalStore = GlobalStore();
|
||||
|
||||
@ -527,6 +540,21 @@ const loadSafeStatus = async () => {
|
||||
isSafety.value = res.data.securityEntrance;
|
||||
};
|
||||
|
||||
const restart = async (type: string) => {
|
||||
ElMessageBox.confirm(
|
||||
i18n.global.t('home.restartHelper', [i18n.global.t('home.restart_' + type)]),
|
||||
i18n.global.t('commons.msg.operate'),
|
||||
{
|
||||
confirmButtonText: i18n.global.t('commons.button.confirm'),
|
||||
cancelButtonText: i18n.global.t('commons.button.cancel'),
|
||||
type: 'info',
|
||||
},
|
||||
).then(async () => {
|
||||
MsgSuccess(i18n.global.t('home.operationSuccess'));
|
||||
await systemRestart(type);
|
||||
});
|
||||
};
|
||||
|
||||
const onFocus = () => {
|
||||
isActive.value = true;
|
||||
};
|
||||
|
Loading…
x
Reference in New Issue
Block a user