有一个表单,需要在填报过程中获取地理位置。定位方式有三种:H5,百度,公众号。因大家习惯了微信操作,最终选择通过微信公众号接口获取位置数据并写入数据库,再调用腾讯地图展示。
开发架构是laravel6.4 ,前端html代码:
前端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);
}
教程完毕,系统使用正常。