微信公众号获取用户地理位置并列出附近的门店

微信js-sdk+JAVA实现“分享到朋友圈”和“发送给朋友”功能详解,js-sdk送给朋友

主要为以下实现步骤:

1.绑定域名

先登录微信公众平台进入“公众号设置”的“功能设置”里填写“JS接口安全域名”。(特别提示不需要加上http或者https,吃过亏)

2.页面引入js文件

   <script src=";
   <script src=";

3.通过config接口注入权限验证配置

wx.config({

debug: true, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。

  appId: '', // 必填,公众号的唯一标识

  timestamp: , // 必填,生成签名的时间戳

  nonceStr: '', // 必填,生成签名的随机串

  signature: '',// 必填,签名,见附录1

  jsApiList: [] // 必填,需要使用的JS接口列表,所有JS接口列表见附录2

});

4.通过ready接口处理成功验证

  wx.ready(function(){

   //详细代码

});

5.通过error接口处理失败验证

wx.error(function(res){});

详细页面代码

<script> 
//微信分享朋友圈 
$(function(){ 
 /***用户点击分享到微信圈后加载接口接口*******/ 
  var url=window.location.href.split('#')[0]; 
   url = url.replace(/&/g, '%26'); 
  console.log("url:"+url); 
  $.ajax({ 
    url: "<%=basePath%>/lottery/shareToFriend.action?url="+url, 
    type: "POST", 
    async:true, 
    cache: false, 
    dataType: "json", 
    success: function(data){ 
      wx.config({ 
       debug: false, 
       appId: 'wx2948dfef9ef421ee', 
       timestamp:data.timeStamp, 
       nonceStr:data.nonceStr, 
       signature:data.signature, 
       jsApiList: [ 
         'checkJsApi', 
         'onMenuShareTimeline', 
         'hideOptionMenu', 
         'onMenuShareAppMessage' 
       ] 
     }); 

     wx.ready(function(){ 
       //wx.hideOptionMenu();/***隐藏分享菜单****/  
       wx.checkJsApi({ 
       jsApiList: [ 
        'getLocation', 
        'onMenuShareTimeline', 
        'onMenuShareAppMessage' 
       ], 
       success: function (res) { 
        //alert(res.errMsg); 
       } 
      }); 

      wx.onMenuShareAppMessage({ 
         title: '刮刮乐', 
         desc: '刮刮乐开始啦', 
         link: '<%=basePath%>/lottery/lottery.action?lottery.id=${lottery.id}', 
         imgUrl: '<%=basePath%>/resources/qjc/img/start.png', 
         trigger: function (res) { 
          //alert('用户点击发送给朋友'); 
         }, 
         success: function (res) { 
          alert('您已获得抽奖机会,赶紧去赢大奖吧~~'); 
          //分享之后增加游戏次数 
          $.ajax({ 
            url: "<%=basePath%>/lottery/rewardPlayCount.action?openId=${openId}&lotteryId=${lottery.id}&shareType=friend", 
            type: "POST", 
            async:true, 
            cache: false, 
            dataType: "json", 
            success: function(data){ 

            } 
           }); 
         }, 
         cancel: function (res) { 
          //alert('已取消'); 
         }, 
         fail: function (res) { 
          alert(res.errMsg); 
         } 
        }); 

       // 2.2 监听“分享到朋友圈”按钮点击、自定义分享内容及分享结果接口 
       wx.onMenuShareTimeline({ 
         title: '刮刮乐', 
         desc: '刮刮乐开始啦', 
         link: '<%=basePath%>/lottery/lottery.action?lottery.id=${lottery.id}', 
         imgUrl: '<%=basePath%>/resources/qjc/img/start.png', 
         trigger: function (res) { 
          //alert('用户点击分享到朋友圈'); 
         }, 
         success: function (res) { 
          alert('您已获得抽奖机会,赶紧去赢大奖吧~~'); 
          //分享之后增加游戏次数 
          $.ajax({ 
            url: "<%=basePath%>/lottery/rewardPlayCount.action?openId=${openId}&lotteryId=${lottery.id}&shareType=friendCircle", 
            type: "POST", 
            async:true, 
            cache: false, 
            dataType: "json", 
            success: function(data){ 

            } 
           }); 
         }, 
         cancel: function (res) { 
          //alert('已取消'); 
         }, 
         fail: function (res) { 
          alert(res.errMsg); 
         } 
      }); 

      wx.error(function (res) { 
          alert(res.errMsg); 
        }); 
      });  
    }, 
    error: function() { 
      alert('ajax request failed!!!!'); 
      return; 
    }  
  }); 
 }); 

