Files
mini-programs/src/pages/search/index.tsx
2025-09-07 13:34:14 +08:00

202 lines
5.3 KiB
TypeScript

import CustomerNavbarBack from "@/components/CustomerNavbarBack";
import { View, Image, Text } from "@tarojs/components";
import { Input } from "@nutui/nutui-react-taro";
import { useEffect, useMemo, useRef } from "react";
import { useListState } from "@/store/listStore";
import img from "@/config/images";
import { withAuth } from "@/components";
import "./index.scss";
import Taro from "@tarojs/taro";
const ListSearch = () => {
const {
searchValue,
updateState,
getSearchHistory,
searchHistory = [],
clearHistory,
searchSuggestion,
suggestionList,
isShowSuggestion,
} = useListState() || {};
const ref = useRef<any>(null);
useEffect(() => {
getSearchHistory();
}, []);
useEffect(() => {
if (ref?.current) {
ref.current.focus();
}
}, [ref.current]);
const regex = useMemo(() => {
return new RegExp(searchValue, "gi");
}, [searchValue]);
/**
* @description 输入
* @param value
*/
const handleChange = (value: string) => {
updateState({ searchValue: value });
if (value) {
searchSuggestion(value);
} else {
updateState({
isShowSuggestion: false,
});
}
};
/**
* @description 点击清空输入内容
*/
const handleClear = () => {
updateState({ searchValue: "" });
};
/**
* @description 点击历史搜索
* @param value
*/
const handleHistoryClick = (value: string) => {
updateState({ searchValue: value });
handleSearch();
};
/**
* @description 清空历史搜索
*/
const handleClearHistory = () => {
clearHistory();
};
/**
* @description 点击联想词
*/
const handleSuggestionSearch = (val: string) => {
updateState({
searchValue: val,
isShowSuggestion: false,
});
handleSearch();
};
/**
* @description 点击搜索
*/
const handleSearch = () => {
Taro.navigateTo({
url: `/pages/searchResult/index`,
});
};
// 是否显示清空图标
const isShowClearIcon = searchValue && searchValue?.length > 0;
// 是否显示搜索历史
const isShowHistory =
!isShowClearIcon && searchHistory && searchHistory?.length > 0;
return (
<>
<View className="listSearchContainer">
{/* 搜索 */}
<View className="topSearch">
<Image className="searchIcon" src={img.ICON_LIST_SEARCH_SEARCH} />
<Input
placeholder="搜索上海的球局和场地"
value={searchValue}
defaultValue={searchValue}
onChange={handleChange}
onClear={handleClear}
autoFocus
clearable={false}
ref={ref}
/>
<View className="searchRight">
{isShowClearIcon && (
<Image
className="clearIcon icon16"
src={img.ICON_LIST_SEARCH_CLEAR}
onClick={handleClear}
/>
)}
<View className="searchLine" />
<Text className="searchText" onClick={handleSearch}>
</Text>
</View>
</View>
{/* 联想词 */}
{isShowSuggestion && (
<View className="searchSuggestion">
{(suggestionList || [])?.map((item) => {
// 替换匹配文本为高亮版本
const highlightedText = item.replace(regex, (match) => {
// 如果匹配不到,则返回原文本
if (!match) return match;
return `<Text class="highlight">${match}</Text>`;
});
return (
<View
className="searchSuggestionItem"
onClick={() => handleSuggestionSearch(item)}
>
<View className="searchSuggestionItemLeft">
<Image
className="icon16"
src={img.ICON_LIST_SEARCH_SEARCH}
/>
<Text
dangerouslySetInnerHTML={{ __html: highlightedText }}
></Text>
</View>
<Image
className="icon16"
src={img.ICON_LIST_SEARCH_SUGGESTION}
/>
</View>
);
})}
</View>
)}
{/* 历史搜索 */}
{!isShowClearIcon && (
<View className="historySearch">
<View className="historySearchTitleWrapper">
<View className="historySearchTitle"></View>
<View className="historySearchClear" onClick={handleClearHistory}>
<Text></Text>
<Image
className="clearIcon icon16"
src={img.ICON_LIST_SEARCH_CLEAR_HISTORY}
/>
</View>
</View>
{isShowHistory && (
<View className="historySearchList">
{(searchHistory || [])?.map((item) => {
return (
<Text
className="historySearchItem"
onClick={() => handleHistoryClick(item)}
>
{item}
</Text>
);
})}
</View>
)}
</View>
)}
</View>
</>
);
};
export default withAuth(ListSearch);