diff --git a/backend/app/api/v1/operation_log.go b/backend/app/api/v1/operation_log.go index 3a25b0376..15f57100e 100644 --- a/backend/app/api/v1/operation_log.go +++ b/backend/app/api/v1/operation_log.go @@ -9,13 +9,13 @@ import ( ) func (b *BaseApi) GetOperationList(c *gin.Context) { - pagenation, isOK := helper.GeneratePaginationFromReq(c) - if !isOK { - helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, constant.ErrPageGenerate) + var req dto.PageInfo + if err := c.ShouldBindJSON(&req); err != nil { + helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err) return } - total, list, err := operationService.Page(pagenation.Page, pagenation.PageSize) + total, list, err := operationService.Page(req) if err != nil { helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err) return diff --git a/backend/app/api/v1/user.go b/backend/app/api/v1/user.go index 2e3587711..ef7b2bac4 100644 --- a/backend/app/api/v1/user.go +++ b/backend/app/api/v1/user.go @@ -68,13 +68,13 @@ func (b *BaseApi) Register(c *gin.Context) { } func (b *BaseApi) PageUsers(c *gin.Context) { - pagenation, isOK := helper.GeneratePaginationFromReq(c) - if !isOK { - helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, constant.ErrPageGenerate) + var req dto.UserPage + if err := c.ShouldBindJSON(&req); err != nil { + helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err) return } - total, list, err := userService.Page(pagenation.Page, pagenation.PageSize) + total, list, err := userService.Page(req) if err != nil { helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err) return diff --git a/backend/app/dto/common_req.go b/backend/app/dto/common_req.go index 0b03c629a..6b198dcb2 100644 --- a/backend/app/dto/common_req.go +++ b/backend/app/dto/common_req.go @@ -3,7 +3,6 @@ package dto type PageInfo struct { Page int `json:"page" validate:"required,number"` PageSize int `json:"pageSize" validate:"required,number"` - Limit int `json:"limit" validate:"required,number"` } type OperationWithName struct { diff --git a/backend/app/service/operation_log.go b/backend/app/service/operation_log.go index 8c52d5b22..a03461cfc 100644 --- a/backend/app/service/operation_log.go +++ b/backend/app/service/operation_log.go @@ -14,7 +14,7 @@ import ( type OperationService struct{} type IOperationService interface { - Page(page, size int) (int64, interface{}, error) + Page(search dto.PageInfo) (int64, interface{}, error) Create(operation model.OperationLog) error BatchDelete(ids []uint) error } @@ -27,8 +27,8 @@ func (u *OperationService) Create(operation model.OperationLog) error { return operationRepo.Create(&operation) } -func (u *OperationService) Page(page, size int) (int64, interface{}, error) { - total, ops, err := operationRepo.Page(page, size, commonRepo.WithOrderBy("created_at desc")) +func (u *OperationService) Page(search dto.PageInfo) (int64, interface{}, error) { + total, ops, err := operationRepo.Page(search.Page, search.PageSize, commonRepo.WithOrderBy("created_at desc")) var dtoOps []dto.OperationLogBack for _, op := range ops { var item dto.OperationLogBack @@ -57,7 +57,7 @@ func (u *OperationService) BatchDelete(ids []uint) error { func filterSensitive(vars string) string { var Sensitives = []string{"password", "Password"} - ops := make(map[string]string) + ops := make(map[string]interface{}) if err := json.Unmarshal([]byte(vars), &ops); err != nil { return vars } diff --git a/backend/app/service/user.go b/backend/app/service/user.go index 910e62b2f..9a8572ae8 100644 --- a/backend/app/service/user.go +++ b/backend/app/service/user.go @@ -18,7 +18,7 @@ type UserService struct{} type IUserService interface { Get(name uint) (*dto.UserBack, error) - Page(page, size int) (int64, interface{}, error) + Page(search dto.UserPage) (int64, interface{}, error) Register(userDto dto.UserCreate) error Login(c *gin.Context, info dto.Login) (*dto.UserLoginInfo, error) LogOut(c *gin.Context) error @@ -44,8 +44,8 @@ func (u *UserService) Get(id uint) (*dto.UserBack, error) { return &dtoUser, err } -func (u *UserService) Page(page, size int) (int64, interface{}, error) { - total, users, err := userRepo.Page(page, size, commonRepo.WithOrderBy("created_at desc")) +func (u *UserService) Page(search dto.UserPage) (int64, interface{}, error) { + total, users, err := userRepo.Page(search.Page, search.PageSize, commonRepo.WithLikeName(search.Name)) var dtoUsers []dto.UserBack for _, user := range users { var item dto.UserBack diff --git a/backend/cmd/gotty/gotty b/backend/cmd/gotty/gotty new file mode 100755 index 000000000..b56d2334e Binary files /dev/null and b/backend/cmd/gotty/gotty differ diff --git a/backend/init/binary/gotty.go b/backend/init/binary/gotty.go new file mode 100644 index 000000000..ebe48bbed --- /dev/null +++ b/backend/init/binary/gotty.go @@ -0,0 +1,23 @@ +package binary + +import ( + "io" + "os" + "os/exec" + + "github.com/1Panel-dev/1Panel/global" +) + +func StartTTY() { + cmd := "gotty" + params := []string{"--permit-write", "bash"} + go func() { + c := exec.Command(cmd, params...) + c.Env = append(c.Env, os.Environ()...) + c.Stdout = io.Discard + c.Stderr = io.Discard + if err := c.Run(); err != nil { + global.LOG.Error(err) + } + }() +} diff --git a/backend/router/operation_log.go b/backend/router/operation_log.go index 21dfcc7d7..97000dede 100644 --- a/backend/router/operation_log.go +++ b/backend/router/operation_log.go @@ -14,7 +14,7 @@ func (s *OperationLogRouter) InitOperationLogRouter(Router *gin.RouterGroup) { operationRouter.Use(middleware.JwtAuth()).Use(middleware.SessionAuth()) baseApi := v1.ApiGroupApp.BaseApi { - operationRouter.GET("", baseApi.GetOperationList) + operationRouter.POST("", baseApi.GetOperationList) operationRouter.POST("/del", baseApi.DeleteOperation) } } diff --git a/backend/router/ro_user.go b/backend/router/ro_user.go index bfcc6ad57..3fa26adc8 100644 --- a/backend/router/ro_user.go +++ b/backend/router/ro_user.go @@ -17,8 +17,8 @@ func (s *UserRouter) InitUserRouter(Router *gin.RouterGroup) { { withRecordRouter.POST("", baseApi.Register) withRecordRouter.POST("/del", baseApi.DeleteUser) - userRouter.GET("", baseApi.PageUsers) + userRouter.POST("/search", baseApi.PageUsers) userRouter.GET(":id", baseApi.GetUserInfo) - userRouter.POST(":id", baseApi.UpdateUser) + userRouter.PUT(":id", baseApi.UpdateUser) } } diff --git a/backend/server/server.go b/backend/server/server.go index 7879e1796..c9fcb93bb 100644 --- a/backend/server/server.go +++ b/backend/server/server.go @@ -9,6 +9,7 @@ import ( "time" "github.com/1Panel-dev/1Panel/global" + "github.com/1Panel-dev/1Panel/init/binary" "github.com/1Panel-dev/1Panel/init/db" "github.com/1Panel-dev/1Panel/init/log" "github.com/1Panel-dev/1Panel/init/migration" @@ -29,6 +30,7 @@ func Start() { gob.Register(psession.SessionUser{}) cache.Init() session.Init() + binary.StartTTY() routers := router.Routers() address := fmt.Sprintf(":%d", global.CONF.System.Port) s := initServer(address, routers) diff --git a/frontend/src/api/modules/operation-log.ts b/frontend/src/api/modules/operation-log.ts index dcc1f4d7f..38aa38d75 100644 --- a/frontend/src/api/modules/operation-log.ts +++ b/frontend/src/api/modules/operation-log.ts @@ -1,9 +1,9 @@ import http from '@/api'; -import { ResPage } from '../interface'; +import { ResPage, ReqPage } from '../interface'; import { ResOperationLog } from '../interface/operation-log'; -export const getOperationList = (currentPage: number, pageSize: number) => { - return http.get>(`/operations?page=${currentPage}&pageSize=${pageSize}`); +export const getOperationList = (info: ReqPage) => { + return http.post>(`/operations`, info); }; export const deleteOperation = (params: { ids: number[] }) => { diff --git a/frontend/src/api/modules/user.ts b/frontend/src/api/modules/user.ts index 247f8452d..f24eab011 100644 --- a/frontend/src/api/modules/user.ts +++ b/frontend/src/api/modules/user.ts @@ -2,8 +2,8 @@ import http from '@/api'; import { ResPage } from '../interface'; import { User } from '../interface/user'; -export const getUserList = (currentPage: number, pageSize: number) => { - return http.get>(`/users?page=${currentPage}&pageSize=${pageSize}`); +export const getUserList = (params: User.ReqGetUserParams) => { + return http.post>(`/users/search`, params); }; export const addUser = (params: User.User) => { @@ -15,7 +15,7 @@ export const getUserById = (id: number) => { }; export const editUser = (params: User.User) => { - return http.post(`/users/` + params.id, params); + return http.put(`/users/` + params.id, params); }; export const deleteUser = (params: { ids: number[] }) => { diff --git a/frontend/src/lang/modules/en.ts b/frontend/src/lang/modules/en.ts index 41a38d99c..f19bb8d20 100644 --- a/frontend/src/lang/modules/en.ts +++ b/frontend/src/lang/modules/en.ts @@ -50,6 +50,7 @@ export default { menu: { home: 'Dashboard', demo: 'Demo', + terminal: 'Terminal', operations: 'Operation logs', }, home: { @@ -83,6 +84,7 @@ export default { login: ' login', logout: ' logout', post: ' create', + put: ' update', update: ' update', delete: ' delete', del: 'delete', diff --git a/frontend/src/lang/modules/zh.ts b/frontend/src/lang/modules/zh.ts index 6dac0dc72..cea59fca4 100644 --- a/frontend/src/lang/modules/zh.ts +++ b/frontend/src/lang/modules/zh.ts @@ -50,6 +50,7 @@ export default { menu: { home: '概览', demo: '样例', + terminal: '终端管理', operations: '操作记录', }, @@ -82,6 +83,7 @@ export default { users: '用户', auth: '用户', post: '创建', + put: '更新', update: '更新', delete: '删除', login: '登录', diff --git a/frontend/src/layout/layout-content.vue b/frontend/src/layout/layout-content.vue index c4a3c79ae..78c168e7a 100644 --- a/frontend/src/layout/layout-content.vue +++ b/frontend/src/layout/layout-content.vue @@ -9,7 +9,7 @@ :header="header" v-if="showBack" > - + {{ header }}
diff --git a/frontend/src/routers/modules/operation-log.ts b/frontend/src/routers/modules/operation-log.ts index ea5027942..61bc1248a 100644 --- a/frontend/src/routers/modules/operation-log.ts +++ b/frontend/src/routers/modules/operation-log.ts @@ -1,7 +1,7 @@ import { Layout } from '@/routers/constant'; const operationRouter = { - sort: 2, + sort: 3, path: '/operations', component: Layout, redirect: '/operation', diff --git a/frontend/src/routers/modules/terminal.ts b/frontend/src/routers/modules/terminal.ts new file mode 100644 index 000000000..08133bb4f --- /dev/null +++ b/frontend/src/routers/modules/terminal.ts @@ -0,0 +1,26 @@ +import { Layout } from '@/routers/constant'; + +const terminalRouter = { + sort: 2, + path: '/terminals', + component: Layout, + redirect: '/terminal', + meta: { + title: 'menu.terminal', + icon: 'monitor', + }, + children: [ + { + path: '/terminal', + name: 'Terminal', + component: () => import('@/views/terminal/index.vue'), + meta: { + keepAlive: true, + requiresAuth: true, + key: 'Terminal', + }, + }, + ], +}; + +export default terminalRouter; diff --git a/frontend/src/views/demos/table/index.vue b/frontend/src/views/demos/table/index.vue index 573ae04bb..7a07787dd 100644 --- a/frontend/src/views/demos/table/index.vue +++ b/frontend/src/views/demos/table/index.vue @@ -41,10 +41,14 @@ const router = useRouter(); const data = ref(); const selects = ref([]); const paginationConfig = reactive({ - currentPage: 1, + page: 1, pageSize: 5, total: 0, }); +const userSearch = reactive({ + page: 1, + pageSize: 5, +}); const openOperate = (row: User.User | null) => { let params: { [key: string]: any } = { @@ -84,8 +88,9 @@ const buttons = [ ]; const search = async () => { - const { currentPage, pageSize } = paginationConfig; - const res = await getUserList(currentPage, pageSize); + userSearch.page = paginationConfig.page; + userSearch.pageSize = paginationConfig.pageSize; + const res = await getUserList(userSearch); data.value = res.data.items; paginationConfig.total = res.data.total; }; diff --git a/frontend/src/views/operation-log/index.vue b/frontend/src/views/operation-log/index.vue index ac6ce8622..1e209466e 100644 --- a/frontend/src/views/operation-log/index.vue +++ b/frontend/src/views/operation-log/index.vue @@ -84,6 +84,11 @@ const paginationConfig = reactive({ total: 0, }); +const logSearch = reactive({ + page: 1, + pageSize: 5, +}); + const selects = ref([]); const batchDelete = async (row: ResOperationLog | null) => { let ids: Array = []; @@ -95,7 +100,6 @@ const batchDelete = async (row: ResOperationLog | null) => { } else { ids.push(row.id); } - console.log(ids); await useDeleteData(deleteOperation, { ids: ids }, 'commons.msg.delete'); search(); }; @@ -109,20 +113,35 @@ const buttons = [ ]; const search = async () => { - const { currentPage, pageSize } = paginationConfig; - const res = await getOperationList(currentPage, pageSize); + logSearch.page = paginationConfig.currentPage; + logSearch.pageSize = paginationConfig.pageSize; + const res = await getOperationList(logSearch); data.value = res.data.items; paginationConfig.total = res.data.total; }; const fmtOperation = (row: ResOperationLog) => { - if (row.source == '' && row.action == '') { + if (row.method.toLocaleLowerCase() !== 'put') { + if (row.source == '' && row.action == '') { + return ( + i18n.global.t('operations.detail.' + row.group.toLocaleLowerCase()) + + i18n.global.t('operations.detail.' + row.method.toLocaleLowerCase()) + ); + } + if (row.action == '') { + return ( + i18n.global.t('operations.detail.' + row.group.toLocaleLowerCase()) + + i18n.global.t('operations.detail.' + row.source.toLocaleLowerCase()) + ); + } + return; + } + if (row.action == '') { return ( i18n.global.t('operations.detail.' + row.group.toLocaleLowerCase()) + i18n.global.t('operations.detail.' + row.method.toLocaleLowerCase()) ); - } - if (row.action == '') { + } else { return ( i18n.global.t('operations.detail.' + row.group.toLocaleLowerCase()) + i18n.global.t('operations.detail.' + row.source.toLocaleLowerCase()) diff --git a/frontend/src/views/terminal/index.vue b/frontend/src/views/terminal/index.vue new file mode 100644 index 000000000..b68826f04 --- /dev/null +++ b/frontend/src/views/terminal/index.vue @@ -0,0 +1,39 @@ +