</script> 

java后台action代码:

//微信分享 
  public void shareToFriend(){ 
    HttpServletRequest request = ServletActionContext.getRequest(); 
    String timeStamp = Sha1Util.getTimeStamp();//时间戳 
    String nonceStr = WxConfig.getUUID();//随机字符串,不长于32位 
    String url=request.getParameter("url"); 
    String signature = WxConfig.getSignature("APPId", "APP_secret", url, timeStamp, nonceStr); 
    request.setAttribute("timeStamp", timeStamp); 
    request.setAttribute("nonceStr", nonceStr); 
    request.setAttribute("url", url); 
    request.setAttribute("signature", signature); 
    WXjssdk result = new WXjssdk(timeStamp,nonceStr,signature,url); 
    CommonUtil.returnMsg(ServletActionContext.getResponse(), new Gson().toJson(result)); 
  } 

WxConfig.java代码 

">//jsapi_ticket 
  public final static String WEIXIN_JSAPI_TICKET_URL ="https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=ACCESS_TOKEN&type=jsapi"; 

  //access_token  
  public static String getAccessToken(String appId,String appSecret){ 
    String access_token; 
    access_token = mapToken.get("accessToken"); 
    if(access_token==null){ 
      String url = HttpUtil.WEIXIN_HOST_API + "/cgi-bin/token?grant_type=client_credential&appid="+appId+"&secret="+appSecret; 
      String menuJsonStr = HttpUtil.get(url); 
      final Type type = new TypeToken<Map<String, Object>>() {}.getType(); 
      final Map<Object, Object> accessTokenInfo = new Gson().fromJson(menuJsonStr, type); 
      try{ 
        access_token = accessTokenInfo.get("access_token").toString(); 
        Object expires_in = accessTokenInfo.get("expires_in"); 
        mapToken.put("accessToken", access_token); 
        logger.info("access_token:"+access_token+";expires_in:"+expires_in); 
      }catch (JSONException e) { 
        access_token = null; 
        e.printStackTrace(); 
        logger.error("errcode:{}:"+accessTokenInfo.get("errcode")+"errmsg:{}:"+accessTokenInfo.get("errmsg")); 
      } 
    } 
    return access_token; 
  } 

  //jsapi_ticket 
  public static String getJsapiTicket(String accessToken){ 
    String ticket; 
    ticket = mapTicket.get("ticket"); 
    if(ticket==null){ 
      String url = HttpUtil.WEIXIN_HOST_API + "/cgi-bin/ticket/getticket?access_token="+accessToken+"&type=jsapi"; 
      String menuJsonStr = HttpUtil.get(url); 
      final Type type = new TypeToken<Map<String, Object>>() {}.getType(); 
      final Map<Object, Object> ticketInfo = new Gson().fromJson(menuJsonStr, type); 
      try{ 
        ticket = ticketInfo.get("ticket").toString(); 
        String expires_in = ticketInfo.get("expires_in").toString(); 
        mapTicket.put("ticket", ticket); 
        logger.info("jsapi_ticket:"+ticket+";expires_in:"+expires_in); 
      }catch (JSONException e) { 
        ticket = null; 
        e.printStackTrace(); 
        logger.error("ticket errcode:{}:"+ticketInfo.get("errcode")+"errmsg:{}:"+ticketInfo.get("errmsg")); 
      } 
    } 
    return ticket; 
  } 

   //生成随机字符串UUID 
  public static String getUUID(){   
     String uuid = UUID.randomUUID().toString().trim().replaceAll("-", "");   
     return uuid;   
  }  

  //JS-SDK Signature 
  public static String getSignature(String appId,String appSecret,String url,String timeStamp,String nonceStr){ 
    String accessToken = getAccessToken(appId,appSecret); 
    String jsapi_ticket = getJsapiTicket(accessToken); 
    logger.info("accessToken==="+accessToken); 
    String signValue = "jsapi_ticket="+jsapi_ticket+"&noncestr="+nonceStr+"×tamp="+timeStamp+"&url="+url; 
    logger.info("微信JS-SDK权限验证的签名串:"+signValue); 
    //这个签名.主要是给加载微信js使用.别和上面的搞混了. 
    String signature = Sha1Util.getSha1((signValue)); 
    logger.info("微信JS-SDK权限验证的签名:"+signature); 
    return signature; 
  } 

另外项目用到的Sha1Util.java和MD5Util.java可以直接在平台下载。 

