diff --git a/src/components/HomeNavbar/index.tsx b/src/components/HomeNavbar/index.tsx index ff5cc8e..3929053 100644 --- a/src/components/HomeNavbar/index.tsx +++ b/src/components/HomeNavbar/index.tsx @@ -180,6 +180,11 @@ const HomeNavbar = (props: IProps) => { // const currentAddress = city + district; const handleInputClick = () => { + // 关闭城市选择器 + if (cityPopupVisible) { + setCityPopupVisible(false); + } + const currentPagePath = getCurrentFullPath(); if (currentPagePath === "/game_pages/searchResult/index") { (Taro as any).navigateBack(); @@ -192,6 +197,11 @@ const HomeNavbar = (props: IProps) => { // 点击logo const handleLogoClick = () => { + // 关闭城市选择器 + if (cityPopupVisible) { + setCityPopupVisible(false); + } + // 如果当前在列表页,点击后页面回到顶部 if (getCurrentFullPath() === "/main_pages/index") { // 使用父组件传递的滚动方法(适配 ScrollView) @@ -212,6 +222,11 @@ const HomeNavbar = (props: IProps) => { }; const handleInputLeftIconClick = () => { + // 关闭城市选择器 + if (cityPopupVisible) { + setCityPopupVisible(false); + } + if (leftIconClick) { leftIconClick(); } else { @@ -231,13 +246,13 @@ const HomeNavbar = (props: IProps) => { // 处理城市切换(仅刷新数据,不保存缓存) const handleCityChangeWithoutCache = async () => { - // 切换城市后,同时更新两个列表接口获取数据,传入当前的 area + // 先调用列表接口 if (refreshBothLists) { - await refreshBothLists(area); + await refreshBothLists(); } - // 更新球局数量,传入当前的 area,确保接口请求的地址与界面显示一致 + // 列表接口完成后,再调用数量接口 if (fetchGetGamesCount) { - await fetchGetGamesCount(area); + await fetchGetGamesCount(); } }; @@ -246,21 +261,17 @@ const HomeNavbar = (props: IProps) => { // 用户手动选择的城市不保存到缓存(临时切换) console.log("用户手动选择城市(不保存缓存):", _newArea); - // 先更新 area 状态(用于界面显示) + // 先更新 area 状态(用于界面显示和接口参数) updateArea(_newArea); - // 确保状态更新完成后再调用接口 - // 切换城市后,同时更新两个列表接口获取数据,传入新的城市信息 - const promises: Promise[] = []; + // 先调用列表接口(会使用更新后的 state.area) if (refreshBothLists) { - promises.push(refreshBothLists(_newArea)); + await refreshBothLists(); } - // 更新球局数量,直接传入新的城市信息,不依赖状态更新时序 + // 列表接口完成后,再调用数量接口(会使用更新后的 state.area) if (fetchGetGamesCount) { - promises.push(fetchGetGamesCount(_newArea)); + await fetchGetGamesCount(); } - // 并行执行,提高性能 - await Promise.all(promises); }; return ( diff --git a/src/components/ListCard/index.tsx b/src/components/ListCard/index.tsx index 291b0b9..c865790 100644 --- a/src/components/ListCard/index.tsx +++ b/src/components/ListCard/index.tsx @@ -246,7 +246,7 @@ const ListCard: React.FC = ({ {/* {game_type} */} diff --git a/src/config/images.js b/src/config/images.js index 2dc8e5c..57e03c6 100644 --- a/src/config/images.js +++ b/src/config/images.js @@ -69,4 +69,5 @@ export default { ICON_CLOSE: require('@/static/publishBall/icon-close.svg'), ICON_LIST_NTPR: require('@/static/list/ntpr.svg'), ICON_LIST_CHANGDA: require('@/static/list/icon-changda.svg'), + ICON_LIST_CHANGDA_QIuju: require('@/static/list/changdaqiuju.png'), } diff --git a/src/main_pages/components/ListPageContent.tsx b/src/main_pages/components/ListPageContent.tsx index b23c60e..3a8528f 100644 --- a/src/main_pages/components/ListPageContent.tsx +++ b/src/main_pages/components/ListPageContent.tsx @@ -236,21 +236,24 @@ const ListPageContent: React.FC = ({ }); // 地址发生变化或不一致,重新加载数据和球局数量 - const promises: Promise[] = []; - if (refreshBothLists) { - promises.push(refreshBothLists(currentArea)); - } - if (fetchGetGamesCount) { - promises.push(fetchGetGamesCount(currentArea)); - } - Promise.all(promises).then(() => { - // 数据加载完成后,更新记录的城市(记录为上一次在列表页加载数据时的城市) - if (currentArea) { - lastLoadedAreaRef.current = [...currentArea] as [string, string]; + // 先调用列表接口,然后在列表接口完成后调用数量接口 + (async () => { + try { + if (refreshBothLists) { + await refreshBothLists(); + } + // 列表接口完成后,再调用数量接口 + if (fetchGetGamesCount) { + await fetchGetGamesCount(); + } + // 数据加载完成后,更新记录的城市(记录为上一次在列表页加载数据时的城市) + if (currentArea) { + lastLoadedAreaRef.current = [...currentArea] as [string, string]; + } + } catch (error) { + console.error("重新加载数据失败:", error); } - }).catch((error) => { - console.error("重新加载数据失败:", error); - }); + })(); } } @@ -312,9 +315,10 @@ const ListPageContent: React.FC = ({ console.error("更新用户位置失败:", error); } } - // 传入当前的 area,确保接口请求的地址与界面显示一致 - await fetchGetGamesCount(area); + // 先调用列表接口 await getMatchesData(); + // 列表接口完成后,再调用数量接口 + await fetchGetGamesCount(); // 初始数据加载完成后,记录当前城市 if (area && isActive) { lastLoadedAreaRef.current = [...area] as [string, string]; diff --git a/src/main_pages/index.tsx b/src/main_pages/index.tsx index 65943ed..90af2fe 100644 --- a/src/main_pages/index.tsx +++ b/src/main_pages/index.tsx @@ -96,6 +96,12 @@ const MainPage: React.FC = () => { if (code === currentTab) { return; } + + // 切换标签时关闭城市选择器 + if (isCityPickerVisible) { + setIsCityPickerVisible(false); + } + setCurrentTab(code as TabType); // 切换标签时滚动到顶部 (Taro as any).pageScrollTo({ @@ -103,7 +109,7 @@ const MainPage: React.FC = () => { duration: 300, }); }, - [currentTab] + [currentTab, isCityPickerVisible] ); // 处理发布菜单显示/隐藏 diff --git a/src/store/listStore.ts b/src/store/listStore.ts index ad2c6fd..0c41c7c 100644 --- a/src/store/listStore.ts +++ b/src/store/listStore.ts @@ -17,7 +17,6 @@ import { ListState, IPayload, } from "../../types/list/types"; -import { useUser } from "./userStore"; function translateCityData(dataTree) { return dataTree.map((item) => { @@ -185,7 +184,8 @@ export const useListStore = create()((set, get) => ({ gamesNum: 0, // 组装搜索数据 - getSearchParams: (overrideArea?: [string, string]) => { + // 注意:始终使用 state.area,不接收 overrideArea 参数,确保参数一致性 + getSearchParams: () => { const state = get(); const currentPageState = state.isSearchResult ? state.searchPageState : state.listPageState; const filterOptions = currentPageState?.filterOptions || {}; @@ -193,12 +193,9 @@ export const useListStore = create()((set, get) => ({ const distanceQuickFilter = currentPageState?.distanceQuickFilter || {}; const { distanceFilter, order, district } = distanceQuickFilter || {}; - // 优先使用 overrideArea(切换城市时传入),其次使用 area 状态 - // area 会在 userLastLocationProvince 更新时自动同步,所以这里直接使用 area 即可 - const areaProvince = overrideArea?.at(1) || state.area?.at(1) || ""; - const userInfo = useUser.getState().user as any; + // 始终使用 state.area,确保所有接口使用一致的城市参数 + const areaProvince = state.area?.at(1) || ""; const last_location_province = areaProvince; - const last_location_city = userInfo?.last_location_city || ""; // city 参数逻辑: // 1. 如果选择了行政区(district 有值),使用行政区的名称(label) @@ -216,6 +213,8 @@ export const useListStore = create()((set, get) => ({ // 使用 filterOptions 中的 dateRange const dateRange: [string, string] = filterOptions?.dateRange || defaultDateRange; + // 构建 searchOption + // 注意:province 必须从 state.area 获取,不能依赖 filterOptions 中可能存在的旧值 const searchOption: any = { ...filterOptions, title: state.searchValue, @@ -223,7 +222,8 @@ export const useListStore = create()((set, get) => ({ ntrpMax: filterOptions?.ntrp?.[1], dateRange: dateRange, // 确保始终是两个值的数组 distanceFilter: distanceFilter, - province: last_location_province, // 使用 province 替代 last_location_province + // 显式设置 province,确保始终使用 state.area 中的最新值 + province: last_location_province, // 始终使用 state.area 中的 province,确保城市参数一致 }; // 只在有值时添加 city 参数 @@ -336,13 +336,14 @@ export const useListStore = create()((set, get) => ({ }, // 同时更新两个列表接口(常规列表和智能排序列表) - refreshBothLists: async (overrideArea?: [string, string]) => { + // 注意:不再接收 overrideArea 参数,始终使用 state.area + refreshBothLists: async () => { const state = get(); const { getSearchParams, setListData } = state; const { getGamesList, getGamesIntegrateList } = await import("../services/listApi"); try { - const searchParams = getSearchParams(overrideArea) || {}; + const searchParams = getSearchParams() || {}; // 调用常规列表接口 const listParams = { @@ -407,11 +408,24 @@ export const useListStore = create()((set, get) => ({ }, // 获取球局数量 - fetchGetGamesCount: async (overrideArea?: [string, string]) => { + // 注意:必须和 games/integrate_list 使用相同的参数构建逻辑,确保数据一致性 + // 不再接收 overrideArea 参数,始终使用 state.area + fetchGetGamesCount: async () => { const state = get(); const { getSearchParams } = state; - const params = getSearchParams(overrideArea) || {}; - console.log("fetchGetGamesCount 参数:", { overrideArea, params: JSON.stringify(params) }); + const searchParams = getSearchParams() || {}; + + // 使用和 games/integrate_list 相同的参数构建逻辑 + const params = { + ...searchParams, + order: "", // 和 integrate_list 保持一致 + seachOption: { + ...searchParams.seachOption, + isRefresh: true, // 和 integrate_list 保持一致 + }, + }; + + console.log("fetchGetGamesCount 参数:", { area: state.area, params: JSON.stringify(params) }); const resData = (await getGamesCount(params)) || {}; const gamesNum = resData?.data?.count || 0; console.log("fetchGetGamesCount 结果:", gamesNum); @@ -527,10 +541,13 @@ export const useListStore = create()((set, get) => ({ }); // 使用 Promise.resolve 确保状态更新后再调用接口 - Promise.resolve().then(() => { + // 先调用列表接口,然后在列表接口完成后调用数量接口 + Promise.resolve().then(async () => { const freshState = get(); // 重新获取最新状态 - // 传入当前的 area,确保接口请求的地址与界面显示一致 - freshState.fetchGetGamesCount(freshState.area); + // 先调用列表接口 + await freshState.getMatchesData(); + // 列表接口完成后,再调用数量接口 + await freshState.fetchGetGamesCount(); }); }, @@ -548,16 +565,18 @@ export const useListStore = create()((set, get) => ({ }); // 使用 Promise.resolve 确保状态更新后再调用接口 - Promise.resolve().then(() => { + // 先调用列表接口,然后在列表接口完成后调用数量接口 + Promise.resolve().then(async () => { const freshState = get(); // 重新获取最新状态 - freshState.getMatchesData(); - // 传入当前的 area,确保接口请求的地址与界面显示一致 - freshState.fetchGetGamesCount(freshState.area); + // 先调用列表接口 + await freshState.getMatchesData(); + // 列表接口完成后,再调用数量接口 + await freshState.fetchGetGamesCount(); }); }, // 清空综合筛选选项 - clearFilterOptions: () => { + clearFilterOptions: async () => { const state = get(); const { getMatchesData, fetchGetGamesCount } = state; @@ -566,8 +585,10 @@ export const useListStore = create()((set, get) => ({ filterCount: 0, pageOption: defaultPageOption, }); - getMatchesData(); - fetchGetGamesCount(); + // 先调用列表接口 + await getMatchesData(); + // 列表接口完成后,再调用数量接口 + await fetchGetGamesCount(); }, // 加载更多数据 @@ -616,8 +637,10 @@ export const useListStore = create()((set, get) => ({ if (!isSearchData) { return; } - await fetchGetGamesCount(); + // 先调用列表接口 await getMatchesData(); + // 列表接口完成后,再调用数量接口 + await fetchGetGamesCount(); }, // 更新store数据 diff --git a/types/list/types.ts b/types/list/types.ts index 69c19de..bc1b8b1 100644 --- a/types/list/types.ts +++ b/types/list/types.ts @@ -111,11 +111,11 @@ export interface ListActions { getSearchHistory: () => Promise; clearHistory: () => void; searchSuggestion: (val: string) => Promise; - getSearchParams: (overrideArea?: [string, string]) => Record; + getSearchParams: () => Record; loadMoreMatches: () => Promise; initialFilterSearch: (isSearchData?: boolean) => void; setListData: (payload: IPayload) => void; - fetchGetGamesCount: (overrideArea?: [string, string]) => Promise; + fetchGetGamesCount: () => Promise; getCurrentPageState: () => { currentPageState: any; currentPageKey: string }; updateCurrentPageState: (payload: Record) => void; updateDistanceQuickFilter: (payload: Record) => void; @@ -123,7 +123,7 @@ export interface ListActions { getCityQrCode: () => Promise; getDistricts: () => Promise; // 新增:获取行政区 updateArea: (payload: [string, string]) => void; - refreshBothLists: (overrideArea?: [string, string]) => Promise; + refreshBothLists: () => Promise; } export interface IPayload {