微信公众号定位地图位置写入数据库,再显示地图的方法
有一个表单,需要在填报过程中获取地理位置。定位方式有三种:H5,百度,公众号。因大家习惯了微信操作,最终选择通过微信公众号接口获取位置数据并写入数据库,再调用腾讯地图展示。
开发架构是laravel6.4 ,前端html代码:
{{$val}}
前端js代码:
//点击地图定位按钮 $(".dtdw").click(function(){ //判断是否微信中打开 var is_weixin = (function(){return navigator.userAgent.toLowerCase().indexOf('micromessenger') !== -1})(); if(is_weixin){ var data = $(this).attr('id'); var strs = new Array(); //定义一数组 strs = data.split(","); //字符分割 var id = strs[0];//待写入id var bm = strs[1];//表名 if(window.confirm('定位需要几秒时间,确认定位?')){ $.ajax({ url:"/getConfig", type:"get", data: {url: location.href}, async:true, dataType:"json", success:function (data){ //console.log(data); wx.config({ debug: false, // 开启调试模式,调用的所有api的返回值会在客户端alert出来 appId: data.appid, // 必填,公众号的唯一标识 timestamp: data.timestamp, // 必填,生成签名的时间戳 nonceStr: data.nonceStr, // 必填,生成签名的随机串 signature: data.signature,// 必填,签名,见附录1 jsApiList: ['getLocation','openLocation'] // 填入需要使用的JS接口列表 }); wx.ready(function(){ wx.checkJsApi({ jsApiList: ['getLocation','openLocation'], }); //config信息验证后会执行ready方法对于用户触发时才调用的接口,则可以直接调用,不需要放在ready函数中。 wx.getLocation({ type: 'gcj02', // 默认为wgs84的gps坐标,如果要返回直接给openLocation用的火星坐标,可传入'gcj02' success: function (res) { console.log(res); var weidu = res.latitude; // 纬度,浮点数,范围为90 ~ -90 var jingdu = res.longitude; // 经度,浮点数,范围为180 ~ -180。 var sudu = res.speed; // 速度,以米/每秒计 var wzjd = res.accuracy; // 位置精度 wxdwxr(weidu,jingdu,sudu,wzjd,id,bm);//传给后端写入数据库 } }); }); wx.error(function(res){ console.log(res); // config信息验证失败会执行error函数,如签名过期导致验证失败,具体错误信息可以打开config的debug模式查看,也可以在返回的res参数中查看,对于SPA可以在这里更新签名。 }); } }); } }else{ alert('地图定位需要使用微信打开!'); } }); //将定位数据写入 function wxdwxr(weidu,jingdu,sudu,wzjd,id,bm){ $.ajax({ headers: { 'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')}, url:"/wxdwxr",//微信支付接口 type:"POST", data:{'weidu':weidu,'jingdu':jingdu,'sudu':sudu,'wzjd':wzjd,'id':id,'bm':bm}, async:true, dataType:"json", success:function (data){ console.log(data); if (data.status == "200"){//成功 alert('定位成功,进入地图查看位置!'); //使用微信内置地图查看位置接口 wx.openLocation({ latitude: data.weidu, // 纬度,浮点数,范围为90 ~ -90 longitude: data.jingdu, // 经度,浮点数,范围为180 ~ -180。 name: '该贫困户位置', // 位置名 address: '车溪乡朱坑村', // 地址详情说明 scale: 15, // 地图缩放级别,整形值,范围从1~28。默认为最大 infoUrl: 'https://blog.dzbfsj.com/cx' // 在查看位置界面底部显示的超链接,可点击跳转 }); } }, error:function (error){ alert(error); } }); } //显示地图 $(".xsdt").click(function(){ //判断是否微信中打开 var is_weixin = (function(){return navigator.userAgent.toLowerCase().indexOf('micromessenger') !== -1})(); if(is_weixin){ var data = $(this).attr('id'); var strs = new Array(); //定义一数组 strs = data.split("_"); //字符分割 var id = strs[0]; var bm = strs[1]; var dwxx = strs[2];//定位的json,包含经纬度 var dwjx = JSON.parse(dwxx);//解析json //console.log(dwjx); $.ajax({ url:"/getConfig", type:"get", data: {url: location.href}, async:true, dataType:"json", success:function (data){ //console.log(data); wx.config({ debug: false, // 开启调试模式,调用的所有api的返回值会在客户端alert出来 appId: data.appid, // 必填,公众号的唯一标识 timestamp: data.timestamp, // 必填,生成签名的时间戳 nonceStr: data.nonceStr, // 必填,生成签名的随机串 signature: data.signature,// 必填,签名,见附录1 jsApiList: ['openLocation'] // 填入需要使用的JS接口列表 }); wx.ready(function(){ wx.checkJsApi({ jsApiList: ['openLocation'], }); wx.openLocation({ latitude: dwjx[0], // 纬度,浮点数,范围为90 ~ -90 longitude: dwjx[1], // 经度,浮点数,范围为180 ~ -180。 name: '该贫困户位置', // 位置名 address: '车溪乡朱坑村', // 地址详情说明 scale: 15, // 地图缩放级别,整形值,范围从1~28。默认为最大 infoUrl: 'https://blog.dzbfsj.com/cx' // 在查看位置界面底部显示的超链接,可点击跳转 }); }); wx.error(function(res){ console.log(res); }); } }); }else{ alert('地图需要使用微信打开!'); } });
后端controller PHP代码:
//地图定位 public function getConfig(Request $request) { //获取参数 $url = $request->get('url'); //公众号的appid、secret $appid = env('WEIXIN_KEY'); $secret = env('WEIXIN_SECRET'); //缓存内是否存在accessToken。 $accessToken = Cache::remember('accessToken11', 120, function () use ($appid, $secret) { //获取access_token的请求地址 $accessTokenUrl = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=$appid&secret=$secret"; //请求地址获取access_token $accessTokenJson = file_get_contents($accessTokenUrl); $accessTokenObj = json_decode($accessTokenJson); $accessToken = $accessTokenObj->access_token; return $accessToken; }); //获取jsapi_ticket的请求地址 $ticketUrl = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=$accessToken&type=jsapi"; $jsapiTicketJson = file_get_contents($ticketUrl); $jsapiTicketObj = json_decode($jsapiTicketJson); $jsapiTicket = $jsapiTicketObj->ticket; //随机生成16位字符 $noncestr = str_random(16); //时间戳 $time = time(); //拼接string1 $jsapiTicketNew = "jsapi_ticket=$jsapiTicket&noncestr=$noncestr×tamp=$time&url=$url"; //对string1作sha1加密 $signature = sha1($jsapiTicketNew); //存入数据 $data = [ 'appid' => $appid, 'timestamp' => $time, 'nonceStr' => $noncestr, 'signature' => $signature, 'jsapiTicket' => $jsapiTicket, 'url' => $url, 'jsApiList' => 'getLocation' ]; return json_encode($data); } //定位数据写入数据库 public function wxdwxr(Request $request) { //获取参数weidu,jingdu,sudu,wzjd,id,bm $weidu = $request->weidu;//纬度 $jingdu = $request->jingdu;//经度 //$sudu = $request->sudu;//速度 //$wzjd = $request->wzjd;//位置精度 $wzsz = array($weidu,$jingdu);//位置数组 $wzjson = json_encode($wzsz);//转json字符串 $id = $request->id; $bm = $request->bm; $xrjg = DB::table($bm)->where('id', $id)->update(['地图位置' => $wzjson]);//更新数据库 $cxmz = array('status' => '200','weidu' => $weidu,'jingdu' => $jingdu); echo json_encode($cxmz,JSON_UNESCAPED_UNICODE); }
教程完毕,系统使用正常。