This commit is contained in:
juguohong
2025-08-30 18:20:50 +08:00
parent 1cb303b86d
commit d92419f3c5
23 changed files with 456 additions and 266 deletions

View File

@@ -12,6 +12,8 @@ import { FilterPopupProps } from "../../../types/list/types";
import CourtType from "@/components/CourtType";
// 玩法
import GamePlayType from "@/components/GamePlayType";
import { useDictionaryActions } from "@/store/dictionaryStore";
import { useMemo } from "react";
const FilterPopup = (props: FilterPopupProps) => {
const {
@@ -27,7 +29,22 @@ const FilterPopup = (props: FilterPopupProps) => {
} = props;
const store = useListStore() || {};
const { timeBubbleData, locationOptions, gamePlayOptions } = store;
const { getDictionaryValue } = useDictionaryActions() || {};
const { timeBubbleData } = store;
const handleOptions = (dictionaryValue: []) => {
return dictionaryValue?.map((item) => ({ label: item, value: item })) || [];
};
const courtType = getDictionaryValue("court_type") || [];
const locationOptions = useMemo(() => {
return courtType ? handleOptions(courtType) : [];
}, [courtType]);
const gamePlay = getDictionaryValue("game_play") || [];
const gamePlayOptions = useMemo(() => {
return gamePlay ? handleOptions(gamePlay) : [];
}, [gamePlay]);
const handleFilterChange = (name, value) => {
onChange({ [name]: value });

View File

@@ -3,20 +3,23 @@
.listTopSearchWrapper {
padding: 0 15px;
position: sticky;
background: #fefefe;
z-index: 999;
}
.isScroll {
border-bottom: 0.5px solid #0000000F;
}
.listTopFilterWrapper {
display: flex;
align-items: center;
margin-top: 5px;
margin-bottom: 10px;
padding-top: 10px;
padding-bottom: 10px;
gap: 5px;
}
.listContentWrapper {
padding: 0 5px;
}
.menuFilter {
padding: 0;
}

View File

@@ -1,29 +1,22 @@
import ListCard from "../../components/ListCard";
import ListCardSkeleton from "../../components/ListCardSkeleton";
import List from "../../components/List";
import Menu from "../../components/Menu";
import CityFilter from "../../components/CityFilter";
import SearchBar from "../../components/SearchBar";
import FilterPopup from "./FilterPopup";
import styles from "./index.module.scss";
import { useEffect } from "react";
import Taro, { useReachBottom } from "@tarojs/taro";
import Taro, { usePageScroll, useReachBottom } from "@tarojs/taro";
import { useListStore } from "@/store/listStore";
import {useGlobalState} from '@/store/global'
import { useGlobalState } from "@/store/global";
import { View } from "@tarojs/components";
import CustomerNavBar from "@/components/CustomNavbar";
import GuideBar from "@/components/GuideBar";
import { useDictionaryActions } from "@/store/dictionaryStore";
import ListContainer from "@/container/listContainer";
const ListPage = () => {
// 从 store 获取数据和方法
const store = useListStore() || {};
const { statusNavbarHeightInfo } = useGlobalState() || {}
const { getDictionaryValue } = useDictionaryActions() || {};
console.log('===getDictionaryValue', getDictionaryValue('court_type'));
// locationOptions 室内
// game_play 玩法
const { statusNavbarHeightInfo } = useGlobalState() || {};
const {
isShowFilterPopup,
error,
@@ -31,7 +24,6 @@ const ListPage = () => {
loading,
fetchMatches,
refreshMatches,
clearError,
updateState,
filterCount,
updateFilterOptions, // 更新筛选条件
@@ -40,8 +32,15 @@ const ListPage = () => {
distanceData,
quickFilterData,
distanceQuickFilter,
isScrollTop,
} = store;
usePageScroll((res) => {
if (res?.scrollTop > 0 && !isScrollTop) {
updateState({ isScrollTop: true });
}
});
useReachBottom(() => {
console.log("触底了");
// 调用 store 的加载更多方法
@@ -82,78 +81,6 @@ const ListPage = () => {
});
});
// 错误处理
useEffect(() => {
if (error) {
Taro.showToast({
title: error,
icon: "error",
duration: 2000,
});
// 3秒后自动清除错误
setTimeout(() => {
clearError();
}, 3000);
}
}, [error, clearError]);
// 加载状态显示
if (loading && matches.length === 0) {
return (
<div
style={{
display: "flex",
flexDirection: "column",
justifyContent: "center",
alignItems: "center",
height: "200px",
fontSize: "14px",
color: "#999",
}}
>
<div style={{ marginBottom: "10px" }}>...</div>
<div style={{ fontSize: "12px", color: "#ccc" }}>
</div>
</div>
);
}
// 错误状态显示
if (error && matches.length === 0) {
return (
<div
style={{
display: "flex",
flexDirection: "column",
justifyContent: "center",
alignItems: "center",
height: "200px",
fontSize: "14px",
color: "#999",
}}
>
<div style={{ marginBottom: "10px" }}></div>
<div style={{ marginBottom: "15px", fontSize: "12px", color: "#ccc" }}>
{error}
</div>
<button
onClick={() => fetchMatches()}
style={{
padding: "8px 16px",
fontSize: "12px",
color: "#fff",
backgroundColor: "#007aff",
border: "none",
borderRadius: "4px",
}}
>
</button>
</div>
);
}
const toggleShowPopup = () => {
updateState({ isShowFilterPopup: !isShowFilterPopup });
};
@@ -183,7 +110,14 @@ const ListPage = () => {
<CustomerNavBar />
<View className={styles.listPage}>
<View className={styles.listTopSearchWrapper}>
<View
className={`${styles.listTopSearchWrapper} ${
isScrollTop ? styles.isScroll : ""
}`}
style={{
top: statusNavbarHeightInfo?.totalHeight,
}}
>
<SearchBar
handleFilterIcon={toggleShowPopup}
isSelect={filterCount > 0}
@@ -227,26 +161,16 @@ const ListPage = () => {
</div>
</View>
<View className={styles.listContentWrapper}>
{/* 列表内容 */}
<List>
{!loading &&
matches.length > 0 &&
matches.map((match, index) => (
<ListCard key={match.id || index} {...match} />
))}
</List>
{/* 空状态 */}
{loading &&
matches.length === 0 &&
new Array(10).fill(0).map(() => {
return <ListCardSkeleton />;
})}
</View>
<ListContainer
data={matches}
loading={loading}
error={error}
reload={refreshMatches}
/>
</View>
<GuideBar currentPage='list' />
<GuideBar currentPage="list" />
</>
);
};