微信&支付宝小程序 获取用户位置(通过经纬度精确到所在城市)

628 阅读3分钟

关于定位

前言

本次的项目上线,笔者忙的焦头烂额,一方面是页面重构的压力太大、留给开发和测试的时间都很短, 我大概只有三四天的时间,在我不分昼夜的努力下,还是给测试留出了两天左右的测试时间,正当我沾沾自喜,觉得可以过一个愉快的端午假期的时候,意外还是来了。。。
公司的主要用户集中在了上海(成都也有部分用户占比大概30-40%之间),这次的首页改版,做了很多活动和促销,成都用户毫无意外,都不能参与进来,但是开发的时候,产品、我都没有考虑到这个情况,在最后这个下午去和老板确定最后上线方案的时候才后知后觉,一时之间,我也不知如何是好。。。

最后还是前端做了简单的处理,对成都用户所有的活动进行了拦截。。。

新的需求

虽然最后项目还是推进了,但是我的任务并没有到此结束,经过这次事件后,公司决定对上海和成都用户的页面展示做条件判断再进行展示。

原来项目中,对用户的所在城市,都是用户登录之后,在数据库里获取这个用户的相关信息,前端再来做处理,相当于给我一道难题,我迅速的查阅了相关文档。

  • 文档如下

支付宝小程序获取用户位置信息

aa.png

aaa.png

从支付宝小程序的文档中就可以得到用户的城市,看到这里,我还是蛮开心的,我以为微信会和支付宝一样,会有相关的API , 但是打脸来的是如此迅速

微信小程序获取用户信息文档

Snipaste_2023-06-25_16-55-27.png

很遗憾微信并没有相关的API可以直接获取到用户所在城市

解决

支付宝这里无须多说,已经有了解决方法

重点就在微信小程序上

1_ 去腾讯位置服务申请Key值

腾讯位置服务

  • 配置如下图,一定要都配置好 vvvv.png

2_ 在代码里引入qqmap-wx-jssdk.js

文件下载链接

  • 解压完成之后,在代码中引入
  • 我是出于对性能的考虑,用条件编译,把微信和支付宝的方法封装在了一起,用promise抛出结果

直接上代码

const QQMapWX = require('../libs/qqmap-wx-jssdk.js');
export const GetLocation = async  (lat , lon) => {
    //  #ifdef MP-WEIXIN
    const qqmapsdk = new QQMapWX({
        key: 'YB6BZ-7QI6Z-NV7X4-TGCDF-2KBVH-ANB56' // 必填
    }); 
    //使用逆编码获取用户详细地址
    const res = await new Promise((resolve)=>{
        qqmapsdk.reverseGeocoder({
            location: `${lat},${lon}`,
            success: async (data) => {
                console.log('微信获取的城市', data.result.address_component.city);
                resolve(data.result.address_component.city)
            }
        });
    })
    // #endif
    // #ifdef MP-ALIPAY
    const res = await new Promise((resolve)=>{
        my.getLocation({
            type:1,    // 传入type 没有type 或者type=0的情况下 是没有城市的
            success(res) {
                console.log('支付宝位置信息',res.city);
                resolve(res.city)
            }
        })
    })
    // #endif
    return res
} 

3_ 调用该方法

剩下在需要的地方调用方法就可以了 注意:这些方法的前提是 用户给微信和支付宝APP授权了位置使用,如果不授权,那么还是不可以的

const city = await GetLocation(this.lat, this.lng)
console.log('所在城市:',city);

补充: 引导用户打开位置授权

//监控用户是否打开了定位权限
monitorLocation() {
    //获取用户设置如果为打开定位提醒用户打开定位
    uni.getSetting({
        success:res => {
            // #ifdef MP-ALIPAY
            const isOpen = res.authSetting.location
            // #endif
            // #ifdef MP-WEIXIN
            const isOpen = res.authSetting['scope.userLocation']
            console.log(res.authSetting,'scope.userLocation',isOpen);
            // #endif
            if(isOpen === undefined) {
                uni.showModal({
                    content:'无法获取您的位置信息,请检查手机是否开启了定位,可在手机设置中查看',
                    showCancel:false
                })
                return
        }
        if (isOpen === false) {
                uni.showModal({
                    title: '温馨提示',
                    content: '您拒绝了获取位置信息,小程序需要获取当前位置来为您展示附件换电柜,请前往打开位置信息',
                    success: res => {
                        if (res.confirm) {
                            uni.openSetting({
                                success:res=> {
                                    if(res.authSetting.location) {
                                	this.map.moveToLocation(); //显示地图
                                   }
                                }
                            })
                        }
                    }
                })
            }
        }
    })
},

如有不妥的地方,欢迎各位朋友交流指正