mirror of
				https://github.com/1Panel-dev/1Panel.git
				synced 2025-10-31 03:07:34 +08:00 
			
		
		
		
	
							parent
							
								
									e9eea9c795
								
							
						
					
					
						commit
						3ff09c8b7a
					
				
					 13 changed files with 180 additions and 2 deletions
				
			
		|  | @ -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…
	
	Add table
		
		Reference in a new issue