1
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
import { useEffect, useState, useRef } from "react";
|
||||
import { useEffect, useState } from "react";
|
||||
import { View, Text, Image } from "@tarojs/components";
|
||||
import img from "@/config/images";
|
||||
import { useGlobalState } from "@/store/global";
|
||||
@@ -96,7 +96,6 @@ const HomeNavbar = (props: IProps) => {
|
||||
detectedProvince: string;
|
||||
cachedCity: [string, string];
|
||||
} | null>(null);
|
||||
const hasShownLocationDialog = useRef(false); // 防止重复弹窗
|
||||
|
||||
// 监听城市选择器状态变化,通知父组件
|
||||
useEffect(() => {
|
||||
@@ -110,44 +109,18 @@ const HomeNavbar = (props: IProps) => {
|
||||
// 只使用省份/直辖市,不使用城市(城市可能是区)
|
||||
const detectedLocation = lastLocationProvince;
|
||||
|
||||
// 初始化城市:优先使用缓存的定位信息,其次使用用户详情中的位置信息
|
||||
useEffect(() => {
|
||||
// 1. 尝试从缓存中读取上次的定位信息
|
||||
const cachedCity = (Taro as any).getStorageSync(CITY_CACHE_KEY);
|
||||
|
||||
if (cachedCity && Array.isArray(cachedCity) && cachedCity.length === 2) {
|
||||
// 如果有缓存的定位信息,使用缓存
|
||||
const cachedCityArray = cachedCity as [string, string];
|
||||
console.log("使用缓存的定位城市:", cachedCityArray);
|
||||
updateArea(cachedCityArray);
|
||||
|
||||
// 如果用户详情中有位置信息且与缓存不同,弹窗询问是否切换
|
||||
if (detectedLocation && cachedCityArray[1] !== detectedLocation && !hasShownLocationDialog.current) {
|
||||
hasShownLocationDialog.current = true;
|
||||
showLocationConfirmDialog(detectedLocation, cachedCityArray);
|
||||
}
|
||||
} else if (detectedLocation) {
|
||||
// 如果没有缓存但有用户详情中的位置信息,直接使用并保存到缓存
|
||||
console.log("没有缓存,使用用户详情中的位置信息:", detectedLocation);
|
||||
const newArea: [string, string] = ["中国", detectedLocation];
|
||||
updateArea(newArea);
|
||||
// 保存定位信息到缓存
|
||||
(Taro as any).setStorageSync(CITY_CACHE_KEY, newArea);
|
||||
}
|
||||
}, [detectedLocation]);
|
||||
|
||||
// 检查是否在2小时内已选择"继续浏览"或切换过城市
|
||||
// 检查是否应该显示定位确认弹窗
|
||||
const should_show_location_dialog = (): boolean => {
|
||||
try {
|
||||
const current_time = Date.now();
|
||||
|
||||
// 检查是否在2小时内切换过城市
|
||||
const city_change_time = (Taro as any).getStorageSync(CITY_CHANGE_TIME_KEY);
|
||||
if (city_change_time) {
|
||||
const current_time = Date.now();
|
||||
const time_diff = current_time - city_change_time;
|
||||
|
||||
// 如果距离上次切换城市还在2小时内,不显示弹窗
|
||||
if (time_diff < TWO_HOURS_MS) {
|
||||
console.log(`距离上次切换城市还不到2小时,剩余时间: ${Math.ceil((TWO_HOURS_MS - time_diff) / 1000 / 60)}分钟,不显示定位弹窗`);
|
||||
console.log(`[HomeNavbar] 距离上次切换城市还不到2小时,剩余时间: ${Math.ceil((TWO_HOURS_MS - time_diff) / 1000 / 60)}分钟,不显示定位弹窗`);
|
||||
return false;
|
||||
} else {
|
||||
// 超过2小时,清除过期记录
|
||||
@@ -161,9 +134,7 @@ const HomeNavbar = (props: IProps) => {
|
||||
return true; // 没有记录,可以显示
|
||||
}
|
||||
|
||||
const current_time = Date.now();
|
||||
const time_diff = current_time - dismiss_time;
|
||||
|
||||
// 如果距离上次选择"继续浏览"已超过2小时,可以再次显示
|
||||
if (time_diff >= TWO_HOURS_MS) {
|
||||
// 清除过期记录
|
||||
@@ -172,30 +143,123 @@ const HomeNavbar = (props: IProps) => {
|
||||
}
|
||||
|
||||
// 在2小时内,不显示弹窗
|
||||
console.log(`距离上次选择"继续浏览"还不到2小时,剩余时间: ${Math.ceil((TWO_HOURS_MS - time_diff) / 1000 / 60)}分钟`);
|
||||
console.log(`[HomeNavbar] 距离上次选择"继续浏览"还不到2小时,剩余时间: ${Math.ceil((TWO_HOURS_MS - time_diff) / 1000 / 60)}分钟`);
|
||||
return false;
|
||||
} catch (error) {
|
||||
console.error('检查定位弹窗显示条件失败:', error);
|
||||
console.error('[HomeNavbar] 检查定位弹窗显示条件失败:', error);
|
||||
return true; // 出错时默认显示
|
||||
}
|
||||
};
|
||||
|
||||
// 显示定位确认弹窗
|
||||
const showLocationConfirmDialog = (detectedLocation: string, cachedCity: [string, string]) => {
|
||||
// 检查是否在2小时内已选择"继续浏览"
|
||||
// 检查是否应该显示弹窗
|
||||
if (!should_show_location_dialog()) {
|
||||
console.log('[LocationDialog] 用户在2小时内已选择"继续浏览",不显示弹窗');
|
||||
console.log('[HomeNavbar] 用户在2小时内已选择"继续浏览"或切换过城市,不显示弹窗');
|
||||
return;
|
||||
}
|
||||
|
||||
console.log('[LocationDialog] 准备显示定位确认弹窗,隐藏 GuideBar');
|
||||
console.log('[HomeNavbar] 准备显示定位确认弹窗,隐藏 GuideBar');
|
||||
setLocationDialogData({ detectedProvince: detectedLocation, cachedCity });
|
||||
setLocationDialogVisible(true);
|
||||
// 显示弹窗时隐藏 GuideBar
|
||||
setShowGuideBar(false);
|
||||
console.log('[LocationDialog] setShowGuideBar(false) 已调用');
|
||||
console.log('[HomeNavbar] setShowGuideBar(false) 已调用');
|
||||
};
|
||||
|
||||
// 初始化城市:优先使用缓存的定位信息,如果缓存城市和用户详情位置不一致,且时间过期,则弹出选择框
|
||||
// 只在组件挂载时执行一次,避免重复执行
|
||||
useEffect(() => {
|
||||
// 1. 优先尝试从缓存中读取上次的定位信息
|
||||
const cachedCity = (Taro as any).getStorageSync(CITY_CACHE_KEY);
|
||||
|
||||
if (cachedCity && Array.isArray(cachedCity) && cachedCity.length === 2) {
|
||||
// 如果有缓存的定位信息,使用缓存
|
||||
const cachedCityArray = cachedCity as [string, string];
|
||||
console.log("[HomeNavbar] 使用缓存的定位城市:", cachedCityArray);
|
||||
updateArea(cachedCityArray);
|
||||
|
||||
// 如果用户详情中有位置信息,且与缓存不一致,检查是否需要弹窗
|
||||
if (detectedLocation && cachedCityArray[1] !== detectedLocation) {
|
||||
// 检查时间缓存,如果没有或过期,则弹出选择框
|
||||
if (should_show_location_dialog()) {
|
||||
console.log("[HomeNavbar] 缓存城市与用户详情位置不一致,且时间过期,弹出选择框");
|
||||
showLocationConfirmDialog(detectedLocation, cachedCityArray);
|
||||
} else {
|
||||
console.log("[HomeNavbar] 缓存城市与用户详情位置不一致,但时间未过期,不弹出选择框");
|
||||
}
|
||||
}
|
||||
} else if (detectedLocation) {
|
||||
// 只有在完全没有缓存的情况下,才使用用户详情中的位置信息
|
||||
console.log("[HomeNavbar] 没有缓存,使用用户详情中的位置信息:", detectedLocation);
|
||||
const newArea: [string, string] = ["中国", detectedLocation];
|
||||
updateArea(newArea);
|
||||
// 保存定位信息到缓存
|
||||
(Taro as any).setStorageSync(CITY_CACHE_KEY, newArea);
|
||||
}
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, []); // 空依赖数组,确保只在组件挂载时执行一次
|
||||
|
||||
// 检查是否在2小时内已选择"继续浏览"或切换过城市(当前不使用,首页重新进入时直接使用缓存中的位置)
|
||||
// const should_show_location_dialog = (): boolean => {
|
||||
// try {
|
||||
// // 检查是否在2小时内切换过城市
|
||||
// const city_change_time = (Taro as any).getStorageSync(CITY_CHANGE_TIME_KEY);
|
||||
// if (city_change_time) {
|
||||
// const current_time = Date.now();
|
||||
// const time_diff = current_time - city_change_time;
|
||||
//
|
||||
// // 如果距离上次切换城市还在2小时内,不显示弹窗
|
||||
// if (time_diff < TWO_HOURS_MS) {
|
||||
// console.log(`距离上次切换城市还不到2小时,剩余时间: ${Math.ceil((TWO_HOURS_MS - time_diff) / 1000 / 60)}分钟,不显示定位弹窗`);
|
||||
// return false;
|
||||
// } else {
|
||||
// // 超过2小时,清除过期记录
|
||||
// (Taro as any).removeStorageSync(CITY_CHANGE_TIME_KEY);
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// // 检查是否在2小时内已选择"继续浏览"
|
||||
// const dismiss_time = (Taro as any).getStorageSync(LOCATION_DIALOG_DISMISS_TIME_KEY);
|
||||
// if (!dismiss_time) {
|
||||
// return true; // 没有记录,可以显示
|
||||
// }
|
||||
//
|
||||
// const current_time = Date.now();
|
||||
// const time_diff = current_time - dismiss_time;
|
||||
//
|
||||
// // 如果距离上次选择"继续浏览"已超过2小时,可以再次显示
|
||||
// if (time_diff >= TWO_HOURS_MS) {
|
||||
// // 清除过期记录
|
||||
// (Taro as any).removeStorageSync(LOCATION_DIALOG_DISMISS_TIME_KEY);
|
||||
// return true;
|
||||
// }
|
||||
//
|
||||
// // 在2小时内,不显示弹窗
|
||||
// console.log(`距离上次选择"继续浏览"还不到2小时,剩余时间: ${Math.ceil((TWO_HOURS_MS - time_diff) / 1000 / 60)}分钟`);
|
||||
// return false;
|
||||
// } catch (error) {
|
||||
// console.error('检查定位弹窗显示条件失败:', error);
|
||||
// return true; // 出错时默认显示
|
||||
// }
|
||||
// };
|
||||
|
||||
// 显示定位确认弹窗(当前不使用,首页重新进入时直接使用缓存中的位置)
|
||||
// const showLocationConfirmDialog = (detectedLocation: string, cachedCity: [string, string]) => {
|
||||
// // 检查是否在2小时内已选择"继续浏览"
|
||||
// if (!should_show_location_dialog()) {
|
||||
// console.log('[LocationDialog] 用户在2小时内已选择"继续浏览",不显示弹窗');
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// console.log('[LocationDialog] 准备显示定位确认弹窗,隐藏 GuideBar');
|
||||
// setLocationDialogData({ detectedProvince: detectedLocation, cachedCity });
|
||||
// setLocationDialogVisible(true);
|
||||
// // 显示弹窗时隐藏 GuideBar
|
||||
// setShowGuideBar(false);
|
||||
// console.log('[LocationDialog] setShowGuideBar(false) 已调用');
|
||||
// };
|
||||
|
||||
// 处理定位弹窗确认
|
||||
const handleLocationDialogConfirm = () => {
|
||||
if (!locationDialogData) return;
|
||||
@@ -206,6 +270,14 @@ const HomeNavbar = (props: IProps) => {
|
||||
updateArea(newArea);
|
||||
// 更新缓存为新的定位信息
|
||||
(Taro as any).setStorageSync(CITY_CACHE_KEY, newArea);
|
||||
// 记录切换城市的时间戳,2小时内不再提示
|
||||
try {
|
||||
const current_time = Date.now();
|
||||
(Taro as any).setStorageSync(CITY_CHANGE_TIME_KEY, current_time);
|
||||
console.log(`[LocationDialog] 已记录用户切换城市的时间,2小时内不再提示`);
|
||||
} catch (error) {
|
||||
console.error('保存城市切换时间失败:', error);
|
||||
}
|
||||
console.log("切换到用户详情中的位置信息并更新缓存:", detectedProvince);
|
||||
|
||||
// 关闭弹窗
|
||||
|
||||
@@ -129,15 +129,37 @@ const ListPageContent: React.FC<ListPageContentProps> = ({
|
||||
// ScrollView 滚动处理
|
||||
const handleScrollViewScroll = useCallback(
|
||||
(e: any) => {
|
||||
|
||||
|
||||
const currentScrollTop = e?.detail?.scrollTop || 0;
|
||||
const scrollHeight = e?.detail?.scrollHeight || 0;
|
||||
const clientHeight = e?.detail?.clientHeight || 0;
|
||||
const lastScrollTop = lastScrollTopRef.current;
|
||||
const currentTime = Date.now();
|
||||
const timeDiff = currentTime - lastScrollTimeRef.current;
|
||||
|
||||
if (timeDiff < 100) return;
|
||||
|
||||
// 计算距离底部的距离,提前加载(距离底部600px时开始加载)
|
||||
// 注意:如果 scrollHeight 或 clientHeight 不可用,则使用 lowerThreshold 触发
|
||||
if (scrollHeight > 0 && clientHeight > 0) {
|
||||
const distanceToBottom = scrollHeight - currentScrollTop - clientHeight;
|
||||
const preloadThreshold = 600; // 提前加载阈值
|
||||
|
||||
// 如果距离底部小于阈值,且正在向下滚动,且有更多数据,则提前加载
|
||||
if (
|
||||
distanceToBottom < preloadThreshold &&
|
||||
distanceToBottom > 0 &&
|
||||
!loading &&
|
||||
!loadingMoreRef.current &&
|
||||
listPageState?.isHasMoreData &&
|
||||
currentScrollTop > lastScrollTop // 向下滚动
|
||||
) {
|
||||
loadingMoreRef.current = true;
|
||||
loadMoreMatches().finally(() => {
|
||||
loadingMoreRef.current = false;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
const scrollDiff = currentScrollTop - lastScrollTop;
|
||||
let newDirection = scrollDirectionRef.current;
|
||||
if (Math.abs(scrollDiff) > 15) {
|
||||
@@ -195,7 +217,7 @@ const ListPageContent: React.FC<ListPageContentProps> = ({
|
||||
lastScrollTopRef.current = currentScrollTop;
|
||||
lastScrollTimeRef.current = currentTime;
|
||||
},
|
||||
[updateListPageState, onNavStateChange]
|
||||
[updateListPageState, onNavStateChange, loading, loadMoreMatches, listPageState?.isHasMoreData]
|
||||
// 移除 showSearchBar 和 isShowInputCustomerNavBar 依赖,使用 ref 获取最新值
|
||||
);
|
||||
|
||||
@@ -550,7 +572,7 @@ const ListPageContent: React.FC<ListPageContentProps> = ({
|
||||
refresherEnabled={true}
|
||||
refresherTriggered={refreshing}
|
||||
onRefresherRefresh={handleRefresh}
|
||||
lowerThreshold={100}
|
||||
lowerThreshold={600}
|
||||
onScrollToLower={async () => {
|
||||
if (
|
||||
!loading &&
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { create } from "zustand";
|
||||
import Taro from "@tarojs/taro";
|
||||
import {
|
||||
fetchUserProfile,
|
||||
updateUserProfile,
|
||||
@@ -44,14 +45,31 @@ export const useUser = create<UserState>()((set) => ({
|
||||
const userData = res.data;
|
||||
set({ user: userData });
|
||||
|
||||
// 当 userLastLocationProvince 更新时,同步更新 area
|
||||
// 优先使用缓存中的城市,不使用用户信息中的位置
|
||||
// 检查是否有缓存的城市
|
||||
const CITY_CACHE_KEY = "USER_SELECTED_CITY";
|
||||
const cachedCity = (Taro as any).getStorageSync?.(CITY_CACHE_KEY);
|
||||
|
||||
if (cachedCity && Array.isArray(cachedCity) && cachedCity.length === 2) {
|
||||
// 如果有缓存的城市,使用缓存,不更新 area
|
||||
console.log("[userStore] 检测到缓存的城市,使用缓存,不更新 area");
|
||||
return userData;
|
||||
}
|
||||
|
||||
// 只有当没有缓存时,才使用用户信息中的位置
|
||||
if (userData?.last_location_province) {
|
||||
const listStore = useListStore.getState();
|
||||
const currentArea = listStore.area;
|
||||
// 只有当 area 不存在或与 userLastLocationProvince 不一致时才更新
|
||||
if (!currentArea || currentArea[1] !== userData.last_location_province) {
|
||||
// 只有当 area 不存在时才使用用户信息中的位置
|
||||
if (!currentArea) {
|
||||
const newArea: [string, string] = ["中国", userData.last_location_province];
|
||||
listStore.updateArea(newArea);
|
||||
// 保存到缓存
|
||||
try {
|
||||
(Taro as any).setStorageSync?.(CITY_CACHE_KEY, newArea);
|
||||
} catch (error) {
|
||||
console.error("保存城市缓存失败:", error);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user