import { getLocationToCity } from '@/api/tea-room' const LOCATION_EXPIRE_MS = 30 * 24 * 60 * 60 * 1000 // 定位缓存30天 const LOCATION_DENY_INTERVAL = 60 * 60 * 1000 // 未授权定位,弹窗间隔1小时 export const LOCATION_EXPIRE_KEY = 'location_expire_time' // 定位缓存KEY export const LOCATION_DENY_TIME_KEY = 'location_deny_time' // 未授权定位,重新授权时间KEY export const LOCATION_CITY_KEY = 'city' // 城市缓存KEY export const LOCATION_LAT_KEY = 'latitude' // 城市缓存KEY export const LOCATION_LNG_KEY = 'longitude' // 城市缓存KEY export const LOCATION_CURRENT = 'current_city' // 城市缓存KEY export const LOCATION_DEFAULT_CITY = '上海市' // 默认城市 export const LOCATION_DEFAULT_LNG = 121.473629 // 上海经度 export const LOCATION_DEFAULT_LAT = 31.230393 // 上海纬度 // 检查过期时间 export function handleCheckLocationCacheHooks() { const expire = uni.getStorageSync(LOCATION_EXPIRE_KEY) if (expire && Date.now() > expire) { uni.removeStorageSync(LOCATION_LAT_KEY) uni.removeStorageSync(LOCATION_LNG_KEY) uni.removeStorageSync(LOCATION_EXPIRE_KEY) return false } return true } // 设置经纬度缓存 export function handleSetLocationCacheHooks(lat: number, lng: number) { uni.setStorageSync(LOCATION_LAT_KEY, lat) uni.setStorageSync(LOCATION_LNG_KEY, lng) // uni.setStorageSync(LOCATION_EXPIRE_KEY, Date.now() + LOCATION_EXPIRE_MS) } // TODO VERSION2: 在获取经纬度之前还有弹出是否搜索附近茶室?-初始化经纬度 // export async function handleEnsureLocationAuthHooks() { // const SEARCH_CONFIRM_KEY = 'search_nearby_confirmed' // const confirmed = uni.getStorageSync(SEARCH_CONFIRM_KEY) // // 1. 检查缓存和是否已确认搜索附近茶室 // if (confirmed && handleCheckLocationCacheHooks()) { // const lat = uni.getStorageSync(LOCATION_LAT_KEY) // const lng = uni.getStorageSync(LOCATION_LNG_KEY) // if (lat && lng) return { lat, lng } // } // // 2. 判断是否已弹过确认弹窗(授权后不再弹) // return new Promise<{ lat: number, lng: number }>((resolve) => { // if (confirmed) { // // 已确认过,直接走授权 // uni.authorize({ // scope: 'scope.userLocation', // success() { // uni.getLocation({ // type: 'gcj02', // success(res) { // handleSetLocationCacheHooks(res.latitude, res.longitude) // resolve({ lat: res.latitude, lng: res.longitude }) // }, // fail() { // handleSetLocationCacheHooks(LOCATION_DEFAULT_LAT, LOCATION_DEFAULT_LNG) // resolve({ lat: LOCATION_DEFAULT_LAT, lng: LOCATION_DEFAULT_LNG }) // } // }) // }, // fail() { // // 用户拒绝授权 // if (shouldShowAuthModal()) { // uni.setStorageSync(LOCATION_DENY_TIME_KEY, Date.now()) // uni.removeStorageSync(SEARCH_CONFIRM_KEY) // 授权失败,下次启动继续弹窗 // uni.showModal({ // title: '提示', // content: '需要获取您的地理位置,请授权定位服务', // showCancel: false, // success: () => { // uni.openSetting({}) // } // }) // } // handleSetLocationCacheHooks(LOCATION_DEFAULT_LAT, LOCATION_DEFAULT_LNG) // resolve({ lat: LOCATION_DEFAULT_LAT, lng: LOCATION_DEFAULT_LNG }) // } // }) // } else { // // 未确认,弹窗 // uni.showModal({ // title: '提示', // content: '是否搜索附近茶室?', // showCancel: true, // confirmText: '是', // cancelText: '否', // success: (modalRes) => { // console.log("🚀 ~ handleEnsureLocationAuthHooks ~ modalRes:", modalRes) // if (modalRes.confirm) { // // 用户点击“是”,标记已确认,下次不再弹窗 // uni.setStorageSync(SEARCH_CONFIRM_KEY, true) // uni.authorize({ // scope: 'scope.userLocation', // success() { // uni.getLocation({ // type: 'gcj02', // success(res) { // handleSetLocationCacheHooks(res.latitude, res.longitude) // console.log("🚀 ~ handleEnsureLocationAuthHooks ~ LOCATION_DEFAULT_LAT:", LOCATION_DEFAULT_LAT, LOCATION_DEFAULT_LNG) // resolve({ lat: res.latitude, lng: res.longitude }) // }, // fail() { // handleSetLocationCacheHooks(LOCATION_DEFAULT_LAT, LOCATION_DEFAULT_LNG) // resolve({ lat: LOCATION_DEFAULT_LAT, lng: LOCATION_DEFAULT_LNG }) // } // }) // }, // fail() { // // 用户拒绝授权 // if (shouldShowAuthModal()) { // uni.setStorageSync(LOCATION_DENY_TIME_KEY, Date.now()) // uni.removeStorageSync(SEARCH_CONFIRM_KEY) // 授权失败,下次启动继续弹窗 // uni.showModal({ // title: '提示', // content: '需要获取您的地理位置,请授权定位服务', // showCancel: false, // success: () => { // uni.openSetting({}) // } // }) // } // handleSetLocationCacheHooks(LOCATION_DEFAULT_LAT, LOCATION_DEFAULT_LNG) // console.log("🚀 ~ handleEnsureLocationAuthHooks ~ LOCATION_DEFAULT_LAT:", LOCATION_DEFAULT_LAT, LOCATION_DEFAULT_LNG) // resolve({ lat: LOCATION_DEFAULT_LAT, lng: LOCATION_DEFAULT_LNG }) // } // }) // } // if (modalRes.cancel) { // // 用户点击“否”,直接返回默认上海 // handleSetLocationCacheHooks(LOCATION_DEFAULT_LAT, LOCATION_DEFAULT_LNG) // console.log("🚀 ~ handleEnsureLocationAuthHooks ~ LOCATION_DEFAULT_LAT:", LOCATION_DEFAULT_LAT, LOCATION_DEFAULT_LNG) // resolve({ lat: LOCATION_DEFAULT_LAT, lng: LOCATION_DEFAULT_LNG }) // } // } // }) // } // }) // } // VERSION1: 初始化经纬度 export async function handleEnsureLocationAuthHooks() { // 1. 检查缓存-先把缓存去掉 // if (handleCheckLocationCacheHooks()) { // const lat = uni.getStorageSync(LOCATION_LAT_KEY) // const lng = uni.getStorageSync(LOCATION_LNG_KEY) // if (lat && lng) return { lat, lng } // } // 2. 获取定位 return new Promise<{ lat: number, lng: number, }>((resolve) => { uni.authorize({ scope: 'scope.userLocation', success() { uni.getLocation({ type: 'gcj02', success(res) { handleSetLocationCacheHooks(res.latitude, res.longitude) resolve({ lat: res.latitude, lng: res.longitude}) }, fail() { // 定位失败,返回默认上海 handleSetLocationCacheHooks(LOCATION_DEFAULT_LAT, LOCATION_DEFAULT_LNG) resolve({ lat: LOCATION_DEFAULT_LAT, lng: LOCATION_DEFAULT_LNG}) } }) }, fail() { // 用户拒绝授权 if (shouldShowAuthModal()) { uni.setStorageSync(LOCATION_DENY_TIME_KEY, Date.now()) uni.showModal({ title: '提示', content: '需要获取您的地理位置,请授权定位服务', showCancel: false, success: () => { // 可引导用户去设置页面 uni.openSetting({}) } }) } // 返回默认上海 handleSetLocationCacheHooks(LOCATION_DEFAULT_LAT, LOCATION_DEFAULT_LNG) resolve({ lat: LOCATION_DEFAULT_LAT, lng: LOCATION_DEFAULT_LNG }) } }) }) } /** * 检查并弹窗授权地理位置(每小时弹一次,授权后自动获取定位) * 返回 Promise,true 表示已授权,false 表示未授权 */ export function checkLocationAuthWithModal(): Promise<{ lat: number, lng: number } | false> { return new Promise((resolve) => { uni.getSetting({ success(settingRes) { const hasAuth = settingRes.authSetting && settingRes.authSetting['scope.userLocation'] if (hasAuth) { // 已授权,自动获取并返回经纬度 uni.getLocation({ type: 'gcj02', success(res) { handleSetLocationCacheHooks(res.latitude, res.longitude) resolve({ lat: res.latitude, lng: res.longitude }) }, fail() { resolve(false) } }) } else { // 未授权,判断是否需要弹窗 const lastDeny = uni.getStorageSync(LOCATION_DENY_TIME_KEY) if (!lastDeny || (Date.now() - lastDeny > LOCATION_DENY_INTERVAL)) { uni.setStorageSync(LOCATION_DENY_TIME_KEY, Date.now()) uni.showModal({ title: '提示', content: '需要获取您的地理位置,请授权定位服务', showCancel: false, success: () => { uni.openSetting({ success(openRes) { const nowAuth = openRes.authSetting && openRes.authSetting['scope.userLocation'] if (nowAuth) { // 用户授权后,自动获取并返回经纬度 uni.getLocation({ type: 'gcj02', success(res) { handleSetLocationCacheHooks(res.latitude, res.longitude) resolve({ lat: res.latitude, lng: res.longitude }) }, fail() { resolve(false) } }) } else { resolve(false) } } }) } }) } else { resolve(false) } } }, fail() { resolve(false) } }) }) } /** * 设置城市 */ export function setLocationCity(city: string) { uni.setStorageSync(LOCATION_CITY_KEY, city) } /** * 经纬度转换为城市 * @returns */ export async function handleGetLocationCity(lat: number, lng: number) { try { console.log("🚀 ~ handleGetLocationCity ~ res:", lat, lng) const res = await getLocationToCity({ latitude: lat, longitude: lng }) if (res.message == "Success") { const params = { latitude: res.result.location.lat, longitude: res.result.location.lng, city: res.result.ad_info.city } // 通过腾讯地图返回的经纬度重新设置缓存 handleSetLocationCacheHooks(res.result.location.lat, res.result.location.lng) setLocationCity(params.city) uni.setStorageSync(LOCATION_CURRENT, params) // uni.$emit('locationUpdate', params) // 通知页面 return params } else { setLocationCity(LOCATION_DEFAULT_CITY) } } catch (error) { setLocationCity(LOCATION_DEFAULT_CITY) } } // 检查是否需要弹授权框 function shouldShowAuthModal() { const lastDeny = uni.getStorageSync(LOCATION_DENY_TIME_KEY) return !lastDeny || (Date.now() - lastDeny > LOCATION_DENY_INTERVAL) } // 强制获取定位(不走缓存,每次都重新定位) export function handleForceGetLocation(): Promise<{ lat: number, lng: number }> { return new Promise((resolve) => { uni.authorize({ scope: 'scope.userLocation', success() { uni.getLocation({ type: 'gcj02', success(res) { console.log("🚀 ~ 开始请求定位授权:handleForceGetLocation ~ res:", res) handleSetLocationCacheHooks(res.latitude, res.longitude) resolve({ lat: res.latitude, lng: res.longitude }) }, fail() { handleSetLocationCacheHooks(LOCATION_DEFAULT_LAT, LOCATION_DEFAULT_LNG) resolve({ lat: LOCATION_DEFAULT_LAT, lng: LOCATION_DEFAULT_LNG }) } }) }, fail() { handleSetLocationCacheHooks(LOCATION_DEFAULT_LAT, LOCATION_DEFAULT_LNG) resolve({ lat: LOCATION_DEFAULT_LAT, lng: LOCATION_DEFAULT_LNG }) } }) }) }