mirror of https://github.com/1Panel-dev/1Panel
feat: 容器、数据库、网站、计划任务增加名称排序 (#1490)
parent
a1c76600e2
commit
38bf54ec3b
|
@ -2,7 +2,9 @@ package dto
|
|||
|
||||
type SearchWithPage struct {
|
||||
PageInfo
|
||||
Info string `json:"info"`
|
||||
Info string `json:"info"`
|
||||
OrderBy string `json:"orderBy"`
|
||||
Order string `json:"order"`
|
||||
}
|
||||
|
||||
type PageInfo struct {
|
||||
|
|
|
@ -5,6 +5,8 @@ import "time"
|
|||
type PageContainer struct {
|
||||
PageInfo
|
||||
Name string `json:"name"`
|
||||
OrderBy string `json:"orderBy"`
|
||||
Order string `json:"order"`
|
||||
Filters string `json:"filters"`
|
||||
}
|
||||
|
||||
|
|
|
@ -7,6 +7,8 @@ import (
|
|||
type WebsiteSearch struct {
|
||||
dto.PageInfo
|
||||
Name string `json:"name"`
|
||||
OrderBy string `json:"orderBy"`
|
||||
Order string `json:"order"`
|
||||
WebsiteGroupID uint `json:"websiteGroupId"`
|
||||
}
|
||||
|
||||
|
|
|
@ -2,6 +2,7 @@ package repo
|
|||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/1Panel-dev/1Panel/backend/constant"
|
||||
|
@ -16,6 +17,7 @@ type ICommonRepo interface {
|
|||
WithByName(name string) DBOption
|
||||
WithByType(tp string) DBOption
|
||||
WithOrderBy(orderStr string) DBOption
|
||||
WithOrderRuleBy(orderBy, order string) DBOption
|
||||
WithByGroupID(groupID uint) DBOption
|
||||
WithLikeName(name string) DBOption
|
||||
WithIdsIn(ids []uint) DBOption
|
||||
|
@ -93,6 +95,21 @@ func (c *CommonRepo) WithOrderBy(orderStr string) DBOption {
|
|||
}
|
||||
}
|
||||
|
||||
func (c *CommonRepo) WithOrderRuleBy(orderBy, order string) DBOption {
|
||||
switch order {
|
||||
case constant.OrderDesc:
|
||||
order = "desc"
|
||||
case constant.OrderAsc:
|
||||
order = "asc"
|
||||
default:
|
||||
orderBy = "created_at"
|
||||
order = "desc"
|
||||
}
|
||||
return func(g *gorm.DB) *gorm.DB {
|
||||
return g.Order(fmt.Sprintf("%s %s", orderBy, order))
|
||||
}
|
||||
}
|
||||
|
||||
func (c *CommonRepo) WithIdsIn(ids []uint) DBOption {
|
||||
return func(g *gorm.DB) *gorm.DB {
|
||||
return g.Where("id in (?)", ids)
|
||||
|
|
|
@ -83,7 +83,7 @@ func (u *CronjobRepo) Page(page, size int, opts ...DBOption) (int64, []model.Cro
|
|||
}
|
||||
count := int64(0)
|
||||
db = db.Count(&count)
|
||||
err := db.Order("created_at desc").Limit(size).Offset(size * (page - 1)).Find(&cronjobs).Error
|
||||
err := db.Limit(size).Offset(size * (page - 1)).Find(&cronjobs).Error
|
||||
return count, cronjobs, err
|
||||
}
|
||||
|
||||
|
|
|
@ -67,9 +67,8 @@ func NewIContainerService() IContainerService {
|
|||
|
||||
func (u *ContainerService) Page(req dto.PageContainer) (int64, interface{}, error) {
|
||||
var (
|
||||
records []types.Container
|
||||
list []types.Container
|
||||
backDatas []dto.ContainerInfo
|
||||
records []types.Container
|
||||
list []types.Container
|
||||
)
|
||||
client, err := docker.NewDockerClient()
|
||||
if err != nil {
|
||||
|
@ -95,9 +94,30 @@ func (u *ContainerService) Page(req dto.PageContainer) (int64, interface{}, erro
|
|||
}
|
||||
}
|
||||
}
|
||||
sort.Slice(list, func(i, j int) bool {
|
||||
return list[i].Created > list[j].Created
|
||||
})
|
||||
switch req.OrderBy {
|
||||
case "name":
|
||||
sort.Slice(list, func(i, j int) bool {
|
||||
if req.Order == constant.OrderAsc {
|
||||
return list[i].Names[0][1:] < list[j].Names[0][1:]
|
||||
}
|
||||
return list[i].Names[0][1:] > list[j].Names[0][1:]
|
||||
})
|
||||
case "state":
|
||||
sort.Slice(list, func(i, j int) bool {
|
||||
if req.Order == constant.OrderAsc {
|
||||
return list[i].State < list[j].State
|
||||
}
|
||||
return list[i].State > list[j].State
|
||||
})
|
||||
default:
|
||||
sort.Slice(list, func(i, j int) bool {
|
||||
if req.Order == constant.OrderAsc {
|
||||
return list[i].Created < list[j].Created
|
||||
}
|
||||
return list[i].Created > list[j].Created
|
||||
})
|
||||
}
|
||||
|
||||
total, start, end := len(list), (req.Page-1)*req.PageSize, req.Page*req.PageSize
|
||||
if start > total {
|
||||
records = make([]types.Container, 0)
|
||||
|
@ -108,10 +128,11 @@ func (u *ContainerService) Page(req dto.PageContainer) (int64, interface{}, erro
|
|||
records = list[start:end]
|
||||
}
|
||||
|
||||
backDatas := make([]dto.ContainerInfo, len(records))
|
||||
var wg sync.WaitGroup
|
||||
wg.Add(len(records))
|
||||
for _, container := range records {
|
||||
go func(item types.Container) {
|
||||
for i := 0; i < len(records); i++ {
|
||||
go func(item types.Container, i int) {
|
||||
IsFromCompose := false
|
||||
if _, ok := item.Labels[composeProjectLabel]; ok {
|
||||
IsFromCompose = true
|
||||
|
@ -129,7 +150,7 @@ func (u *ContainerService) Page(req dto.PageContainer) (int64, interface{}, erro
|
|||
ports = append(ports, fmt.Sprintf("%v:%v/%s", port.PublicPort, port.PrivatePort, port.Type))
|
||||
}
|
||||
cpu, mem := loadCpuAndMem(client, item.ID)
|
||||
backDatas = append(backDatas, dto.ContainerInfo{
|
||||
backDatas[i] = dto.ContainerInfo{
|
||||
ContainerID: item.ID,
|
||||
CreateTime: time.Unix(item.Created, 0).Format("2006-01-02 15:04:05"),
|
||||
Name: item.Names[0][1:],
|
||||
|
@ -142,9 +163,9 @@ func (u *ContainerService) Page(req dto.PageContainer) (int64, interface{}, erro
|
|||
Ports: ports,
|
||||
IsFromApp: IsFromApp,
|
||||
IsFromCompose: IsFromCompose,
|
||||
})
|
||||
}
|
||||
wg.Done()
|
||||
}(container)
|
||||
}(records[i], i)
|
||||
}
|
||||
wg.Wait()
|
||||
|
||||
|
|
|
@ -36,7 +36,7 @@ func NewICronjobService() ICronjobService {
|
|||
}
|
||||
|
||||
func (u *CronjobService) SearchWithPage(search dto.SearchWithPage) (int64, interface{}, error) {
|
||||
total, cronjobs, err := cronjobRepo.Page(search.Page, search.PageSize, commonRepo.WithLikeName(search.Info))
|
||||
total, cronjobs, err := cronjobRepo.Page(search.Page, search.PageSize, commonRepo.WithLikeName(search.Info), commonRepo.WithOrderRuleBy(search.OrderBy, search.Order))
|
||||
var dtoCronjobs []dto.CronjobInfo
|
||||
for _, cronjob := range cronjobs {
|
||||
var item dto.CronjobInfo
|
||||
|
|
|
@ -48,7 +48,7 @@ func NewIMysqlService() IMysqlService {
|
|||
}
|
||||
|
||||
func (u *MysqlService) SearchWithPage(search dto.SearchWithPage) (int64, interface{}, error) {
|
||||
total, mysqls, err := mysqlRepo.Page(search.Page, search.PageSize, commonRepo.WithLikeName(search.Info))
|
||||
total, mysqls, err := mysqlRepo.Page(search.Page, search.PageSize, commonRepo.WithLikeName(search.Info), commonRepo.WithOrderRuleBy(search.OrderBy, search.Order))
|
||||
var dtoMysqls []dto.MysqlDBInfo
|
||||
for _, mysql := range mysqls {
|
||||
var item dto.MysqlDBInfo
|
||||
|
|
|
@ -8,6 +8,14 @@ import (
|
|||
"encoding/pem"
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
"path"
|
||||
"reflect"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/1Panel-dev/1Panel/backend/app/api/v1/helper"
|
||||
"github.com/1Panel-dev/1Panel/backend/utils/cmd"
|
||||
"github.com/1Panel-dev/1Panel/backend/utils/common"
|
||||
|
@ -18,13 +26,6 @@ import (
|
|||
"golang.org/x/crypto/bcrypt"
|
||||
"gopkg.in/ini.v1"
|
||||
"gorm.io/gorm"
|
||||
"os"
|
||||
"path"
|
||||
"reflect"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/1Panel-dev/1Panel/backend/app/dto/request"
|
||||
"github.com/1Panel-dev/1Panel/backend/app/dto/response"
|
||||
|
@ -96,7 +97,7 @@ func (w WebsiteService) PageWebsite(req request.WebsiteSearch) (int64, []respons
|
|||
}
|
||||
return 0, nil, err
|
||||
}
|
||||
opts = append(opts, commonRepo.WithOrderBy("created_at desc"))
|
||||
opts = append(opts, commonRepo.WithOrderRuleBy(req.OrderBy, req.Order))
|
||||
if req.Name != "" {
|
||||
opts = append(opts, websiteRepo.WithDomainLike(req.Name))
|
||||
}
|
||||
|
|
|
@ -10,4 +10,7 @@ const (
|
|||
StatusEnable = "Enable"
|
||||
StatusDisable = "Disable"
|
||||
StatusNone = "None"
|
||||
|
||||
OrderDesc = "descending"
|
||||
OrderAsc = "ascending"
|
||||
)
|
||||
|
|
|
@ -9,6 +9,8 @@ export namespace Container {
|
|||
export interface ContainerSearch extends ReqPage {
|
||||
name: string;
|
||||
filters: string;
|
||||
orderBy: string;
|
||||
order: string;
|
||||
}
|
||||
export interface ResourceLimit {
|
||||
cpu: number;
|
||||
|
|
|
@ -22,6 +22,8 @@ export interface SearchWithPage {
|
|||
info: string;
|
||||
page: number;
|
||||
pageSize: number;
|
||||
orderBy?: string;
|
||||
order?: string;
|
||||
}
|
||||
export interface CommonModel {
|
||||
id: number;
|
||||
|
|
|
@ -39,6 +39,8 @@ export namespace Website {
|
|||
|
||||
export interface WebSiteSearch extends ReqPage {
|
||||
name: string;
|
||||
orderBy: string;
|
||||
order: string;
|
||||
websiteGroupId: number;
|
||||
}
|
||||
|
||||
|
|
|
@ -60,10 +60,11 @@
|
|||
:pagination-config="paginationConfig"
|
||||
v-model:selects="selects"
|
||||
:data="data"
|
||||
@sort-change="search"
|
||||
@search="search"
|
||||
>
|
||||
<el-table-column type="selection" fix />
|
||||
<el-table-column :label="$t('commons.table.name')" min-width="80" prop="name" fix>
|
||||
<el-table-column :label="$t('commons.table.name')" min-width="80" prop="name" sortable fix>
|
||||
<template #default="{ row }">
|
||||
<Tooltip @click="onInspect(row.containerID)" :text="row.name" />
|
||||
</template>
|
||||
|
@ -74,7 +75,7 @@
|
|||
min-width="80"
|
||||
prop="imageName"
|
||||
/>
|
||||
<el-table-column :label="$t('commons.table.status')" min-width="60" prop="state" fix>
|
||||
<el-table-column :label="$t('commons.table.status')" min-width="60" prop="state" sortable fix>
|
||||
<template #default="{ row }">
|
||||
<Status :key="row.state" :status="row.state"></Status>
|
||||
</template>
|
||||
|
@ -225,13 +226,15 @@ const mydetail = ref();
|
|||
const dialogContainerLogRef = ref();
|
||||
const dialogReNameRef = ref();
|
||||
|
||||
const search = async () => {
|
||||
const search = async (column?: any) => {
|
||||
let filterItem = props.filters ? props.filters : '';
|
||||
let params = {
|
||||
name: searchName.value,
|
||||
page: paginationConfig.currentPage,
|
||||
pageSize: paginationConfig.pageSize,
|
||||
filters: filterItem,
|
||||
orderBy: column?.order ? column.prop : 'created_at',
|
||||
order: column?.order ? column.order : 'null',
|
||||
};
|
||||
loading.value = true;
|
||||
await searchContainer(params)
|
||||
|
|
|
@ -45,16 +45,17 @@
|
|||
<ComplexTable
|
||||
:pagination-config="paginationConfig"
|
||||
v-model:selects="selects"
|
||||
@sort-change="search"
|
||||
@search="search"
|
||||
:data="data"
|
||||
>
|
||||
<el-table-column type="selection" fix />
|
||||
<el-table-column :label="$t('cronjob.taskName')" :min-width="120" prop="name">
|
||||
<el-table-column :label="$t('cronjob.taskName')" :min-width="120" prop="name" sortable>
|
||||
<template #default="{ row }">
|
||||
<Tooltip @click="loadDetail(row)" :text="row.name" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column :label="$t('commons.table.status')" :min-width="80" prop="status">
|
||||
<el-table-column :label="$t('commons.table.status')" :min-width="80" prop="status" sortable>
|
||||
<template #default="{ row }">
|
||||
<el-button
|
||||
v-if="row.status === 'Enable'"
|
||||
|
@ -155,7 +156,7 @@
|
|||
</el-dialog>
|
||||
|
||||
<OperatrDialog @search="search" ref="dialogRef" />
|
||||
<Records @search="search()" ref="dialogRecordRef" />
|
||||
<Records @search="search" ref="dialogRecordRef" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
@ -199,11 +200,13 @@ const weekOptions = [
|
|||
{ label: i18n.global.t('cronjob.sunday'), value: 7 },
|
||||
];
|
||||
|
||||
const search = async () => {
|
||||
const search = async (column?: any) => {
|
||||
let params = {
|
||||
info: searchName.value,
|
||||
page: paginationConfig.currentPage,
|
||||
pageSize: paginationConfig.pageSize,
|
||||
orderBy: column?.order ? column.prop : 'created_at',
|
||||
order: column?.order ? column.order : 'null',
|
||||
};
|
||||
loading.value = true;
|
||||
await getCronjobPage(params)
|
||||
|
|
|
@ -43,11 +43,12 @@
|
|||
<template #main v-if="mysqlIsExist && !isOnSetting">
|
||||
<ComplexTable
|
||||
:pagination-config="paginationConfig"
|
||||
@sort-change="search"
|
||||
@search="search"
|
||||
:data="data"
|
||||
:class="{ mask: mysqlStatus != 'Running' }"
|
||||
>
|
||||
<el-table-column :label="$t('commons.table.name')" prop="name" />
|
||||
<el-table-column :label="$t('commons.table.name')" prop="name" sortable />
|
||||
<el-table-column :label="$t('commons.login.username')" prop="username" />
|
||||
<el-table-column :label="$t('commons.login.password')" prop="password">
|
||||
<template #default="{ row }">
|
||||
|
@ -239,11 +240,13 @@ const onSetting = async () => {
|
|||
settingRef.value!.acceptParams(params);
|
||||
};
|
||||
|
||||
const search = async () => {
|
||||
const search = async (column?: any) => {
|
||||
let params = {
|
||||
page: paginationConfig.currentPage,
|
||||
pageSize: paginationConfig.pageSize,
|
||||
info: searchName.value,
|
||||
orderBy: column?.order ? column.prop : 'created_at',
|
||||
order: column?.order ? column.order : 'null',
|
||||
};
|
||||
const res = await searchMysqlDBs(params);
|
||||
data.value = res.data.items || [];
|
||||
|
|
|
@ -64,19 +64,28 @@
|
|||
<ComplexTable
|
||||
:pagination-config="paginationConfig"
|
||||
:data="data"
|
||||
@sort-change="search"
|
||||
@search="search()"
|
||||
:class="{ mask: nginxStatus != 'Running' }"
|
||||
>
|
||||
<el-table-column :label="$t('commons.table.name')" fix prop="primaryDomain" min-width="120px">
|
||||
<el-table-column
|
||||
:label="$t('commons.table.name')"
|
||||
fix
|
||||
prop="primaryDomain"
|
||||
min-width="120px"
|
||||
sortable
|
||||
>
|
||||
<template #default="{ row }">
|
||||
<Tooltip @click="openConfig(row.id)" :text="row.primaryDomain" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column :label="$t('commons.table.type')" fix show-overflow-tooltip prop="type">
|
||||
<el-table-column :label="$t('commons.table.type')" fix show-overflow-tooltip prop="type" sortable>
|
||||
<template #default="{ row }">
|
||||
{{ $t('website.' + row.type) }}
|
||||
<span v-if="row.type === 'deployment'">[{{ row.appName }}]</span>
|
||||
<span v-if="row.type === 'runtime'">[{{ row.runtimeName }}]</span>
|
||||
<div v-if="row.type">
|
||||
{{ $t('website.' + row.type) }}
|
||||
<span v-if="row.type === 'deployment'">[{{ row.appName }}]</span>
|
||||
<span v-if="row.type === 'runtime'">[{{ row.runtimeName }}]</span>
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column :label="$t('website.sitePath')" prop="sitePath">
|
||||
|
@ -233,14 +242,19 @@ let req = reactive({
|
|||
name: '',
|
||||
page: 1,
|
||||
pageSize: 10,
|
||||
orderBy: 'created_at',
|
||||
order: 'null',
|
||||
websiteGroupId: 0,
|
||||
});
|
||||
const mobile = computed(() => {
|
||||
return globalStore.isMobile();
|
||||
});
|
||||
const search = async () => {
|
||||
const search = async (column?: any) => {
|
||||
req.page = paginationConfig.currentPage;
|
||||
req.pageSize = paginationConfig.pageSize;
|
||||
req.orderBy = column?.order ? column.prop : 'created_at';
|
||||
req.orderBy = req.orderBy === 'primaryDomain' ? 'primary_domain' : req.orderBy;
|
||||
req.order = column?.order ? column.order : 'null';
|
||||
loading.value = true;
|
||||
await SearchWebsites(req)
|
||||
.then((res) => {
|
||||
|
|
Loading…
Reference in New Issue