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([]); const isLoading = ref(false); const error = ref(null); const { wrapAsync } = useErrorHandler(); const { locale } = useI18n(); /** * 搜索产品数据 * @param keyword 搜索关键词 * @returns Promise */ 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, '$1'); }; return { searchResults, isLoading, error, searchProducts, highlightText }; }