feat: 应用商店分类增加排序 (#2455)

This commit is contained in:
zhengkunwang 2023-10-08 01:54:14 -05:00 committed by GitHub
parent 9d0eca723c
commit 154ea0b4ce
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
10 changed files with 105 additions and 12 deletions

View file

@ -98,6 +98,7 @@ type AppConfigVersion struct {
type Tag struct {
Key string `json:"key"`
Name string `json:"name"`
Sort int `json:"sort"`
}
type AppForm struct {

View file

@ -4,4 +4,5 @@ type Tag struct {
BaseModel
Key string `json:"key" 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"`
}

View file

@ -31,7 +31,7 @@ func (t TagRepo) DeleteAll(ctx context.Context) error {
func (t TagRepo) All() ([]model.Tag, error) {
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 tags, nil

View file

@ -774,6 +774,7 @@ func (a AppService) SyncAppListFromRemote() (err error) {
tags = append(tags, &model.Tag{
Key: t.Key,
Name: t.Name,
Sort: t.Sort,
})
}
oldApps, err := appRepo.GetBy(appRepo.WithResource(constant.AppResourceRemote))

View file

@ -46,6 +46,7 @@ func Init() {
migrations.AddDefaultNetwork,
migrations.UpdateRuntime,
migrations.UpdateTag,
})
if err := m.Migrate(); err != nil {
global.LOG.Error(err)

View file

@ -34,3 +34,13 @@ var UpdateRuntime = &gormigrate.Migration{
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
},
}

View file

@ -23,6 +23,7 @@ export namespace App {
export interface Tag {
key: string;
name: string;
sort: number;
}
export interface AppResPage {

View file

@ -82,3 +82,7 @@
.el-sub-menu__title {
padding-right: 0;
}
.p-mr-5 {
margin-right: 5px;
}

View file

@ -12,7 +12,7 @@
>
{{ $t('app.all') }}
</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
class="tag-button"
:class="activeTag === item.key ? '' : 'no-active'"
@ -23,6 +23,31 @@
{{ language == 'zh' || language == 'tw' ? item.name : item.key }}
</el-button>
</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 :xs="24" :sm="4" :md="4" :lg="4" :xl="4">
<div class="search-button">
@ -103,12 +128,12 @@
</span>
</div>
<div class="app-tag">
<el-tag v-for="(tag, ind) in app.tags" :key="ind" style="margin-right: 5px">
<span :style="{ color: getColor(ind) }">
<el-tag v-for="(tag, ind) in app.tags" :key="ind" class="p-mr-5">
<span>
{{ language == 'zh' || language == 'tw' ? tag.name : tag.key }}
</span>
</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>
</el-tag>
</div>
@ -170,7 +195,6 @@ const req = reactive({
const apps = ref<App.AppDTO[]>([]);
const tags = ref<App.Tag[]>([]);
const colorArr = ['#005eeb', '#008B45', '#BEBEBE', '#FFF68F', '#FFFF00', '#8B0000'];
const loading = ref(false);
const activeTag = ref('all');
const showDetail = ref(false);
@ -179,10 +203,7 @@ const syncing = ref(false);
const detailRef = ref();
const installRef = ref();
const installKey = ref('');
const getColor = (index: number) => {
return colorArr[index];
};
const moreTag = ref('');
const search = async (req: App.AppReq) => {
loading.value = true;
@ -244,9 +265,22 @@ const changeTag = (key: string) => {
if (key !== 'all') {
req.tags = [key];
}
const index = tags.value.findIndex((tag) => tag.key === key);
if (index > 5) {
moreTag.value = key;
} else {
moreTag.value = '';
}
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) => {
req.name = name;
search(req);
@ -345,6 +379,7 @@ onMounted(() => {
border: none;
}
}
@media only screen and (min-width: 768px) and (max-width: 1200px) {
.app-col-12 {
max-width: 50%;

View file

@ -13,7 +13,7 @@
>
{{ $t('app.all') }}
</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
class="tag-button"
:class="activeTag === item.key ? '' : 'no-active'"
@ -24,8 +24,34 @@
{{ language == 'zh' || language == 'tw' ? item.name : item.key }}
</el-button>
</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>
</el-col>
<el-col :xs="24" :sm="4" :md="4" :lg="4" :xl="4">
<div class="search-button">
<el-input
@ -341,7 +367,7 @@ const searchReq = reactive({
const router = useRouter();
const activeName = ref(i18n.global.t('app.installed'));
const mode = ref('installed');
const moreTag = ref('');
const language = useI18n().locale.value;
const sync = () => {
@ -362,9 +388,22 @@ const changeTag = (key: string) => {
if (key !== 'all') {
searchReq.tags = [key];
}
const index = tags.value.findIndex((tag) => tag.key === key);
if (index > 5) {
moreTag.value = key;
} else {
moreTag.value = '';
}
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 = () => {
loading.value = true;
searchReq.page = paginationConfig.currentPage;