微信接口调用百度地图api实现微信公众号打卡

时间:2019-07-20
本文章向大家介绍微信接口调用百度地图api实现微信公众号打卡,主要包括微信接口调用百度地图api实现微信公众号打卡使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

前言

因最近给的需求要在微信公众号完成考勤打卡,刚开始说根据员工连接公司的wifi去判断,网上查了下java好像没得这个功能,所以只能选择在地图来完成。

本人也是第一次接触微信公众号,所以刚开始动手比较困难,好在经过一番摸索还是完成了。这里记录下自己的地图方案。

准备工作

既然是微信公众号肯定是基于微信接口的,也不用想的那么复杂,其实就是基于前台weui样式+微信js接口。下面详细说明步骤。

首先需要在公众号设置功能设置中配置微信公众号js接口安全域名

按流程把文件放在项目工程静态资源下

另外在基本配置中查看开发者密码后设置IP白名单,否则后续调用jssdk会报自身IP不在白名单内的错误

获取微信接口回调的数据

  1 public class GetWeChatUtil {    
  2     public static final String wechat_token_url = "https://api.weixin.qq.com/cgi-bin/token"
  3 
  4     public static final String wechat_appid = "xxx";
  5     
  6     public static final String wechat_secret = "xxx";
  7     
  8     public static final String wechat_token_grant_type = "client_credential";
  9     
 10     public static final String wechat_jsapi_ticket_url = "https://api.weixin.qq.com/cgi-bin/ticket/getticket";
 11     
 12     public static final String wechat_jsapi_ticket_type = "jsapi";
 13 
 14     public static Map<String,Object> getWeChatToken(){
 15         Map<String,Object> map = new HashMap<>();        
 16         try {
 17             Map<String,String> params = new HashMap<String, String>();
 18             String ss = HttpConnectionUtil.httpsSendPost(wechat_token_url + "?grant_type=" + wechat_token_grant_type+"&appid="+wechat_appid+"&secret="+wechat_secret, null, "", "UTF-8", null);
 19             System.out.println("----获取token返回信息:"+ss);    
 20             JSONObject json = JSONObject.parseObject(ss);
 21             if(json.containsKey("access_token")){
 22                 map.put("token", json.get("access_token"));
 23                 map.put("expires", json.get("expires_in"));
 24             }
 25         } catch (Exception e) {
 26             e.printStackTrace();
 27         }
 28         return map;
 29     }
 30     
 31     public static Map<String,Object> getJsapiTicket(String token) {
 32         Map<String,Object> map = new HashMap<String, Object>();
 33         try {
 34             Map<String,String> params = new HashMap<>();
 35             params.put("access_token", token);
 36             params.put("type", "jsapi");
 37             String ss = HttpConnectionUtil.httpsSendPost(wechat_jsapi_ticket_url + "?access_token=" + token + "&type=" + wechat_jsapi_ticket_type, null, "", "UTF-8", null);
 38             System.out.println("----获取JsapiTicket返回信息:"+ss);
 39             JSONObject json = JSONObject.parseObject(ss);
 40             if (json.getIntValue("errcode") == 0) {
 41                 map.put("ticket", json.get("ticket"));
 42                 map.put("expires", json.get("expires_in"));
 43             }
 44         }catch (Exception e) {
 45             e.printStackTrace();
 46         }    
 47         return map;
 48     }
 49     
 50     public static Map<String, String> sign(String jsapi_ticket, String url) {
 51         Map<String, String> ret = new HashMap<>();
 52         String nonce_str = create_nonce_str();
 53         String timestamp = create_timestamp();
 54         String string1;
 55         String signature = "";
 56 
 57         string1 = "jsapi_ticket=" + jsapi_ticket +
 58                   "&noncestr=" + nonce_str +
 59                   "&timestamp=" + timestamp +
 60                   "&url=" + url;
 61         try {
 62             MessageDigest crypt = MessageDigest.getInstance("SHA-1");
 63             crypt.reset();
 64             crypt.update(string1.getBytes("UTF-8"));
 65             signature = byteToHex(crypt.digest());
 66         }
 67         catch (NoSuchAlgorithmException e) {
 68             e.printStackTrace();
 69         }
 70         catch (UnsupportedEncodingException e) {
 71             e.printStackTrace();
 72         }
 73 
 74         ret.put("url", url);
 75         ret.put("jsapi_ticket", jsapi_ticket);
 76         ret.put("nonceStr", nonce_str);
 77         ret.put("timestamp", timestamp);
 78         ret.put("signature", signature);
 79 
 80         return ret;
 81     }
 82     
 83     private static String byteToHex(final byte[] hash) {
 84         Formatter formatter = new Formatter();
 85         for (byte b : hash) {
 86             formatter.format("%02x", b);
 87         }
 88         String result = formatter.toString();
 89         formatter.close();
 90         return result;
 91     }
 92     
 93     private static String create_nonce_str() {
 94         return UUID.randomUUID().toString();
 95     }
 96 
 97     private static String create_timestamp() {
 98         return Long.toString(System.currentTimeMillis() / 1000);
 99     }
100 }

