From 2b0cc7f389d7d73b48db18432cd7410f86c12309 Mon Sep 17 00:00:00 2001 From: zhangjing1 Date: Mon, 16 Mar 2026 22:37:00 +0800 Subject: [PATCH] =?UTF-8?q?bug(=E9=A6=96=E9=A1=B5=E8=BF=94=E5=9B=9E?= =?UTF-8?q?=E5=88=B7=E6=96=B0):?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/hooks/useLocation.js | 18 ++++++++----- src/pages/index.js | 5 ++++ src/utils/entryLaunch.js | 57 +++++++++++++++++++++++++++++++++------- 3 files changed, 63 insertions(+), 17 deletions(-) diff --git a/src/hooks/useLocation.js b/src/hooks/useLocation.js index 619b822e6..9c42e782a 100644 --- a/src/hooks/useLocation.js +++ b/src/hooks/useLocation.js @@ -16,25 +16,28 @@ export default (props) => { /** * 未登录状态 && 授权定位 == 定位 * 未登录状态 && 不授权定位 == 默认值 + * 仅当位置相对上次有变化时才请求逆地理(getAreaByJwd)并更新 store */ const updateAddress = async () => { if (S.getAuthToken()) { await addressLogic() } else { - const res1 = await fetchLocation() + const res1 = await fetchLocation(location?.lng, location?.lat) + if (res1 === null) return // 位置未变化,不更新 if (res1 instanceof Object && res1.lat) { dispatch(updateLocation(res1)) } } } - // 获取当前定位 - const fetchLocation = async () => { + // 获取当前定位,仅位置变化时才解析地址 + const fetchLocation = async (previousLng, previousLat) => { try { const res = await new Promise((resolve) => { - entryLaunch.isOpenPosition((res1) => { - resolve(res1) - }) + entryLaunch.isOpenPosition( + (res1) => resolve(res1), + previousLng != null && previousLat != null ? { previousLng, previousLat } : {} + ) }) return res } catch (e) { @@ -132,7 +135,8 @@ export default (props) => { const addressLogic = async () => { const { list } = await api.member.addressList() const arr = await processingAddress(list) - const res = await fetchLocation() + const res = await fetchLocation(location?.lng, location?.lat) + if (res === null) return // 位置未变化,不更新 // 开启定位 if (res instanceof Object && res.lat) { if (arr.length == 0) { diff --git a/src/pages/index.js b/src/pages/index.js index bd54d621b..34b1ec189 100644 --- a/src/pages/index.js +++ b/src/pages/index.js @@ -112,6 +112,11 @@ function Home() { setNavigationBarTitle(appName) }, []) + // 首次进入时 useDidShow 可能在组件挂载前就触发了,导致不会执行,这里补一次 + useEffect(() => { + updateAddress() + }, []) + useDidShow(() => { dispatch(updatePurchaseShareInfo()) dispatch(updateInviteCode()) diff --git a/src/utils/entryLaunch.js b/src/utils/entryLaunch.js index 212223ea1..807406f9b 100644 --- a/src/utils/entryLaunch.js +++ b/src/utils/entryLaunch.js @@ -24,8 +24,14 @@ function getS() { const $instance = getCurrentInstance() || {} const { store } = configStore() + +// 经纬度逆地理缓存:同一位置在有效期内不重复请求 getAreaByJwd(避免每次返回首页都调接口) +const LNGLAT_CACHE_TTL_MS = 5 * 60 * 1000 // 5 分钟 +const LNGLAT_CACHE_PRECISION = 4 // 小数点位数,约 10m 内视为同位置 + class EntryLaunch { constructor() { + this._lnglatCache = null // { key: string, at: number, data: object } this.init() } @@ -317,20 +323,29 @@ class EntryLaunch { } /** - * @function 根据经纬度解析地址 + * @function 根据经纬度解析地址(带短期缓存,同一位置 5 分钟内不重复请求 getAreaByJwd) * @params lng Number 经度 * @params lat Number 纬度 */ async getAddressByLnglatWebAPI(lng, lat) { + if (lat == null || lng == null) return { error: '地址解析错误' } + const key = `${Number(lng).toFixed(LNGLAT_CACHE_PRECISION)}_${Number(lat).toFixed(LNGLAT_CACHE_PRECISION)}` + const now = Date.now() + if ( + this._lnglatCache && + this._lnglatCache.key === key && + now - this._lnglatCache.at < LNGLAT_CACHE_TTL_MS + ) { + return this._lnglatCache.data + } try { const res = await api.wx.getAreaByLnglat({ lng, lat }) - console.log('getAddressByLnglatWebAPI res:', res) if (res && res.address) { const { address_component: { province, city, district }, address } = res - return { + const data = { lng, lat, address, @@ -338,16 +353,14 @@ class EntryLaunch { city: isArray(city) ? province : city, district } + this._lnglatCache = { key, at: now, data } + return data } else { - return { - error: '地址解析错误' - } + return { error: '地址解析错误' } } } catch (error) { console.error('getAddressByLnglatWebAPI error:', error) - return { - error: '地址解析错误' - } + return { error: '地址解析错误' } } } @@ -367,8 +380,20 @@ class EntryLaunch { /** * 判断是否开启定位,去获取经纬度,根据经纬度去获取地址 + * @param {Function} callback - 回调 (res),res 为 null 表示位置未变化、跳过解析 + * @param {{ previousLng?: number, previousLat?: number }} [opts] - 上次经纬度,与当前一致则不请求逆地理 */ - async isOpenPosition(callback) { + async isOpenPosition(callback, opts = {}) { + const { previousLng, previousLat } = opts + const posUnchanged = (lng, lat) => { + if (previousLng == null || previousLat == null) return false + const p = LNGLAT_CACHE_PRECISION + return ( + Number(lng).toFixed(p) === Number(previousLng).toFixed(p) && + Number(lat).toFixed(p) === Number(previousLat).toFixed(p) + ) + } + if (process.env.TARO_ENV === 'weapp') { const { authSetting } = await Taro.getSetting() if (!authSetting['scope.userLocation']) { @@ -376,6 +401,10 @@ class EntryLaunch { scope: 'scope.userLocation', success: async () => { let { lng, lat } = await this.getLocationInfo() + if (lat != null && posUnchanged(lng, lat)) { + if (callback) callback(null) + return + } let res = {} if (lat) { res = await this.getAddressByLnglatWebAPI(lng, lat) @@ -392,6 +421,10 @@ class EntryLaunch { const setting = await Taro.getSetting() if (setting.authSetting['scope.userLocation']) { let { lng, lat } = await this.getLocationInfo() + if (lat != null && posUnchanged(lng, lat)) { + if (callback) callback(null) + return + } let res = {} if (lat) { res = await this.getAddressByLnglatWebAPI(lng, lat) @@ -409,6 +442,10 @@ class EntryLaunch { }) } else { let { lng, lat } = await this.getLocationInfo() + if (lat != null && posUnchanged(lng, lat)) { + if (callback) callback(null) + return + } let res = {} if (lat) { res = await this.getAddressByLnglatWebAPI(lng, lat)