202 lines
5.3 KiB
TypeScript
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);
|