import { useState, useMemo, useEffect } from 'react' import Taro from '@tarojs/taro' import { View, Text, ScrollView } from '@tarojs/components' import { Search, Tag } from '@antmjs/vantui' import { shops } from '@/mock/shops' import { forumPosts } from '@/mock/forum' import ShopCard from '@/components/ShopCard' import ForumPostCard from '@/components/ForumPostCard' import type { Article } from '@/types/article' import type { Shop } from '@/types/shop' import './index.less' /** 状态栏 + 导航栏高度 */ function getNavBarHeight() { try { const sys = Taro.getSystemInfoSync() return { statusBarHeight: sys.statusBarHeight || 20, navBarHeight: 44 } } catch { return { statusBarHeight: 20, navBarHeight: 44 } } } /** 搜索结果项的联合类型 */ type SearchResult = | { kind: 'shop'; data: Shop } | { kind: 'post'; data: Article } export default function SearchPage() { const [keyword, setKeyword] = useState('') const [submittedKeyword, setSubmittedKeyword] = useState('') const [history, setHistory] = useState(['麻辣烫', '二手 iPad', '考研资料']) const [navBarHeight, setNavBarHeight] = useState({ statusBarHeight: 20, navBarHeight: 44 }) useEffect(() => { setNavBarHeight(getNavBarHeight()) }, []) /** 热门搜索 */ const hotKeywords = ['麻辣烫', '奶茶', '二手 iPad', '考研资料', '黄焖鸡', '失物招领', '六级', '外卖红包'] /** 执行搜索(综合匹配商家和帖子) */ const results = useMemo(() => { if (!submittedKeyword.trim()) return [] const kw = submittedKeyword.toLowerCase().trim() const matchedShops: Shop[] = shops.filter( (s) => s.name.toLowerCase().includes(kw) || s.description.toLowerCase().includes(kw) || s.tags.some((t) => t.toLowerCase().includes(kw)), ) const matchedPosts: Article[] = forumPosts.filter( (p) => p.title.toLowerCase().includes(kw) || p.excerpt.toLowerCase().includes(kw) || p.source.toLowerCase().includes(kw), ) return [ ...matchedShops.map((s) => ({ kind: 'shop' as const, data: s })), ...matchedPosts.map((p) => ({ kind: 'post' as const, data: p })), ] }, [submittedKeyword]) /** 返回 */ const handleBack = () => { Taro.navigateBack() } /** 点击搜索 */ const handleSearch = () => { const kw = keyword.trim() if (!kw) { Taro.showToast({ title: '请输入搜索关键词', icon: 'none' }) return } setSubmittedKeyword(kw) // 保存到历史(去重,最多 8 条) setHistory((prev) => { const next = [kw, ...prev.filter((h) => h !== kw)] return next.slice(0, 8) }) } /** 点击历史/热门 */ const handleQuickKeyword = (kw: string) => { setKeyword(kw) setSubmittedKeyword(kw) setHistory((prev) => { const next = [kw, ...prev.filter((h) => h !== kw)] return next.slice(0, 8) }) } /** 清空历史 */ const handleClearHistory = () => { setHistory([]) } /** 商家点击 */ const handleShopClick = (shop: Shop) => { Taro.navigateTo({ url: `/pages/shop-detail/index?id=${shop.id}` }) } /** 帖子点击 */ const handlePostClick = (post: Article) => { Taro.navigateTo({ url: `/pages/article/index?id=${post.id}` }) } return ( {/* ========== 自定义导航栏(带返回 + 搜索框 + 搜索按钮) ========== */} setKeyword(e.detail.value)} onSearch={handleSearch} /> 搜索 {/* 占位 */} {/* ========== 搜索结果(已提交关键词时显示) ========== */} {submittedKeyword ? ( 搜索 "{submittedKeyword}" 的结果 共 {results.length} 条 {results.length > 0 ? ( {results.map((r) => r.kind === 'shop' ? ( ) : ( ), )} ) : ( 🔍 未找到相关内容,换个词试试 )} ) : ( <> {/* ========== 搜索历史 ========== */} {history.length > 0 && ( 搜索历史 🗑 {history.map((h) => ( handleQuickKeyword(h)} > {h} ))} )} {/* ========== 热门搜索 ========== */} 热门搜索 {hotKeywords.map((kw, idx) => ( handleQuickKeyword(kw)} > {idx < 3 && {idx + 1}} {kw} ))} )} ) }