返回给前端调用微信接口必要参数

 1 @Resource
 2 private RedisTemplate<String,String> redisTemplate;
 3 
 4 @RequestMapping("getwechatparams")
 5 @ResponseBody
 6 public Map<String,String> getParams(@RequestParam String url) {
 7     if (redisTemplate.opsForValue().get("token") == null) {
 8         Map<String,Object> map = GetWeChatUtil.getWeChatToken();
 9     if (map.get("token") != null) {
10         redisTemplate.opsForValue().set("token", map.get("token").toString(), Long.parseLong(map.get("expires").toString()), TimeUnit.SECONDS);
11     }
12     }
13     System.out.println("-----getWeToken:"+redisTemplate.opsForValue().get("token"));
14     if (redisTemplate.opsForValue().get("ticket") == null) {
15     Map<String,Object> mm = GetWeChatUtil.getJsapiTicket(redisTemplate.opsForValue().get("token"));
16     if (mm.get("ticket") != null) {
17         redisTemplate.opsForValue().set("ticket", mm.get("ticket").toString(), Long.parseLong(mm.get("expires").toString()), TimeUnit.SECONDS);
18     }
19     }
20     System.out.println("-----getWeTicket:"+redisTemplate.opsForValue().get("ticket"));
21     String weTicket = redisTemplate.opsForValue().get("ticket");
22     Map<String, String> ret = GetWeChatUtil.sign(weTicket, url);
23     ret.put("appId", GetWeChatUtil.wechat_appid);
24     return ret;
25 }

前端百度地图显示

这里就只贴显示地图的关键性代码

1 <script type="text/javascript" src="https://api.map.baidu.com/api?v=2.0&ak=ak密匙"></script>
2 <script type="text/javascript" src="https://res.wx.qq.com/open/js/jweixin-1.0.0.js"></script>
3 
4 <div id="allmap" style="width: 100%; height: 410px;"></div>