主要为以下实现步骤: 1.绑定域名 先登录微信公众平台进入...

思路分析:
1、在微信公众号内获取用户地理位置
需要js-sdk签名包(关于如何获取文档有介绍)
2、根据获取的地理位置ajax去后台请求,通过sql语句,查询中距离最近的门店(sql语句在网上搜的,位置是通过后台添加的)
3、根据城市查询门店列表,使用通过表单提交事件,ajax请求后台获取列表
4、百度地图导航页面要注意引入地址

一、开始开发

1、该功能的实现需要调用微信公众号的js-sdk接口实现

简介:
微信JS-SDK是微信公众平台面向网页开发者提供的基于微信内的网页开发工具包。
通过使用微信JS-SDK,网页开发者可借助微信高效地使用拍照、选图、语音、位置等手机系统的能力,同时可以直接使用微信 分享、扫一扫、卡券、支付等微信特有的能力,为微信用户提供更优质的网页体验。

2、调用微信js-sdk的步骤:官方的网址:https://mp.weixin.qq.com/wiki

步骤一:绑定域名

先登录微信公众平台进入“公众号设置”的“功能设置”里填写“JS接口安全域名”。

步骤二:引入JS文件

在需要调用JS接口的页面引入如下JS文件,(支持https):http://res.wx.qq.com/open/js/jweixin-1.2.0.js
备注:支持使用 AMD/CMD 标准模块加载方法加载

步骤三:通过config接口注入权限验证配置

所有需要使用JS-SDK的页面必须先注入配置信息,否则将无法调用(同一个url仅需调用一次,对于变化url的SPA的web app可在每次url变化时进行调用,目前Android微信客户端不支持pushState的H5新特性,所以使用pushState来实现web app的页面会导致签名失败,此问题会在Android6.2中修复)
具体的使用可以查看官方的文档

wx.config({
    debug: true, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
    appId: '', // 必填,公众号的唯一标识
    timestamp: , // 必填,生成签名的时间戳
    nonceStr: '', // 必填,生成签名的随机串
    signature: '',// 必填,签名,见附录1
    jsApiList: [] // 必填,需要使用的JS接口列表,所有JS接口列表见附录2
});
步骤四:通过ready接口处理成功验证
wx.ready(function(){
    // config信息验证后会执行ready方法,所有接口调用都必须在config接口获得结果之后,config是一个客户端的异步操作,所以如果需要在页面加载时就调用相关接口,则须把相关接口放在ready函数中调用来确保正确执行。对于用户触发时才调用的接口,则可以直接调用,不需要放在ready函数中。
});
步骤五:通过error接口处理失败验证
wx.error(function(res){
    // config信息验证失败会执行error函数,如签名过期导致验证失败,具体错误信息可以打开config的debug模式查看,也可以在返回的res参数中查看,对于SPA可以在这里更新签名。
})

自己的程序代码附上(我做的是获取用户的地理位置,就是出现一个获取地理位置的弹窗):
html页面:

<script src="http://res.wx.qq.com/open/js/jweixin-1.0.0.js"></script>
<script type="text/JavaScript">
//配置信息验证接口
wx.config({
   debug: false,
   appId: '<?PHP echo $signPackage["appId"];?>',
   timestamp: '<?php echo $signPackage["timestamp"];?>',
   nonceStr: '<?php echo $signPackage["nonceStr"];?>',
   signature: '<?php echo $signPackage["signature"];?>',
   jsApiList: [
       // 所有要调用的 API 都要加到这个列表中
       'checkJsApi',
       'openLocation',
       'getLocation'
     ]
           });
