feat(组件): 添加应用商店过滤功能并优化来源标识显示

在AppGrid组件中添加storeFilter属性以支持应用商店过滤
重构AppCard组件的来源标识显示逻辑,新增合并标识显示
当storeFilter为'both'时显示合并标识,否则显示单独标识
This commit is contained in:
2026-03-29 19:34:38 +08:00
parent dd0a17d674
commit f382e6d75d
3 changed files with 39 additions and 21 deletions

View File

@@ -59,6 +59,7 @@
<AppGrid <AppGrid
:apps="filteredApps" :apps="filteredApps"
:loading="loading" :loading="loading"
:store-filter="storeFilter"
@open-detail="openDetail" @open-detail="openDetail"
/> />
</template> </template>

View File

@@ -21,8 +21,17 @@
> >
{{ app.name || "" }} {{ app.name || "" }}
</div> </div>
<!-- 来源标识支持同时显示多个 --> <!-- 来源标识 -->
<div class="flex shrink-0 gap-1"> <div class="flex shrink-0 gap-1">
<!-- 合并标识两个来源都有时显示 -->
<span
v-if="showMergedBadge"
class="rounded-md px-1.5 py-0.5 text-[10px] font-bold uppercase tracking-wider shadow-sm bg-purple-100 text-purple-600 dark:bg-purple-900/30 dark:text-purple-400"
>
SPARK/APM
</span>
<!-- 单独标识 -->
<template v-else>
<span <span
v-if="showSparkBadge" v-if="showSparkBadge"
class="rounded-md px-1.5 py-0.5 text-[10px] font-bold uppercase tracking-wider shadow-sm bg-orange-100 text-orange-600 dark:bg-orange-900/30 dark:text-orange-400" class="rounded-md px-1.5 py-0.5 text-[10px] font-bold uppercase tracking-wider shadow-sm bg-orange-100 text-orange-600 dark:bg-orange-900/30 dark:text-orange-400"
@@ -35,6 +44,7 @@
> >
APM APM
</span> </span>
</template>
</div> </div>
</div> </div>
<div class="text-sm text-slate-500 dark:text-slate-400 leading-tight"> <div class="text-sm text-slate-500 dark:text-slate-400 leading-tight">
@@ -56,9 +66,8 @@ import type { App } from "../global/typedefinition";
const props = defineProps<{ const props = defineProps<{
app: App; app: App;
// 从外部传入的 Spark/APM 可用性信息 // 是否显示来源标识(仅在混合模式下显示)
sparkAvailable?: boolean; showOrigin?: boolean;
apmAvailable?: boolean;
}>(); }>();
const emit = defineEmits<{ const emit = defineEmits<{
@@ -71,20 +80,26 @@ const loadedIcon = ref(
'data:image/svg+xml,%3Csvg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100"%3E%3Crect fill="%23f0f0f0" width="100" height="100"/%3E%3C/svg%3E', 'data:image/svg+xml,%3Csvg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100"%3E%3Crect fill="%23f0f0f0" width="100" height="100"/%3E%3C/svg%3E',
); );
// 是否显示合并标识(两个来源都有)
const showMergedBadge = computed(() => {
// 只有在 showOrigin 为 true 且 isMerged 为 true 时才显示合并标识
return props.showOrigin === true && props.app.isMerged === true;
});
// 是否显示 Spark 标识 // 是否显示 Spark 标识
const showSparkBadge = computed(() => { const showSparkBadge = computed(() => {
// 如果明确指定了 sparkAvailable使用它 // 只有在 showOrigin 为 true 且不是合并状态时才显示单独标识
if (props.sparkAvailable !== undefined) return props.sparkAvailable; if (props.showOrigin !== true || props.app.isMerged === true) return false;
// 否则根据 app 的 origin 或 isMerged 判断 // 根据 app 的 origin 判断
return props.app.origin === "spark" || props.app.isMerged === true; return props.app.origin === "spark";
}); });
// 是否显示 APM 标识 // 是否显示 APM 标识
const showApmBadge = computed(() => { const showApmBadge = computed(() => {
// 如果明确指定了 apmAvailable使用它 // 只有在 showOrigin 为 true 且不是合并状态时才显示单独标识
if (props.apmAvailable !== undefined) return props.apmAvailable; if (props.showOrigin !== true || props.app.isMerged === true) return false;
// 否则根据 app 的 origin 或 isMerged 判断 // 根据 app 的 origin 判断
return props.app.origin === "apm" || props.app.isMerged === true; return props.app.origin === "apm";
}); });
const iconPath = computed(() => { const iconPath = computed(() => {

View File

@@ -24,6 +24,7 @@
v-for="(app, index) in apps" v-for="(app, index) in apps"
:key="index" :key="index"
:app="app" :app="app"
:show-origin="storeFilter === 'both'"
@open-detail="$emit('open-detail', app)" @open-detail="$emit('open-detail', app)"
/> />
</div> </div>
@@ -58,6 +59,7 @@ import type { App } from "../global/typedefinition";
defineProps<{ defineProps<{
apps: App[]; apps: App[];
loading: boolean; loading: boolean;
storeFilter?: "spark" | "apm" | "both";
}>(); }>();
defineEmits<{ defineEmits<{