mirror of
https://github.com/1Panel-dev/1Panel.git
synced 2025-01-31 14:08:06 +08:00
feat: 应用商店分类增加排序 (#2455)
This commit is contained in:
parent
9d0eca723c
commit
154ea0b4ce
@ -98,6 +98,7 @@ type AppConfigVersion struct {
|
|||||||
type Tag struct {
|
type Tag struct {
|
||||||
Key string `json:"key"`
|
Key string `json:"key"`
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
|
Sort int `json:"sort"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type AppForm struct {
|
type AppForm struct {
|
||||||
|
@ -4,4 +4,5 @@ type Tag struct {
|
|||||||
BaseModel
|
BaseModel
|
||||||
Key string `json:"key" gorm:"type:varchar(64);not null"`
|
Key string `json:"key" gorm:"type:varchar(64);not null"`
|
||||||
Name string `json:"name" gorm:"type:varchar(64);not null"`
|
Name string `json:"name" gorm:"type:varchar(64);not null"`
|
||||||
|
Sort int `json:"sort" gorm:"type:int;not null;default:1"`
|
||||||
}
|
}
|
||||||
|
@ -31,7 +31,7 @@ func (t TagRepo) DeleteAll(ctx context.Context) error {
|
|||||||
|
|
||||||
func (t TagRepo) All() ([]model.Tag, error) {
|
func (t TagRepo) All() ([]model.Tag, error) {
|
||||||
var tags []model.Tag
|
var tags []model.Tag
|
||||||
if err := getDb().Where("1 = 1 ").Find(&tags).Error; err != nil {
|
if err := getDb().Where("1 = 1 ").Order("sort asc").Find(&tags).Error; err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return tags, nil
|
return tags, nil
|
||||||
|
@ -774,6 +774,7 @@ func (a AppService) SyncAppListFromRemote() (err error) {
|
|||||||
tags = append(tags, &model.Tag{
|
tags = append(tags, &model.Tag{
|
||||||
Key: t.Key,
|
Key: t.Key,
|
||||||
Name: t.Name,
|
Name: t.Name,
|
||||||
|
Sort: t.Sort,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
oldApps, err := appRepo.GetBy(appRepo.WithResource(constant.AppResourceRemote))
|
oldApps, err := appRepo.GetBy(appRepo.WithResource(constant.AppResourceRemote))
|
||||||
|
@ -46,6 +46,7 @@ func Init() {
|
|||||||
|
|
||||||
migrations.AddDefaultNetwork,
|
migrations.AddDefaultNetwork,
|
||||||
migrations.UpdateRuntime,
|
migrations.UpdateRuntime,
|
||||||
|
migrations.UpdateTag,
|
||||||
})
|
})
|
||||||
if err := m.Migrate(); err != nil {
|
if err := m.Migrate(); err != nil {
|
||||||
global.LOG.Error(err)
|
global.LOG.Error(err)
|
||||||
|
@ -34,3 +34,13 @@ var UpdateRuntime = &gormigrate.Migration{
|
|||||||
return nil
|
return nil
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var UpdateTag = &gormigrate.Migration{
|
||||||
|
ID: "20231008-update-tag",
|
||||||
|
Migrate: func(tx *gorm.DB) error {
|
||||||
|
if err := tx.AutoMigrate(&model.Tag{}); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
}
|
||||||
|
@ -23,6 +23,7 @@ export namespace App {
|
|||||||
export interface Tag {
|
export interface Tag {
|
||||||
key: string;
|
key: string;
|
||||||
name: string;
|
name: string;
|
||||||
|
sort: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface AppResPage {
|
export interface AppResPage {
|
||||||
|
@ -82,3 +82,7 @@
|
|||||||
.el-sub-menu__title {
|
.el-sub-menu__title {
|
||||||
padding-right: 0;
|
padding-right: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.p-mr-5 {
|
||||||
|
margin-right: 5px;
|
||||||
|
}
|
||||||
|
@ -12,7 +12,7 @@
|
|||||||
>
|
>
|
||||||
{{ $t('app.all') }}
|
{{ $t('app.all') }}
|
||||||
</el-button>
|
</el-button>
|
||||||
<div v-for="item in tags" :key="item.key" style="display: inline">
|
<div v-for="item in tags.slice(0, 6)" :key="item.key" class="inline">
|
||||||
<el-button
|
<el-button
|
||||||
class="tag-button"
|
class="tag-button"
|
||||||
:class="activeTag === item.key ? '' : 'no-active'"
|
:class="activeTag === item.key ? '' : 'no-active'"
|
||||||
@ -23,6 +23,31 @@
|
|||||||
{{ language == 'zh' || language == 'tw' ? item.name : item.key }}
|
{{ language == 'zh' || language == 'tw' ? item.name : item.key }}
|
||||||
</el-button>
|
</el-button>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="inline">
|
||||||
|
<el-dropdown>
|
||||||
|
<el-button
|
||||||
|
class="tag-button"
|
||||||
|
:type="moreTag !== '' ? 'primary' : ''"
|
||||||
|
:class="moreTag !== '' ? '' : 'no-active'"
|
||||||
|
>
|
||||||
|
{{ moreTag == '' ? $t('tabs.more') : getTagValue(moreTag) }}
|
||||||
|
<el-icon class="el-icon--right">
|
||||||
|
<arrow-down />
|
||||||
|
</el-icon>
|
||||||
|
</el-button>
|
||||||
|
<template #dropdown>
|
||||||
|
<el-dropdown-menu>
|
||||||
|
<el-dropdown-item
|
||||||
|
v-for="item in tags.slice(6)"
|
||||||
|
@click="changeTag(item.key)"
|
||||||
|
:key="item.key"
|
||||||
|
>
|
||||||
|
{{ language == 'zh' || language == 'tw' ? item.name : item.key }}
|
||||||
|
</el-dropdown-item>
|
||||||
|
</el-dropdown-menu>
|
||||||
|
</template>
|
||||||
|
</el-dropdown>
|
||||||
|
</div>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :xs="24" :sm="4" :md="4" :lg="4" :xl="4">
|
<el-col :xs="24" :sm="4" :md="4" :lg="4" :xl="4">
|
||||||
<div class="search-button">
|
<div class="search-button">
|
||||||
@ -103,12 +128,12 @@
|
|||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="app-tag">
|
<div class="app-tag">
|
||||||
<el-tag v-for="(tag, ind) in app.tags" :key="ind" style="margin-right: 5px">
|
<el-tag v-for="(tag, ind) in app.tags" :key="ind" class="p-mr-5">
|
||||||
<span :style="{ color: getColor(ind) }">
|
<span>
|
||||||
{{ language == 'zh' || language == 'tw' ? tag.name : tag.key }}
|
{{ language == 'zh' || language == 'tw' ? tag.name : tag.key }}
|
||||||
</span>
|
</span>
|
||||||
</el-tag>
|
</el-tag>
|
||||||
<el-tag v-if="app.status === 'TakeDown'" style="margin-right: 5px">
|
<el-tag v-if="app.status === 'TakeDown'" class="p-mr-5">
|
||||||
<span style="color: red">{{ $t('app.takeDown') }}</span>
|
<span style="color: red">{{ $t('app.takeDown') }}</span>
|
||||||
</el-tag>
|
</el-tag>
|
||||||
</div>
|
</div>
|
||||||
@ -170,7 +195,6 @@ const req = reactive({
|
|||||||
|
|
||||||
const apps = ref<App.AppDTO[]>([]);
|
const apps = ref<App.AppDTO[]>([]);
|
||||||
const tags = ref<App.Tag[]>([]);
|
const tags = ref<App.Tag[]>([]);
|
||||||
const colorArr = ['#005eeb', '#008B45', '#BEBEBE', '#FFF68F', '#FFFF00', '#8B0000'];
|
|
||||||
const loading = ref(false);
|
const loading = ref(false);
|
||||||
const activeTag = ref('all');
|
const activeTag = ref('all');
|
||||||
const showDetail = ref(false);
|
const showDetail = ref(false);
|
||||||
@ -179,10 +203,7 @@ const syncing = ref(false);
|
|||||||
const detailRef = ref();
|
const detailRef = ref();
|
||||||
const installRef = ref();
|
const installRef = ref();
|
||||||
const installKey = ref('');
|
const installKey = ref('');
|
||||||
|
const moreTag = ref('');
|
||||||
const getColor = (index: number) => {
|
|
||||||
return colorArr[index];
|
|
||||||
};
|
|
||||||
|
|
||||||
const search = async (req: App.AppReq) => {
|
const search = async (req: App.AppReq) => {
|
||||||
loading.value = true;
|
loading.value = true;
|
||||||
@ -244,9 +265,22 @@ const changeTag = (key: string) => {
|
|||||||
if (key !== 'all') {
|
if (key !== 'all') {
|
||||||
req.tags = [key];
|
req.tags = [key];
|
||||||
}
|
}
|
||||||
|
const index = tags.value.findIndex((tag) => tag.key === key);
|
||||||
|
if (index > 5) {
|
||||||
|
moreTag.value = key;
|
||||||
|
} else {
|
||||||
|
moreTag.value = '';
|
||||||
|
}
|
||||||
search(req);
|
search(req);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const getTagValue = (key: string) => {
|
||||||
|
const tag = tags.value.find((tag) => tag.key === key);
|
||||||
|
if (tag) {
|
||||||
|
return language == 'zh' || language == 'tw' ? tag.name : tag.key;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
const searchByName = (name: string) => {
|
const searchByName = (name: string) => {
|
||||||
req.name = name;
|
req.name = name;
|
||||||
search(req);
|
search(req);
|
||||||
@ -345,6 +379,7 @@ onMounted(() => {
|
|||||||
border: none;
|
border: none;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@media only screen and (min-width: 768px) and (max-width: 1200px) {
|
@media only screen and (min-width: 768px) and (max-width: 1200px) {
|
||||||
.app-col-12 {
|
.app-col-12 {
|
||||||
max-width: 50%;
|
max-width: 50%;
|
||||||
|
@ -13,7 +13,7 @@
|
|||||||
>
|
>
|
||||||
{{ $t('app.all') }}
|
{{ $t('app.all') }}
|
||||||
</el-button>
|
</el-button>
|
||||||
<div v-for="item in tags" :key="item.key" class="inline">
|
<div v-for="item in tags.slice(0, 6)" :key="item.key" class="inline">
|
||||||
<el-button
|
<el-button
|
||||||
class="tag-button"
|
class="tag-button"
|
||||||
:class="activeTag === item.key ? '' : 'no-active'"
|
:class="activeTag === item.key ? '' : 'no-active'"
|
||||||
@ -24,8 +24,34 @@
|
|||||||
{{ language == 'zh' || language == 'tw' ? item.name : item.key }}
|
{{ language == 'zh' || language == 'tw' ? item.name : item.key }}
|
||||||
</el-button>
|
</el-button>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="inline">
|
||||||
|
<el-dropdown>
|
||||||
|
<el-button
|
||||||
|
class="tag-button"
|
||||||
|
:type="moreTag !== '' ? 'primary' : ''"
|
||||||
|
:class="moreTag !== '' ? '' : 'no-active'"
|
||||||
|
>
|
||||||
|
{{ moreTag == '' ? $t('tabs.more') : getTagValue(moreTag) }}
|
||||||
|
<el-icon class="el-icon--right">
|
||||||
|
<arrow-down />
|
||||||
|
</el-icon>
|
||||||
|
</el-button>
|
||||||
|
<template #dropdown>
|
||||||
|
<el-dropdown-menu>
|
||||||
|
<el-dropdown-item
|
||||||
|
v-for="item in tags.slice(6)"
|
||||||
|
@click="changeTag(item.key)"
|
||||||
|
:key="item.key"
|
||||||
|
>
|
||||||
|
{{ language == 'zh' || language == 'tw' ? item.name : item.key }}
|
||||||
|
</el-dropdown-item>
|
||||||
|
</el-dropdown-menu>
|
||||||
|
</template>
|
||||||
|
</el-dropdown>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</el-col>
|
</el-col>
|
||||||
|
|
||||||
<el-col :xs="24" :sm="4" :md="4" :lg="4" :xl="4">
|
<el-col :xs="24" :sm="4" :md="4" :lg="4" :xl="4">
|
||||||
<div class="search-button">
|
<div class="search-button">
|
||||||
<el-input
|
<el-input
|
||||||
@ -341,7 +367,7 @@ const searchReq = reactive({
|
|||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const activeName = ref(i18n.global.t('app.installed'));
|
const activeName = ref(i18n.global.t('app.installed'));
|
||||||
const mode = ref('installed');
|
const mode = ref('installed');
|
||||||
|
const moreTag = ref('');
|
||||||
const language = useI18n().locale.value;
|
const language = useI18n().locale.value;
|
||||||
|
|
||||||
const sync = () => {
|
const sync = () => {
|
||||||
@ -362,9 +388,22 @@ const changeTag = (key: string) => {
|
|||||||
if (key !== 'all') {
|
if (key !== 'all') {
|
||||||
searchReq.tags = [key];
|
searchReq.tags = [key];
|
||||||
}
|
}
|
||||||
|
const index = tags.value.findIndex((tag) => tag.key === key);
|
||||||
|
if (index > 5) {
|
||||||
|
moreTag.value = key;
|
||||||
|
} else {
|
||||||
|
moreTag.value = '';
|
||||||
|
}
|
||||||
search();
|
search();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const getTagValue = (key: string) => {
|
||||||
|
const tag = tags.value.find((tag) => tag.key === key);
|
||||||
|
if (tag) {
|
||||||
|
return language == 'zh' || language == 'tw' ? tag.name : tag.key;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
const search = () => {
|
const search = () => {
|
||||||
loading.value = true;
|
loading.value = true;
|
||||||
searchReq.page = paginationConfig.currentPage;
|
searchReq.page = paginationConfig.currentPage;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user