diff --git a/backend/app/api/v1/compose_template.go b/backend/app/api/v1/compose_template.go index b85bf7d5a..8ec990f9a 100644 --- a/backend/app/api/v1/compose_template.go +++ b/backend/app/api/v1/compose_template.go @@ -38,13 +38,13 @@ func (b *BaseApi) CreateComposeTemplate(c *gin.Context) { // @Summary Page compose templates // @Description 获取容器编排模版列表分页 // @Accept json -// @Param request body dto.PageInfo true "request" +// @Param request body dto.SearchWithPage true "request" // @Produce json // @Success 200 {object} dto.PageResult // @Security ApiKeyAuth // @Router /containers/template/search [post] func (b *BaseApi) SearchComposeTemplate(c *gin.Context) { - var req dto.PageInfo + var req dto.SearchWithPage if err := c.ShouldBindJSON(&req); err != nil { helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err) return diff --git a/backend/app/api/v1/container.go b/backend/app/api/v1/container.go index c5b614877..13c5048ab 100644 --- a/backend/app/api/v1/container.go +++ b/backend/app/api/v1/container.go @@ -50,12 +50,12 @@ func (b *BaseApi) SearchContainer(c *gin.Context) { // @Summary Page composes // @Description 获取编排列表分页 // @Accept json -// @Param request body dto.PageInfo true "request" +// @Param request body dto.SearchWithPage true "request" // @Success 200 {object} dto.PageResult // @Security ApiKeyAuth // @Router /containers/compose/search [post] func (b *BaseApi) SearchCompose(c *gin.Context) { - var req dto.PageInfo + var req dto.SearchWithPage if err := c.ShouldBindJSON(&req); err != nil { helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err) return @@ -318,13 +318,13 @@ func (b *BaseApi) ContainerLogs(c *gin.Context) { // @Summary Page networks // @Description 获取容器网络列表分页 // @Accept json -// @Param request body dto.PageInfo true "request" +// @Param request body dto.SearchWithPage true "request" // @Produce json // @Success 200 {object} dto.PageResult // @Security ApiKeyAuth // @Router /containers/network/search [post] func (b *BaseApi) SearchNetwork(c *gin.Context) { - var req dto.PageInfo + var req dto.SearchWithPage if err := c.ShouldBindJSON(&req); err != nil { helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err) return @@ -403,13 +403,13 @@ func (b *BaseApi) CreateNetwork(c *gin.Context) { // @Summary Page volumes // @Description 获取容器存储卷分页 // @Accept json -// @Param request body dto.PageInfo true "request" +// @Param request body dto.SearchWithPage true "request" // @Produce json // @Success 200 {object} dto.PageResult // @Security ApiKeyAuth // @Router /containers/volume/search [post] func (b *BaseApi) SearchVolume(c *gin.Context) { - var req dto.PageInfo + var req dto.SearchWithPage if err := c.ShouldBindJSON(&req); err != nil { helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err) return diff --git a/backend/app/api/v1/database_mysql.go b/backend/app/api/v1/database_mysql.go index bf2b94e9d..dc56ab1ec 100644 --- a/backend/app/api/v1/database_mysql.go +++ b/backend/app/api/v1/database_mysql.go @@ -169,12 +169,12 @@ func (b *BaseApi) UpdateMysqlConfByFile(c *gin.Context) { // @Summary Page mysql databases // @Description 获取 mysql 数据库列表分页 // @Accept json -// @Param request body dto.PageInfo true "request" +// @Param request body dto.SearchWithPage true "request" // @Success 200 {object} dto.PageResult // @Security ApiKeyAuth // @Router /databases/search [post] func (b *BaseApi) SearchMysql(c *gin.Context) { - var req dto.PageInfo + var req dto.SearchWithPage if err := c.ShouldBindJSON(&req); err != nil { helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err) return diff --git a/backend/app/api/v1/image.go b/backend/app/api/v1/image.go index c4cd68579..bb1bcf017 100644 --- a/backend/app/api/v1/image.go +++ b/backend/app/api/v1/image.go @@ -12,13 +12,13 @@ import ( // @Summary Page images // @Description 获取镜像列表分页 // @Accept json -// @Param request body dto.PageInfo true "request" +// @Param request body dto.SearchWithPage true "request" // @Produce json // @Success 200 {object} dto.PageResult // @Security ApiKeyAuth // @Router /containers/image/search [post] func (b *BaseApi) SearchImage(c *gin.Context) { - var req dto.PageInfo + var req dto.SearchWithPage if err := c.ShouldBindJSON(&req); err != nil { helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err) return diff --git a/backend/app/api/v1/image_repo.go b/backend/app/api/v1/image_repo.go index cbc1ad2a4..35375d7cd 100644 --- a/backend/app/api/v1/image_repo.go +++ b/backend/app/api/v1/image_repo.go @@ -12,13 +12,13 @@ import ( // @Summary Page image repos // @Description 获取镜像仓库列表分页 // @Accept json -// @Param request body dto.PageInfo true "request" +// @Param request body dto.SearchWithPage true "request" // @Produce json // @Success 200 {object} dto.PageResult // @Security ApiKeyAuth // @Router /containers/repo/search [post] func (b *BaseApi) SearchRepo(c *gin.Context) { - var req dto.PageInfo + var req dto.SearchWithPage if err := c.ShouldBindJSON(&req); err != nil { helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err) return diff --git a/backend/app/api/v1/logs.go b/backend/app/api/v1/logs.go index 82a9d5c85..e723a0721 100644 --- a/backend/app/api/v1/logs.go +++ b/backend/app/api/v1/logs.go @@ -12,12 +12,12 @@ import ( // @Summary Page login logs // @Description 获取系统登录日志列表分页 // @Accept json -// @Param request body dto.PageInfo true "request" +// @Param request body dto.SearchLgLogWithPage true "request" // @Success 200 {object} dto.PageResult // @Security ApiKeyAuth // @Router /logs/login [post] func (b *BaseApi) GetLoginLogs(c *gin.Context) { - var req dto.PageInfo + var req dto.SearchLgLogWithPage if err := c.ShouldBindJSON(&req); err != nil { helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err) return @@ -39,12 +39,12 @@ func (b *BaseApi) GetLoginLogs(c *gin.Context) { // @Summary Page operation logs // @Description 获取系统操作日志列表分页 // @Accept json -// @Param request body dto.PageInfo true "request" +// @Param request body dto.SearchOpLogWithPage true "request" // @Success 200 {object} dto.PageResult // @Security ApiKeyAuth // @Router /logs/operation [post] func (b *BaseApi) GetOperationLogs(c *gin.Context) { - var req dto.PageInfo + var req dto.SearchOpLogWithPage if err := c.ShouldBindJSON(&req); err != nil { helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err) return diff --git a/backend/app/dto/common_req.go b/backend/app/dto/common_req.go index 61d8907d0..809ea720b 100644 --- a/backend/app/dto/common_req.go +++ b/backend/app/dto/common_req.go @@ -2,7 +2,7 @@ package dto type SearchWithPage struct { PageInfo - Info string `json:"info" validate:"required"` + Info string `json:"info"` } type PageInfo struct { diff --git a/backend/app/dto/container.go b/backend/app/dto/container.go index 11b5463ab..650425dae 100644 --- a/backend/app/dto/container.go +++ b/backend/app/dto/container.go @@ -4,6 +4,7 @@ import "time" type PageContainer struct { PageInfo + Name string `json:"name"` Filters string `json:"filters"` } diff --git a/backend/app/dto/logs.go b/backend/app/dto/logs.go index f3601482d..8831801db 100644 --- a/backend/app/dto/logs.go +++ b/backend/app/dto/logs.go @@ -5,8 +5,8 @@ import ( ) type OperationLog struct { - ID uint `json:"id"` - Group string `json:"group"` + ID uint `json:"id"` + Source string `json:"source"` IP string `json:"ip"` Path string `json:"path"` @@ -22,6 +22,19 @@ type OperationLog struct { CreatedAt time.Time `json:"createdAt"` } +type SearchOpLogWithPage struct { + PageInfo + Source string `json:"source"` + Status string `json:"status"` + Operation string `json:"operation"` +} + +type SearchLgLogWithPage struct { + PageInfo + IP string `json:"ip"` + Status string `json:"status"` +} + type LoginLog struct { ID uint `json:"id"` IP string `json:"ip"` diff --git a/backend/app/model/logs.go b/backend/app/model/logs.go index bddea98c3..4018f4322 100644 --- a/backend/app/model/logs.go +++ b/backend/app/model/logs.go @@ -6,7 +6,7 @@ import ( type OperationLog struct { BaseModel - Group string `gorm:"type:varchar(64)" json:"group"` + Source string `gorm:"type:varchar(64)" json:"source"` IP string `gorm:"type:varchar(64)" json:"ip"` Path string `gorm:"type:varchar(64)" json:"path"` diff --git a/backend/app/repo/common.go b/backend/app/repo/common.go index a521e38c7..262101567 100644 --- a/backend/app/repo/common.go +++ b/backend/app/repo/common.go @@ -65,6 +65,9 @@ func (c *CommonRepo) WithByStatus(status string) DBOption { func (c *CommonRepo) WithLikeName(name string) DBOption { return func(g *gorm.DB) *gorm.DB { + if len(name) == 0 { + return g + } return g.Where("name like ?", "%"+name+"%") } } diff --git a/backend/app/repo/logs.go b/backend/app/repo/logs.go index 05ffac772..5309ee6b7 100644 --- a/backend/app/repo/logs.go +++ b/backend/app/repo/logs.go @@ -3,6 +3,7 @@ package repo import ( "github.com/1Panel-dev/1Panel/backend/app/model" "github.com/1Panel-dev/1Panel/backend/global" + "gorm.io/gorm" ) type LogRepo struct{} @@ -12,6 +13,10 @@ type ILogRepo interface { CreateLoginLog(user *model.LoginLog) error PageLoginLog(limit, offset int, opts ...DBOption) (int64, []model.LoginLog, error) + WithByIP(ip string) DBOption + WithByStatus(status string) DBOption + WithByGroup(group string) DBOption + WithByLikeOperation(operation string) DBOption CleanOperation() error CreateOperationLog(user *model.OperationLog) error PageOperationLog(limit, offset int, opts ...DBOption) (int64, []model.OperationLog, error) @@ -60,3 +65,37 @@ func (u *LogRepo) PageOperationLog(page, size int, opts ...DBOption) (int64, []m err := db.Limit(size).Offset(size * (page - 1)).Find(&ops).Error return count, ops, err } + +func (c *LogRepo) WithByStatus(status string) DBOption { + return func(g *gorm.DB) *gorm.DB { + if len(status) == 0 { + return g + } + return g.Where("status = ?", status) + } +} +func (c *LogRepo) WithByGroup(group string) DBOption { + return func(g *gorm.DB) *gorm.DB { + if len(group) == 0 { + return g + } + return g.Where("source = ?", group) + } +} +func (c *LogRepo) WithByIP(ip string) DBOption { + return func(g *gorm.DB) *gorm.DB { + if len(ip) == 0 { + return g + } + return g.Where("ip LIKE ?", "%"+ip+"%") + } +} +func (c *LogRepo) WithByLikeOperation(operation string) DBOption { + return func(g *gorm.DB) *gorm.DB { + if len(operation) == 0 { + return g + } + infoStr := "%" + operation + "%" + return g.Where("detail_zh LIKE ? OR detail_en LIKE ?", infoStr, infoStr) + } +} diff --git a/backend/app/service/compose_template.go b/backend/app/service/compose_template.go index e75a7f73d..e3bcb7a65 100644 --- a/backend/app/service/compose_template.go +++ b/backend/app/service/compose_template.go @@ -11,7 +11,7 @@ type ComposeTemplateService struct{} type IComposeTemplateService interface { List() ([]dto.ComposeTemplateInfo, error) - SearchWithPage(search dto.PageInfo) (int64, interface{}, error) + SearchWithPage(search dto.SearchWithPage) (int64, interface{}, error) Create(composeDto dto.ComposeTemplateCreate) error Update(id uint, upMap map[string]interface{}) error Delete(ids []uint) error @@ -37,8 +37,8 @@ func (u *ComposeTemplateService) List() ([]dto.ComposeTemplateInfo, error) { return dtoLists, err } -func (u *ComposeTemplateService) SearchWithPage(search dto.PageInfo) (int64, interface{}, error) { - total, composes, err := composeRepo.Page(search.Page, search.PageSize) +func (u *ComposeTemplateService) SearchWithPage(req dto.SearchWithPage) (int64, interface{}, error) { + total, composes, err := composeRepo.Page(req.Page, req.PageSize, commonRepo.WithLikeName(req.Info)) var dtoComposeTemplates []dto.ComposeTemplateInfo for _, compose := range composes { var item dto.ComposeTemplateInfo diff --git a/backend/app/service/container.go b/backend/app/service/container.go index a1b812315..f9fe4d2dc 100644 --- a/backend/app/service/container.go +++ b/backend/app/service/container.go @@ -29,10 +29,10 @@ type ContainerService struct{} type IContainerService interface { Page(req dto.PageContainer) (int64, interface{}, error) - PageNetwork(req dto.PageInfo) (int64, interface{}, error) - PageVolume(req dto.PageInfo) (int64, interface{}, error) + PageNetwork(req dto.SearchWithPage) (int64, interface{}, error) + PageVolume(req dto.SearchWithPage) (int64, interface{}, error) ListVolume() ([]dto.Options, error) - PageCompose(req dto.PageInfo) (int64, interface{}, error) + PageCompose(req dto.SearchWithPage) (int64, interface{}, error) CreateCompose(req dto.ComposeCreate) error ComposeOperation(req dto.ComposeOperation) error ContainerCreate(req dto.ContainerCreate) error @@ -69,6 +69,17 @@ func (u *ContainerService) Page(req dto.PageContainer) (int64, interface{}, erro if err != nil { return 0, nil, err } + if len(req.Name) != 0 { + lenth, count := len(list), 0 + for count < lenth { + if !strings.Contains(list[count].Names[0][1:], req.Name) { + list = append(list[:count], list[(count+1):]...) + lenth-- + } else { + count++ + } + } + } sort.Slice(list, func(i, j int) bool { return list[i].Created > list[j].Created }) diff --git a/backend/app/service/container_compose.go b/backend/app/service/container_compose.go index 0bc3f3973..f3deb4df4 100644 --- a/backend/app/service/container_compose.go +++ b/backend/app/service/container_compose.go @@ -25,7 +25,7 @@ const composeConfigLabel = "com.docker.compose.project.config_files" const composeWorkdirLabel = "com.docker.compose.project.working_dir" const composeCreatedBy = "createdBy" -func (u *ContainerService) PageCompose(req dto.PageInfo) (int64, interface{}, error) { +func (u *ContainerService) PageCompose(req dto.SearchWithPage) (int64, interface{}, error) { var ( records []dto.ComposeInfo BackDatas []dto.ComposeInfo @@ -90,13 +90,24 @@ func (u *ContainerService) PageCompose(req dto.PageInfo) (int64, interface{}, er } for _, item := range composeCreatedByLocal { if err := composeRepo.DeleteRecord(commonRepo.WithByName(item.Name)); err != nil { - fmt.Println(err) + global.LOG.Error(err) } } for key, value := range composeMap { value.Name = key records = append(records, value) } + if len(req.Info) != 0 { + lenth, count := len(records), 0 + for count < lenth { + if !strings.Contains(records[count].Name, req.Info) { + records = append(records[:count], records[(count+1):]...) + lenth-- + } else { + count++ + } + } + } sort.Slice(records, func(i, j int) bool { return records[i].CreatedAt > records[j].CreatedAt }) diff --git a/backend/app/service/container_network.go b/backend/app/service/container_network.go index ec2a22c76..ab5785b90 100644 --- a/backend/app/service/container_network.go +++ b/backend/app/service/container_network.go @@ -4,6 +4,7 @@ import ( "context" "fmt" "sort" + "strings" "github.com/1Panel-dev/1Panel/backend/app/dto" "github.com/1Panel-dev/1Panel/backend/utils/docker" @@ -11,7 +12,7 @@ import ( "github.com/docker/docker/api/types/network" ) -func (u *ContainerService) PageNetwork(req dto.PageInfo) (int64, interface{}, error) { +func (u *ContainerService) PageNetwork(req dto.SearchWithPage) (int64, interface{}, error) { client, err := docker.NewDockerClient() if err != nil { return 0, nil, err @@ -20,6 +21,17 @@ func (u *ContainerService) PageNetwork(req dto.PageInfo) (int64, interface{}, er if err != nil { return 0, nil, err } + if len(req.Info) != 0 { + lenth, count := len(list), 0 + for count < lenth { + if !strings.Contains(list[count].Name, req.Info) { + list = append(list[:count], list[(count+1):]...) + lenth-- + } else { + count++ + } + } + } var ( data []dto.Network records []types.NetworkResource diff --git a/backend/app/service/container_volume.go b/backend/app/service/container_volume.go index c0469d0d3..71766964c 100644 --- a/backend/app/service/container_volume.go +++ b/backend/app/service/container_volume.go @@ -3,6 +3,7 @@ package service import ( "context" "sort" + "strings" "time" "github.com/1Panel-dev/1Panel/backend/app/dto" @@ -12,7 +13,7 @@ import ( "github.com/docker/docker/api/types/volume" ) -func (u *ContainerService) PageVolume(req dto.PageInfo) (int64, interface{}, error) { +func (u *ContainerService) PageVolume(req dto.SearchWithPage) (int64, interface{}, error) { client, err := docker.NewDockerClient() if err != nil { return 0, nil, err @@ -21,6 +22,17 @@ func (u *ContainerService) PageVolume(req dto.PageInfo) (int64, interface{}, err if err != nil { return 0, nil, err } + if len(req.Info) != 0 { + lenth, count := len(list.Volumes), 0 + for count < lenth { + if !strings.Contains(list.Volumes[count].Name, req.Info) { + list.Volumes = append(list.Volumes[:count], list.Volumes[(count+1):]...) + lenth-- + } else { + count++ + } + } + } var ( data []dto.Volume records []*types.Volume diff --git a/backend/app/service/database_mysql.go b/backend/app/service/database_mysql.go index 513ec5cb7..db63af635 100644 --- a/backend/app/service/database_mysql.go +++ b/backend/app/service/database_mysql.go @@ -30,7 +30,7 @@ import ( type MysqlService struct{} type IMysqlService interface { - SearchWithPage(search dto.PageInfo) (int64, interface{}, error) + SearchWithPage(search dto.SearchWithPage) (int64, interface{}, error) ListDBName() ([]string, error) Create(ctx context.Context, req dto.MysqlDBCreate) (*model.DatabaseMysql, error) ChangeAccess(info dto.ChangeDBInfo) error @@ -55,8 +55,8 @@ func NewIMysqlService() IMysqlService { return &MysqlService{} } -func (u *MysqlService) SearchWithPage(search dto.PageInfo) (int64, interface{}, error) { - total, mysqls, err := mysqlRepo.Page(search.Page, search.PageSize) +func (u *MysqlService) SearchWithPage(search dto.SearchWithPage) (int64, interface{}, error) { + total, mysqls, err := mysqlRepo.Page(search.Page, search.PageSize, commonRepo.WithLikeName(search.Info)) var dtoMysqls []dto.MysqlDBInfo for _, mysql := range mysqls { var item dto.MysqlDBInfo diff --git a/backend/app/service/image.go b/backend/app/service/image.go index 0dfc087a7..01320332f 100644 --- a/backend/app/service/image.go +++ b/backend/app/service/image.go @@ -25,7 +25,7 @@ var dockerLogDir = constant.TmpDir + "/docker_logs" type ImageService struct{} type IImageService interface { - Page(req dto.PageInfo) (int64, interface{}, error) + Page(req dto.SearchWithPage) (int64, interface{}, error) List() ([]dto.Options, error) ImageBuild(req dto.ImageBuild) (string, error) ImagePull(req dto.ImagePull) (string, error) @@ -38,7 +38,7 @@ type IImageService interface { func NewIImageService() IImageService { return &ImageService{} } -func (u *ImageService) Page(req dto.PageInfo) (int64, interface{}, error) { +func (u *ImageService) Page(req dto.SearchWithPage) (int64, interface{}, error) { var ( list []types.ImageSummary records []dto.ImageInfo @@ -52,6 +52,24 @@ func (u *ImageService) Page(req dto.PageInfo) (int64, interface{}, error) { if err != nil { return 0, nil, err } + if len(req.Info) != 0 { + lenth, count := len(list), 0 + for count < lenth { + hasTag := false + for _, tag := range list[count].RepoTags { + if strings.Contains(tag, req.Info) { + hasTag = true + break + } + } + if !hasTag { + list = append(list[:count], list[(count+1):]...) + lenth-- + } else { + count++ + } + } + } for _, image := range list { size := formatFileSize(image.Size) diff --git a/backend/app/service/image_repo.go b/backend/app/service/image_repo.go index c20634a73..74c4b443b 100644 --- a/backend/app/service/image_repo.go +++ b/backend/app/service/image_repo.go @@ -19,7 +19,7 @@ import ( type ImageRepoService struct{} type IImageRepoService interface { - Page(search dto.PageInfo) (int64, interface{}, error) + Page(search dto.SearchWithPage) (int64, interface{}, error) List() ([]dto.ImageRepoOption, error) Create(req dto.ImageRepoCreate) error Update(req dto.ImageRepoUpdate) error @@ -30,8 +30,8 @@ func NewIImageRepoService() IImageRepoService { return &ImageRepoService{} } -func (u *ImageRepoService) Page(search dto.PageInfo) (int64, interface{}, error) { - total, ops, err := imageRepoRepo.Page(search.Page, search.PageSize, commonRepo.WithOrderBy("created_at desc")) +func (u *ImageRepoService) Page(req dto.SearchWithPage) (int64, interface{}, error) { + total, ops, err := imageRepoRepo.Page(req.Page, req.PageSize, commonRepo.WithLikeName(req.Info), commonRepo.WithOrderBy("created_at desc")) var dtoOps []dto.ImageRepoInfo for _, op := range ops { var item dto.ImageRepoInfo diff --git a/backend/app/service/logs.go b/backend/app/service/logs.go index f63e5f93a..cc0f90b4d 100644 --- a/backend/app/service/logs.go +++ b/backend/app/service/logs.go @@ -12,10 +12,10 @@ type LogService struct{} type ILogService interface { CreateLoginLog(operation model.LoginLog) error - PageLoginLog(search dto.PageInfo) (int64, interface{}, error) + PageLoginLog(search dto.SearchLgLogWithPage) (int64, interface{}, error) CreateOperationLog(operation model.OperationLog) error - PageOperationLog(search dto.PageInfo) (int64, interface{}, error) + PageOperationLog(search dto.SearchOpLogWithPage) (int64, interface{}, error) CleanLogs(logtype string) error } @@ -28,8 +28,14 @@ func (u *LogService) CreateLoginLog(operation model.LoginLog) error { return logRepo.CreateLoginLog(&operation) } -func (u *LogService) PageLoginLog(search dto.PageInfo) (int64, interface{}, error) { - total, ops, err := logRepo.PageLoginLog(search.Page, search.PageSize, commonRepo.WithOrderBy("created_at desc")) +func (u *LogService) PageLoginLog(req dto.SearchLgLogWithPage) (int64, interface{}, error) { + total, ops, err := logRepo.PageLoginLog( + req.Page, + req.PageSize, + logRepo.WithByIP(req.IP), + logRepo.WithByStatus(req.Status), + commonRepo.WithOrderBy("created_at desc"), + ) var dtoOps []dto.LoginLog for _, op := range ops { var item dto.LoginLog @@ -45,8 +51,15 @@ func (u *LogService) CreateOperationLog(operation model.OperationLog) error { return logRepo.CreateOperationLog(&operation) } -func (u *LogService) PageOperationLog(search dto.PageInfo) (int64, interface{}, error) { - total, ops, err := logRepo.PageOperationLog(search.Page, search.PageSize, commonRepo.WithOrderBy("created_at desc")) +func (u *LogService) PageOperationLog(req dto.SearchOpLogWithPage) (int64, interface{}, error) { + total, ops, err := logRepo.PageOperationLog( + req.Page, + req.PageSize, + logRepo.WithByGroup(req.Source), + logRepo.WithByLikeOperation(req.Operation), + logRepo.WithByStatus(req.Status), + commonRepo.WithOrderBy("created_at desc"), + ) var dtoOps []dto.OperationLog for _, op := range ops { var item dto.OperationLog diff --git a/backend/middleware/operation.go b/backend/middleware/operation.go index 00f622f51..0fcf5916a 100644 --- a/backend/middleware/operation.go +++ b/backend/middleware/operation.go @@ -25,9 +25,9 @@ func OperationLog() gin.HandlerFunc { return } - group := loadLogInfo(c.Request.URL.Path) + source := loadLogInfo(c.Request.URL.Path) record := model.OperationLog{ - Group: group, + Source: source, IP: c.ClientIP(), Method: strings.ToLower(c.Request.Method), Path: strings.ReplaceAll(c.Request.URL.Path, "/api/v1", ""), diff --git a/cmd/server/docs/docs.go b/cmd/server/docs/docs.go index dae0d9d84..8addf541d 100644 --- a/cmd/server/docs/docs.go +++ b/cmd/server/docs/docs.go @@ -1553,7 +1553,7 @@ var doc = `{ "in": "body", "required": true, "schema": { - "$ref": "#/definitions/dto.PageInfo" + "$ref": "#/definitions/dto.SearchWithPage" } } ], @@ -2140,7 +2140,7 @@ var doc = `{ "in": "body", "required": true, "schema": { - "$ref": "#/definitions/dto.PageInfo" + "$ref": "#/definitions/dto.SearchWithPage" } } ], @@ -2351,7 +2351,7 @@ var doc = `{ "in": "body", "required": true, "schema": { - "$ref": "#/definitions/dto.PageInfo" + "$ref": "#/definitions/dto.SearchWithPage" } } ], @@ -2556,7 +2556,7 @@ var doc = `{ "in": "body", "required": true, "schema": { - "$ref": "#/definitions/dto.PageInfo" + "$ref": "#/definitions/dto.SearchWithPage" } } ], @@ -2871,7 +2871,7 @@ var doc = `{ "in": "body", "required": true, "schema": { - "$ref": "#/definitions/dto.PageInfo" + "$ref": "#/definitions/dto.SearchWithPage" } } ], @@ -3082,7 +3082,7 @@ var doc = `{ "in": "body", "required": true, "schema": { - "$ref": "#/definitions/dto.PageInfo" + "$ref": "#/definitions/dto.SearchWithPage" } } ], @@ -4423,7 +4423,7 @@ var doc = `{ "in": "body", "required": true, "schema": { - "$ref": "#/definitions/dto.PageInfo" + "$ref": "#/definitions/dto.SearchWithPage" } } ], @@ -5777,7 +5777,7 @@ var doc = `{ "in": "body", "required": true, "schema": { - "$ref": "#/definitions/dto.PageInfo" + "$ref": "#/definitions/dto.SearchLgLogWithPage" } } ], @@ -5813,7 +5813,7 @@ var doc = `{ "in": "body", "required": true, "schema": { - "$ref": "#/definitions/dto.PageInfo" + "$ref": "#/definitions/dto.SearchOpLogWithPage" } } ], @@ -6582,7 +6582,7 @@ var doc = `{ "ApiKeyAuth": [] } ], - "description": "从 OSS 加载系统更新信息", + "description": "系统更新信息", "tags": [ "System Setting" ], @@ -9996,6 +9996,9 @@ var doc = `{ "filters": { "type": "string" }, + "name": { + "type": "string" + }, "page": { "type": "integer" }, @@ -10253,6 +10256,51 @@ var doc = `{ } } }, + "dto.SearchLgLogWithPage": { + "type": "object", + "required": [ + "page", + "pageSize" + ], + "properties": { + "ip": { + "type": "string" + }, + "page": { + "type": "integer" + }, + "pageSize": { + "type": "integer" + }, + "status": { + "type": "string" + } + } + }, + "dto.SearchOpLogWithPage": { + "type": "object", + "required": [ + "page", + "pageSize" + ], + "properties": { + "operation": { + "type": "string" + }, + "page": { + "type": "integer" + }, + "pageSize": { + "type": "integer" + }, + "source": { + "type": "string" + }, + "status": { + "type": "string" + } + } + }, "dto.SearchRecord": { "type": "object", "required": [ @@ -10283,7 +10331,6 @@ var doc = `{ "dto.SearchWithPage": { "type": "object", "required": [ - "info", "page", "pageSize" ], @@ -11251,6 +11298,9 @@ var doc = `{ "request.FileOption": { "type": "object", "properties": { + "containSub": { + "type": "boolean" + }, "dir": { "type": "boolean" }, diff --git a/cmd/server/docs/swagger.json b/cmd/server/docs/swagger.json index be4e7f103..281472950 100644 --- a/cmd/server/docs/swagger.json +++ b/cmd/server/docs/swagger.json @@ -1539,7 +1539,7 @@ "in": "body", "required": true, "schema": { - "$ref": "#/definitions/dto.PageInfo" + "$ref": "#/definitions/dto.SearchWithPage" } } ], @@ -2126,7 +2126,7 @@ "in": "body", "required": true, "schema": { - "$ref": "#/definitions/dto.PageInfo" + "$ref": "#/definitions/dto.SearchWithPage" } } ], @@ -2337,7 +2337,7 @@ "in": "body", "required": true, "schema": { - "$ref": "#/definitions/dto.PageInfo" + "$ref": "#/definitions/dto.SearchWithPage" } } ], @@ -2542,7 +2542,7 @@ "in": "body", "required": true, "schema": { - "$ref": "#/definitions/dto.PageInfo" + "$ref": "#/definitions/dto.SearchWithPage" } } ], @@ -2857,7 +2857,7 @@ "in": "body", "required": true, "schema": { - "$ref": "#/definitions/dto.PageInfo" + "$ref": "#/definitions/dto.SearchWithPage" } } ], @@ -3068,7 +3068,7 @@ "in": "body", "required": true, "schema": { - "$ref": "#/definitions/dto.PageInfo" + "$ref": "#/definitions/dto.SearchWithPage" } } ], @@ -4409,7 +4409,7 @@ "in": "body", "required": true, "schema": { - "$ref": "#/definitions/dto.PageInfo" + "$ref": "#/definitions/dto.SearchWithPage" } } ], @@ -5763,7 +5763,7 @@ "in": "body", "required": true, "schema": { - "$ref": "#/definitions/dto.PageInfo" + "$ref": "#/definitions/dto.SearchLgLogWithPage" } } ], @@ -5799,7 +5799,7 @@ "in": "body", "required": true, "schema": { - "$ref": "#/definitions/dto.PageInfo" + "$ref": "#/definitions/dto.SearchOpLogWithPage" } } ], @@ -6568,7 +6568,7 @@ "ApiKeyAuth": [] } ], - "description": "从 OSS 加载系统更新信息", + "description": "系统更新信息", "tags": [ "System Setting" ], @@ -9982,6 +9982,9 @@ "filters": { "type": "string" }, + "name": { + "type": "string" + }, "page": { "type": "integer" }, @@ -10239,6 +10242,51 @@ } } }, + "dto.SearchLgLogWithPage": { + "type": "object", + "required": [ + "page", + "pageSize" + ], + "properties": { + "ip": { + "type": "string" + }, + "page": { + "type": "integer" + }, + "pageSize": { + "type": "integer" + }, + "status": { + "type": "string" + } + } + }, + "dto.SearchOpLogWithPage": { + "type": "object", + "required": [ + "page", + "pageSize" + ], + "properties": { + "operation": { + "type": "string" + }, + "page": { + "type": "integer" + }, + "pageSize": { + "type": "integer" + }, + "source": { + "type": "string" + }, + "status": { + "type": "string" + } + } + }, "dto.SearchRecord": { "type": "object", "required": [ @@ -10269,7 +10317,6 @@ "dto.SearchWithPage": { "type": "object", "required": [ - "info", "page", "pageSize" ], @@ -11237,6 +11284,9 @@ "request.FileOption": { "type": "object", "properties": { + "containSub": { + "type": "boolean" + }, "dir": { "type": "boolean" }, diff --git a/cmd/server/docs/swagger.yaml b/cmd/server/docs/swagger.yaml index efb4e241f..70339dbde 100644 --- a/cmd/server/docs/swagger.yaml +++ b/cmd/server/docs/swagger.yaml @@ -1049,6 +1049,8 @@ definitions: properties: filters: type: string + name: + type: string page: type: integer pageSize: @@ -1222,6 +1224,36 @@ definitions: info: type: string type: object + dto.SearchLgLogWithPage: + properties: + ip: + type: string + page: + type: integer + pageSize: + type: integer + status: + type: string + required: + - page + - pageSize + type: object + dto.SearchOpLogWithPage: + properties: + operation: + type: string + page: + type: integer + pageSize: + type: integer + source: + type: string + status: + type: string + required: + - page + - pageSize + type: object dto.SearchRecord: properties: cronjobID: @@ -1249,7 +1281,6 @@ definitions: pageSize: type: integer required: - - info - page - pageSize type: object @@ -1883,6 +1914,8 @@ definitions: type: object request.FileOption: properties: + containSub: + type: boolean dir: type: boolean expand: @@ -3562,7 +3595,7 @@ paths: name: request required: true schema: - $ref: '#/definitions/dto.PageInfo' + $ref: '#/definitions/dto.SearchWithPage' responses: "200": description: OK @@ -3935,7 +3968,7 @@ paths: name: request required: true schema: - $ref: '#/definitions/dto.PageInfo' + $ref: '#/definitions/dto.SearchWithPage' produces: - application/json responses: @@ -4069,7 +4102,7 @@ paths: name: request required: true schema: - $ref: '#/definitions/dto.PageInfo' + $ref: '#/definitions/dto.SearchWithPage' produces: - application/json responses: @@ -4200,7 +4233,7 @@ paths: name: request required: true schema: - $ref: '#/definitions/dto.PageInfo' + $ref: '#/definitions/dto.SearchWithPage' produces: - application/json responses: @@ -4398,7 +4431,7 @@ paths: name: request required: true schema: - $ref: '#/definitions/dto.PageInfo' + $ref: '#/definitions/dto.SearchWithPage' produces: - application/json responses: @@ -4532,7 +4565,7 @@ paths: name: request required: true schema: - $ref: '#/definitions/dto.PageInfo' + $ref: '#/definitions/dto.SearchWithPage' produces: - application/json responses: @@ -5390,7 +5423,7 @@ paths: name: request required: true schema: - $ref: '#/definitions/dto.PageInfo' + $ref: '#/definitions/dto.SearchWithPage' responses: "200": description: OK @@ -6253,7 +6286,7 @@ paths: name: request required: true schema: - $ref: '#/definitions/dto.PageInfo' + $ref: '#/definitions/dto.SearchLgLogWithPage' responses: "200": description: OK @@ -6275,7 +6308,7 @@ paths: name: request required: true schema: - $ref: '#/definitions/dto.PageInfo' + $ref: '#/definitions/dto.SearchOpLogWithPage' responses: "200": description: OK @@ -6763,7 +6796,7 @@ paths: paramKeys: [] /settings/upgrade: get: - description: 从 OSS 加载系统更新信息 + description: 系统更新信息 responses: "200": description: OK diff --git a/frontend/src/api/interface/container.ts b/frontend/src/api/interface/container.ts index 186681131..fefb58a8e 100644 --- a/frontend/src/api/interface/container.ts +++ b/frontend/src/api/interface/container.ts @@ -7,6 +7,7 @@ export namespace Container { newName: string; } export interface ContainerSearch extends ReqPage { + name: string; filters: string; } export interface ContainerCreate { diff --git a/frontend/src/api/interface/index.ts b/frontend/src/api/interface/index.ts index 631dc601b..d8f285d36 100644 --- a/frontend/src/api/interface/index.ts +++ b/frontend/src/api/interface/index.ts @@ -18,6 +18,11 @@ export interface ReqPage { page: number; pageSize: number; } +export interface SearchWithPage { + info: string; + page: number; + pageSize: number; +} export interface CommonModel { id: number; CreatedAt?: string; diff --git a/frontend/src/api/interface/log.ts b/frontend/src/api/interface/log.ts index f43f01742..7bdc367bb 100644 --- a/frontend/src/api/interface/log.ts +++ b/frontend/src/api/interface/log.ts @@ -1,9 +1,9 @@ import { DateTimeFormats } from '@intlify/core-base'; +import { ReqPage } from '.'; export namespace Log { export interface OperationLog { id: number; - group: string; source: string; action: string; ip: string; @@ -20,6 +20,15 @@ export namespace Log { detail: string; createdAt: DateTimeFormats; } + export interface SearchOpLog extends ReqPage { + source: string; + status: string; + operation: string; + } + export interface SearchLgLog extends ReqPage { + ip: string; + status: string; + } export interface LoginLogs { ip: string; address: string; diff --git a/frontend/src/api/modules/container.ts b/frontend/src/api/modules/container.ts index 981a579d7..474483ca1 100644 --- a/frontend/src/api/modules/container.ts +++ b/frontend/src/api/modules/container.ts @@ -1,5 +1,5 @@ import http from '@/api'; -import { ResPage, ReqPage } from '../interface'; +import { ResPage, SearchWithPage } from '../interface'; import { Container } from '../interface/container'; export const searchContainer = (params: Container.ContainerSearch) => { @@ -22,7 +22,7 @@ export const inspect = (params: Container.ContainerInspect) => { }; // image -export const searchImage = (params: ReqPage) => { +export const searchImage = (params: SearchWithPage) => { return http.post>(`/containers/image/search`, params); }; export const listImage = () => { @@ -51,7 +51,7 @@ export const imageRemove = (params: Container.BatchDelete) => { }; // network -export const searchNetwork = (params: ReqPage) => { +export const searchNetwork = (params: SearchWithPage) => { return http.post>(`/containers/network/search`, params); }; export const deleteNetwork = (params: Container.BatchDelete) => { @@ -62,7 +62,7 @@ export const createNetwork = (params: Container.NetworkCreate) => { }; // volume -export const searchVolume = (params: ReqPage) => { +export const searchVolume = (params: SearchWithPage) => { return http.post>(`/containers/volume/search`, params); }; export const listVolume = () => { @@ -76,7 +76,7 @@ export const createVolume = (params: Container.VolumeCreate) => { }; // repo -export const searchImageRepo = (params: ReqPage) => { +export const searchImageRepo = (params: SearchWithPage) => { return http.post>(`/containers/repo/search`, params); }; export const listImageRepo = () => { @@ -93,7 +93,7 @@ export const deleteImageRepo = (params: Container.RepoDelete) => { }; // composeTemplate -export const searchComposeTemplate = (params: ReqPage) => { +export const searchComposeTemplate = (params: SearchWithPage) => { return http.post>(`/containers/template/search`, params); }; export const listComposeTemplate = () => { @@ -110,7 +110,7 @@ export const updateComposeTemplate = (params: Container.TemplateUpdate) => { }; // compose -export const searchCompose = (params: ReqPage) => { +export const searchCompose = (params: SearchWithPage) => { return http.post>(`/containers/compose/search`, params); }; export const upCompose = (params: Container.ComposeCreate) => { diff --git a/frontend/src/api/modules/cronjob.ts b/frontend/src/api/modules/cronjob.ts index 0c9e9c99b..de64b3560 100644 --- a/frontend/src/api/modules/cronjob.ts +++ b/frontend/src/api/modules/cronjob.ts @@ -1,8 +1,8 @@ import http from '@/api'; -import { ResPage, ReqPage } from '../interface'; +import { ResPage, SearchWithPage } from '../interface'; import { Cronjob } from '../interface/cronjob'; -export const getCronjobPage = (params: ReqPage) => { +export const getCronjobPage = (params: SearchWithPage) => { return http.post>(`/cronjobs/search`, params); }; diff --git a/frontend/src/api/modules/database.ts b/frontend/src/api/modules/database.ts index 54012f6ae..121c04f4c 100644 --- a/frontend/src/api/modules/database.ts +++ b/frontend/src/api/modules/database.ts @@ -1,8 +1,8 @@ import http from '@/api'; -import { ReqPage, ResPage } from '../interface'; +import { SearchWithPage, ReqPage, ResPage } from '../interface'; import { Database } from '../interface/database'; -export const searchMysqlDBs = (params: ReqPage) => { +export const searchMysqlDBs = (params: SearchWithPage) => { return http.post>(`/databases/search`, params); }; diff --git a/frontend/src/api/modules/log.ts b/frontend/src/api/modules/log.ts index 02c628a1d..8cc8a9998 100644 --- a/frontend/src/api/modules/log.ts +++ b/frontend/src/api/modules/log.ts @@ -1,12 +1,12 @@ import http from '@/api'; -import { ResPage, ReqPage } from '../interface'; +import { ResPage } from '../interface'; import { Log } from '../interface/log'; -export const getOperationLogs = (info: ReqPage) => { +export const getOperationLogs = (info: Log.SearchOpLog) => { return http.post>(`/logs/operation`, info); }; -export const getLoginLogs = (info: ReqPage) => { +export const getLoginLogs = (info: Log.SearchLgLog) => { return http.post>(`/logs/login`, info); }; diff --git a/frontend/src/lang/modules/en.ts b/frontend/src/lang/modules/en.ts index 94706c168..af1c06466 100644 --- a/frontend/src/lang/modules/en.ts +++ b/frontend/src/lang/modules/en.ts @@ -43,6 +43,7 @@ export default { dateEnd: 'Date end', }, table: { + all: 'All', total: 'Total {0}', name: 'Name', type: 'Type', @@ -611,6 +612,7 @@ export default { users: 'User', hosts: 'Host', apps: 'App', + websites: 'Website', containers: 'Container', commands: 'Command', groups: 'System Group', diff --git a/frontend/src/lang/modules/zh.ts b/frontend/src/lang/modules/zh.ts index 4bc5738d5..7e6e474c1 100644 --- a/frontend/src/lang/modules/zh.ts +++ b/frontend/src/lang/modules/zh.ts @@ -45,6 +45,7 @@ export default { dateEnd: '结束日期', }, table: { + all: '所有', total: '共 {0} 条', name: '名称', type: '类型', @@ -528,9 +529,6 @@ export default { website: '备份网站', rulesHelper: '压缩排除规则(以 ; 号为分隔符),例如: \n*.log;*.sql', lastRecrodTime: '上次执行时间', - all: '所有', - failedRecord: '失败任务', - successRecord: '成功任务', database: '备份数据库', missBackupAccount: '未能找到备份账号', syncDate: '同步时间 ', @@ -569,7 +567,7 @@ export default { shellContent: '脚本内容', errRecord: '错误的日志记录', errHandle: '任务执行失败', - noRecord: '执行未产生任何日志', + noRecord: '当前计划任务暂未产生记录', }, monitor: { avgLoad: '平均负载', @@ -634,6 +632,7 @@ export default { users: '用户', hosts: '主机', apps: '应用', + websites: '网站', containers: '容器', groups: '系统组', commands: '快捷命令', diff --git a/frontend/src/views/container/compose/index.vue b/frontend/src/views/container/compose/index.vue index 043ad286a..0b25e7e26 100644 --- a/frontend/src/views/container/compose/index.vue +++ b/frontend/src/views/container/compose/index.vue @@ -18,9 +18,26 @@ :class="{ mask: dockerStatus != 'Running' }" >