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"))
|
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, errors.New("error netOption in path"))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
data := dashboardService.LoadCurrentInfo(ioOption, netOption)
|
data := dashboardService.LoadCurrentInfo(ioOption, netOption)
|
||||||
helper.SuccessWithData(c, data)
|
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 (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/1Panel-dev/1Panel/backend/app/dto"
|
"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/1Panel-dev/1Panel/backend/utils/cmd"
|
||||||
"github.com/shirou/gopsutil/v3/cpu"
|
"github.com/shirou/gopsutil/v3/cpu"
|
||||||
"github.com/shirou/gopsutil/v3/disk"
|
"github.com/shirou/gopsutil/v3/disk"
|
||||||
@ -20,11 +22,31 @@ type DashboardService struct{}
|
|||||||
type IDashboardService interface {
|
type IDashboardService interface {
|
||||||
LoadBaseInfo(ioOption string, netOption string) (*dto.DashboardBase, error)
|
LoadBaseInfo(ioOption string, netOption string) (*dto.DashboardBase, error)
|
||||||
LoadCurrentInfo(ioOption string, netOption string) *dto.DashboardCurrent
|
LoadCurrentInfo(ioOption string, netOption string) *dto.DashboardCurrent
|
||||||
|
|
||||||
|
Restart(operation string) error
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewIDashboardService() IDashboardService {
|
func NewIDashboardService() IDashboardService {
|
||||||
return &DashboardService{}
|
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) {
|
func (u *DashboardService) LoadBaseInfo(ioOption string, netOption string) (*dto.DashboardBase, error) {
|
||||||
var baseInfo dto.DashboardBase
|
var baseInfo dto.DashboardBase
|
||||||
hostInfo, err := host.Info()
|
hostInfo, err := host.Info()
|
||||||
|
@ -18,5 +18,6 @@ func (s *CronjobRouter) InitDashboardRouter(Router *gin.RouterGroup) {
|
|||||||
{
|
{
|
||||||
cmdRouter.GET("/base/:ioOption/:netOption", baseApi.LoadDashboardBaseInfo)
|
cmdRouter.GET("/base/:ioOption/:netOption", baseApi.LoadDashboardBaseInfo)
|
||||||
cmdRouter.GET("/current/:ioOption/:netOption", baseApi.LoadDashboardCurrentInfo)
|
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": {
|
"/databases": {
|
||||||
"post": {
|
"post": {
|
||||||
"security": [
|
"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": {
|
"/databases": {
|
||||||
"post": {
|
"post": {
|
||||||
"security": [
|
"security": [
|
||||||
|
@ -6536,6 +6536,25 @@ paths:
|
|||||||
summary: Load dashboard current info
|
summary: Load dashboard current info
|
||||||
tags:
|
tags:
|
||||||
- Dashboard
|
- 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:
|
/databases:
|
||||||
post:
|
post:
|
||||||
consumes:
|
consumes:
|
||||||
|
@ -8,3 +8,7 @@ export const loadBaseInfo = (ioOption: string, netOption: string) => {
|
|||||||
export const loadCurrentInfo = (ioOption: string, netOption: string) => {
|
export const loadCurrentInfo = (ioOption: string, netOption: string) => {
|
||||||
return http.get<Dashboard.CurrentInfo>(`/dashboard/current/${ioOption}/${netOption}`);
|
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-badge>
|
||||||
</el-radio-button>
|
</el-radio-button>
|
||||||
</el-radio-group>
|
</el-radio-group>
|
||||||
|
<slot name="route-button"></slot>
|
||||||
</el-card>
|
</el-card>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
@ -277,6 +277,11 @@ const message = {
|
|||||||
supervisor: 'Supervisor',
|
supervisor: 'Supervisor',
|
||||||
},
|
},
|
||||||
home: {
|
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',
|
overview: 'Overview',
|
||||||
entranceHelper:
|
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.',
|
'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: '進程守護',
|
supervisor: '進程守護',
|
||||||
},
|
},
|
||||||
home: {
|
home: {
|
||||||
|
restart_1panel: '重啟面板',
|
||||||
|
restart_system: '重啟伺服器',
|
||||||
|
restartHelper: '您是否要對這台機器執行 [{0}] 操作?此操作將導致服務暫時無法使用。您要繼續嗎?',
|
||||||
|
operationSuccess: '操作成功!正在重啟,請稍候...',
|
||||||
overview: '概覽',
|
overview: '概覽',
|
||||||
entranceHelper: '設置安全入口有利於提高系統的安全性,如有需要,前往 面板設置-安全 中,啟用安全入口',
|
entranceHelper: '設置安全入口有利於提高系統的安全性,如有需要,前往 面板設置-安全 中,啟用安全入口',
|
||||||
appInstalled: '已安裝應用',
|
appInstalled: '已安裝應用',
|
||||||
|
@ -275,6 +275,10 @@ const message = {
|
|||||||
supervisor: '进程守护',
|
supervisor: '进程守护',
|
||||||
},
|
},
|
||||||
home: {
|
home: {
|
||||||
|
restart_1panel: '重启面板',
|
||||||
|
restart_system: '重启服务器',
|
||||||
|
restartHelper: '是否对该机器进行 [{0}] 操作,该操作将导致服务暂时不可用,是否继续?',
|
||||||
|
operationSuccess: '操作成功!正在重启,请稍候...',
|
||||||
overview: '概览',
|
overview: '概览',
|
||||||
entranceHelper: '设置安全入口有利于提高系统的安全性,如有需要,前往 面板设置-安全 中,启用安全入口',
|
entranceHelper: '设置安全入口有利于提高系统的安全性,如有需要,前往 面板设置-安全 中,启用安全入口',
|
||||||
appInstalled: '已安装应用',
|
appInstalled: '已安装应用',
|
||||||
|
@ -376,4 +376,10 @@ html {
|
|||||||
.limit-height-popover {
|
.limit-height-popover {
|
||||||
max-height: 300px;
|
max-height: 300px;
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.router-button {
|
||||||
|
margin-top: 12px;
|
||||||
|
float: right;
|
||||||
|
margin-right: 50px;
|
||||||
}
|
}
|
@ -7,7 +7,19 @@
|
|||||||
path: '/',
|
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
|
<el-alert
|
||||||
v-if="!isSafety && globalStore.showEntranceWarn"
|
v-if="!isSafety && globalStore.showEntranceWarn"
|
||||||
style="margin-top: 20px"
|
style="margin-top: 20px"
|
||||||
@ -231,10 +243,11 @@ import i18n from '@/lang';
|
|||||||
import { Dashboard } from '@/api/interface/dashboard';
|
import { Dashboard } from '@/api/interface/dashboard';
|
||||||
import { dateFormatForSecond, computeSize } from '@/utils/util';
|
import { dateFormatForSecond, computeSize } from '@/utils/util';
|
||||||
import { useRouter } from 'vue-router';
|
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 { getIOOptions, getNetworkOptions } from '@/api/modules/monitor';
|
||||||
import { getSettingInfo, loadUpgradeInfo } from '@/api/modules/setting';
|
import { getSettingInfo, loadUpgradeInfo } from '@/api/modules/setting';
|
||||||
import { GlobalStore } from '@/store';
|
import { GlobalStore } from '@/store';
|
||||||
|
import { MsgSuccess } from '@/utils/message';
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const globalStore = GlobalStore();
|
const globalStore = GlobalStore();
|
||||||
|
|
||||||
@ -527,6 +540,21 @@ const loadSafeStatus = async () => {
|
|||||||
isSafety.value = res.data.securityEntrance;
|
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 = () => {
|
const onFocus = () => {
|
||||||
isActive.value = true;
|
isActive.value = true;
|
||||||
};
|
};
|
||||||
|
Loading…
x
Reference in New Issue
Block a user