feat: 为搜索条目添加细分类型
- 类型细分:有原先的四大分类添加细分类型,例如产品(原纸分切机) - 接口调整:原先的type分类改为sectionType并将type作为细分类型使用
This commit is contained in:
@ -6,9 +6,12 @@
|
|||||||
<p v-if="item.summary" class="result-summary">
|
<p v-if="item.summary" class="result-summary">
|
||||||
{{ item.summary }}
|
{{ item.summary }}
|
||||||
</p>
|
</p>
|
||||||
<p v-if="item.type" class="result-type">
|
<p v-if="item.sectionType" class="result-type">
|
||||||
<span>{{ $t('search.section') }}: </span>
|
<span>{{ $t('search.section') }}: </span>
|
||||||
<span class="result-type-name">{{ typeLabel }}</span>
|
<span class="result-type-name">{{ typeLabel }}</span>
|
||||||
|
<span v-if="item.type" class="result-type-name"
|
||||||
|
>({{ item.type }})</span
|
||||||
|
>
|
||||||
</p>
|
</p>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="12" class="image-col">
|
<el-col :span="12" class="image-col">
|
||||||
|
|||||||
@ -3,10 +3,13 @@
|
|||||||
<div class="search-results">
|
<div class="search-results">
|
||||||
<NuxtLink
|
<NuxtLink
|
||||||
v-for="hit in paginatedHits"
|
v-for="hit in paginatedHits"
|
||||||
:key="`${hit.type}-${hit.id}`"
|
:key="`${hit.sectionType}-${hit.id}`"
|
||||||
:to="localePath(resolveHitLink(hit))"
|
:to="localePath(resolveHitLink(hit))"
|
||||||
>
|
>
|
||||||
<search-result-card :item="hit" :type-label="getIndexLabel(hit.type)" />
|
<search-result-card
|
||||||
|
:item="hit"
|
||||||
|
:type-label="getIndexLabel(hit.sectionType)"
|
||||||
|
/>
|
||||||
</NuxtLink>
|
</NuxtLink>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -63,7 +66,7 @@
|
|||||||
const items = props.searchItems;
|
const items = props.searchItems;
|
||||||
const filteredHits = computed(() => {
|
const filteredHits = computed(() => {
|
||||||
if (props.category) {
|
if (props.category) {
|
||||||
return items.filter((item) => item.type === props.category);
|
return items.filter((item) => item.sectionType === props.category);
|
||||||
} else {
|
} else {
|
||||||
return items;
|
return items;
|
||||||
}
|
}
|
||||||
@ -107,19 +110,19 @@
|
|||||||
|
|
||||||
const slug = String(slugCandidate);
|
const slug = String(slugCandidate);
|
||||||
|
|
||||||
if (item.type === 'product') {
|
if (item.sectionType === 'product') {
|
||||||
return localePath({ path: `/products/${slug}` });
|
return localePath({ path: `/products/${slug}` });
|
||||||
}
|
}
|
||||||
|
|
||||||
if (item.type === 'solution') {
|
if (item.sectionType === 'solution') {
|
||||||
return localePath({ path: `/solutions/${slug}` });
|
return localePath({ path: `/solutions/${slug}` });
|
||||||
}
|
}
|
||||||
|
|
||||||
if (item.type === 'document') {
|
if (item.sectionType === 'document') {
|
||||||
return localePath({ path: `/download/${slug}` });
|
return localePath({ path: `/download/${slug}` });
|
||||||
}
|
}
|
||||||
|
|
||||||
if (item.type === 'question') {
|
if (item.sectionType === 'question') {
|
||||||
return localePath({ path: `/support/faq`, query: { focus: slug } });
|
return localePath({ path: `/support/faq`, query: { focus: slug } });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -32,7 +32,7 @@
|
|||||||
const resultCount = computed(() => {
|
const resultCount = computed(() => {
|
||||||
const map: Record<string, number> = { all: props.searchItems.length };
|
const map: Record<string, number> = { all: props.searchItems.length };
|
||||||
for (const item of props.searchItems) {
|
for (const item of props.searchItems) {
|
||||||
map[item.type] = (map[item.type] ?? 0) + 1;
|
map[item.sectionType] = (map[item.sectionType] ?? 0) + 1;
|
||||||
}
|
}
|
||||||
return map;
|
return map;
|
||||||
});
|
});
|
||||||
|
|||||||
@ -17,9 +17,10 @@ describe('converters', () => {
|
|||||||
const result = converters.products(item);
|
const result = converters.products(item);
|
||||||
expect(result).toEqual({
|
expect(result).toEqual({
|
||||||
id: 1,
|
id: 1,
|
||||||
type: 'product',
|
sectionType: 'product',
|
||||||
title: 'Hydraulic Pump',
|
title: 'Hydraulic Pump',
|
||||||
summary: 'High efficiency',
|
summary: 'High efficiency',
|
||||||
|
type: 'pump',
|
||||||
thumbnail: '/api/assets/rand-om__-uuid-1234',
|
thumbnail: '/api/assets/rand-om__-uuid-1234',
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@ -36,9 +37,10 @@ describe('converters', () => {
|
|||||||
const result = converters.solutions(item);
|
const result = converters.solutions(item);
|
||||||
expect(result).toEqual({
|
expect(result).toEqual({
|
||||||
id: 1,
|
id: 1,
|
||||||
type: 'solution',
|
sectionType: 'solution',
|
||||||
title: 'Solution A',
|
title: 'Solution A',
|
||||||
summary: 'Effective solution',
|
summary: 'Effective solution',
|
||||||
|
type: 'Type A',
|
||||||
thumbnail: '/api/assets/rand-om__-uuid-5678',
|
thumbnail: '/api/assets/rand-om__-uuid-5678',
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@ -51,13 +53,15 @@ describe('converters', () => {
|
|||||||
'This is a detailed explanation of how to use the product effectively.',
|
'This is a detailed explanation of how to use the product effectively.',
|
||||||
products: ['Product A'],
|
products: ['Product A'],
|
||||||
product_types: ['Type A'],
|
product_types: ['Type A'],
|
||||||
|
type: 'Question Type',
|
||||||
};
|
};
|
||||||
const result = converters.questions(item);
|
const result = converters.questions(item);
|
||||||
expect(result).toEqual({
|
expect(result).toEqual({
|
||||||
id: 1,
|
id: 1,
|
||||||
title: 'How to use product?',
|
title: 'How to use product?',
|
||||||
summary: '',
|
summary: undefined,
|
||||||
type: 'question',
|
type: 'Question Type',
|
||||||
|
sectionType: 'question',
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -68,13 +72,15 @@ describe('converters', () => {
|
|||||||
products: ['Product A'],
|
products: ['Product A'],
|
||||||
product_types: ['Type A'],
|
product_types: ['Type A'],
|
||||||
fileUUID: 'TEST-UUID',
|
fileUUID: 'TEST-UUID',
|
||||||
|
type: 'manual',
|
||||||
};
|
};
|
||||||
const result = converters.product_documents(item);
|
const result = converters.product_documents(item);
|
||||||
expect(result).toEqual({
|
expect(result).toEqual({
|
||||||
id: 'TEST-UUID',
|
id: 'TEST-UUID',
|
||||||
title: 'User Manual',
|
title: 'User Manual',
|
||||||
summary: '',
|
summary: undefined,
|
||||||
type: 'document',
|
sectionType: 'document',
|
||||||
|
type: 'manual',
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@ -6,33 +6,35 @@ export const converters: {
|
|||||||
} = {
|
} = {
|
||||||
products: (item: MeiliIndexMap['products']): SearchItemView => ({
|
products: (item: MeiliIndexMap['products']): SearchItemView => ({
|
||||||
id: item.id,
|
id: item.id,
|
||||||
type: 'product',
|
sectionType: 'product',
|
||||||
title: item.name,
|
title: item.name,
|
||||||
summary: item?.summary ?? '',
|
summary: item?.summary,
|
||||||
|
type: item?.type,
|
||||||
thumbnail: item?.cover ? `/api/assets/${item.cover}` : undefined,
|
thumbnail: item?.cover ? `/api/assets/${item.cover}` : undefined,
|
||||||
}),
|
}),
|
||||||
|
|
||||||
solutions: (item: MeiliIndexMap['solutions']): SearchItemView => ({
|
solutions: (item: MeiliIndexMap['solutions']): SearchItemView => ({
|
||||||
id: item.id,
|
id: item.id,
|
||||||
type: 'solution',
|
sectionType: 'solution',
|
||||||
title: item.title,
|
title: item.title,
|
||||||
summary: item?.summary ?? '',
|
summary: item?.summary,
|
||||||
|
type: item?.type,
|
||||||
thumbnail: item?.cover ? `/api/assets/${item.cover}` : undefined,
|
thumbnail: item?.cover ? `/api/assets/${item.cover}` : undefined,
|
||||||
}),
|
}),
|
||||||
|
|
||||||
questions: (item: MeiliIndexMap['questions']): SearchItemView => ({
|
questions: (item: MeiliIndexMap['questions']): SearchItemView => ({
|
||||||
id: item.id,
|
id: item.id,
|
||||||
type: 'question',
|
sectionType: 'question',
|
||||||
title: item.title,
|
title: item.title,
|
||||||
summary: '',
|
type: item?.type,
|
||||||
}),
|
}),
|
||||||
|
|
||||||
product_documents: (
|
product_documents: (
|
||||||
item: MeiliIndexMap['product_documents']
|
item: MeiliIndexMap['product_documents']
|
||||||
): SearchItemView => ({
|
): SearchItemView => ({
|
||||||
id: item.fileUUID || item.id,
|
id: item.fileUUID || item.id,
|
||||||
type: 'document',
|
sectionType: 'document',
|
||||||
title: item.title,
|
title: item.title,
|
||||||
summary: '',
|
type: item?.type,
|
||||||
}),
|
}),
|
||||||
};
|
};
|
||||||
|
|||||||
@ -57,6 +57,9 @@ export interface MeiliQuestionIndex {
|
|||||||
/** 问题内容 **/
|
/** 问题内容 **/
|
||||||
content?: string;
|
content?: string;
|
||||||
|
|
||||||
|
/** 问题类型 **/
|
||||||
|
type?: string;
|
||||||
|
|
||||||
/** 相关产品 **/
|
/** 相关产品 **/
|
||||||
products: string[];
|
products: string[];
|
||||||
|
|
||||||
@ -74,6 +77,9 @@ export interface MeiliProductDocumentIndex {
|
|||||||
/** 文档标题 **/
|
/** 文档标题 **/
|
||||||
title: string;
|
title: string;
|
||||||
|
|
||||||
|
/** 文档类型 **/
|
||||||
|
type?: string;
|
||||||
|
|
||||||
/** 相关产品 **/
|
/** 相关产品 **/
|
||||||
products: string[];
|
products: string[];
|
||||||
|
|
||||||
|
|||||||
@ -3,13 +3,16 @@ export interface SearchItemView {
|
|||||||
id: number | string;
|
id: number | string;
|
||||||
|
|
||||||
/** 条目类型 **/
|
/** 条目类型 **/
|
||||||
type: 'product' | 'solution' | 'question' | 'document';
|
sectionType: 'product' | 'solution' | 'question' | 'document';
|
||||||
|
|
||||||
/** 条目标题 **/
|
/** 条目标题 **/
|
||||||
title: string;
|
title: string;
|
||||||
|
|
||||||
/** 条目摘要 **/
|
/** 条目摘要 **/
|
||||||
summary: string;
|
summary?: string;
|
||||||
|
|
||||||
|
/** 条目分类 **/
|
||||||
|
type?: string;
|
||||||
|
|
||||||
/** 条目预览图 **/
|
/** 条目预览图 **/
|
||||||
thumbnail?: string;
|
thumbnail?: string;
|
||||||
|
|||||||
Reference in New Issue
Block a user