微信接口调用百度地图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="width: 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;
}

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

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

时间: 2024-08-05 04:48:36

微信接口调用百度地图api实现微信公众号打卡的相关文章

HTML5页面直接调用百度地图API,获取当前位置,直接导航目的地(转)

HTML5页面直接调用百度地图API,获取当前位置,直接导航目的地 我是应用在微信中,自定义菜单,菜单直接链接到这个HTML5页面,获取当前位置后,页面中定好目的地,这样打开页面后直接进入导航页面 可以省下先发送位置信息后,点确定再出导航,省一步, <!DOCTYPE html> <html lang="zh-cmn-Hans"> <meta charset="UTF-8"> <meta name="viewpor

HTML5 调用百度地图API地理定位

<!DOCTYPE html> <html> <title>HTML5 HTML5 调用百度地图API地理定位实例</title> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> <script type="text/javascript" src="ht

C#调用百度地图API入门&amp;解决BMap未定义问题

本文主要是最近帮助好友研究JavaScript的百度地图API,同时显示到C# Winform界面.同时遇到了BMap未定义的错误(BMap is not defined)及解决方法.以前写过基于Android的百度地图,其实原理都差不多,希望文章对你有所帮助吧! 一. C#显示百度地图 使用C# Winform显示百度地图主要包括两个步骤: 1.调用百度地图API,通过申请的密钥AK访问JavaScript版本地图: 2.再在C#中webBrowser浏览器控件中访问JS文件,显示地图到窗口.

HTML5调用百度地图API进行地理定位实例

自从HTML5的标准确定以后,越来越多的网站使用HTML5来进行开发.虽然对HTML5支持的浏览器不是很多,但是依然抵挡不了大伙对HTML5开发的热情.今天为大家带来的是使用HTML5调用百度地图API进行地理定位实例.请看下面代码: <!DOCTYPE html> <html> <title>HTML5调用百度地图API进行地理定位实例</title> <head> <meta http-equiv="Content-Type&

调用百度地图Api实现的查看地图功能的小插件

1. 功能 bMap.js 可根据地理位置调用出百度地图,采用弹出框形式 2.用法 var city = '青岛市'; var address = '香港中路'; bMap.init({ city : city, address : address }); 3.依赖 需自行引入jquery以及layer.js(弹出框插件) 4. 局限 各模块之间耦合度过于紧密,插件化程度太低,依赖性太强 5. demo下载 地址 :http://pan.baidu.com/s/1pJAxOnT 6. 源码预览

ionic 调用百度地图API,并定位当前位置示例

首先,可以参考JS版本的百度地图API示例. 由于在ionic程序中,我们一般使用的ES5 或 ES6 或者是Typescript. 这与JS 还有有一些区别的.所以,在我们的程序中,代码与官方示例代码格式上不完全相同. 下面,简单说明一下如何在 ionic 程序中 调用 百度地图API. 1. 在ionic程序中,定位到文件: \src\index.html.  添加如下代码 , 注意将"您的密钥" 替换成 您申请的密钥 <script type="text/java

C#调用百度地图 api

转  http://blog.csdn.net/kkkkkxiaofei/article/details/8663377 这一篇,记录一下我调用的地图API实现的功能.下面介绍的都是一些片段的节选,不能直接复制就运行.在实现之前肯定要加载地图,先放一个webbroser控件,然后如下: [csharp] view plaincopyprint? private void Form1_Load(object sender, EventArgs e) { string str_url = Appli

如何在网页中调用百度地图api

我想在木有提供地图接口的年代,前端工程师门要么只写上企业的具体地址,要么就是用一张标有自己位置的地图图片.但是现在不一样啦!为了增强用户体验,谷歌,甚至百度都很开放了,你可以在他们的网站上找到地图接口,通过进行直接的调用就可以了. 下面我来教你怎么在网页中用好百度地图,当然了,你也可以去百度地图网站去查找相关的技术资料. 首先你需要进入到百度地图官网http://developer.baidu.com/map/ .因为我们是用的脚本进行加载的,所以我们要选择上图中的第一个"javascript 

C#调用百度地图API经验分享(一)

最近客户提了一个需求,要在网站中添加百度地图的显示,其实原来是有谷歌地图的,但由于谷歌在大陆遭到封杀,只好再给用户增加一个选择了. 下面我将自己最近整理的一些知识分享给大家. 如何使用百度地图API: 1.要先引用API库的链接: eg:<script type="text/javascript" src="http://api.map.baidu.com/api?v=2.0&ak=您的密钥"></script> <script