zoukankan      html  css  js  c++  java
  • 微信接口调用百度地图api实现微信公众号打卡

    前言

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

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

    准备工作

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

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

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

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

    获取微信接口回调的数据

    public class GetWeChatUtil {    
        public static final String wechat_token_url = "https://api.weixin.qq.com/cgi-bin/token"
    
        public static final String wechat_appid = "xxx";
        
        public static final String wechat_secret = "xxx";
        
        public static final String wechat_token_grant_type = "client_credential";
        
        public static final String wechat_jsapi_ticket_url = "https://api.weixin.qq.com/cgi-bin/ticket/getticket";
        
        public static final String wechat_jsapi_ticket_type = "jsapi";
    
        public static Map<String,Object> getWeChatToken(){
            Map<String,Object> map = new HashMap<>();        
            try {
                Map<String,String> params = new HashMap<String, String>();
                String ss = HttpConnectionUtil.httpsSendPost(wechat_token_url+"?grant_type="+wechat_token_grant_type
                  +"&appid="+wechat_appid+"&secret="+wechat_secret, null, "", "UTF-8", null); System.out.println("----获取token返回信息:"+ss); JSONObject json = JSONObject.parseObject(ss); if(json.containsKey("access_token")){ map.put("token", json.get("access_token")); map.put("expires", json.get("expires_in")); } } catch (Exception e) { e.printStackTrace(); } return map; } public static Map<String,Object> getJsapiTicket(String token) { Map<String,Object> map = new HashMap<String, Object>(); try { Map<String,String> params = new HashMap<>(); params.put("access_token", token); params.put("type", "jsapi"); String ss = HttpConnectionUtil.httpsSendPost(wechat_jsapi_ticket_url + "?access_token=" + token + "&type=" + wechat_jsapi_ticket_type, null, "", "UTF-8", null); System.out.println("----获取JsapiTicket返回信息:"+ss); JSONObject json = JSONObject.parseObject(ss); if (json.getIntValue("errcode") == 0) { map.put("ticket", json.get("ticket")); map.put("expires", json.get("expires_in")); } }catch (Exception e) { e.printStackTrace(); } return map; } public static Map<String, String> sign(String jsapi_ticket, String url) { Map<String, String> ret = new HashMap<>(); String nonce_str = create_nonce_str(); String timestamp = create_timestamp(); String string1; String signature = ""; string1 = "jsapi_ticket=" + jsapi_ticket + "&noncestr=" + nonce_str + "&timestamp=" + timestamp + "&url=" + url; try { MessageDigest crypt = MessageDigest.getInstance("SHA-1"); crypt.reset(); crypt.update(string1.getBytes("UTF-8")); signature = byteToHex(crypt.digest()); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } ret.put("url", url); ret.put("jsapi_ticket", jsapi_ticket); ret.put("nonceStr", nonce_str); ret.put("timestamp", timestamp); ret.put("signature", signature); return ret; } private static String byteToHex(final byte[] hash) { Formatter formatter = new Formatter(); for (byte b : hash) { formatter.format("%02x", b); } String result = formatter.toString(); formatter.close(); return result; } private static String create_nonce_str() { return UUID.randomUUID().toString(); } private static String create_timestamp() { return Long.toString(System.currentTimeMillis() / 1000); } }

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

    @Resource
    private RedisTemplate<String,String> redisTemplate;
    
    @RequestMapping("getwechatparams")
    @ResponseBody
    public Map<String,String> getParams(@RequestParam String url) {
        if (redisTemplate.opsForValue().get("token") == null) {
            Map<String,Object> map = GetWeChatUtil.getWeChatToken();
        if (map.get("token") != null) {
            redisTemplate
            .opsForValue()
            .set("token", map.get("token").toString(), 
                Long.parseLong(map.get("expires").toString()), TimeUnit.SECONDS);
        }
        }
        System.out.println("-----getWeToken:"+redisTemplate.opsForValue().get("token"));
        if (redisTemplate.opsForValue().get("ticket") == null) {
        Map<String,Object> mm = GetWeChatUtil.getJsapiTicket(redisTemplate.opsForValue().get("token"));
        if (mm.get("ticket") != null) {
            redisTemplate
            .opsForValue()
            .set("ticket", mm.get("ticket").toString(), 
                Long.parseLong(mm.get("expires").toString()), TimeUnit.SECONDS);
        }
        }
        System.out.println("-----getWeTicket:"+redisTemplate.opsForValue().get("ticket"));
            String weTicket = redisTemplate.opsForValue().get("ticket");
        Map<String, String> ret = GetWeChatUtil.sign(weTicket, url);
        ret.put("appId", GetWeChatUtil.wechat_appid);
        return ret;
    }

    前端百度地图显示

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

    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=" 100%; height: 410px;"></div>

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

    $(function () {
        $.ajax({
            async: false,
            url: "/getwechatparams",
            type: "POST",
            data: {
                "url": window.location.href
            },
            dataType: "json",
            success: function (bal) {
                wx.config({
                    debug: false, // 开启调试模式,调用的所有api的返回值会在客户端alert出来
                    appId: bal.appId, // 必填,公众号的唯一标识
                    timestamp: bal.timestamp, // 必填,生成签名的时间戳
                    nonceStr: bal.nonceStr, // 必填,生成签名的随机串
                    signature: bal.signature,// 必填,签名,见附录1
                    jsApiList: ['openLocation', 'getLocation'] // 必填,需要使用的JS接口列表,所有JS接口列表见附录2
                });
                wx.ready(function () {
                    wx.getLocation({    // 获取微信接口中的当前坐标经纬度
                        type: 'wgs84',  // GPS坐标
                        success: function (res) {
                            //alert("gps转换前:" + res.longitude + "," + res.latitude)
    
                            var lnggg = '';  // 经度
                            var lattt = '';  // 纬度
                            var coordinate = '';  // 签到地点坐标
    
                            $.ajax({
                                async: false,
                                url: "/get/location",
                                data: {
                                    "longitude": res.longitude,
                                    "latitude": res.latitude
                                },
                                dataType: 'json',
                                success: function (responseData) {
                                    lnggg = responseData.obj.lng;
                                    lattt = responseData.obj.lat;
                                },
                                error: function (responseData) {
                                    alert(responseData.msg);
                                }
                            });
    
                            // 百度地图API功能
                            var map = new BMap.Map("allmap");
                            map.enableScrollWheelZoom(true);
    
                            //alert("gps转换后" + lnggg + ',' + lattt);
                            var point = new BMap.Point(lnggg, lattt);
    
                            var geo = new BMap.Geocoder();
                            geo.getLocation(point, function (rs) {
                                var addComp = rs.addressComponents;
                                var address = addComp.city + addComp.district + addComp.street;  // 当前自身详情街道地址
                                //alert(address)
                            });
    
                            var geolocation = new BMap.Geolocation();
                            geolocation.getCurrentPosition(function (r) {
                                r.point.lng = lnggg;
                                r.point.lat = lattt;
                                //alert("r.point.lng:" + r.point.lng + ",r.point.lat:" + r.point.lat);
                                if (this.getStatus() == BMAP_STATUS_SUCCESS) {
                                    var mk = new BMap.Marker(r.point); // 创建标注
                                    map.addOverlay(mk); // 将标注小红点添加到地图中
                                    map.centerAndZoom(r.point, 16); // 缩放级别16
                                    map.panTo(r.point);
    
                                    coordinate = "116.40213223,40.10213223";    // 签到地点坐标
                                    var arr = coordinate.split(",");
                                    var lon = arr[0];
                                    var latt = arr[1];
                                    var pointAttendance = new BMap.Point(lon, latt);
                                    r.point.lng = lon;
                                    r.point.lat = latt;
                                    var mk2 = new BMap.Marker(r.point);
                                    var label = new BMap.Label("显示的文字", {offset: new BMap.Size(20, -10)});
                                    mk2.setLabel(label);
                                    map.addOverlay(mk2);
                                    map.addOverlay(pointAttendance);
                                    mk2.setAnimation(BMAP_ANIMATION_BOUNCE); // 点跳动,没反应
    
                                    circle = new BMap.Circle(pointAttendance, 200, {
                                        fillColor: "blue",
                                        strokeWeight: 1,
                                        fillOpacity: 0.2,
                                        strokeOpacity: 0.2
                                    });// 显示签到点的位置(半径为200米的一个圆)
                                    map.addOverlay(circle);
    
                                    //计算当前位置与考勤点距离
                                    var distance = map.getDistance(pointAttendance, point).toFixed(2);
                                    //alert("距离为" + distance);
    
                                } else {
                                    switch (this.getStatus()) {
                                        case 2:
                                            $.alert("位置结果未知 获取位置失败...", "加载地图失败", function () {});
                                            break;
                                        case 3:
                                            $.alert("导航结果未知 获取位置失败...", "加载地图失败", function () {});
                                            break;
                                        case 4:
                                            $.alert("非法密钥 获取位置失败...", "加载地图失败", function () {});
                                            break;
                                        case 5:
                                            $.alert("非法请求位置 获取位置失败...", "加载地图失败", function () {});
                                            break;
                                        case 6:
                                            $.alert("sorry 当前没有权限 获取位置失败...", "加载地图失败", function () {});
                                            break;
                                        case 7:
                                            $.alert("sorry 服务不可用 获取位置失败...", "加载地图失败", function () {});
                                            break;
                                        case 8:
                                            $.alert("sorry 请求超时 获取位置失败...", "加载地图失败", function () {});
                                            break;
                                    }
                                }
                            }, {
                                enableHighAccuracy: true
                            })
                        },
                        error: function () {
                            $.alert("请检查GPS网络是否正常", "加载地图失败", function () {});
                        }
                        }
                    );
                });
            }
        });
    });

    GPS坐标系转百度坐标系

    @RequestMapping("get/location")
    @ResponseBody
    public AjaxResponse getLocation(String longitude, String latitude) {
        try {
            Map<String, String> mapLocation = ScHttpRequestUtil.getWpsToBaiduLocation(longitude, latitude);
            return new AjaxResponse().setObj(mapLocation);
        } catch (IOException e) {
            log.error("{[]}", e);
            return new AjaxResponse().setMsg("地址解析错误请重试!");
        }
    }
    
    public static synchronized Map<String, String> getWpsToBaiduLocation(String longitude, String latitude) throws IOException {
        BufferedReader br = null;
        StringBuffer sb = new StringBuffer();
        URL url = new URL("http://api.map.baidu.com/ag/coord/convert?from=0&to=4&x=" + longitude + "&y=" + latitude);
        br = new BufferedReader(new InputStreamReader(url.openStream(), "utf-8"));
        String str = null;
        while ((str = br.readLine()) != null) {
            sb.append(str);
        }
        Map<String,String> map = (Map<String, String>) JSON.parse(sb.toString());
    
        Base64.Decoder decoder = Base64.getDecoder();
    
        String lng = new String(decoder.decode(map.get("x")), "utf-8");
        String lat = new String(decoder.decode(map.get("y")), "utf-8");
        Map<String, String> mapLocation = new HashMap<>();
        map.put("lng", lng);
        map.put("lat", lat);
        return map;
    }

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

  • 相关阅读:
    Linux常用的命令
    【练习】分区
    【测试】RAC搭建(裸设备)
    【练习】使用事务和锁定语句
    【练习】使用事务控制语句
    【练习】设置数据类型
    【练习】显示MySQLadmin 库户籍选项
    【练习】显示MYSQL客户机选项
    【练习】如何显示本地主机上的MySQL客户机版本
    【测试】切换保护模式,最大性能到最大可用
  • 原文地址:https://www.cnblogs.com/swanyf/p/11207729.html
Copyright © 2011-2022 走看看