diff --git a/agent/app/api/v2/image.go b/agent/app/api/v2/image.go index 610642b3f805..52633bf68593 100644 --- a/agent/app/api/v2/image.go +++ b/agent/app/api/v2/image.go @@ -9,14 +9,14 @@ import ( // @Tags Container Image // @Summary Page images // @Accept json -// @Param request body dto.SearchWithPage true "request" +// @Param request body dto.PageImage true "request" // @Produce json // @Success 200 {object} dto.PageResult // @Security ApiKeyAuth // @Security Timestamp // @Router /containers/image/search [post] func (b *BaseApi) SearchImage(c *gin.Context) { - var req dto.SearchWithPage + var req dto.PageImage if err := helper.CheckBindAndValidate(&req, c); err != nil { return } diff --git a/agent/app/dto/image.go b/agent/app/dto/image.go index bd4e1f8cd510..b89400b29e9e 100644 --- a/agent/app/dto/image.go +++ b/agent/app/dto/image.go @@ -2,12 +2,19 @@ package dto import "time" +type PageImage struct { + PageInfo + Name string `json:"name"` + OrderBy string `json:"orderBy" validate:"required,oneof=size tags createdAt isUsed"` + Order string `json:"order" validate:"required,oneof=null ascending descending"` +} + type ImageInfo struct { ID string `json:"id"` CreatedAt time.Time `json:"createdAt"` IsUsed bool `json:"isUsed"` Tags []string `json:"tags"` - Size string `json:"size"` + Size int64 `json:"size"` } type ImageLoad struct { diff --git a/agent/app/service/image.go b/agent/app/service/image.go index 4c0345912679..2832a6c132cf 100644 --- a/agent/app/service/image.go +++ b/agent/app/service/image.go @@ -10,6 +10,7 @@ import ( "io" "os" "path" + "sort" "strings" "time" @@ -34,7 +35,7 @@ import ( type ImageService struct{} type IImageService interface { - Page(req dto.SearchWithPage) (int64, interface{}, error) + Page(req dto.PageImage) (int64, interface{}, error) List() ([]dto.Options, error) ListAll() ([]dto.ImageInfo, error) ImageBuild(req dto.ImageBuild) error @@ -49,7 +50,7 @@ type IImageService interface { func NewIImageService() IImageService { return &ImageService{} } -func (u *ImageService) Page(req dto.SearchWithPage) (int64, interface{}, error) { +func (u *ImageService) Page(req dto.PageImage) (int64, interface{}, error) { var ( list []image.Summary records []dto.ImageInfo @@ -65,12 +66,12 @@ func (u *ImageService) Page(req dto.SearchWithPage) (int64, interface{}, error) return 0, nil, err } containers, _ := client.ContainerList(context.Background(), container.ListOptions{All: true}) - if len(req.Info) != 0 { + if len(req.Name) != 0 { length, count := len(list), 0 for count < length { hasTag := false for _, tag := range list[count].RepoTags { - if strings.Contains(tag, req.Info) { + if strings.Contains(tag, req.Name) { hasTag = true break } @@ -85,15 +86,41 @@ func (u *ImageService) Page(req dto.SearchWithPage) (int64, interface{}, error) } for _, image := range list { - size := formatFileSize(image.Size) records = append(records, dto.ImageInfo{ ID: image.ID, Tags: image.RepoTags, IsUsed: checkUsed(image.ID, containers), CreatedAt: time.Unix(image.Created, 0), - Size: size, + Size: image.Size, }) } + switch req.OrderBy { + case "size": + sort.Slice(records, func(i, j int) bool { + if req.Order == constant.OrderAsc { + return records[i].Size < records[j].Size + } + return records[i].Size > records[j].Size + }) + case "tags": + sort.Slice(records, func(i, j int) bool { + if len(records[i].Tags) == 0 || len(records[j].Tags) == 0 { + return true + } + if req.Order == constant.OrderAsc { + return records[i].Tags[0] < records[j].Tags[0] + } + return records[i].Tags[0] > records[j].Tags[0] + }) + default: + sort.Slice(records, func(i, j int) bool { + if req.Order == constant.OrderAsc { + return records[i].CreatedAt.Before(records[j].CreatedAt) + } + return records[i].CreatedAt.After(records[j].CreatedAt) + }) + } + total, start, end := len(records), (req.Page-1)*req.PageSize, req.Page*req.PageSize if start > total { backDatas = make([]dto.ImageInfo, 0) @@ -120,13 +147,12 @@ func (u *ImageService) ListAll() ([]dto.ImageInfo, error) { } containers, _ := client.ContainerList(context.Background(), container.ListOptions{All: true}) for _, image := range list { - size := formatFileSize(image.Size) records = append(records, dto.ImageInfo{ ID: image.ID, Tags: image.RepoTags, IsUsed: checkUsed(image.ID, containers), CreatedAt: time.Unix(image.Created, 0), - Size: size, + Size: image.Size, }) } return records, nil diff --git a/frontend/src/api/interface/container.ts b/frontend/src/api/interface/container.ts index 7726f399ffca..538606cca3ba 100644 --- a/frontend/src/api/interface/container.ts +++ b/frontend/src/api/interface/container.ts @@ -164,6 +164,11 @@ export namespace Container { option: string; } + export interface ImageSearch extends ReqPage { + name: string; + orderBy: string; + order: string; + } export interface ImageInfo { id: string; createdAt: Date; diff --git a/frontend/src/api/modules/container.ts b/frontend/src/api/modules/container.ts index 9421d87ec1f9..6edd74f74b04 100644 --- a/frontend/src/api/modules/container.ts +++ b/frontend/src/api/modules/container.ts @@ -70,7 +70,7 @@ export const DownloadFile = (params: Container.ContainerLogInfo) => { }; // image -export const searchImage = (params: SearchWithPage) => { +export const searchImage = (params: Container.ImageSearch) => { return http.post>(`/containers/image/search`, params); }; export const listAllImage = () => { diff --git a/frontend/src/views/container/image/index.vue b/frontend/src/views/container/image/index.vue index 877b390f80de..ef481789d093 100644 --- a/frontend/src/views/container/image/index.vue +++ b/frontend/src/views/container/image/index.vue @@ -27,12 +27,19 @@ - + + + { +const search = async (column?: any) => { if (!isActive.value || !isExist.value) { return; } - const repoSearch = { - info: searchName.value, + paginationConfig.orderBy = column?.order ? column.prop : paginationConfig.orderBy; + paginationConfig.order = column?.order ? column.order : paginationConfig.order; + const params = { + name: paginationConfig.name, page: paginationConfig.currentPage, pageSize: paginationConfig.pageSize, + orderBy: paginationConfig.orderBy, + order: paginationConfig.order, }; loading.value = true; - await searchImage(repoSearch) + await searchImage(params) .then((res) => { loading.value = false; data.value = res.data.items || [];