这里需要调用wx.getLocation()回调成功后的参数res中存放的是当前自身的GPS经纬度坐标,需要将GPS坐标系通过百度接口转换成百度坐标系

  1 $(function () {
  2     $.ajax({
  3         async: false,
  4         url: "/getwechatparams",
  5         type: "POST",
  6         data: {
  7             "url": window.location.href
  8         },
  9         dataType: "json",
 10         success: function (bal) {
 11             wx.config({
 12                 debug: false, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
 13                 appId: bal.appId, // 必填,公众号的唯一标识
 14                 timestamp: bal.timestamp, // 必填,生成签名的时间戳
 15                 nonceStr: bal.nonceStr, // 必填,生成签名的随机串
 16                 signature: bal.signature,// 必填,签名,见附录1
 17                 jsApiList: ['openLocation', 'getLocation'] // 必填,需要使用的JS接口列表,所有JS接口列表见附录2
 18             });
 19             wx.ready(function () {
 20                 wx.getLocation({    // 获取微信接口中的当前坐标经纬度
 21                     type: 'wgs84',  // GPS坐标
 22                     success: function (res) {
 23                         //alert("gps转换前:" + res.longitude + "," + res.latitude)
 24 
 25                         var lnggg = '';  // 经度
 26                         var lattt = '';  // 纬度
 27                         var coordinate = '';  // 签到地点坐标
 28 
 29                         $.ajax({
 30                             async: false,
 31                             url: "/get/location",
 32                             data: {
 33                                 "longitude": res.longitude,
 34                                 "latitude": res.latitude
 35                             },
 36                             dataType: 'json',
 37                             success: function (responseData) {
 38                                 lnggg = responseData.obj.lng;
 39                                 lattt = responseData.obj.lat;
 40                             },
 41                             error: function (responseData) {
 42                                 alert(responseData.msg);
 43                             }
 44                         });
 45 
 46                         // 百度地图API功能
 47                         var map = new BMap.Map("allmap");
 48                         map.enableScrollWheelZoom(true);
 49 
 50                         //alert("gps转换后" + lnggg + ',' + lattt);
 51                         var point = new BMap.Point(lnggg, lattt);
 52 
 53                         var geo = new BMap.Geocoder();
 54                         geo.getLocation(point, function (rs) {
 55                             var addComp = rs.addressComponents;
 56                             var address = addComp.city + addComp.district + addComp.street;  // 当前自身详情街道地址
 57                             //alert(address)
 58                         });
 59 
 60                         var geolocation = new BMap.Geolocation();
 61                         geolocation.getCurrentPosition(function (r) {
 62                             r.point.lng = lnggg;
 63                             r.point.lat = lattt;
 64                             //alert("r.point.lng:" + r.point.lng + ",r.point.lat:" + r.point.lat);
 65                             if (this.getStatus() == BMAP_STATUS_SUCCESS) {
 66                                 var mk = new BMap.Marker(r.point); // 创建标注
 67                                 map.addOverlay(mk); // 将标注小红点添加到地图中
 68                                 map.centerAndZoom(r.point, 16); // 缩放级别16
 69                                 map.panTo(r.point);
 70 
 71                                 coordinate = "116.40213223,40.10213223";    // 签到地点坐标
 72                                 var arr = coordinate.split(",");
 73                                 var lon = arr[0];
 74                                 var latt = arr[1];
 75                                 var pointAttendance = new BMap.Point(lon, latt);
 76                                 r.point.lng = lon;
 77                                 r.point.lat = latt;
 78                                 var mk2 = new BMap.Marker(r.point);
 79                                 var label = new BMap.Label("显示的文字", {offset: new BMap.Size(20, -10)});
 80                                 mk2.setLabel(label);
 81                                 map.addOverlay(mk2);
 82                                 map.addOverlay(pointAttendance);
 83                                 mk2.setAnimation(BMAP_ANIMATION_BOUNCE); // 点跳动,没反应
 84 
 85                                 circle = new BMap.Circle(pointAttendance, 200, {
 86                                     fillColor: "blue",
 87                                     strokeWeight: 1,
 88                                     fillOpacity: 0.2,
 89                                     strokeOpacity: 0.2
 90                                 });// 显示签到点的位置(半径为200米的一个圆)
 91                                 map.addOverlay(circle);
 92 
 93                                 //计算当前位置与考勤点距离
 94                                 var distance = map.getDistance(pointAttendance, point).toFixed(2);
 95                                 //alert("距离为" + distance);
 96 
 97                             } else {
 98                                 switch (this.getStatus()) {
 99                                     case 2:
100                                         $.alert("位置结果未知 获取位置失败...", "加载地图失败", function () {});
101                                         break;
102                                     case 3:
103                                         $.alert("导航结果未知 获取位置失败...", "加载地图失败", function () {});
104                                         break;
105                                     case 4:
106                                         $.alert("非法密钥 获取位置失败...", "加载地图失败", function () {});
107                                         break;
108                                     case 5:
109                                         $.alert("非法请求位置 获取位置失败...", "加载地图失败", function () {});
110                                         break;
111                                     case 6:
112                                         $.alert("sorry 当前没有权限 获取位置失败...", "加载地图失败", function () {});
113                                         break;
114                                     case 7:
115                                         $.alert("sorry 服务不可用 获取位置失败...", "加载地图失败", function () {});
116                                         break;
117                                     case 8:
118                                         $.alert("sorry 请求超时 获取位置失败...", "加载地图失败", function () {});
119                                         break;
120                                 }
121                             }
122                         }, {
123                             enableHighAccuracy: true
124                         })
125                     },
126                     error: function () {
127                         $.alert("请检查GPS网络是否正常", "加载地图失败", function () {});
128                     }
129                     }
130                 );
131             });
132         }
133     });
134 });

GPS坐标系转百度坐标系

 1 @RequestMapping("get/location")
 2 @ResponseBody
 3 public AjaxResponse getLocation(String longitude, String latitude) {
 4     try {
 5         Map<String, String> mapLocation = ScHttpRequestUtil.getWpsToBaiduLocation(longitude, latitude);
 6         return new AjaxResponse().setObj(mapLocation);
 7     } catch (IOException e) {
 8         log.error("{[]}", e);
 9         return new AjaxResponse().setMsg("地址解析错误请重试!");
10     }
11 }
12 
13 public static synchronized Map<String, String> getWpsToBaiduLocation(String longitude, String latitude) throws IOException {
14     BufferedReader br = null;
15     StringBuffer sb = new StringBuffer();
16     URL url = new URL("http://api.map.baidu.com/ag/coord/convert?from=0&to=4&x=" + longitude + "&y=" + latitude);
17     br = new BufferedReader(new InputStreamReader(url.openStream(), "utf-8"));
18     String str = null;
19     while ((str = br.readLine()) != null) {
20         sb.append(str);
21     }
22     Map<String,String> map = (Map<String, String>) JSON.parse(sb.toString());
23 
24     Base64.Decoder decoder = Base64.getDecoder();
25 
26     String lng = new String(decoder.decode(map.get("x")), "utf-8");
27     String lat = new String(decoder.decode(map.get("y")), "utf-8");
28     Map<String, String> mapLocation = new HashMap<>();
29     map.put("lng", lng);
30     map.put("lat", lat);
31     return map;
32 }

至此,基于微信接口实现百度地图的功能就完成了,功能就这么简单

原文地址:https://www.cnblogs.com/swanyf/p/11207729.html