feat: 为搜索页栏目添加图片缩略图功能
- 图片预览:产品与解决方案栏目添加缩略图功能 - 组件提取:在搜索结果页,将单个搜索结果单独提取为组件SearchResultCard
This commit is contained in:
72
app/components/pages/search/SearchResultCard.vue
Normal file
72
app/components/pages/search/SearchResultCard.vue
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
<template>
|
||||||
|
<el-card class="result-card">
|
||||||
|
<el-row>
|
||||||
|
<el-col :span="12">
|
||||||
|
<h3 class="result-title">{{ item.title }}</h3>
|
||||||
|
<p v-if="item.summary" class="result-summary">
|
||||||
|
{{ item.summary }}
|
||||||
|
</p>
|
||||||
|
<p v-if="item.type" class="result-type">
|
||||||
|
<span>{{ $t('search.section') }}: </span>
|
||||||
|
<span class="result-type-name">{{ typeLabel }}</span>
|
||||||
|
</p>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="12" class="image-col">
|
||||||
|
<el-image
|
||||||
|
v-if="item.thumbnail"
|
||||||
|
:src="item.thumbnail"
|
||||||
|
:alt="item.title"
|
||||||
|
style="width: 150px"
|
||||||
|
/>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
</el-card>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
defineProps<{
|
||||||
|
item: SearchItemView;
|
||||||
|
typeLabel: string;
|
||||||
|
}>();
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.result-card {
|
||||||
|
border-radius: 12px;
|
||||||
|
transition: box-shadow 0.2s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.result-card:hover {
|
||||||
|
box-shadow: 0 12px 24px rgba(0, 0, 0, 0.06);
|
||||||
|
}
|
||||||
|
|
||||||
|
.result-title {
|
||||||
|
font-size: 1.2rem;
|
||||||
|
font-weight: 600;
|
||||||
|
color: var(--el-color-primary);
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.result-summary {
|
||||||
|
font-size: 0.95rem;
|
||||||
|
color: var(--el-text-color-regular);
|
||||||
|
margin-bottom: 0.5rem;
|
||||||
|
line-height: 1.6;
|
||||||
|
}
|
||||||
|
|
||||||
|
.result-type {
|
||||||
|
font-size: 0.8rem;
|
||||||
|
color: var(--el-text-color-secondary);
|
||||||
|
}
|
||||||
|
|
||||||
|
.result-type-name {
|
||||||
|
margin-left: 4px;
|
||||||
|
color: var(--el-color-primary);
|
||||||
|
}
|
||||||
|
|
||||||
|
.image-col {
|
||||||
|
display: flex;
|
||||||
|
justify-content: end;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@ -6,16 +6,7 @@
|
|||||||
:key="`${hit.type}-${hit.id}`"
|
:key="`${hit.type}-${hit.id}`"
|
||||||
:to="localePath(resolveHitLink(hit))"
|
:to="localePath(resolveHitLink(hit))"
|
||||||
>
|
>
|
||||||
<el-card class="result-card">
|
<search-result-card :item="hit" :type-label="getIndexLabel(hit.type)" />
|
||||||
<h3 class="result-title">{{ hit.title }}</h3>
|
|
||||||
<p v-if="hit.summary" class="result-summary">
|
|
||||||
{{ hit.summary }}
|
|
||||||
</p>
|
|
||||||
<p v-if="hit.type" class="result-type">
|
|
||||||
<span>{{ $t('search.section') }}: </span>
|
|
||||||
<span class="result-type-name">{{ getIndexLabel(hit.type) }}</span>
|
|
||||||
</p>
|
|
||||||
</el-card>
|
|
||||||
</NuxtLink>
|
</NuxtLink>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@ -9,6 +9,7 @@ export const converters: {
|
|||||||
type: 'product',
|
type: 'product',
|
||||||
title: item.name,
|
title: item.name,
|
||||||
summary: item.summary,
|
summary: item.summary,
|
||||||
|
thumbnail: `/api/assets/${item.cover}`,
|
||||||
}),
|
}),
|
||||||
|
|
||||||
solutions: (item: MeiliIndexMap['solutions']): SearchItemView => ({
|
solutions: (item: MeiliIndexMap['solutions']): SearchItemView => ({
|
||||||
@ -16,6 +17,7 @@ export const converters: {
|
|||||||
type: 'solution',
|
type: 'solution',
|
||||||
title: item.title,
|
title: item.title,
|
||||||
summary: item.summary,
|
summary: item.summary,
|
||||||
|
thumbnail: `/api/assets/${item.cover}`,
|
||||||
}),
|
}),
|
||||||
|
|
||||||
questions: (item: MeiliIndexMap['questions']): SearchItemView => ({
|
questions: (item: MeiliIndexMap['questions']): SearchItemView => ({
|
||||||
|
|||||||
@ -16,6 +16,9 @@ export interface MeiliProductIndex {
|
|||||||
|
|
||||||
/** 产品类型 **/
|
/** 产品类型 **/
|
||||||
type: string;
|
type: string;
|
||||||
|
|
||||||
|
/** 产品缩略图 **/
|
||||||
|
cover: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -36,6 +39,9 @@ export interface MeiliSolutionIndex {
|
|||||||
|
|
||||||
/** 解决方案类型 **/
|
/** 解决方案类型 **/
|
||||||
type: string;
|
type: string;
|
||||||
|
|
||||||
|
/** 解决方案缩略图 **/
|
||||||
|
cover: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -10,4 +10,7 @@ export interface SearchItemView {
|
|||||||
|
|
||||||
/** 条目摘要 **/
|
/** 条目摘要 **/
|
||||||
summary: string;
|
summary: string;
|
||||||
|
|
||||||
|
/** 条目预览图 **/
|
||||||
|
thumbnail?: string;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user