列表搜索页面
This commit is contained in:
@@ -52,7 +52,6 @@ const Bubble: React.FC<BubbleProps> = ({
|
|||||||
);
|
);
|
||||||
onChange(name, newSelectedValues, selectedOptions);
|
onChange(name, newSelectedValues, selectedOptions);
|
||||||
} else {
|
} else {
|
||||||
console.log('===111', name, option.value)
|
|
||||||
onChange(name, option.value, option);
|
onChange(name, option.value, option);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,11 +19,12 @@ const Demo3 = (props) => {
|
|||||||
const itemRef = useRef(null);
|
const itemRef = useRef(null);
|
||||||
|
|
||||||
const handleChange = (name: string, value: string) => {
|
const handleChange = (name: string, value: string) => {
|
||||||
// setIsChange(true);
|
|
||||||
onChange && onChange(name, value);
|
onChange && onChange(name, value);
|
||||||
(itemRef.current as any)?.toggle(false);
|
(itemRef.current as any)?.toggle(false);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// const cityTitle = cityOptions.find((item) => item.value === cityValue)?.label;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Menu
|
<Menu
|
||||||
className="distanceQuickFilterWrap"
|
className="distanceQuickFilterWrap"
|
||||||
|
|||||||
@@ -1,13 +1,10 @@
|
|||||||
import { Popup } from "@nutui/nutui-react-taro";
|
import { Popup } from "@nutui/nutui-react-taro";
|
||||||
import Range from "../../components/Range";
|
import Range from "../../components/Range";
|
||||||
import Bubble from "../../components/Bubble";
|
import Bubble from "../../components/Bubble";
|
||||||
import styles from "./filterPopup.module.scss";
|
import styles from "./index.module.scss";
|
||||||
import TitleComponent from "@/components/Title";
|
|
||||||
import { Button } from "@nutui/nutui-react-taro";
|
import { Button } from "@nutui/nutui-react-taro";
|
||||||
import { Image } from "@tarojs/components";
|
|
||||||
import img from "../../config/images";
|
|
||||||
import { useListStore } from "src/store/listStore";
|
import { useListStore } from "src/store/listStore";
|
||||||
import { FilterPopupProps } from "../../../types/list/types";
|
import { BubbleOption, FilterPopupProps } from "../../../types/list/types";
|
||||||
// 场地
|
// 场地
|
||||||
import CourtType from "@/components/CourtType";
|
import CourtType from "@/components/CourtType";
|
||||||
// 玩法
|
// 玩法
|
||||||
@@ -37,7 +34,7 @@ const FilterPopup = (props: FilterPopupProps) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const courtType = getDictionaryValue("court_type") || [];
|
const courtType = getDictionaryValue("court_type") || [];
|
||||||
const locationOptions = useMemo(() => {
|
const locationOptions: BubbleOption[] = useMemo(() => {
|
||||||
return courtType ? handleOptions(courtType) : [];
|
return courtType ? handleOptions(courtType) : [];
|
||||||
}, [courtType]);
|
}, [courtType]);
|
||||||
|
|
||||||
@@ -108,16 +105,16 @@ const FilterPopup = (props: FilterPopupProps) => {
|
|||||||
{/* CourtType */}
|
{/* CourtType */}
|
||||||
<CourtType
|
<CourtType
|
||||||
onChange={handleFilterChange}
|
onChange={handleFilterChange}
|
||||||
name="court_type"
|
name="venueType"
|
||||||
options={locationOptions}
|
options={locationOptions}
|
||||||
value={filterOptions?.site}
|
value={filterOptions?.venueType}
|
||||||
/>
|
/>
|
||||||
{/* 玩法 */}
|
{/* 玩法 */}
|
||||||
<GamePlayType
|
<GamePlayType
|
||||||
onChange={handleFilterChange}
|
onChange={handleFilterChange}
|
||||||
name="game_play"
|
name="playType"
|
||||||
options={gamePlayOptions}
|
options={gamePlayOptions}
|
||||||
value={filterOptions?.game_play}
|
value={filterOptions?.playType}
|
||||||
/>
|
/>
|
||||||
{/* 按钮 */}
|
{/* 按钮 */}
|
||||||
<div className={styles.filterPopupBtnWrapper}>
|
<div className={styles.filterPopupBtnWrapper}>
|
||||||
@@ -8,14 +8,14 @@ const ListCard: React.FC<ListCardProps> = ({
|
|||||||
id,
|
id,
|
||||||
title,
|
title,
|
||||||
dateTime,
|
dateTime,
|
||||||
location,
|
venue_description,
|
||||||
distance,
|
distance_km,
|
||||||
registeredCount,
|
registeredCount,
|
||||||
maxCount,
|
maxCount,
|
||||||
skillLevel,
|
skillLevel,
|
||||||
matchType,
|
play_type,
|
||||||
images = [],
|
images = [],
|
||||||
shinei,
|
court_type,
|
||||||
}) => {
|
}) => {
|
||||||
const renderItemImage = (src: string) => {
|
const renderItemImage = (src: string) => {
|
||||||
return <Image src={src} className="image" mode="aspectFill" />;
|
return <Image src={src} className="image" mode="aspectFill" />;
|
||||||
@@ -64,17 +64,16 @@ const ListCard: React.FC<ListCardProps> = ({
|
|||||||
{/* 左侧内容区域 */}
|
{/* 左侧内容区域 */}
|
||||||
<View className="content">
|
<View className="content">
|
||||||
{/* 标题 */}
|
{/* 标题 */}
|
||||||
<View className="titleWrapper">
|
{title && <View className="titleWrapper">
|
||||||
<Text className="title">{title}</Text>
|
<Text className="title">{title}</Text>
|
||||||
<Image
|
<Image
|
||||||
src={img.ICON_LIST_RIGHT_ARROW}
|
src={img.ICON_LIST_RIGHT_ARROW}
|
||||||
className="title-right-arrow"
|
className="title-right-arrow"
|
||||||
mode="aspectFit"
|
mode="aspectFit"
|
||||||
/>
|
/>
|
||||||
</View>
|
</View>}
|
||||||
|
|
||||||
{/* 时间信息 */}
|
{/* 时间信息 */}
|
||||||
|
|
||||||
<View className="date-time">
|
<View className="date-time">
|
||||||
<Text>{dateTime}</Text>
|
<Text>{dateTime}</Text>
|
||||||
</View>
|
</View>
|
||||||
@@ -82,10 +81,11 @@ const ListCard: React.FC<ListCardProps> = ({
|
|||||||
{/* 地点,室内外,距离 */}
|
{/* 地点,室内外,距离 */}
|
||||||
|
|
||||||
<View className="location">
|
<View className="location">
|
||||||
<Text className="location-text location-position">{location}</Text>
|
{venue_description &&
|
||||||
|
<Text className="location-text location-position">{venue_description}</Text>}
|
||||||
<Text className="location-text location-time-distance">
|
<Text className="location-text location-time-distance">
|
||||||
{shinei && `・${shinei}`}
|
{court_type && `・${court_type}`}
|
||||||
{distance && `・${distance}`}
|
{distance_km && `・${distance_km}`}
|
||||||
</Text>
|
</Text>
|
||||||
</View>
|
</View>
|
||||||
|
|
||||||
@@ -115,11 +115,11 @@ const ListCard: React.FC<ListCardProps> = ({
|
|||||||
</Text>
|
</Text>
|
||||||
</View>
|
</View>
|
||||||
<View className="tag">
|
<View className="tag">
|
||||||
<Text className="tag-text">{skillLevel}</Text>
|
<Text className="tag-text">{skill_level_max} zh {skill_level_max}</Text>
|
||||||
</View>
|
|
||||||
<View className="tag">
|
|
||||||
<Text className="tag-text">{matchType}</Text>
|
|
||||||
</View>
|
</View>
|
||||||
|
{play_type && <View className="tag">
|
||||||
|
<Text className="tag-text">{play_type}</Text>
|
||||||
|
</View>}
|
||||||
</View>
|
</View>
|
||||||
</View>
|
</View>
|
||||||
</View>
|
</View>
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ const SearchBarComponent = (props: IProps) => {
|
|||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<SearchBar
|
<SearchBar
|
||||||
|
disabled
|
||||||
clearable={false}
|
clearable={false}
|
||||||
leftIn={
|
leftIn={
|
||||||
<View className={styles.searchBarLeft}>
|
<View className={styles.searchBarLeft}>
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
gap: 5px;
|
gap: 5px;
|
||||||
// background-color: red;
|
padding-bottom: 34px;
|
||||||
|
|
||||||
.recommendTextWrapper {
|
.recommendTextWrapper {
|
||||||
display: flex;
|
display: flex;
|
||||||
@@ -19,4 +19,17 @@
|
|||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
line-height: 24px;
|
line-height: 24px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.bottomTextWrapper {
|
||||||
|
width: 100%;
|
||||||
|
height: 68px;
|
||||||
|
padding: 0 16px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
color: rgba(0, 0, 0, 0.85);
|
||||||
|
font-size: 14px;
|
||||||
|
font-weight: 500;
|
||||||
|
line-height: 24px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -3,10 +3,17 @@ import ListCard from "@/components/ListCard";
|
|||||||
import ListLoadError from "@/components/ListLoadError";
|
import ListLoadError from "@/components/ListLoadError";
|
||||||
import ListCardSkeleton from "@/components/ListCardSkeleton";
|
import ListCardSkeleton from "@/components/ListCardSkeleton";
|
||||||
import "./index.scss";
|
import "./index.scss";
|
||||||
|
import { useReachBottom } from "@tarojs/taro";
|
||||||
|
|
||||||
const ListContainer = (props) => {
|
const ListContainer = (props) => {
|
||||||
const { loading, data = [], error, reload, recommendList } = props;
|
const { loading, data = [], error, reload, recommendList } = props;
|
||||||
|
|
||||||
|
useReachBottom(() => {
|
||||||
|
console.log("触底了");
|
||||||
|
// 调用 store 的加载更多方法
|
||||||
|
// loadMoreMatches();
|
||||||
|
});
|
||||||
|
|
||||||
if (error) {
|
if (error) {
|
||||||
return <ListLoadError reload={reload} />;
|
return <ListLoadError reload={reload} />;
|
||||||
}
|
}
|
||||||
@@ -38,6 +45,8 @@ const ListContainer = (props) => {
|
|||||||
<Text className="recommendText">搜索结果较少,已为你推荐其他内容</Text>
|
<Text className="recommendText">搜索结果较少,已为你推荐其他内容</Text>
|
||||||
</View>
|
</View>
|
||||||
{renderList(recommendList)}
|
{renderList(recommendList)}
|
||||||
|
{/* 到底了 */}
|
||||||
|
<View className="bottomTextWrapper">到底了</View>
|
||||||
</View>
|
</View>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,10 +1,8 @@
|
|||||||
import Menu from "../../components/Menu";
|
|
||||||
import CityFilter from "../../components/CityFilter";
|
|
||||||
import SearchBar from "../../components/SearchBar";
|
import SearchBar from "../../components/SearchBar";
|
||||||
import FilterPopup from "./FilterPopup";
|
import FilterPopup from "@/components/FilterPopup";
|
||||||
import styles from "./index.module.scss";
|
import styles from "./index.module.scss";
|
||||||
import { useEffect } from "react";
|
import { useEffect } from "react";
|
||||||
import Taro, { usePageScroll, useReachBottom } from "@tarojs/taro";
|
import Taro, { usePageScroll } from "@tarojs/taro";
|
||||||
import { useListStore } from "@/store/listStore";
|
import { useListStore } from "@/store/listStore";
|
||||||
import { useGlobalState } from "@/store/global";
|
import { useGlobalState } from "@/store/global";
|
||||||
import { View } from "@tarojs/components";
|
import { View } from "@tarojs/components";
|
||||||
@@ -19,7 +17,7 @@ const ListPage = () => {
|
|||||||
// 从 store 获取数据和方法
|
// 从 store 获取数据和方法
|
||||||
const store = useListStore() || {};
|
const store = useListStore() || {};
|
||||||
|
|
||||||
const { statusNavbarHeightInfo } = useGlobalState() || {};
|
const { statusNavbarHeightInfo, location } = useGlobalState() || {};
|
||||||
const { totalHeight } = statusNavbarHeightInfo || {};
|
const { totalHeight } = statusNavbarHeightInfo || {};
|
||||||
const {
|
const {
|
||||||
isShowFilterPopup,
|
isShowFilterPopup,
|
||||||
@@ -43,25 +41,18 @@ const ListPage = () => {
|
|||||||
} = store;
|
} = store;
|
||||||
|
|
||||||
usePageScroll((res) => {
|
usePageScroll((res) => {
|
||||||
// if (res?.scrollTop > 0 && !isScrollTop) {
|
|
||||||
// updateState({ isScrollTop: true });
|
|
||||||
// }
|
|
||||||
if (res?.scrollTop >= totalHeight && !isScrollTop) {
|
if (res?.scrollTop >= totalHeight && !isScrollTop) {
|
||||||
updateState({ isShowInputCustomerNavBar: true });
|
!isShowInputCustomerNavBar && updateState({ isShowInputCustomerNavBar: true });
|
||||||
} else {
|
} else {
|
||||||
updateState({ isShowInputCustomerNavBar: false });
|
isShowInputCustomerNavBar && updateState({ isShowInputCustomerNavBar: false });
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
useReachBottom(() => {
|
|
||||||
console.log("触底了");
|
|
||||||
// 调用 store 的加载更多方法
|
|
||||||
// loadMoreMatches();
|
|
||||||
});
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
// 页面加载时获取数据
|
// 页面加载时获取数据
|
||||||
fetchMatches();
|
fetchMatches();
|
||||||
|
// 保存位置
|
||||||
|
updateState({ location });
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
// 下拉刷新处理函数 - 使用Taro生命周期钩子
|
// 下拉刷新处理函数 - 使用Taro生命周期钩子
|
||||||
|
|||||||
@@ -5,11 +5,60 @@
|
|||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
gap: 5px;
|
gap: 5px;
|
||||||
padding: 5px 0px 10px 0px;
|
padding: 5px 15px 10px 15px;
|
||||||
position: sticky;
|
position: sticky;
|
||||||
top: -1px;
|
top: -1px;
|
||||||
background-color: #fefefe;
|
background-color: #fefefe;
|
||||||
z-index: 123;
|
z-index: 123;
|
||||||
|
|
||||||
|
.nut-menu-bar {
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nut-menu-container-wrap {
|
||||||
|
left: -15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.filterIconWrapper {
|
||||||
|
display: flex;
|
||||||
|
width: 28px;
|
||||||
|
height: 28px;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
gap: 10px;
|
||||||
|
flex-shrink: 0;
|
||||||
|
aspect-ratio: 1/1;
|
||||||
|
border-radius: 999px;
|
||||||
|
border: 0.5px solid rgba(0, 0, 0, 0.06);
|
||||||
|
background: #FFF;
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
&.active {
|
||||||
|
background-color: #000000;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.filterIcon {
|
||||||
|
width: 14px;
|
||||||
|
height: 14px;
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.filterCount {
|
||||||
|
background-color: #000000;
|
||||||
|
position: absolute;
|
||||||
|
width: 15px;
|
||||||
|
height: 15px;
|
||||||
|
border: 2px solid #ffffff;
|
||||||
|
border-radius: 50%;
|
||||||
|
right: -5px;
|
||||||
|
bottom: -5px;
|
||||||
|
color: #ffffff;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
font-size: 11px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.menuFilter {
|
.menuFilter {
|
||||||
|
|||||||
@@ -1,34 +1,53 @@
|
|||||||
import { View } from "@tarojs/components";
|
import { View, Image, Text } from "@tarojs/components";
|
||||||
import { useListState } from "@/store/listStore";
|
import { useSearchResultState } from "@/store/searchResultStore";
|
||||||
import { useGlobalState } from "@/store/global";
|
import { useGlobalState } from "@/store/global";
|
||||||
import ListContainer from "@/container/listContainer";
|
import ListContainer from "@/container/listContainer";
|
||||||
|
import img from "@/config/images";
|
||||||
|
|
||||||
import "./index.scss";
|
import "./index.scss";
|
||||||
import DistanceQuickFilter from "@/components/DistanceQuickFilter";
|
import DistanceQuickFilter from "@/components/DistanceQuickFilter";
|
||||||
import { useEffect } from "react";
|
import { useEffect } from "react";
|
||||||
|
import FilterPopup from "@/components/FilterPopup";
|
||||||
|
|
||||||
const SearchResult = () => {
|
const SearchResult = () => {
|
||||||
const {
|
const {
|
||||||
distanceData,
|
isShowFilterPopup,
|
||||||
quickFilterData,
|
error,
|
||||||
distanceQuickFilter,
|
distanceQuickFilter,
|
||||||
updateState,
|
|
||||||
matches,
|
matches,
|
||||||
recommendList,
|
recommendList,
|
||||||
loading,
|
loading,
|
||||||
error,
|
|
||||||
refreshMatches,
|
|
||||||
fetchMatches,
|
fetchMatches,
|
||||||
} = useListState() || {};
|
refreshMatches,
|
||||||
|
updateState,
|
||||||
|
filterCount,
|
||||||
|
updateFilterOptions, // 更新筛选条件
|
||||||
|
filterOptions,
|
||||||
|
clearFilterOptions,
|
||||||
|
distanceData,
|
||||||
|
quickFilterData,
|
||||||
|
} = useSearchResultState() || {};
|
||||||
const { statusNavbarHeightInfo } = useGlobalState() || {};
|
const { statusNavbarHeightInfo } = useGlobalState() || {};
|
||||||
const { totalHeight } = statusNavbarHeightInfo || {}
|
const { totalHeight } = statusNavbarHeightInfo || {};
|
||||||
|
const isSelect = filterCount > 0;
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
// 页面加载时获取数据
|
// 页面加载时获取数据
|
||||||
fetchMatches();
|
fetchMatches();
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description 更新筛选条件
|
||||||
|
* @param {Record<string, any>} params 筛选项
|
||||||
|
*/
|
||||||
|
const handleUpdateFilterOptions = (params: Record<string, any>) => {
|
||||||
|
updateFilterOptions(params);
|
||||||
|
};
|
||||||
|
|
||||||
|
const toggleShowPopup = () => {
|
||||||
|
updateState({ isShowFilterPopup: !isShowFilterPopup });
|
||||||
|
};
|
||||||
|
|
||||||
// 距离筛选
|
// 距离筛选
|
||||||
const handleDistanceOrQuickChange = (name, value) => {
|
const handleDistanceOrQuickChange = (name, value) => {
|
||||||
updateState({
|
updateState({
|
||||||
@@ -42,10 +61,15 @@ const SearchResult = () => {
|
|||||||
return (
|
return (
|
||||||
<View className="searchResultPage">
|
<View className="searchResultPage">
|
||||||
{/* 筛选 */}
|
{/* 筛选 */}
|
||||||
<View className='searchResultFilterWrapper' style={{
|
<View
|
||||||
// top: `${totalHeight}px`
|
className="searchResultFilterWrapper"
|
||||||
}}>
|
style={
|
||||||
<DistanceQuickFilter
|
{
|
||||||
|
// top: `${totalHeight}px`
|
||||||
|
}
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<DistanceQuickFilter
|
||||||
cityOptions={distanceData}
|
cityOptions={distanceData}
|
||||||
quickOptions={quickFilterData}
|
quickOptions={quickFilterData}
|
||||||
onChange={handleDistanceOrQuickChange}
|
onChange={handleDistanceOrQuickChange}
|
||||||
@@ -54,6 +78,31 @@ const SearchResult = () => {
|
|||||||
cityValue={distanceQuickFilter?.distance}
|
cityValue={distanceQuickFilter?.distance}
|
||||||
quickValue={distanceQuickFilter?.quick}
|
quickValue={distanceQuickFilter?.quick}
|
||||||
/>
|
/>
|
||||||
|
{/* 筛选 icon */}
|
||||||
|
<View className={`filterIconWrapper ${isSelect && 'active'}`} onClick={toggleShowPopup}>
|
||||||
|
<Image
|
||||||
|
src={isSelect ? img.ICON_FILTER_SELECTED : img.ICON_FILTER}
|
||||||
|
className={`filterIcon ${isSelect && 'active'}`}
|
||||||
|
/>
|
||||||
|
{isSelect && <Text className="filterCount">{filterCount}</Text>}
|
||||||
|
</View>
|
||||||
|
{/* 筛选弹框 */}
|
||||||
|
{/* 综合筛选 */}
|
||||||
|
{isShowFilterPopup && (
|
||||||
|
<View>
|
||||||
|
<FilterPopup
|
||||||
|
loading={loading}
|
||||||
|
onCancel={toggleShowPopup}
|
||||||
|
onConfirm={toggleShowPopup}
|
||||||
|
onChange={handleUpdateFilterOptions}
|
||||||
|
filterOptions={filterOptions}
|
||||||
|
onClear={clearFilterOptions}
|
||||||
|
visible={isShowFilterPopup}
|
||||||
|
onClose={toggleShowPopup}
|
||||||
|
statusNavbarHeigh={0}
|
||||||
|
/>
|
||||||
|
</View>
|
||||||
|
)}
|
||||||
</View>
|
</View>
|
||||||
|
|
||||||
{/* 列表内容 */}
|
{/* 列表内容 */}
|
||||||
@@ -68,4 +117,4 @@ const SearchResult = () => {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default SearchResult;
|
export default SearchResult;
|
||||||
|
|||||||
@@ -12,39 +12,39 @@ interface ApiResponse<T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取网球比赛列表
|
* 获取列表
|
||||||
* @param params 查询参数
|
* @param params 查询参数
|
||||||
* @returns Promise<TennisMatch[]>
|
* @returns Promise<TennisMatch[]>
|
||||||
*/
|
*/
|
||||||
export const getTennisMatches = async (params?: {
|
export const getGamesList = async (params?: {
|
||||||
page?: number;
|
page?: number;
|
||||||
pageSize?: number;
|
pageSize?: number;
|
||||||
location?: string;
|
location?: string;
|
||||||
skillLevel?: string;
|
skillLevel?: string;
|
||||||
}) => {
|
}) => {
|
||||||
try {
|
try {
|
||||||
return httpService.post('/venues/list', params, { showLoading: false })
|
return httpService.post('/games/list', params, { showLoading: false })
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("列表数据获取失败:", error);
|
console.error("列表数据获取失败:", error);
|
||||||
throw error;
|
throw error;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
export const getGamesIntegrateList = async (params?: {
|
||||||
* 刷新网球比赛数据
|
page?: number;
|
||||||
* @returns Promise<TennisMatch[]>
|
pageSize?: number;
|
||||||
*/
|
location?: string;
|
||||||
export const refreshTennisMatches = async (params) => {
|
skillLevel?: string;
|
||||||
|
}) => {
|
||||||
try {
|
try {
|
||||||
// 生成新的动态数据
|
return httpService.post('/games/integrate_list', params, { showLoading: false })
|
||||||
const matches = generateDynamicData(params);
|
|
||||||
return matches;
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("API刷新失败:", error);
|
console.error("列表数据获取失败:", error);
|
||||||
throw error;
|
throw error;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取搜索历史记录的异步函数
|
* 获取搜索历史记录的异步函数
|
||||||
* @param {Object} params - 查询参数对象
|
* @param {Object} params - 查询参数对象
|
||||||
@@ -69,8 +69,8 @@ export const getSearchHistory = async (params) => {
|
|||||||
export const clearHistory = async () => {
|
export const clearHistory = async () => {
|
||||||
try {
|
try {
|
||||||
// 调用HTTP服务清除搜索历史记录
|
// 调用HTTP服务清除搜索历史记录
|
||||||
return httpService.post('/games/clear_history')
|
return httpService.post('/search_history/delete_all')
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
// 捕获并打印错误信息
|
// 捕获并打印错误信息
|
||||||
console.error("清除历史记录失败:", error);
|
console.error("清除历史记录失败:", error);
|
||||||
// 抛出错误以便上层处理
|
// 抛出错误以便上层处理
|
||||||
@@ -86,7 +86,7 @@ export const clearHistory = async () => {
|
|||||||
export const searchSuggestion = async (params) => {
|
export const searchSuggestion = async (params) => {
|
||||||
try {
|
try {
|
||||||
// 调用HTTP服务获取搜索建议
|
// 调用HTTP服务获取搜索建议
|
||||||
return httpService.get('/games/search_suggestion', params)
|
return httpService.get('/games/search_recommendations', params)
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
// 捕获并打印错误信息
|
// 捕获并打印错误信息
|
||||||
console.error("搜索建议获取失败:", error);
|
console.error("搜索建议获取失败:", error);
|
||||||
|
|||||||
@@ -1,16 +1,16 @@
|
|||||||
import { create } from 'zustand'
|
import { create } from 'zustand'
|
||||||
import { getTennisMatches, getSearchHistory, clearHistory, searchSuggestion } from '../services/listApi'
|
import { getGamesList, getGamesIntegrateList, getSearchHistory, clearHistory, searchSuggestion } from '../services/listApi'
|
||||||
import { ListActions, IFilterOptions, ListState } from '../../types/list/types'
|
import { ListActions, IFilterOptions, ListState } from '../../types/list/types'
|
||||||
|
|
||||||
// 完整的 Store 类型
|
// 完整的 Store 类型
|
||||||
type TennisStore = ListState & ListActions
|
type TennisStore = ListState & ListActions
|
||||||
|
|
||||||
const defaultFilterOptions: IFilterOptions = {
|
const defaultFilterOptions: IFilterOptions = {
|
||||||
location: '', // 位置
|
dateRange: [], // 日期区间
|
||||||
time: '', // 时间
|
timeSlot: '', // 时间段
|
||||||
ntrp: [1.0, 5.0], // NTRP 水平区间
|
ntrp: [1, 5], // NTRP 水平区间
|
||||||
court_type: '', // 场地类型
|
venueType: '', // 场地类型
|
||||||
game_play: '', // 玩法
|
playType: '', // 玩法
|
||||||
};
|
};
|
||||||
|
|
||||||
const defaultDistance = 'all'; // 默认距离
|
const defaultDistance = 'all'; // 默认距离
|
||||||
@@ -21,6 +21,10 @@ export const useListStore = create<TennisStore>()((set, get) => ({
|
|||||||
matches: [],
|
matches: [],
|
||||||
// 推荐列表
|
// 推荐列表
|
||||||
recommendList: [],
|
recommendList: [],
|
||||||
|
location: {
|
||||||
|
latitude: 0,
|
||||||
|
longitude: 0,
|
||||||
|
}, // 位置
|
||||||
// 是否加载中
|
// 是否加载中
|
||||||
loading: false,
|
loading: false,
|
||||||
error: null,
|
error: null,
|
||||||
@@ -38,10 +42,10 @@ export const useListStore = create<TennisStore>()((set, get) => ({
|
|||||||
quickFilter: 1, // 1: 默认 2: 好评 3: 销量
|
quickFilter: 1, // 1: 默认 2: 好评 3: 销量
|
||||||
// 距离筛选数据
|
// 距离筛选数据
|
||||||
distanceData: [
|
distanceData: [
|
||||||
{ id: 0, label: "全城", value: "全城" },
|
{ id: 0, label: "全城", value: "0" },
|
||||||
{ id: 1, label: "3km", value: "3km" },
|
{ id: 1, label: "3km", value: "3" },
|
||||||
{ id: 2, label: "5km", value: "5km" },
|
{ id: 2, label: "5km", value: "5" },
|
||||||
{ id: 3, label: "10km", value: "10km" },
|
{ id: 3, label: "10km", value: "10" },
|
||||||
],
|
],
|
||||||
// 快捷筛选数据
|
// 快捷筛选数据
|
||||||
quickFilterData: [
|
quickFilterData: [
|
||||||
@@ -100,13 +104,42 @@ export const useListStore = create<TennisStore>()((set, get) => ({
|
|||||||
isOpenDistancePopup: false,
|
isOpenDistancePopup: false,
|
||||||
// 打开快捷筛选框
|
// 打开快捷筛选框
|
||||||
isOpenQuickFilterPopup: false,
|
isOpenQuickFilterPopup: false,
|
||||||
|
// 分页
|
||||||
|
pageOption: {
|
||||||
|
page: 1,
|
||||||
|
pageSize: 20,
|
||||||
|
},
|
||||||
|
|
||||||
// 获取比赛数据
|
// 组装搜索数据
|
||||||
|
getSearchParams: () => {
|
||||||
|
const state = get()
|
||||||
|
const filterOptions = state?.filterOptions || {};
|
||||||
|
const params = {
|
||||||
|
pageOption: state.pageOption,
|
||||||
|
seachOption: {
|
||||||
|
...filterOptions,
|
||||||
|
title: state.searchValue,
|
||||||
|
},
|
||||||
|
order: '',
|
||||||
|
lat: state?.location?.latitude,
|
||||||
|
lng: state?.location?.longitude,
|
||||||
|
}
|
||||||
|
return params;
|
||||||
|
},
|
||||||
|
|
||||||
|
// 初始化获取比赛数据
|
||||||
fetchMatches: async (params) => {
|
fetchMatches: async (params) => {
|
||||||
set({ loading: true, error: null })
|
set({ loading: true, error: null })
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const resData = await getTennisMatches(params) || {};
|
const { getSearchParams } = get();
|
||||||
|
const searchParams = getSearchParams() || {};
|
||||||
|
const reqParams = {
|
||||||
|
...(searchParams || {}),
|
||||||
|
...params,
|
||||||
|
}
|
||||||
|
const resData = await getGamesList(reqParams) || {};
|
||||||
|
console.log('===resData', resData)
|
||||||
const { data = {}, code } = resData;
|
const { data = {}, code } = resData;
|
||||||
if (code !== 0) {
|
if (code !== 0) {
|
||||||
set({
|
set({
|
||||||
@@ -116,25 +149,25 @@ export const useListStore = create<TennisStore>()((set, get) => ({
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
const { count, rows } = data;
|
const { count, rows } = data;
|
||||||
const list = (rows || []).map(() => {
|
// const list = (rows || []).map(() => {
|
||||||
return {
|
// return {
|
||||||
id: "3",
|
// id: "3",
|
||||||
title: "黄浦区双打约球",
|
// title: "黄浦区双打约球",
|
||||||
dateTime: "7月20日(周日)下午6点 2小时",
|
// dateTime: "7月20日(周日)下午6点 2小时",
|
||||||
location: "仁恒河滨花园网球场",
|
// location: "仁恒河滨花园网球场",
|
||||||
distance: "3.5km",
|
// distance: "3.5km",
|
||||||
registeredCount: 3,
|
// registeredCount: 3,
|
||||||
maxCount: 4,
|
// maxCount: 4,
|
||||||
skillLevel: "2.0 至 2.5",
|
// skillLevel: "2.0 至 2.5",
|
||||||
matchType: "双打",
|
// matchType: "双打",
|
||||||
images: [
|
// images: [
|
||||||
"https://images.unsplash.com/photo-1554068865-24cecd4e34b8?w=200&h=200&fit=crop&crop=center",
|
// "https://images.unsplash.com/photo-1554068865-24cecd4e34b8?w=200&h=200&fit=crop&crop=center",
|
||||||
],
|
// ],
|
||||||
}
|
// }
|
||||||
})
|
// })
|
||||||
set({
|
set({
|
||||||
matches: list || rows || [],
|
matches: rows || [],
|
||||||
recommendList: list || rows || [],
|
recommendList: rows || [],
|
||||||
error: null,
|
error: null,
|
||||||
loading: false,
|
loading: false,
|
||||||
gamesNum: count,
|
gamesNum: count,
|
||||||
@@ -149,22 +182,6 @@ export const useListStore = create<TennisStore>()((set, get) => ({
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
// 刷新比赛数据
|
|
||||||
refreshMatches: async () => {
|
|
||||||
set({ loading: true, error: null })
|
|
||||||
|
|
||||||
try {
|
|
||||||
const resData = await getTennisMatches() || {};
|
|
||||||
const { data = {}, code } = resData;
|
|
||||||
const { count, rows } = data;
|
|
||||||
set({
|
|
||||||
matches: rows,
|
|
||||||
loading: false,
|
|
||||||
})
|
|
||||||
} catch (error) {
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
// 获取历史搜索数据
|
// 获取历史搜索数据
|
||||||
getSearchHistory: async () => {
|
getSearchHistory: async () => {
|
||||||
try {
|
try {
|
||||||
@@ -212,10 +229,10 @@ export const useListStore = create<TennisStore>()((set, get) => ({
|
|||||||
|
|
||||||
// 更新综合筛选项
|
// 更新综合筛选项
|
||||||
updateFilterOptions: (payload: Record<string, any>) => {
|
updateFilterOptions: (payload: Record<string, any>) => {
|
||||||
console.log('===更新综合筛选项', payload)
|
|
||||||
const preFilterOptions = get()?.filterOptions || {}
|
const preFilterOptions = get()?.filterOptions || {}
|
||||||
const filterOptions = { ...preFilterOptions, ...payload }
|
const filterOptions = { ...preFilterOptions, ...payload }
|
||||||
const filterCount = Object.values(filterOptions).filter(Boolean).length
|
const filterCount = Object.values(filterOptions).filter(Boolean).length
|
||||||
|
console.log('===更新综合筛选项', filterOptions, filterCount)
|
||||||
set({
|
set({
|
||||||
filterOptions,
|
filterOptions,
|
||||||
filterCount
|
filterCount
|
||||||
|
|||||||
255
src/store/searchResultStore.ts
Normal file
255
src/store/searchResultStore.ts
Normal file
@@ -0,0 +1,255 @@
|
|||||||
|
import { create } from 'zustand'
|
||||||
|
import { getTennisMatches, getSearchHistory, clearHistory, searchSuggestion } from '../services/listApi'
|
||||||
|
import { ListActions, ISearchOptions, ListState } from '../../types/list/types'
|
||||||
|
|
||||||
|
// 完整的 Store 类型
|
||||||
|
type TennisStore = ListState & ListActions
|
||||||
|
|
||||||
|
const defaultSearchOptions: ISearchOptions = {
|
||||||
|
title: '', // 标题
|
||||||
|
dateRange: ['', ''], // 日期区间
|
||||||
|
timeSlot: '', // 时间段
|
||||||
|
ntrpMin: 1, // NTRP 最小值
|
||||||
|
ntrpMax: 5, // NTRP 最大值
|
||||||
|
venueType: '', // 场地类型
|
||||||
|
playType: '', // 玩法
|
||||||
|
distanceFilter: '', // 距离筛选
|
||||||
|
lat: '', // 纬度
|
||||||
|
lng: '', // 经度
|
||||||
|
};
|
||||||
|
|
||||||
|
const defaultDistance = 'all'; // 默认距离
|
||||||
|
|
||||||
|
// 创建 store
|
||||||
|
export const useSearchResultStore = create<TennisStore>()((set, get) => ({
|
||||||
|
// 初始状态
|
||||||
|
matches: [],
|
||||||
|
// 推荐列表
|
||||||
|
recommendList: [],
|
||||||
|
// 是否加载中
|
||||||
|
loading: false,
|
||||||
|
error: null,
|
||||||
|
// 搜索的value
|
||||||
|
searchValue: '',
|
||||||
|
// 是否展示综合筛选弹窗
|
||||||
|
isShowFilterPopup: false,
|
||||||
|
// 综合筛选项
|
||||||
|
searchOption: defaultSearchOptions,
|
||||||
|
// 综合筛选 选择的筛选数量
|
||||||
|
filterCount: 0,
|
||||||
|
// 距离筛选
|
||||||
|
distance: defaultDistance,
|
||||||
|
// 快捷筛选
|
||||||
|
quickFilter: 1, // 1: 默认 2: 好评 3: 销量
|
||||||
|
// 距离筛选数据
|
||||||
|
distanceData: [
|
||||||
|
{ id: 0, label: "全城", value: "全城" },
|
||||||
|
{ id: 1, label: "3km", value: "3km" },
|
||||||
|
{ id: 2, label: "5km", value: "5km" },
|
||||||
|
{ id: 3, label: "10km", value: "10km" },
|
||||||
|
],
|
||||||
|
// 快捷筛选数据
|
||||||
|
quickFilterData: [
|
||||||
|
{ text: "默认排序", value: "0" },
|
||||||
|
{ text: "好评排序", value: "1" },
|
||||||
|
{ text: "销量排序", value: "2" },
|
||||||
|
],
|
||||||
|
// 距离筛选和快捷筛选
|
||||||
|
distanceQuickFilter: {
|
||||||
|
distance: '全城',
|
||||||
|
quick: '0',
|
||||||
|
},
|
||||||
|
// 时间气泡数据
|
||||||
|
timeBubbleData: [
|
||||||
|
{ id: 1, label: "晨间 6:00-10:00", value: "1" },
|
||||||
|
{ id: 2, label: "上午 10:00-12:00", value: "2" },
|
||||||
|
{ id: 3, label: "中午 12:00-14:00", value: "3" },
|
||||||
|
{ id: 4, label: "下午 14:00-18:00", value: "4" },
|
||||||
|
{ id: 5, label: "晚上 18:00-22:00", value: "5" },
|
||||||
|
{ id: 6, label: "夜间 22:00-24:00", value: "6" },
|
||||||
|
],
|
||||||
|
// 场地类型数据
|
||||||
|
locationOptions: [
|
||||||
|
{ id: 1, label: "室内", value: "1" },
|
||||||
|
{ id: 2, label: "室外", value: "2" },
|
||||||
|
{ id: 3, label: "半室外", value: "3" },
|
||||||
|
],
|
||||||
|
// 玩法数据
|
||||||
|
gamePlayOptions: [
|
||||||
|
{ id: 1, label: "不限", value: "不限" },
|
||||||
|
{ id: 2, label: "单打", value: "单打" },
|
||||||
|
{ id: 3, label: "双打", value: "双打" },
|
||||||
|
{ id: 4, label: "娱乐", value: "娱乐" },
|
||||||
|
{ id: 5, label: "拉球", value: "拉球" },
|
||||||
|
],
|
||||||
|
// 球局数量
|
||||||
|
gamesNum: 124,
|
||||||
|
// 页面滚动距离顶部距离 是否大于0
|
||||||
|
isScrollTop: false,
|
||||||
|
// 搜索历史数据
|
||||||
|
searchHistory: ['上海', '黄浦', '上海', '静安', '徐汇', '黄浦', '普陀', '黄浦', '长宁', '黄浦'],
|
||||||
|
// 搜索历史数据默认 Top 15
|
||||||
|
searchHistoryParams: {
|
||||||
|
page: 1,
|
||||||
|
pageSize: 15,
|
||||||
|
},
|
||||||
|
// 联想词
|
||||||
|
suggestionList: [],
|
||||||
|
// 是否显示联想词
|
||||||
|
isShowSuggestion: false,
|
||||||
|
// 列表页是否显示搜索框自定义导航
|
||||||
|
isShowInputCustomerNavBar: false,
|
||||||
|
// 结果页是否显示搜索框自定义导航
|
||||||
|
isShowResultInputCustomerNavBar: false,
|
||||||
|
// 打开距离筛选框
|
||||||
|
isOpenDistancePopup: false,
|
||||||
|
// 打开快捷筛选框
|
||||||
|
isOpenQuickFilterPopup: false,
|
||||||
|
|
||||||
|
// 分页
|
||||||
|
pageOption: {
|
||||||
|
page: 1,
|
||||||
|
pageSize: 10,
|
||||||
|
},
|
||||||
|
|
||||||
|
// 获取比赛数据
|
||||||
|
fetchMatches: async (params) => {
|
||||||
|
set({ loading: true, error: null })
|
||||||
|
|
||||||
|
try {
|
||||||
|
const resData = await getTennisMatches(params) || {};
|
||||||
|
const { data = {}, code } = resData;
|
||||||
|
if (code !== 0) {
|
||||||
|
set({
|
||||||
|
error: '1',
|
||||||
|
matches: [],
|
||||||
|
loading: false,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
const { count, rows } = data;
|
||||||
|
const list = (rows || []).map(() => {
|
||||||
|
return {
|
||||||
|
id: "3",
|
||||||
|
title: "黄浦区双打约球",
|
||||||
|
dateTime: "7月20日(周日)下午6点 2小时",
|
||||||
|
location: "仁恒河滨花园网球场",
|
||||||
|
distance: "3.5km",
|
||||||
|
registeredCount: 3,
|
||||||
|
maxCount: 4,
|
||||||
|
skillLevel: "2.0 至 2.5",
|
||||||
|
matchType: "双打",
|
||||||
|
images: [
|
||||||
|
"https://images.unsplash.com/photo-1554068865-24cecd4e34b8?w=200&h=200&fit=crop&crop=center",
|
||||||
|
],
|
||||||
|
}
|
||||||
|
})
|
||||||
|
set({
|
||||||
|
matches: list || rows || [],
|
||||||
|
recommendList: list || rows || [],
|
||||||
|
error: null,
|
||||||
|
loading: false,
|
||||||
|
gamesNum: count,
|
||||||
|
})
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
set({
|
||||||
|
error,
|
||||||
|
matches: [],
|
||||||
|
loading: false,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
// 刷新比赛数据
|
||||||
|
refreshMatches: async () => {
|
||||||
|
set({ loading: true, error: null })
|
||||||
|
|
||||||
|
try {
|
||||||
|
const resData = await getTennisMatches() || {};
|
||||||
|
const { data = {}, code } = resData;
|
||||||
|
const { count, rows } = data;
|
||||||
|
set({
|
||||||
|
matches: rows,
|
||||||
|
loading: false,
|
||||||
|
})
|
||||||
|
} catch (error) {
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
// 获取历史搜索数据
|
||||||
|
getSearchHistory: async () => {
|
||||||
|
try {
|
||||||
|
const params = get()?.searchHistoryParams || {}
|
||||||
|
const resData = await getSearchHistory(params) || {};
|
||||||
|
console.log('===resData', resData)
|
||||||
|
} catch (error) {
|
||||||
|
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
// 清空历史记录
|
||||||
|
clearHistory: async () => {
|
||||||
|
try {
|
||||||
|
const resData = await clearHistory() || {};
|
||||||
|
} catch (error) {
|
||||||
|
|
||||||
|
}
|
||||||
|
set({
|
||||||
|
searchHistory: [],
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
// 获取联想
|
||||||
|
searchSuggestion: async (val: string) => {
|
||||||
|
try {
|
||||||
|
const resData = await searchSuggestion({ val }) || {};
|
||||||
|
console.log('===获取联想', resData)
|
||||||
|
// set({
|
||||||
|
// suggestionList: ['上海球局', '黄浦球局', '上海球局', '静安球局', '徐汇球局', '黄浦球局', '普陀球局', '黄浦球局', '长宁球局', '黄浦球局'],
|
||||||
|
// isShowSuggestion: true,
|
||||||
|
// })
|
||||||
|
} catch (error) {
|
||||||
|
set({
|
||||||
|
suggestionList: ['上海球局', '黄浦球局', '上海球局', '静安球局', '徐汇球局', '黄浦球局', '普陀球局', '黄浦球局', '长宁球局', '黄浦球局'],
|
||||||
|
isShowSuggestion: true,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
// 清除错误信息
|
||||||
|
clearError: () => {
|
||||||
|
set({ error: null })
|
||||||
|
},
|
||||||
|
|
||||||
|
// 更新综合筛选项
|
||||||
|
updateSearchOptions: (payload: Record<string, any>) => {
|
||||||
|
console.log('===更新综合筛选项', payload)
|
||||||
|
const preSearchOptions = get()?.searchOption || {}
|
||||||
|
const searchOption = { ...preSearchOptions, ...payload }
|
||||||
|
const filterCount = Object.values(searchOption).filter(Boolean).length
|
||||||
|
set({
|
||||||
|
searchOption,
|
||||||
|
filterCount
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
// 清空综合筛选选项
|
||||||
|
clearSearchOptions: () => {
|
||||||
|
set({
|
||||||
|
searchOption: defaultSearchOptions,
|
||||||
|
filterCount: 0
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
// 更新store数据
|
||||||
|
updateState: (payload: Record<string, any>) => {
|
||||||
|
const state = get();
|
||||||
|
console.log('Store: 更新数据:', state);
|
||||||
|
set({
|
||||||
|
...(payload || {})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}))
|
||||||
|
|
||||||
|
// 导出便捷的 hooks
|
||||||
|
export const useSearchResultState = () => useSearchResultStore((state) => state)
|
||||||
@@ -13,15 +13,19 @@ export interface TennisMatch {
|
|||||||
shinei: string
|
shinei: string
|
||||||
}
|
}
|
||||||
export interface IFilterOptions {
|
export interface IFilterOptions {
|
||||||
location: string
|
dateRange: [], // 日期区间
|
||||||
time: string
|
timeSlot?: string, // 时间段
|
||||||
ntrp: [number, number]
|
ntrp?: [number, number], // NTRP 水平区间
|
||||||
court_type: string
|
venueType?: string, // 场地类型
|
||||||
game_play: string
|
playType?: string, // 玩法
|
||||||
}
|
}
|
||||||
export interface ListState {
|
export interface ListState {
|
||||||
matches: TennisMatch[]
|
matches: TennisMatch[]
|
||||||
recommendList: TennisMatch[]
|
recommendList: TennisMatch[]
|
||||||
|
location: {
|
||||||
|
latitude: number
|
||||||
|
longitude: number
|
||||||
|
}
|
||||||
loading: boolean
|
loading: boolean
|
||||||
error: string | null
|
error: string | null
|
||||||
searchValue: string
|
searchValue: string
|
||||||
@@ -49,6 +53,10 @@ export interface ListState {
|
|||||||
isShowResultInputCustomerNavBar: boolean
|
isShowResultInputCustomerNavBar: boolean
|
||||||
isOpenDistancePopup: boolean,
|
isOpenDistancePopup: boolean,
|
||||||
isOpenQuickFilterPopup: boolean,
|
isOpenQuickFilterPopup: boolean,
|
||||||
|
pageOption: {
|
||||||
|
page: number
|
||||||
|
pageSize: number
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ListActions {
|
export interface ListActions {
|
||||||
@@ -58,7 +66,7 @@ export interface ListActions {
|
|||||||
location?: string
|
location?: string
|
||||||
skillLevel?: string
|
skillLevel?: string
|
||||||
}) => Promise<void>
|
}) => Promise<void>
|
||||||
refreshMatches: () => Promise<void>
|
// refreshMatches: () => Promise<void>
|
||||||
clearError: () => void
|
clearError: () => void
|
||||||
updateState: (payload: Record<string, any>) => void
|
updateState: (payload: Record<string, any>) => void
|
||||||
updateFilterOptions: (payload: Record<string, any>) => void
|
updateFilterOptions: (payload: Record<string, any>) => void
|
||||||
@@ -66,6 +74,7 @@ export interface ListActions {
|
|||||||
getSearchHistory: () => Promise<void>
|
getSearchHistory: () => Promise<void>
|
||||||
clearHistory: () => void
|
clearHistory: () => void
|
||||||
searchSuggestion: (val: string) => Promise<void>
|
searchSuggestion: (val: string) => Promise<void>
|
||||||
|
getSearchParams: () => Record<string, any>
|
||||||
}
|
}
|
||||||
|
|
||||||
// 快捷筛选
|
// 快捷筛选
|
||||||
@@ -94,7 +103,7 @@ export interface DistanceFilterProps {
|
|||||||
|
|
||||||
// bubble 组件
|
// bubble 组件
|
||||||
export interface BubbleOption {
|
export interface BubbleOption {
|
||||||
id: string | number;
|
id?: string | number;
|
||||||
label: string;
|
label: string;
|
||||||
value: string | number;
|
value: string | number;
|
||||||
disabled?: boolean;
|
disabled?: boolean;
|
||||||
|
|||||||
Reference in New Issue
Block a user