From 3c770ce63b30be9db21c9f230c5732c916ac2c6f Mon Sep 17 00:00:00 2001 From: ssongliu Date: Thu, 1 Sep 2022 10:25:38 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=A2=9E=E5=8A=A0=E4=B8=BB=E6=9C=BA?= =?UTF-8?q?=E6=B5=8B=E8=AF=95=E8=BF=9E=E6=8E=A5=E6=8C=89=E9=92=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend/app/api/v1/command.go | 11 ++-- backend/app/api/v1/host.go | 37 +++++++++--- backend/app/api/v1/terminal.go | 2 +- backend/app/dto/command.go | 8 +-- backend/app/service/command.go | 23 ++++---- backend/app/service/host.go | 14 ++--- backend/router/ro_host.go | 3 +- frontend/src/api/modules/host.ts | 4 ++ frontend/src/lang/modules/en.ts | 14 ++++- frontend/src/lang/modules/zh.ts | 9 ++- frontend/src/views/terminal/command/index.vue | 15 ++--- frontend/src/views/terminal/host/index.vue | 59 ++++++++++++------- 12 files changed, 128 insertions(+), 71 deletions(-) diff --git a/backend/app/api/v1/command.go b/backend/app/api/v1/command.go index cf3cfd705..c877a1e13 100644 --- a/backend/app/api/v1/command.go +++ b/backend/app/api/v1/command.go @@ -9,7 +9,7 @@ import ( ) func (b *BaseApi) CreateCommand(c *gin.Context) { - var req dto.CommandCreate + var req dto.CommandOperate if err := c.ShouldBindJSON(&req); err != nil { helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err) return @@ -45,7 +45,7 @@ func (b *BaseApi) SearchCommand(c *gin.Context) { } func (b *BaseApi) ListCommand(c *gin.Context) { - list, err := commandService.Search() + list, err := commandService.List() if err != nil { helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err) return @@ -55,7 +55,7 @@ func (b *BaseApi) ListCommand(c *gin.Context) { } func (b *BaseApi) DeleteCommand(c *gin.Context) { - var req dto.DeleteByName + var req dto.BatchDeleteReq if err := c.ShouldBindJSON(&req); err != nil { helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err) return @@ -65,7 +65,7 @@ func (b *BaseApi) DeleteCommand(c *gin.Context) { return } - if err := commandService.Delete(req.Name); err != nil { + if err := commandService.Delete(req.Ids); err != nil { helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err) return } @@ -73,7 +73,7 @@ func (b *BaseApi) DeleteCommand(c *gin.Context) { } func (b *BaseApi) UpdateCommand(c *gin.Context) { - var req dto.CommandUpdate + var req dto.CommandOperate if err := c.ShouldBindJSON(&req); err != nil { helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err) return @@ -90,6 +90,7 @@ func (b *BaseApi) UpdateCommand(c *gin.Context) { upMap := make(map[string]interface{}) upMap["name"] = req.Name + upMap["command"] = req.Command if err := commandService.Update(id, upMap); err != nil { helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err) return diff --git a/backend/app/api/v1/host.go b/backend/app/api/v1/host.go index 481a1dd5d..f5fbf5e9f 100644 --- a/backend/app/api/v1/host.go +++ b/backend/app/api/v1/host.go @@ -6,6 +6,7 @@ import ( "github.com/1Panel-dev/1Panel/constant" "github.com/1Panel-dev/1Panel/global" "github.com/1Panel-dev/1Panel/utils/copier" + "github.com/1Panel-dev/1Panel/utils/ssh" "github.com/gin-gonic/gin" ) @@ -27,6 +28,32 @@ func (b *BaseApi) CreateHost(c *gin.Context) { helper.SuccessWithData(c, host) } +func (b *BaseApi) TestConn(c *gin.Context) { + var req dto.HostOperate + if err := c.ShouldBindJSON(&req); err != nil { + helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err) + return + } + if err := global.VALID.Struct(req); err != nil { + helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err) + return + } + + var connInfo ssh.ConnInfo + if err := copier.Copy(&connInfo, &req); err != nil { + helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, constant.ErrStructTransform) + return + } + client, err := connInfo.NewClient() + if err != nil { + helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err) + return + } + defer client.Close() + + helper.SuccessWithData(c, nil) +} + func (b *BaseApi) HostTree(c *gin.Context) { var req dto.SearchForTree if err := c.ShouldBindJSON(&req); err != nil { @@ -63,17 +90,13 @@ func (b *BaseApi) GetHostInfo(c *gin.Context) { } func (b *BaseApi) DeleteHost(c *gin.Context) { - var req dto.BatchDeleteReq - if err := c.ShouldBindJSON(&req); err != nil { - helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err) - return - } - if err := global.VALID.Struct(req); err != nil { + id, err := helper.GetParamID(c) + if err != nil { helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err) return } - if err := hostService.BatchDelete(req.Ids); err != nil { + if err := hostService.Delete(id); err != nil { helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err) return } diff --git a/backend/app/api/v1/terminal.go b/backend/app/api/v1/terminal.go index b29b11007..4867c94d3 100644 --- a/backend/app/api/v1/terminal.go +++ b/backend/app/api/v1/terminal.go @@ -51,7 +51,7 @@ func (b *BaseApi) WsSsh(c *gin.Context) { defer wsConn.Close() client, err := connInfo.NewClient() - if wshandleError(wsConn, errors.WithMessage(err, " Failed to set up the connection. Please check the host information")) { + if wshandleError(wsConn, errors.WithMessage(err, "failed to set up the connection. Please check the host information")) { return } defer client.Close() diff --git a/backend/app/dto/command.go b/backend/app/dto/command.go index 0af9d96d7..84fbf726c 100644 --- a/backend/app/dto/command.go +++ b/backend/app/dto/command.go @@ -1,16 +1,12 @@ package dto -type CommandCreate struct { +type CommandOperate struct { Name string `json:"name" validate:"required"` Command string `json:"command" validate:"required"` } -type CommandUpdate struct { - Name string `json:"name" validate:"required"` -} - type CommandInfo struct { - ID string `json:"id"` + ID uint `json:"id"` Name string `json:"name"` Command string `json:"command"` } diff --git a/backend/app/service/command.go b/backend/app/service/command.go index f84b1987b..337ff6014 100644 --- a/backend/app/service/command.go +++ b/backend/app/service/command.go @@ -11,18 +11,18 @@ import ( type CommandService struct{} type ICommandService interface { - Search() ([]model.Command, error) + List() ([]model.Command, error) SearchWithPage(search dto.SearchWithPage) (int64, interface{}, error) - Create(commandDto dto.CommandCreate) error + Create(commandDto dto.CommandOperate) error Update(id uint, upMap map[string]interface{}) error - Delete(name string) error + Delete(ids []uint) error } func NewICommandService() ICommandService { return &CommandService{} } -func (u *CommandService) Search() ([]model.Command, error) { +func (u *CommandService) List() ([]model.Command, error) { commands, err := commandRepo.GetList() if err != nil { return nil, constant.ErrRecordNotFound @@ -43,7 +43,7 @@ func (u *CommandService) SearchWithPage(search dto.SearchWithPage) (int64, inter return total, dtoCommands, err } -func (u *CommandService) Create(commandDto dto.CommandCreate) error { +func (u *CommandService) Create(commandDto dto.CommandOperate) error { command, _ := commandRepo.Get(commonRepo.WithByName(commandDto.Name)) if command.ID != 0 { return constant.ErrRecordExist @@ -57,12 +57,15 @@ func (u *CommandService) Create(commandDto dto.CommandCreate) error { return nil } -func (u *CommandService) Delete(name string) error { - command, _ := commandRepo.Get(commonRepo.WithByName(name)) - if command.ID == 0 { - return constant.ErrRecordNotFound +func (u *CommandService) Delete(ids []uint) error { + if len(ids) == 1 { + command, _ := commandRepo.Get(commonRepo.WithByID(ids[0])) + if command.ID == 0 { + return constant.ErrRecordNotFound + } + return commandRepo.Delete(commonRepo.WithByID(ids[0])) } - return commandRepo.Delete(commonRepo.WithByID(command.ID)) + return commandRepo.Delete(commonRepo.WithIdsIn(ids)) } func (u *CommandService) Update(id uint, upMap map[string]interface{}) error { diff --git a/backend/app/service/host.go b/backend/app/service/host.go index 8f36fc256..b3ba32039 100644 --- a/backend/app/service/host.go +++ b/backend/app/service/host.go @@ -17,7 +17,7 @@ type IHostService interface { SearchForTree(search dto.SearchForTree) ([]dto.HostTree, error) Create(hostDto dto.HostOperate) (*dto.HostInfo, error) Update(id uint, upMap map[string]interface{}) error - BatchDelete(ids []uint) error + Delete(id uint) error } func NewIHostService() IHostService { @@ -75,14 +75,12 @@ func (u *HostService) Create(hostDto dto.HostOperate) (*dto.HostInfo, error) { return &hostinfo, nil } -func (u *HostService) BatchDelete(ids []uint) error { - if len(ids) == 1 { - host, _ := hostRepo.Get(commonRepo.WithByID(ids[0])) - if host.ID == 0 { - return constant.ErrRecordNotFound - } +func (u *HostService) Delete(id uint) error { + host, _ := hostRepo.Get(commonRepo.WithByID(id)) + if host.ID == 0 { + return constant.ErrRecordNotFound } - return hostRepo.Delete(commonRepo.WithIdsIn(ids)) + return hostRepo.Delete(commonRepo.WithByID(id)) } func (u *HostService) Update(id uint, upMap map[string]interface{}) error { diff --git a/backend/router/ro_host.go b/backend/router/ro_host.go index e336012d5..579a98668 100644 --- a/backend/router/ro_host.go +++ b/backend/router/ro_host.go @@ -16,8 +16,9 @@ func (s *HostRouter) InitHostRouter(Router *gin.RouterGroup) { { withRecordRouter.POST("", baseApi.CreateHost) withRecordRouter.DELETE(":id", baseApi.DeleteHost) + withRecordRouter.PUT(":id", baseApi.UpdateHost) hostRouter.POST("/search", baseApi.HostTree) + hostRouter.POST("/testconn", baseApi.TestConn) hostRouter.GET(":id", baseApi.GetHostInfo) - hostRouter.PUT(":id", baseApi.UpdateHost) } } diff --git a/frontend/src/api/modules/host.ts b/frontend/src/api/modules/host.ts index 2c304a53e..073e38952 100644 --- a/frontend/src/api/modules/host.ts +++ b/frontend/src/api/modules/host.ts @@ -13,6 +13,10 @@ export const addHost = (params: Host.HostOperate) => { return http.post(`/hosts`, params); }; +export const testConn = (params: Host.HostOperate) => { + return http.post(`/hosts/testconn`, params); +}; + export const editHost = (params: Host.HostOperate) => { console.log(params.id); return http.put(`/hosts/` + params.id, params); diff --git a/frontend/src/lang/modules/en.ts b/frontend/src/lang/modules/en.ts index 4541178d4..1b341ac20 100644 --- a/frontend/src/lang/modules/en.ts +++ b/frontend/src/lang/modules/en.ts @@ -90,8 +90,16 @@ export default { logout: 'Logout', }, terminal: { - connHistory: 'historys', - hostHistory: 'History record', + conn: 'connection', + testConn: 'Test connection', + connTestOk: 'Connection information available', + hostList: 'Host information', + createConn: 'Create a connection', + createGroup: 'Create a group', + expand: 'Expand all', + fold: 'All contract', + groupDeleteHelper: + 'After the group is removed, all connections in the group will be migrated to the default group. Confirm the information', addHost: 'Add Host', localhost: 'Localhost', name: 'Name', @@ -108,6 +116,8 @@ export default { detail: { users: 'User', hosts: 'Host', + groups: 'Group', + commands: 'Command', auth: 'User', login: ' login', logout: ' logout', diff --git a/frontend/src/lang/modules/zh.ts b/frontend/src/lang/modules/zh.ts index 05eec9981..06767eb7c 100644 --- a/frontend/src/lang/modules/zh.ts +++ b/frontend/src/lang/modules/zh.ts @@ -94,7 +94,14 @@ export default { }, terminal: { conn: '连接', + testConn: '连接测试', + connTestOk: '连接信息可用', hostList: '主机信息', + createConn: '创建连接', + createGroup: '创建分组', + expand: '全部展开', + fold: '全部收缩', + groupDeleteHelper: '移除组后,组内所有连接将迁移到 default 组内,是否确认', quickCmd: '快捷命令', command: '命令', addHost: '添加主机', @@ -114,7 +121,7 @@ export default { users: '用户', hosts: '主机', groups: '组', - command: '快捷命令', + commands: '快捷命令', auth: '用户', post: '创建', put: '更新', diff --git a/frontend/src/views/terminal/command/index.vue b/frontend/src/views/terminal/command/index.vue index 5876521aa..28e50b10a 100644 --- a/frontend/src/views/terminal/command/index.vue +++ b/frontend/src/views/terminal/command/index.vue @@ -83,7 +83,6 @@ const submitAddCommand = (formEl: FormInstance | undefined) => { if (!formEl) return; formEl.validate(async (valid) => { if (!valid) return; - console.log(commandInfo.id); if (operate.value === 'create') { await addCommand(commandInfo); } else { @@ -97,12 +96,11 @@ const submitAddCommand = (formEl: FormInstance | undefined) => { const onEdit = async (row: Command.CommandInfo | null) => { if (row !== null) { - console.log(row.id); - // commandInfo.id = row.id; - // commandInfo.name = row.name; - // commandInfo.command = row.command; - // operate.value = 'edit'; - // cmdVisiable.value = true; + commandInfo.id = row.id; + commandInfo.name = row.name; + commandInfo.command = row.command; + operate.value = 'edit'; + cmdVisiable.value = true; } }; @@ -142,9 +140,6 @@ const search = async () => { commandSearch.pageSize = paginationConfig.pageSize; const res = await getCommandPage(commandSearch); data.value = res.data.items; - for (const d of data.value) { - d.id = d.id + ''; - } paginationConfig.total = res.data.total; }; diff --git a/frontend/src/views/terminal/host/index.vue b/frontend/src/views/terminal/host/index.vue index 3a763db6a..5c8535800 100644 --- a/frontend/src/views/terminal/host/index.vue +++ b/frontend/src/views/terminal/host/index.vue @@ -2,16 +2,16 @@ - + - + - + - + - + @@ -105,10 +105,21 @@ {{ $t('commons.button.reset') }} - + + {{ $t('terminal.testConn') }} + + {{ $t('commons.button.create') }} - + {{ $t('commons.button.confirm') }} @@ -124,7 +135,7 @@ import type { ElForm } from 'element-plus'; import { Rules } from '@/global/form-rues'; import { Host } from '@/api/interface/host'; import { Group } from '@/api/interface/group'; -import { getHostList, getHostInfo, addHost, editHost, deleteHost } from '@/api/modules/host'; +import { testConn, getHostList, getHostInfo, addHost, editHost, deleteHost } from '@/api/modules/host'; import { getGroupList, addGroup, editGroup, deleteGroup } from '@/api/modules/group'; import { useDeleteData } from '@/hooks/use-delete-data'; import { ElMessage } from 'element-plus'; @@ -203,18 +214,29 @@ function restHostForm() { } } -const submitAddHost = (formEl: FormInstance | undefined) => { +const submitAddHost = (formEl: FormInstance | undefined, ops: string) => { if (!formEl) return; formEl.validate(async (valid) => { if (!valid) return; - if (hostOperation.value === 'create') { - await addHost(hostInfo); - } else { - await editHost(hostInfo); + console.log(ops); + switch (ops) { + case 'create': + await addHost(hostInfo); + restHostForm(); + ElMessage.success(i18n.global.t('commons.msg.operationSuccess')); + loadHostTree(); + break; + case 'edit': + await editHost(hostInfo); + restHostForm(); + ElMessage.success(i18n.global.t('commons.msg.operationSuccess')); + loadHostTree(); + break; + case 'testconn': + await testConn(hostInfo); + ElMessage.success(i18n.global.t('terminal.connTestOk')); + break; } - restHostForm(); - ElMessage.success(i18n.global.t('commons.msg.operationSuccess')); - loadHostTree(); }); }; @@ -224,7 +246,6 @@ const onGroupCreate = () => { groupOperation.value = 'create'; }; const onCreateGroup = async () => { - console.log(groupOperation.value); if (groupOperation.value === 'create') { let group = { id: 0, name: groupInputValue.value, type: 'host' }; await addGroup(group); @@ -246,7 +267,7 @@ const onDelete = async (node: Node, data: Tree) => { return; } if (node.level === 1) { - await useDeleteData(deleteGroup, data.id - 10000, '移除组后,组内所有连接将迁移到 default 组内,是否确认?'); + await useDeleteData(deleteGroup, data.id - 10000, i18n.global.t('terminal.groupDeleteHelper')); loadGroups(); } else { await useDeleteData(deleteHost, data.id, 'commons.msg.delete'); @@ -259,13 +280,11 @@ const onEdit = async (node: Node, data: Tree) => { if (node.level === 1 && data.label === 'default') { return; } - console.log(node.level === 1); if (node.level === 1) { groupInputShow.value = true; groupInputValue.value = data.label; currentGroupID.value = data.id - 10000; groupOperation.value = 'edit'; - console.log(groupOperation.value); return; } else { const res = await getHostInfo(data.id);