//验证之后进入该函数,所有需要加载页面时调用的接口都必须写在该里面
wx.ready(function () {
//基础接口判断当前客户端版本是否支持指定JS接口
wx.checkJsApi({
   jsApiList: [
       'getLocation'
   ],
   success: function (res) {
       // alert(JSON.stringify(res));
       // alert(JSON.stringify(res.checkResult.getLocation));
       if (res.checkResult.getLocation == false) {
           alert('你的微信版本太低,不支持微信JS接口,请升级到最新的微信版本!');
           return;
       }
   }
});
                 //微信获取地理位置并拉取用户列表(用户允许获取用户的经纬度)
wx.getLocation({
   success: function (res) {
       var latitude = res.latitude; // 纬度,浮点数,范围为90 ~ -90
       var longitude = res.longitude; // 经度,浮点数,范围为180 ~ -180。
               //去数据库查询获取附近的门店
                        $.ajax({
                        type: 'post',
                        url: '__CONTROLLER__/shopList',
                        dataType: 'json',
                        data: {"latitude": latitude,"longitude":longitude},
                        success:function(shopInfo){
                        //index是下表,el是值
                               $(shopInfo).each(function(index,el){
                                    $("#list").append('<div class="item-store"> <a class="s-top ui-width-100 ui-flex" href="__CONTROLLER__/shopDetail/shop_id/'+el.shop_id+'"> ![]('+el.shop_logo.substring(1)+') <div class="s-message"> <h4>'+el.shop_name+'</h4> <div class="s-address">'+el.shop_position+'</div> </div> </a> <div class="s-bottom-block ui-width-100"> <ul>  <li> <a href="__CONTROLLER__/daohang/shop_id/'+el.shop_id+'" class="db-block"> <i class="icon iconfont"></i> 一键导航  '+el.distance/1000+'km  </a> </li> </ul> </div> </div>');
                               })                        
                          }
                        });
   },
   cancel: function (res) {
    $(".city").triggerHandler("focus");
   }
                });
            });
</script>
控制器中获取门店通过sql语句获取距离一定距离的门店的列表:
if(IS_AJAX){
    $post = I('post.');
    //纬度小,经度大
    // 5公里范围是5000
    $longitude = $post['longitude'];//经度信息
    $latitude = $post['latitude'];//纬度信息
               //通过sql语句查询距离5公里之内的门店
    $sql = "select * from (select shop_id,shop_name,shop_tel,shop_position,shop_logo,  ROUND(6378.138*2*ASIN(SQRT(POW(SIN(($latitude*PI()/180-`shop_wei`*PI()/180)/2),2)+COS($latitude*PI()/180)*COS(`shop_wei`*PI()/180)*POW(SIN(($longitude*PI()/180-`shop_jing`*PI()/180)/2),2)))*1000) AS distance from sp_shop order by distance ) as a where a.distance<=5000";
    // $sql = "select * from (select shop_id,shop_name,shop_tel,shop_position,shop_logo, ROUND(6378.138*2*ASIN(SQRT(POW(SIN((36.09297*PI()/180-`shop_wei`*PI()/180)/2),2)+COS(36.09297*PI()/180)*COS(`shop_wei`*PI()/180)*POW(SIN((120.3743*PI()/180-`shop_jing`*PI()/180)/2),2)))*1000) AS distance from sp_shop order by distance ) as a where a.distance<=5000";
    $shopInfo = M()->query($sql);
    echo json_encode($shopInfo);exit;
    }else{
            if(session('openid')){
                //获取微信签名包信息(用户地理位置的获取)填写的配置信息中,需要写入的东西(调用签名包封装的类:http://blog.csdn.NET/bj123467/article/details/72910160)
                $jssdk = new HomeModelWechatModel();
                $signPackage = $jssdk->GetSignPackage();
                $this->assign('signPackage', $signPackage);
            $this->display();
            }else{
                //判断该用户是否存在
                 $model = new HomeModelWechatModel();
                 $openid_accesstoken = $model->openId();
                 $rst = M('user')->where(array('user_openid' => $openid_accesstoken['openid']))->find();
                 if($rst){
                    session('openid',$openid_accesstoken['openid']);
                    session('user_id', $rst['user_id']);
                    $jssdk = new HomeModelWechatModel();
                    $signPackage = $jssdk->GetSignPackage();
                    $this->assign('signPackage', $signPackage);
                    $this->display();exit;
                }else{
                    //如果不存在获取微信用户的基本信息
                    $userInfo = $model->getOpenId($openid_accesstoken['openid'],$openid_accesstoken['access_token']);
                    $data = array(
                        'user_img' => $userInfo['headimgurl'],
                        'user_openid' => $userInfo['openid'],
                        'user_name' => filter($userInfo['nickname']),
                        'user_register_time' => time(),
                        'city' => $userInfo['province'].'-'.$userInfo['city'],
                    );
                    $id = M('user')->add($data);
                    session('openid', $userInfo['openid']);
                    session('user_id',$id);
                    $jssdk = new HomeModelWechatModel();
                    $signPackage = $jssdk->GetSignPackage();
                    $this->assign('signPackage', $signPackage);
                    $this->display();
                }
            }
    }```

微信文档:https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140841

微信门店视频开发教程:http://edu.csdn.net/course/detail/4567

本文由365bet体育在线官网发布于365bet,转载请注明出处:微信公众号获取用户地理位置并列出附近的门店

TAG标签:
Ctrl+D 将本页面保存为书签,全面了解最新资讯,方便快捷。