From 2d0d7289695339903d9e00645a450af9cc6ea4de Mon Sep 17 00:00:00 2001 From: juguohong Date: Sat, 6 Sep 2025 22:08:34 +0800 Subject: [PATCH] =?UTF-8?q?=E5=88=97=E8=A1=A8=E6=90=9C=E7=B4=A2=E9=A1=B5?= =?UTF-8?q?=E9=9D=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/Bubble/index.tsx | 1 - src/components/DistanceQuickFilter/index.tsx | 3 +- .../FilterPopup/index.module.scss} | 0 .../FilterPopup/index.tsx} | 17 +- src/components/ListCard/index.tsx | 28 +- src/components/SearchBar/index.tsx | 1 + src/container/listContainer/index.scss | 15 +- src/container/listContainer/index.tsx | 9 + src/pages/list/index.tsx | 23 +- src/pages/searchResult/index.scss | 51 +++- src/pages/searchResult/index.tsx | 79 ++++-- src/services/listApi.ts | 30 +-- src/store/listStore.ts | 111 ++++---- src/store/searchResultStore.ts | 255 ++++++++++++++++++ types/list/types.ts | 23 +- 15 files changed, 518 insertions(+), 128 deletions(-) rename src/{pages/list/filterPopup.module.scss => components/FilterPopup/index.module.scss} (100%) rename src/{pages/list/FilterPopup.tsx => components/FilterPopup/index.tsx} (89%) create mode 100644 src/store/searchResultStore.ts diff --git a/src/components/Bubble/index.tsx b/src/components/Bubble/index.tsx index 30dee30..c7c902f 100644 --- a/src/components/Bubble/index.tsx +++ b/src/components/Bubble/index.tsx @@ -52,7 +52,6 @@ const Bubble: React.FC = ({ ); onChange(name, newSelectedValues, selectedOptions); } else { - console.log('===111', name, option.value) onChange(name, option.value, option); } } diff --git a/src/components/DistanceQuickFilter/index.tsx b/src/components/DistanceQuickFilter/index.tsx index 5d82195..0bfc283 100644 --- a/src/components/DistanceQuickFilter/index.tsx +++ b/src/components/DistanceQuickFilter/index.tsx @@ -19,11 +19,12 @@ const Demo3 = (props) => { const itemRef = useRef(null); const handleChange = (name: string, value: string) => { - // setIsChange(true); onChange && onChange(name, value); (itemRef.current as any)?.toggle(false); }; + // const cityTitle = cityOptions.find((item) => item.value === cityValue)?.label; + return ( { }; const courtType = getDictionaryValue("court_type") || []; - const locationOptions = useMemo(() => { + const locationOptions: BubbleOption[] = useMemo(() => { return courtType ? handleOptions(courtType) : []; }, [courtType]); @@ -108,16 +105,16 @@ const FilterPopup = (props: FilterPopupProps) => { {/* CourtType */} {/* 玩法 */} {/* 按钮 */}
diff --git a/src/components/ListCard/index.tsx b/src/components/ListCard/index.tsx index 3fb3538..b7e3c7b 100644 --- a/src/components/ListCard/index.tsx +++ b/src/components/ListCard/index.tsx @@ -8,14 +8,14 @@ const ListCard: React.FC = ({ id, title, dateTime, - location, - distance, + venue_description, + distance_km, registeredCount, maxCount, skillLevel, - matchType, + play_type, images = [], - shinei, + court_type, }) => { const renderItemImage = (src: string) => { return ; @@ -64,17 +64,16 @@ const ListCard: React.FC = ({ {/* 左侧内容区域 */} {/* 标题 */} - + {title && {title} - + } {/* 时间信息 */} - {dateTime} @@ -82,10 +81,11 @@ const ListCard: React.FC = ({ {/* 地点,室内外,距离 */} - {location} + {venue_description && + {venue_description}} - {shinei && `・${shinei}`} - {distance && `・${distance}`} + {court_type && `・${court_type}`} + {distance_km && `・${distance_km}`} @@ -115,11 +115,11 @@ const ListCard: React.FC = ({ - {skillLevel} - - - {matchType} + {skill_level_max} zh {skill_level_max} + {play_type && + {play_type} + } diff --git a/src/components/SearchBar/index.tsx b/src/components/SearchBar/index.tsx index f0aa118..d8b74d5 100644 --- a/src/components/SearchBar/index.tsx +++ b/src/components/SearchBar/index.tsx @@ -21,6 +21,7 @@ const SearchBarComponent = (props: IProps) => { return ( <> diff --git a/src/container/listContainer/index.scss b/src/container/listContainer/index.scss index d466de1..7d2ded3 100644 --- a/src/container/listContainer/index.scss +++ b/src/container/listContainer/index.scss @@ -4,7 +4,7 @@ display: flex; flex-direction: column; gap: 5px; - // background-color: red; + padding-bottom: 34px; .recommendTextWrapper { display: flex; @@ -19,4 +19,17 @@ font-weight: 500; 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; + } } \ No newline at end of file diff --git a/src/container/listContainer/index.tsx b/src/container/listContainer/index.tsx index 6543a98..bd97347 100644 --- a/src/container/listContainer/index.tsx +++ b/src/container/listContainer/index.tsx @@ -3,10 +3,17 @@ import ListCard from "@/components/ListCard"; import ListLoadError from "@/components/ListLoadError"; import ListCardSkeleton from "@/components/ListCardSkeleton"; import "./index.scss"; +import { useReachBottom } from "@tarojs/taro"; const ListContainer = (props) => { const { loading, data = [], error, reload, recommendList } = props; + useReachBottom(() => { + console.log("触底了"); + // 调用 store 的加载更多方法 + // loadMoreMatches(); + }); + if (error) { return ; } @@ -38,6 +45,8 @@ const ListContainer = (props) => { 搜索结果较少,已为你推荐其他内容 {renderList(recommendList)} + {/* 到底了 */} + 到底了 ); }; diff --git a/src/pages/list/index.tsx b/src/pages/list/index.tsx index b76c3f0..bb4a6fd 100644 --- a/src/pages/list/index.tsx +++ b/src/pages/list/index.tsx @@ -1,10 +1,8 @@ -import Menu from "../../components/Menu"; -import CityFilter from "../../components/CityFilter"; import SearchBar from "../../components/SearchBar"; -import FilterPopup from "./FilterPopup"; +import FilterPopup from "@/components/FilterPopup"; import styles from "./index.module.scss"; import { useEffect } from "react"; -import Taro, { usePageScroll, useReachBottom } from "@tarojs/taro"; +import Taro, { usePageScroll } from "@tarojs/taro"; import { useListStore } from "@/store/listStore"; import { useGlobalState } from "@/store/global"; import { View } from "@tarojs/components"; @@ -19,7 +17,7 @@ const ListPage = () => { // 从 store 获取数据和方法 const store = useListStore() || {}; - const { statusNavbarHeightInfo } = useGlobalState() || {}; + const { statusNavbarHeightInfo, location } = useGlobalState() || {}; const { totalHeight } = statusNavbarHeightInfo || {}; const { isShowFilterPopup, @@ -43,25 +41,18 @@ const ListPage = () => { } = store; usePageScroll((res) => { - // if (res?.scrollTop > 0 && !isScrollTop) { - // updateState({ isScrollTop: true }); - // } if (res?.scrollTop >= totalHeight && !isScrollTop) { - updateState({ isShowInputCustomerNavBar: true }); + !isShowInputCustomerNavBar && updateState({ isShowInputCustomerNavBar: true }); } else { - updateState({ isShowInputCustomerNavBar: false }); + isShowInputCustomerNavBar && updateState({ isShowInputCustomerNavBar: false }); } }); - useReachBottom(() => { - console.log("触底了"); - // 调用 store 的加载更多方法 - // loadMoreMatches(); - }); - useEffect(() => { // 页面加载时获取数据 fetchMatches(); + // 保存位置 + updateState({ location }); }, []); // 下拉刷新处理函数 - 使用Taro生命周期钩子 diff --git a/src/pages/searchResult/index.scss b/src/pages/searchResult/index.scss index 8812cee..8f599dd 100644 --- a/src/pages/searchResult/index.scss +++ b/src/pages/searchResult/index.scss @@ -5,11 +5,60 @@ display: flex; align-items: center; gap: 5px; - padding: 5px 0px 10px 0px; + padding: 5px 15px 10px 15px; position: sticky; top: -1px; background-color: #fefefe; 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 { diff --git a/src/pages/searchResult/index.tsx b/src/pages/searchResult/index.tsx index cc47c16..7ddcfb6 100644 --- a/src/pages/searchResult/index.tsx +++ b/src/pages/searchResult/index.tsx @@ -1,34 +1,53 @@ -import { View } from "@tarojs/components"; -import { useListState } from "@/store/listStore"; +import { View, Image, Text } from "@tarojs/components"; +import { useSearchResultState } from "@/store/searchResultStore"; import { useGlobalState } from "@/store/global"; import ListContainer from "@/container/listContainer"; +import img from "@/config/images"; import "./index.scss"; import DistanceQuickFilter from "@/components/DistanceQuickFilter"; import { useEffect } from "react"; +import FilterPopup from "@/components/FilterPopup"; const SearchResult = () => { const { - distanceData, - quickFilterData, + isShowFilterPopup, + error, distanceQuickFilter, - updateState, matches, recommendList, loading, - error, - refreshMatches, fetchMatches, - } = useListState() || {}; - + refreshMatches, + updateState, + filterCount, + updateFilterOptions, // 更新筛选条件 + filterOptions, + clearFilterOptions, + distanceData, + quickFilterData, + } = useSearchResultState() || {}; const { statusNavbarHeightInfo } = useGlobalState() || {}; - const { totalHeight } = statusNavbarHeightInfo || {} + const { totalHeight } = statusNavbarHeightInfo || {}; + const isSelect = filterCount > 0; useEffect(() => { // 页面加载时获取数据 fetchMatches(); }, []); + /** + * @description 更新筛选条件 + * @param {Record} params 筛选项 + */ + const handleUpdateFilterOptions = (params: Record) => { + updateFilterOptions(params); + }; + + const toggleShowPopup = () => { + updateState({ isShowFilterPopup: !isShowFilterPopup }); + }; + // 距离筛选 const handleDistanceOrQuickChange = (name, value) => { updateState({ @@ -42,10 +61,15 @@ const SearchResult = () => { return ( {/* 筛选 */} - - + { cityValue={distanceQuickFilter?.distance} quickValue={distanceQuickFilter?.quick} /> + {/* 筛选 icon */} + + + {isSelect && {filterCount}} + + {/* 筛选弹框 */} + {/* 综合筛选 */} + {isShowFilterPopup && ( + + + + )} {/* 列表内容 */} @@ -68,4 +117,4 @@ const SearchResult = () => { ); }; -export default SearchResult; \ No newline at end of file +export default SearchResult; diff --git a/src/services/listApi.ts b/src/services/listApi.ts index 414efbb..3cc89d0 100644 --- a/src/services/listApi.ts +++ b/src/services/listApi.ts @@ -12,39 +12,39 @@ interface ApiResponse { } /** - * 获取网球比赛列表 + * 获取列表 * @param params 查询参数 * @returns Promise */ -export const getTennisMatches = async (params?: { +export const getGamesList = async (params?: { page?: number; pageSize?: number; location?: string; skillLevel?: string; }) => { try { - return httpService.post('/venues/list', params, { showLoading: false }) + return httpService.post('/games/list', params, { showLoading: false }) } catch (error) { console.error("列表数据获取失败:", error); throw error; } }; -/** - * 刷新网球比赛数据 - * @returns Promise - */ -export const refreshTennisMatches = async (params) => { +export const getGamesIntegrateList = async (params?: { + page?: number; + pageSize?: number; + location?: string; + skillLevel?: string; +}) => { try { - // 生成新的动态数据 - const matches = generateDynamicData(params); - return matches; + return httpService.post('/games/integrate_list', params, { showLoading: false }) } catch (error) { - console.error("API刷新失败:", error); + console.error("列表数据获取失败:", error); throw error; } }; + /** * 获取搜索历史记录的异步函数 * @param {Object} params - 查询参数对象 @@ -69,8 +69,8 @@ export const getSearchHistory = async (params) => { export const clearHistory = async () => { try { // 调用HTTP服务清除搜索历史记录 - return httpService.post('/games/clear_history') - } catch (error) { + return httpService.post('/search_history/delete_all') + } catch (error) { // 捕获并打印错误信息 console.error("清除历史记录失败:", error); // 抛出错误以便上层处理 @@ -86,7 +86,7 @@ export const clearHistory = async () => { export const searchSuggestion = async (params) => { try { // 调用HTTP服务获取搜索建议 - return httpService.get('/games/search_suggestion', params) + return httpService.get('/games/search_recommendations', params) } catch (error) { // 捕获并打印错误信息 console.error("搜索建议获取失败:", error); diff --git a/src/store/listStore.ts b/src/store/listStore.ts index bf7b901..d5b354c 100644 --- a/src/store/listStore.ts +++ b/src/store/listStore.ts @@ -1,16 +1,16 @@ 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' // 完整的 Store 类型 type TennisStore = ListState & ListActions const defaultFilterOptions: IFilterOptions = { - location: '', // 位置 - time: '', // 时间 - ntrp: [1.0, 5.0], // NTRP 水平区间 - court_type: '', // 场地类型 - game_play: '', // 玩法 + dateRange: [], // 日期区间 + timeSlot: '', // 时间段 + ntrp: [1, 5], // NTRP 水平区间 + venueType: '', // 场地类型 + playType: '', // 玩法 }; const defaultDistance = 'all'; // 默认距离 @@ -21,6 +21,10 @@ export const useListStore = create()((set, get) => ({ matches: [], // 推荐列表 recommendList: [], + location: { + latitude: 0, + longitude: 0, + }, // 位置 // 是否加载中 loading: false, error: null, @@ -38,10 +42,10 @@ export const useListStore = create()((set, get) => ({ 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" }, + { id: 0, label: "全城", value: "0" }, + { id: 1, label: "3km", value: "3" }, + { id: 2, label: "5km", value: "5" }, + { id: 3, label: "10km", value: "10" }, ], // 快捷筛选数据 quickFilterData: [ @@ -100,13 +104,42 @@ export const useListStore = create()((set, get) => ({ isOpenDistancePopup: 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) => { set({ loading: true, error: null }) 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; if (code !== 0) { set({ @@ -116,25 +149,25 @@ export const useListStore = create()((set, get) => ({ }) } 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", - ], - } - }) + // 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 || [], + matches: rows || [], + recommendList: rows || [], error: null, loading: false, gamesNum: count, @@ -149,22 +182,6 @@ export const useListStore = create()((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 () => { try { @@ -212,10 +229,10 @@ export const useListStore = create()((set, get) => ({ // 更新综合筛选项 updateFilterOptions: (payload: Record) => { - console.log('===更新综合筛选项', payload) const preFilterOptions = get()?.filterOptions || {} const filterOptions = { ...preFilterOptions, ...payload } const filterCount = Object.values(filterOptions).filter(Boolean).length + console.log('===更新综合筛选项', filterOptions, filterCount) set({ filterOptions, filterCount diff --git a/src/store/searchResultStore.ts b/src/store/searchResultStore.ts new file mode 100644 index 0000000..22558a8 --- /dev/null +++ b/src/store/searchResultStore.ts @@ -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()((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) => { + 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) => { + const state = get(); + console.log('Store: 更新数据:', state); + set({ + ...(payload || {}) + }) + } +})) + +// 导出便捷的 hooks +export const useSearchResultState = () => useSearchResultStore((state) => state) diff --git a/types/list/types.ts b/types/list/types.ts index 144697a..be04f78 100644 --- a/types/list/types.ts +++ b/types/list/types.ts @@ -13,15 +13,19 @@ export interface TennisMatch { shinei: string } export interface IFilterOptions { - location: string - time: string - ntrp: [number, number] - court_type: string - game_play: string + dateRange: [], // 日期区间 + timeSlot?: string, // 时间段 + ntrp?: [number, number], // NTRP 水平区间 + venueType?: string, // 场地类型 + playType?: string, // 玩法 } export interface ListState { matches: TennisMatch[] recommendList: TennisMatch[] + location: { + latitude: number + longitude: number + } loading: boolean error: string | null searchValue: string @@ -49,6 +53,10 @@ export interface ListState { isShowResultInputCustomerNavBar: boolean isOpenDistancePopup: boolean, isOpenQuickFilterPopup: boolean, + pageOption: { + page: number + pageSize: number + } } export interface ListActions { @@ -58,7 +66,7 @@ export interface ListActions { location?: string skillLevel?: string }) => Promise - refreshMatches: () => Promise + // refreshMatches: () => Promise clearError: () => void updateState: (payload: Record) => void updateFilterOptions: (payload: Record) => void @@ -66,6 +74,7 @@ export interface ListActions { getSearchHistory: () => Promise clearHistory: () => void searchSuggestion: (val: string) => Promise + getSearchParams: () => Record } // 快捷筛选 @@ -94,7 +103,7 @@ export interface DistanceFilterProps { // bubble 组件 export interface BubbleOption { - id: string | number; + id?: string | number; label: string; value: string | number; disabled?: boolean;