123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114 |
- import { ref, computed } from 'vue';
- import { useErrorHandler } from './useErrorHandler';
- import { useI18n } from 'vue-i18n';
-
- /**
- * 产品数据接口
- */
- interface Product {
- id: string;
- title: string;
- description: string;
- summary: string;
- [key: string]: any;
- }
-
- /**
- * 搜索结果项接口
- */
- interface SearchResult {
- id: string;
- title: string;
- name: string;
- description: string;
- summary: string;
- matchedField: string;
- matchedText: string;
- }
-
- /**
- * 全局搜索功能钩子
- * @returns 搜索相关状态和方法
- */
- export function useSearch() {
- const searchResults = ref<SearchResult[]>([]);
- const isLoading = ref(false);
- const error = ref<string | null>(null);
- const { wrapAsync } = useErrorHandler();
- const { locale } = useI18n();
-
- /**
- * 搜索产品数据
- * @param keyword 搜索关键词
- * @returns Promise<void>
- */
- const searchProducts = async (keyword: string) => {
- if (!keyword.trim()) {
- searchResults.value = [];
- return;
- }
-
- isLoading.value = true;
- error.value = null;
-
- try {
- // 根据当前语言选择对应的JSON文件
- const lang = locale.value;
- const products = await fetch(`/data/products-${lang}.json`).then(res => res.json()) as Product[];
-
- const results: SearchResult[] = [];
-
- // 搜索数据
- products.forEach(product => {
- const fields = [
- { name: 'title', value: product.title },
- { name: 'description', value: product.description },
- { name: 'summary', value: product.summary }
- ];
-
- fields.forEach(field => {
- if (field.value && field.value.toLowerCase().includes(keyword.toLowerCase())) {
- results.push({
- id: product.id,
- title: product.title,
- name: product.name,
- description: product.description,
- summary: product.summary,
- matchedField: field.name,
- matchedText: field.value
- });
- }
- });
- });
-
- // 去重
- searchResults.value = Array.from(new Map(results.map(item => [item.id, item])).values());
- } catch (err) {
- error.value = '搜索失败,请稍后重试';
- console.error('Search error:', err);
- } finally {
- isLoading.value = false;
- }
- };
-
- /**
- * 高亮显示匹配的文本
- * @param text 原始文本
- * @param keyword 关键词
- * @returns 高亮后的HTML字符串
- */
- const highlightText = (text: string, keyword: string) => {
- if (!keyword || !text) return text;
- const regex = new RegExp(`(${keyword})`, 'gi');
- return text.replace(regex, '<span class="highlight">$1</span>');
- };
-
- return {
- searchResults,
- isLoading,
- error,
- searchProducts,
- highlightText
- };
- }
|