368 lines
9.6 KiB
TypeScript
368 lines
9.6 KiB
TypeScript
import { create } from "zustand";
|
|
import {
|
|
getGamesList,
|
|
getGamesIntegrateList,
|
|
getSearchHistory,
|
|
clearHistory,
|
|
searchSuggestion,
|
|
} from "../services/listApi";
|
|
import {
|
|
ListActions,
|
|
IFilterOptions,
|
|
ListState,
|
|
IPayload,
|
|
} from "../../types/list/types";
|
|
|
|
import dateRangeUtils from '@/utils/dateRange'
|
|
|
|
// 完整的 Store 类型
|
|
type TennisStore = ListState & ListActions;
|
|
|
|
const defaultFilterOptions: IFilterOptions = {
|
|
dateRange: [new Date(), new Date()], // 日期区间
|
|
dateRangeQuick: '',
|
|
timeSlot: "", // 时间段
|
|
ntrp: [1, 5], // NTRP 水平区间
|
|
venueType: "", // 场地类型
|
|
playType: "", // 玩法
|
|
};
|
|
|
|
// const defaultDistance = "all"; // 默认距离
|
|
const defaultDistanceQuickFilter = {
|
|
distance: "",
|
|
quick: "0",
|
|
};
|
|
|
|
const defaultPageOption = {
|
|
page: 1,
|
|
pageSize: 20,
|
|
};
|
|
|
|
// 创建 store
|
|
export const useListStore = create<TennisStore>()((set, get) => ({
|
|
currentPage: "",
|
|
isSearchResult: false,
|
|
searchResultData: [],
|
|
// dateRange: [new Date(), new Date()], // 日期区间
|
|
// 初始状态
|
|
matches: [],
|
|
// 推荐列表
|
|
recommendList: [],
|
|
location: {
|
|
latitude: 0,
|
|
longitude: 0,
|
|
}, // 位置
|
|
// 是否加载中
|
|
loading: true,
|
|
error: null,
|
|
// 搜索的value
|
|
searchValue: "",
|
|
// 是否展示综合筛选弹窗
|
|
isShowFilterPopup: false,
|
|
// 综合筛选项
|
|
filterOptions: defaultFilterOptions,
|
|
// 综合筛选 选择的筛选数量
|
|
filterCount: 0,
|
|
// 距离筛选数据
|
|
distanceData: [
|
|
{ id: 0, label: "全城", value: "" },
|
|
{ id: 1, label: "3km", value: "3" },
|
|
{ id: 2, label: "5km", value: "5" },
|
|
{ id: 3, label: "10km", value: "10" },
|
|
],
|
|
// 快捷筛选数据
|
|
quickFilterData: [
|
|
{ label: "智能排序", value: "0" },
|
|
{ label: "距离更近", value: "1" },
|
|
{ label: "时间更近", value: "2" },
|
|
],
|
|
// 距离筛选和快捷筛选
|
|
distanceQuickFilter: defaultDistanceQuickFilter,
|
|
|
|
// 气泡日期范围
|
|
dateRangeOptions: [
|
|
{ id: 1, label: "本周末", value: "1" },
|
|
{ id: 2, label: "一周内", value: "2" },
|
|
{ id: 3, label: "一月内", value: "3" },
|
|
],
|
|
// 时间气泡数据
|
|
timeBubbleData: [
|
|
{ id: 1, label: "晨间 6:00-10:00", value: "6:00-10:00" },
|
|
{ id: 2, label: "上午 10:00-12:00", value: "10:00-12:00" },
|
|
{ id: 3, label: "中午 12:00-14:00", value: "12:00-14:00" },
|
|
{ id: 4, label: "下午 14:00-18:00", value: "14:00-18:00" },
|
|
{ id: 5, label: "晚上 18:00-22:00", value: "18:00-22:00" },
|
|
{ id: 6, label: "夜间 22:00-24:00", value: "22:00-24:00" },
|
|
],
|
|
// 球局数量
|
|
gamesNum: 0,
|
|
// 页面滚动距离顶部距离 是否大于0
|
|
isScrollTop: false,
|
|
// 搜索历史数据
|
|
searchHistory: [],
|
|
// 搜索历史数据默认 Top 15
|
|
searchHistoryParams: {
|
|
page: 1,
|
|
pageSize: 15,
|
|
},
|
|
// 联想词
|
|
suggestionList: [],
|
|
// 是否显示联想词
|
|
isShowSuggestion: false,
|
|
// 列表页是否显示搜索框自定义导航
|
|
isShowInputCustomerNavBar: false,
|
|
// 结果页是否显示搜索框自定义导航
|
|
isShowResultInputCustomerNavBar: false,
|
|
// 打开距离筛选框
|
|
isOpenDistancePopup: false,
|
|
// 打开快捷筛选框
|
|
isOpenQuickFilterPopup: false,
|
|
// 分页
|
|
pageOption: defaultPageOption,
|
|
|
|
// 组装搜索数据
|
|
getSearchParams: () => {
|
|
const state = get();
|
|
const filterOptions = state?.filterOptions || {};
|
|
console.log('===1111filterOptions', filterOptions)
|
|
const distanceQuickFilter = state?.distanceQuickFilter || {};
|
|
const params = {
|
|
pageOption: state.pageOption,
|
|
seachOption: {
|
|
...filterOptions,
|
|
title: state.searchValue,
|
|
ntrpMin: filterOptions?.ntrp?.[0],
|
|
ntrpMax: filterOptions?.ntrp?.[1],
|
|
dateRange: [
|
|
dateRangeUtils.formatDate(filterOptions?.dateRange?.[0]),
|
|
dateRangeUtils.formatDate(filterOptions?.dateRange?.[1])
|
|
],
|
|
},
|
|
order: distanceQuickFilter?.quick,
|
|
lat: state?.location?.latitude,
|
|
lng: state?.location?.longitude,
|
|
};
|
|
console.log('===列表参数params', params)
|
|
return params;
|
|
},
|
|
|
|
// 设置搜索的列表结果
|
|
setListData: (payload: IPayload) => {
|
|
const { isSearchResult } = get();
|
|
const { error, data, loading, gamesNum } = payload;
|
|
const saveKey = isSearchResult ? "searchResultData" : "matches";
|
|
const saveData = { error, loading, gamesNum, [saveKey]: data };
|
|
set(saveData);
|
|
},
|
|
|
|
// 获取列表数据(常规搜索)
|
|
fetchMatches: async (params) => {
|
|
set({ loading: true, error: null });
|
|
const { getSearchParams, setListData, distanceQuickFilter } = get();
|
|
|
|
try {
|
|
const searchParams = getSearchParams() || {};
|
|
const reqParams = {
|
|
...(searchParams || {}),
|
|
...params,
|
|
};
|
|
|
|
// 是否选择了智能排序
|
|
const isIntegrate = distanceQuickFilter?.quick === "0";
|
|
let fetchFn = getGamesList;
|
|
|
|
if (isIntegrate) {
|
|
reqParams.order = "";
|
|
fetchFn = getGamesIntegrateList;
|
|
}
|
|
|
|
console.log("===fetchMatches 获取列表数据参数:", reqParams);
|
|
const resData = (await fetchFn(reqParams)) || {};
|
|
const { data = {}, code } = resData;
|
|
if (code !== 0) {
|
|
setListData({
|
|
error: "-1",
|
|
data: [],
|
|
loading: false,
|
|
gamesNum: 0,
|
|
});
|
|
}
|
|
const { count, rows } = data;
|
|
setListData({
|
|
// recommendList: rows || [],
|
|
error: '',
|
|
data: rows || [],
|
|
loading: false,
|
|
gamesNum: count,
|
|
});
|
|
} catch (error) {
|
|
setListData({
|
|
error: "-1",
|
|
data: [],
|
|
loading: false,
|
|
gamesNum: 0,
|
|
});
|
|
}
|
|
},
|
|
|
|
// 获取列表数据(智能筛选)
|
|
// getIntegrateListData: async (params) => {
|
|
// set({ loading: true, error: null });
|
|
// const { getSearchParams, setListData } = get();
|
|
// try {
|
|
// const searchParams = getSearchParams() || {};
|
|
// const reqParams = {
|
|
// ...(searchParams || {}),
|
|
// ...params,
|
|
// };
|
|
// reqParams.order = "";
|
|
// console.log("===getGamesIntegrateList 获取列表数据参数:", reqParams);
|
|
// const resData = (await getGamesIntegrateList(reqParams)) || {};
|
|
// const { data = {}, code } = resData;
|
|
// if (code !== 0) {
|
|
// setListData({
|
|
// error: '-1',
|
|
// data: [],
|
|
// loading: false,
|
|
// gamesNum: 0,
|
|
// });
|
|
// }
|
|
// const { count, rows } = data;
|
|
// setListData({
|
|
// // recommendList: rows || [],
|
|
// error: null,
|
|
// data: rows || [],
|
|
// loading: false,
|
|
// gamesNum: count,
|
|
// });
|
|
// } catch (error) {
|
|
// setListData({
|
|
// error: null,
|
|
// matches: [],
|
|
// loading: false,
|
|
// gamesNum: 0,
|
|
// });
|
|
// }
|
|
// },
|
|
|
|
// 获取列表数据
|
|
getMatchesData: () => {
|
|
const { fetchMatches } = get();
|
|
fetchMatches();
|
|
// if (distanceQuickFilter?.quick === "0") {
|
|
// getIntegrateListData();
|
|
// } else {
|
|
// fetchMatches();
|
|
// }
|
|
},
|
|
|
|
// 获取历史搜索数据
|
|
getSearchHistory: async () => {
|
|
try {
|
|
const params = get()?.searchHistoryParams || {};
|
|
const resData = (await getSearchHistory(params)) || {};
|
|
const searchHistory = resData?.data?.records || [];
|
|
set({
|
|
searchHistory,
|
|
});
|
|
} catch (error) { }
|
|
},
|
|
|
|
// 清空历史记录
|
|
clearHistory: async () => {
|
|
try {
|
|
const params = {};
|
|
const resData = (await clearHistory(params)) || {};
|
|
if (resData?.code === 0) {
|
|
set({
|
|
searchHistory: [],
|
|
});
|
|
}
|
|
} catch (error) { }
|
|
},
|
|
|
|
// 获取联想
|
|
searchSuggestion: async (val: string) => {
|
|
try {
|
|
const resData = (await searchSuggestion({ val, limit: 10 })) || {};
|
|
const recommendations = resData?.data?.recommendations || [];
|
|
const total = resData?.data?.total;
|
|
set({
|
|
suggestionList: recommendations,
|
|
isShowSuggestion: total > 0,
|
|
});
|
|
} catch (error) {
|
|
set({
|
|
suggestionList: [],
|
|
isShowSuggestion: true,
|
|
});
|
|
}
|
|
},
|
|
|
|
// 清除错误信息
|
|
clearError: () => {
|
|
set({ error: null });
|
|
},
|
|
|
|
// 更新综合筛选项
|
|
updateFilterOptions: (payload: Record<string, any>) => {
|
|
const { filterOptions: preFilterOptions, getMatchesData } = get() || {};
|
|
const filterOptions = { ...preFilterOptions, ...payload };
|
|
const filterCount = Object.values(filterOptions).filter(Boolean).length;
|
|
console.log("===更新综合筛选项", filterOptions, filterCount);
|
|
set({
|
|
filterOptions,
|
|
filterCount,
|
|
pageOption: defaultPageOption,
|
|
});
|
|
// 重新搜索数据
|
|
getMatchesData();
|
|
},
|
|
|
|
// 清空综合筛选选项
|
|
clearFilterOptions: () => {
|
|
const { getMatchesData } = get() || {};
|
|
set({
|
|
filterOptions: defaultFilterOptions,
|
|
filterCount: 0,
|
|
pageOption: defaultPageOption,
|
|
});
|
|
getMatchesData();
|
|
},
|
|
|
|
// 加载更多数据
|
|
loadMoreMatches: () => {
|
|
const { pageOption, getMatchesData } = get() || {};
|
|
set({
|
|
pageOption: {
|
|
page: pageOption?.page + 1,
|
|
pageSize: 20,
|
|
},
|
|
});
|
|
getMatchesData();
|
|
},
|
|
|
|
// 初始化搜索条件 重新搜索
|
|
initialFilterSearch: () => {
|
|
const { getMatchesData } = get();
|
|
set({
|
|
distanceQuickFilter: defaultDistanceQuickFilter,
|
|
filterOptions: defaultFilterOptions,
|
|
pageOption: defaultPageOption,
|
|
});
|
|
getMatchesData();
|
|
},
|
|
|
|
// 更新store数据
|
|
updateState: (payload: Record<string, any>) => {
|
|
const state = get();
|
|
console.log("Store: 更新数据:", state);
|
|
set({
|
|
...(payload || {}),
|
|
});
|
|
},
|
|
}));
|
|
|
|
// 导出便捷的 hooks
|
|
export const useListState = () => useListStore((state) => state);
|