import SearchBar from "@/components/SearchBar"; import FilterPopup from "@/components/FilterPopup"; import styles from "./index.module.scss"; import { useEffect, useRef, useCallback } from "react"; import Taro, { usePageScroll } from "@tarojs/taro"; import { useListStore } from "@/store/listStore"; import { useGlobalState } from "@/store/global"; import { View } from "@tarojs/components"; import CustomerNavBar from "@/container/listCustomNavbar"; import GuideBar from "@/components/GuideBar"; import ListContainer from "@/container/listContainer"; import DistanceQuickFilter from "@/components/DistanceQuickFilter"; import { withAuth } from "@/components"; import { updateUserLocation } from "@/services/userService"; import { useDictionaryStore } from "@/store/dictionaryStore"; const ListPage = () => { // 从 store 获取数据和方法 const store = useListStore() || {}; const { statusNavbarHeightInfo, getCurrentLocationInfo } = useGlobalState() || {}; const { totalHeight } = statusNavbarHeightInfo || {}; const { listPageState, loading, error, searchValue, distanceData, quickFilterData, getMatchesData, updateState, updateListPageState, updateFilterOptions, // 更新筛选条件 clearFilterOptions, initialFilterSearch, loadMoreMatches, fetchGetGamesCount, updateDistanceQuickFilter, } = store; const { isShowFilterPopup, data: matches, recommendList, filterCount, filterOptions, distanceQuickFilter, isShowInputCustomerNavBar, pageOption } = listPageState || {}; // 防抖的滚动处理函数 const handleScroll = useCallback((res) => { const currentScrollTop = res?.scrollTop || 0; // 添加缓冲区,避免临界点频繁切换 const buffer = 10; // 10px 缓冲区 const shouldShowInputNav = currentScrollTop >= (totalHeight + buffer); const shouldHideInputNav = currentScrollTop < (totalHeight - buffer); // 清除之前的定时器 if (scrollTimeoutRef.current) { clearTimeout(scrollTimeoutRef.current); } // 防抖处理,避免频繁更新状态 scrollTimeoutRef.current = setTimeout(() => { // 只有在状态真正需要改变时才更新 if (shouldShowInputNav && !isShowInputCustomerNavBar) { updateListPageState({ isShowInputCustomerNavBar: true }); } else if (shouldHideInputNav && isShowInputCustomerNavBar) { updateListPageState({ isShowInputCustomerNavBar: false }); } lastScrollTopRef.current = currentScrollTop; }, 16); // 约60fps的防抖间隔 }, [totalHeight, isShowInputCustomerNavBar, updateState]); usePageScroll(handleScroll); const scrollContextRef = useRef(null) const scrollTimeoutRef = useRef(null) const lastScrollTopRef = useRef(0) useEffect(() => { getLocation() }, []); // 监听数据变化,如果是第一页就滚动到顶部 useEffect(() => { if (pageOption?.page === 1 && matches?.length > 0) { Taro.pageScrollTo({ scrollTop: 0, duration: 300 }); } }, [matches, pageOption?.page]); // 清理定时器 useEffect(() => { return () => { if (scrollTimeoutRef.current) { clearTimeout(scrollTimeoutRef.current); } }; }, []); // 监听距离和排序方式变化,自动调用接口 // useEffect(() => { // // 只有当 distanceQuickFilter 有值时才调用接口 // if (distanceQuickFilter?.distanceFilter !== undefined || distanceQuickFilter?.order !== undefined) { // // if (distanceQuickFilter?.quick !== "0") { // getMatchesData(); // // } // } // }, [distanceQuickFilter?.distanceFilter, distanceQuickFilter?.order]); // 获取位置信息 const getLocation = async () => { const location = await getCurrentLocationInfo() // 保存位置到全局状态 updateState({ location }); // 同时更新用户位置到后端和 store if (location && location.latitude && location.longitude) { try { await updateUserLocation(location.latitude, location.longitude); } catch (error) { console.error('更新用户位置失败:', error); } } fetchGetGamesCount(); // 页面加载时获取数据 getMatchesData(); return location; } const refreshMatches = () => { initialFilterSearch(true); }; // const getLoadMoreMatches = () => { // loadMoreMatches() // } // 下拉刷新处理函数 - 使用Taro生命周期钩子 Taro.usePullDownRefresh(async () => { try { // 调用刷新方法 await refreshMatches(); // 刷新完成后停止下拉刷新动画 Taro.stopPullDownRefresh(); // 显示刷新成功提示 Taro.showToast({ title: "刷新成功", icon: "success", duration: 1000, }); } catch (error) { // 刷新失败时也停止动画 Taro.stopPullDownRefresh(); Taro.showToast({ title: "刷新失败,请重试", icon: "error", duration: 1000, }); } }); /** * @description 综合筛选确认 * @returns */ const handleFilterConfirm = () => { toggleShowPopup(); getMatchesData(); } /** * @description 综合筛选弹框 * @returns */ const toggleShowPopup = () => { updateListPageState({ isShowFilterPopup: !isShowFilterPopup }); }; /** * @description 更新筛选条件 * @param {Record} params 筛选项 */ const handleUpdateFilterOptions = (params: Record) => { updateFilterOptions(params); }; const handleSearchChange = () => { }; // 距离筛选 const handleDistanceOrQuickChange = (name, value) => { updateDistanceQuickFilter({ [name]: value, }); // updateListPageState({ // distanceQuickFilter: { // ...distanceQuickFilter, // [name]: value, // }, // }); }; const handleSearchClick = () => { Taro.navigateTo({ url: "/game_pages/search/index", }); }; // 初始化字典数据 const initDictionaryData = async () => { try { const { fetchDictionary } = useDictionaryStore.getState(); await fetchDictionary(); } catch (error) { console.error("初始化字典数据失败:", error); } } useEffect(() => { initDictionaryData() }, []); return ( <> {/* 自定义导航 */} {/* */} {/* 列表内容 */} {/* 综合筛选 */} {isShowFilterPopup && ( )} 0} filterCount={filterCount} onChange={handleSearchChange} value={searchValue} onInputClick={handleSearchClick} /> {/* 筛选 */} {/* 列表内容 */} ); }; export default withAuth(ListPage);