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;
    }

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

  • 相关阅读:
    leetcode 13. Roman to Integer
    python 判断是否为有效域名
    leetcode 169. Majority Element
    leetcode 733. Flood Fill
    最大信息系数——检测变量之间非线性相关性
    leetcode 453. Minimum Moves to Equal Array Elements
    leetcode 492. Construct the Rectangle
    leetcode 598. Range Addition II
    leetcode 349. Intersection of Two Arrays
    leetcode 171. Excel Sheet Column Number
  • 原文地址:https://www.cnblogs.com/swanyf/p/11207729.html
Copyright © 2011-2022 走看看