您现在的位置是:主页 > news > 长沙网站运营外包公司/网站优化seo推广服务

长沙网站运营外包公司/网站优化seo推广服务

admin2025/6/20 8:47:51news

简介长沙网站运营外包公司,网站优化seo推广服务,网站建设运营部部长岗位职责,网站开发项目工期流程因公司业务需要,开发一款外出打卡的服务公众号,本篇文章介绍获取手机地址位置. 一,获取用户授权,获取用户地址位置为隐私行为,需要得到用户的同意,这是微信设置的一个规则. 获取accesstoken代码 官方文档里说明accessToken有效期为2小时.这里我们需要用JAVA代码每2小时进行一次…

长沙网站运营外包公司,网站优化seo推广服务,网站建设运营部部长岗位职责,网站开发项目工期流程因公司业务需要,开发一款外出打卡的服务公众号,本篇文章介绍获取手机地址位置. 一,获取用户授权,获取用户地址位置为隐私行为,需要得到用户的同意,这是微信设置的一个规则. 获取accesstoken代码 官方文档里说明accessToken有效期为2小时.这里我们需要用JAVA代码每2小时进行一次…

因公司业务需要,开发一款外出打卡的服务公众号,本篇文章介绍获取手机地址位置.

 

一,获取用户授权,获取用户地址位置为隐私行为,需要得到用户的同意,这是微信设置的一个规则.

 

获取accesstoken代码

官方文档里说明accessToken有效期为2小时.这里我们需要用JAVA代码每2小时进行一次重新获取accessToken,用程序来实现accessToken更新.

public interface WeiXinConfig {static final String appid = "你的";static final String secret = "你的";}
package com.cosun.cosunp.weixin;import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;/*** @author:homey Wong* @Date: 2019/9/16  上午 11:26* @Description:* @Modified By:* @Modified-date:**/
@WebServlet(name = "AccessTokenServlet")
public class AccessTokenServlet extends HttpServlet {public void init() throws ServletException {TokenThread.appId = WeiXinConfig.appid;  //获取servlet初始参数appid和appsecretTokenThread.appSecret = WeiXinConfig.secret;new Thread(new TokenThread()).start(); //启动进程}protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {}protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {}}
package com.cosun.cosunp.weixin;import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;/*** @author:homey Wong* @Date: 2019/9/16 上午 11:29* @Description:* @Modified By:* @Modified-date:*/
public class TokenThread implements Runnable {public static String appId = "";public static String appSecret = "";public static AccessToken accessToken = null;public static String jsapi_ticket = "";public void run() {System.out.println("123456789");while (true) {try {accessToken = this.getAccessToken();if (null != accessToken) {//jsapi_ticket = WeiXinUtil.getTicket(accessToken.getAccessToken());//accessToken.setJsapi_ticket(jsapi_ticket);new WeiXinServlet().setRedisValue(accessToken);Thread.sleep(2 * 60 * 60 * 1000); //获取到access_token 休眠7000秒//Thread.sleep(7000 * 1000); //获取到access_token 休眠7000秒//Thread.sleep(30 * 1000); //获取到access_token 休眠7000秒} else {Thread.sleep(1000 * 3); //获取的access_token为空 休眠3秒}} catch (Exception e) {System.out.println("发生异常:" + e.getMessage());e.printStackTrace();try {Thread.sleep(1000 * 10); //发生异常休眠1秒} catch (Exception e1) {}}}}/*** 获取access_token** @return*/private AccessToken getAccessToken() {NetWorkHelper netHelper = new NetWorkHelper();//String Url = String.format("https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=%s&secret=%s", this.appId, this.appSecret);String Url = String.format("https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid=%s&corpsecret=%s", this.appId, this.appSecret);String result = netHelper.getHttpsResponse(Url, "");//response.getWriter().println(result);JSONObject json = JSON.parseObject(result);AccessToken token = new AccessToken();token.setAccessToken(json.getString("access_token"));token.setExpiresin(json.getInteger("expires_in"));return token;}}
 package com.cosun.cosunp.weixin;import com.cosun.cosunp.service.IPersonServ;
import com.cosun.cosunp.tool.Constants;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.context.support.SpringBeanAutowiringSupport;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Date;
import java.util.List;
import java.util.Map;/*** @author:homey Wong* @Date: 2019/9/11 0011 上午 9:03* @Description:* @Modified By:* @Modified-date:*/
@WebServlet(urlPatterns = "/weixin/hello")
public class WeiXinServlet extends HttpServlet {private static Logger logger = LogManager.getLogger(WeiXinServlet.class);@AutowiredIPersonServ personServ;public static final String tooken = "homeyhomeyhomey";private static JedisPool pool;private static Jedis jedis;
public void setRedisValue(AccessToken accessToken) {// 初始化Redis连接池pool = new JedisPool(new JedisPoolConfig(), "127.0.0.1");jedis = pool.getResource();jedis.set(Constants.accessToken, accessToken.getAccessToken());jedis.set(Constants.expiresin, accessToken.getExpiresin() + "");//jedis.set(Constants.jsapi_ticket, accessToken.getJsapi_ticket());}
}
package com.cosun.cosunp.weixin;import com.cosun.cosunp.entity.QYweixinSend;
import com.cosun.cosunp.tool.JSONUtils;import javax.net.ssl.*;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.URL;
import java.security.cert.Certificate;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;/*** @author:homey Wong* @Date: 2019/9/16  上午 11:33* @Description:* @Modified By:* @Modified-date:*/
public class NetWorkHelper {public String getHttpsResponse2(String hsUrl, QYweixinSend text, String requestMethod) {URL url;InputStream is = null;String resultData = "";OutputStreamWriter out = null;try {url = new URL(hsUrl);HttpsURLConnection con = (HttpsURLConnection) url.openConnection();con.setDoOutput(true);con.setDoInput(true);TrustManager[] tm = {xtm};SSLContext ctx = SSLContext.getInstance("TLS");ctx.init(null, tm, null);con.setSSLSocketFactory(ctx.getSocketFactory());con.setHostnameVerifier(new HostnameVerifier() {@Overridepublic boolean verify(String arg0, SSLSession arg1) {return true;}});con.setDoInput(true); //允许输入流,即允许下载//在android中必须将此项设置为falsecon.setDoOutput(false); //允许输出流,即允许上传con.setUseCaches(false); //不使用缓冲if (null != requestMethod && !requestMethod.equals("")) {con.setRequestMethod(requestMethod); //使用指定的方式//con.setRequestProperty("opencheckindatatype", text.getOpencheckindatatype().toString());//con.setRequestProperty("starttime", text.getStarttime().toString());//con.setRequestProperty("endtime", text.getEndtime().toString());// con.setRequestProperty("useridlist", JSONUtils.toJSONString(text.getUseridlist()));} else {con.setRequestMethod("GET"); //使用get请求}con.setDoOutput(true);con.setDoInput(true);con.connect();out = new OutputStreamWriter(con.getOutputStream(), "utf-8");//解决传参时中文乱码out.write(JSONUtils.toJSONString(text).substring(1,JSONUtils.toJSONString(text).length()-1));System.out.println(JSONUtils.toJSONString(text).substring(1,JSONUtils.toJSONString(text).length()-1));out.flush();InputStream inStream = con.getInputStream();is = con.getInputStream();   //获取输入流,此时才真正建立链接InputStreamReader isr = new InputStreamReader(is);BufferedReader bufferReader = new BufferedReader(isr);String inputLine = "";while ((inputLine = bufferReader.readLine()) != null) {resultData += inputLine + "\n";}System.out.println(resultData);Certificate[] certs = con.getServerCertificates();int certNum = 1;for (Certificate cert : certs) {X509Certificate xcert = (X509Certificate) cert;}} catch (Exception e) {e.printStackTrace();}return resultData;}public String getHttpsResponse(String hsUrl, String requestMethod) {URL url;InputStream is = null;String resultData = "";try {url = new URL(hsUrl);HttpsURLConnection con = (HttpsURLConnection) url.openConnection();TrustManager[] tm = {xtm};SSLContext ctx = SSLContext.getInstance("TLS");ctx.init(null, tm, null);con.setSSLSocketFactory(ctx.getSocketFactory());con.setHostnameVerifier(new HostnameVerifier() {@Overridepublic boolean verify(String arg0, SSLSession arg1) {return true;}});con.setDoInput(true); //允许输入流,即允许下载//在android中必须将此项设置为falsecon.setDoOutput(false); //允许输出流,即允许上传con.setUseCaches(false); //不使用缓冲if (null != requestMethod && !requestMethod.equals("")) {con.setRequestMethod(requestMethod); //使用指定的方式} else {con.setRequestMethod("GET"); //使用get请求}is = con.getInputStream();   //获取输入流,此时才真正建立链接InputStreamReader isr = new InputStreamReader(is);BufferedReader bufferReader = new BufferedReader(isr);String inputLine = "";while ((inputLine = bufferReader.readLine()) != null) {resultData += inputLine + "\n";}System.out.println(resultData);Certificate[] certs = con.getServerCertificates();int certNum = 1;for (Certificate cert : certs) {X509Certificate xcert = (X509Certificate) cert;}} catch (Exception e) {e.printStackTrace();}return resultData;}X509TrustManager xtm = new X509TrustManager() {@Overridepublic X509Certificate[] getAcceptedIssuers() {// TODO Auto-generated method stubreturn null;}@Overridepublic void checkServerTrusted(X509Certificate[] arg0, String arg1)throws CertificateException {// TODO Auto-generated method stub}@Overridepublic void checkClientTrusted(X509Certificate[] arg0, String arg1)throws CertificateException {// TODO Auto-generated method stub}};}
package com.cosun.cosunp.weixin;import java.io.Serializable;/*** @author:homey Wong* @Date: 2019/9/16 0016 上午 11:25* @Description:* @Modified By:* @Modified-date:*/
public class AccessToken implements Serializable {private static final long serialVersionUID = 1635100667332681613L;private String accessToken;private int expiresin;private String jsapi_ticket;private String openId;public String getOpenId() {return openId;}public void setOpenId(String openId) {this.openId = openId;}public String getAccessToken() {return accessToken;}public String getJsapi_ticket() {return jsapi_ticket;}public void setJsapi_ticket(String jsapi_ticket) {this.jsapi_ticket = jsapi_ticket;}public void setAccessToken(String accessToken) {this.accessToken = accessToken;}public int getExpiresin() {return expiresin;}public void setExpiresin(int expiresin) {this.expiresin = expiresin;}
}

至此,我们做了个线程,每2小时跑一次去看accessToken是否过期,过期重新取accessToken.

 

下面开始自定菜单,自定义菜单官方网址:

http://mp.weixin.qq.com/debug?token=1256496067&lang=zh_CN

我的如下

{"button": [{"name": "外出打卡","sub_button": ["type": "view","url": "https://open.weixin.qq.com/connect/oauth2/authorize?appid=你的ID&redirect_uri=http://homey.nat100.top/weixin/getMobileLocate&response_type=code&scope=snsapi_userinfo&state=1#wechat_redirect","name": "地址打卡"},{"type": "view","url": "https://open.weixin.qq.com/connect/oauth2/authorize?appid=你的ID&redirect_uri=http://homey.nat100.top/weixin/getCamera&response_type=code&scope=snsapi_userinfo&state=1#wechat_redirect","name": "照相打卡"}]},{"name": "考勤查询","sub_button": [{"type": "view","url": "https://open.weixin.qq.com/connect/oauth2/authorize?appid=你的ID&redirect_uri=http://homey.nat100.top/weixin/queryOutClockIn&response_type=code&scope=snsapi_userinfo&state=1#wechat_redirect","name": "外出考勤记录"},{"type": "view","url": "https://open.weixin.qq.com/connect/oauth2/authorize?appid=你的ID&redirect_uri=http://homey.nat100.top/weixin/queryLeaveSheet&response_type=code&scope=snsapi_userinfo&state=1#wechat_redirect","name": "因公外出单"},{"type": "view","url": "https://open.weixin.qq.com/connect/oauth2/authorize?appid=你的ID&redirect_uri=http://homey.nat100.top/weixin/outClockInNote&response_type=code&scope=snsapi_userinfo&state=1#wechat_redirect","name": "打卡条件须知"}]}

然后我们去做getMobileLocate这个controller

@Controller
@RequestMapping("/weixin")
public class WeiXinController {private static Logger logger = LogManager.getLogger(WeiXinController.class);@Value("${spring.servlet.multipart.location}")private String finalDirPath;@AutowiredIPersonServ personServ;private static JedisPool pool;private static Jedis jedis;@ResponseBody@RequestMapping(value = "/getMobileLocate")public ModelAndView getMobileLocate(HttpServletRequest request, HttpServletResponse response) throws Exception {ModelAndView view = new ModelAndView("weixin");String code = request.getParameter("code");pool = new JedisPool(new JedisPoolConfig(), "127.0.0.1");jedis = pool.getResource();AccessToken accessToken = WeiXinUtil.getTheCode(code, jedis);view.addObject("bean", accessToken.getOpenId());return view;}
}

工具类

package com.cosun.cosunp.weixin;import com.alibaba.fastjson.JSON;
import com.aspose.cad.internal.bouncycastle.crypto.engines.AESEngine;
import com.cosun.cosunp.entity.QYweixinSend;
import com.cosun.cosunp.entity.WeiXinUsrId;
import com.cosun.cosunp.tool.Constants;
import com.cosun.cosunp.tool.JSONUtils;
import com.thoughtworks.xstream.XStream;
import net.sf.json.JSONObject;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import redis.clients.jedis.Jedis;import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;/*** @author:homey Wong* @Date: 2019/9/11 0011 下午 2:13* @Description:* @Modified By:* @Modified-date:*/
public class WeiXinUtil {public static Map<String, String> xmlToMap(HttpServletRequest request) throws IOException,DocumentException {Map<String, String> map = new HashMap<String, String>();SAXReader reader = new SAXReader();InputStream ins = request.getInputStream();if (ins != null) {Document doc = reader.read(ins);//获取根节点Element root = doc.getRootElement();List<Element> list = root.elements();for (Element e : list) {map.put(e.getName(), e.getText());}ins.close();return map;} else {return null;}}public static AccessToken getTheCode(String code, Jedis jedis) {Map<String, String> authInfo = new HashMap<>();AccessToken at = new AccessToken();String openId = "";if (code != null) {// 调用根据用户的code得到需要的授权信息authInfo = getAuthInfo(code, jedis);//获取到openIdopenId = authInfo.get("Openid");}// 获取基础刷新的接口访问凭证(目前还没明白为什么用authInfo.get("AccessToken");这里面的access_token就不行)String accessToken = jedis.get(Constants.accessToken);//获取到微信用户的信息at.setOpenId(openId);return at;}public static Map<String, String> oauth2GetOpenid(String code, Jedis jedis) {//自己的配置appid(公众号进行查阅)String appid = WeiXinConfig.appid;//自己的配置APPSECRET;(公众号进行查阅)String appsecret = WeiXinConfig.secret;//拼接用户授权接口信息String requestUrl = ProjectConst.GET_WEBAUTH_URL.replace("APPID", appid).replace("SECRET", appsecret).replace("CODE", code);//存储获取到的授权字段信息Map<String, String> result = new HashMap<String, String>();try {URL urlGet = new URL(requestUrl);HttpURLConnection http = (HttpURLConnection) urlGet.openConnection();http.setRequestMethod("GET"); // 必须是get方式请求http.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");http.setDoOutput(true);http.setDoInput(true);System.setProperty("sun.net.client.defaultConnectTimeout", "30000");// 连接超时30秒System.setProperty("sun.net.client.defaultReadTimeout", "30000"); // 读取超时30秒http.connect();InputStream is = http.getInputStream();int size = is.available();byte[] jsonBytes = new byte[size];is.read(jsonBytes);String message = new String(jsonBytes, "UTF-8");JSONObject OpenidJSONO = JSONObject.fromObject(message);//OpenidJSONO可以得到的内容:access_token expires_in  refresh_token openid scopeString Openid = String.valueOf(OpenidJSONO.get("openid"));String AccessToken = String.valueOf(OpenidJSONO.get("access_token"));//用户保存的作用域String Scope = String.valueOf(OpenidJSONO.get("scope"));String refresh_token = String.valueOf(OpenidJSONO.get("refresh_token"));result.put("Openid", Openid);result.put("AccessToken", AccessToken);result.put("scope", Scope);result.put("refresh_token", refresh_token);} catch (Exception e) {e.printStackTrace();}return result;}public static Map<String, String> getAuthInfo(String code, Jedis jedis) {//进行授权验证,获取到OpenID字段等信息Map<String, String> result = oauth2GetOpenid(code, jedis);// 从这里可以得到用户openidString openId = result.get("Openid");return result;}public static String textMessageToXml(InMsgEntity textMessage) {XStream xstream = new XStream();xstream.alias("xml", textMessage.getClass());return xstream.toXML(textMessage);}public static String textMessageToXml2(QYweixinSend textMessage) {XStream xstream = new XStream();xstream.alias("xml", textMessage.getClass());return xstream.toXML(textMessage);}//    public String CODE_TO_USERINFO = "https://qyapi.weixin.qq.com/cgi-bin/user/getuserinfo?access_token=ACCESS_TOKEN&code=CODE&agentid=AGENTID";
//
//
//    /**
//     * 根据code获取成员信息
//     *
//     * @param access_token 调用接口凭证
//     * @param code         通过员工授权获取到的code,每次员工授权带上的code将不一样,code只能使用一次,5分钟未被使用自动过期
//     * @param agentid      跳转链接时所在的企业应用ID 管理员须拥有agent的使用权限;agentid必须和跳转链接时所在的企业应用ID相同
//     */
//    public String getUserID(String access_token, String code, String agentid) {
//        String UserId = "";
//        CODE_TO_USERINFO = CODE_TO_USERINFO.replace("ACCESS_TOKEN", access_token).replace("CODE", code).replace("AGENTID", agentid);
//        JSONObject jsonobject = httpRequest(CODE_TO_USERINFO, "GET", null);
//        if (null != jsonobject) {
//            UserId = jsonobject.getString("UserId");
//            if (!"".equals(UserId)) {
//                System.out.println("获取信息成功,o(∩_∩)o ————UserID:" + UserId);
//            } else {
//                int errorrcode = jsonobject.getInt("errcode");
//                String errmsg = jsonobject.getString("errmsg");
//                String error = "错误码:" + errorrcode + "————" + "错误信息:" + errmsg;
//                System.out.println(error);
//            }
//        } else {
//            System.out.println("获取授权失败了");
//        }
//        return UserId;
//    }public static boolean isChinese(String str) {boolean result = false;for (int i = 0; i < str.length(); i++) {int chr1 = (char) str.charAt(i);if (chr1 >= 19968 && chr1 <= 171941) {// 汉字范围 \u4e00-\u9fa5 (中文)result = true;}}return result;}//获取ticketpublic static List<String> getAddressBook(String access_token) {String ticket = null;List<String> userList = new ArrayList<>();String url = "https://qyapi.weixin.qq.com/cgi-bin/user/simplelist?access_token=" + access_token + "&department_id=1&fetch_child=1";//这个url链接和参数不能变try {URL urlGet = new URL(url);HttpURLConnection http = (HttpURLConnection) urlGet.openConnection();http.setRequestMethod("GET"); // 必须是get方式请求http.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");http.setDoOutput(true);http.setDoInput(true);System.setProperty("sun.net.client.defaultConnectTimeout", "30000");// 连接超时30秒System.setProperty("sun.net.client.defaultReadTimeout", "30000"); // 读取超时30秒http.connect();InputStream is = http.getInputStream();int size = is.available();byte[] jsonBytes = new byte[size];is.read(jsonBytes);String message = new String(jsonBytes, "UTF-8");JSONObject demoJson = JSONObject.fromObject(message);ticket = demoJson.getString("userlist");List<WeiXinUsrId> wechatUsers = JSONUtils.toList(ticket, WeiXinUsrId.class);for (WeiXinUsrId wx : wechatUsers) {userList.add(wx.getUserid());}is.close();} catch (Exception e) {e.printStackTrace();}return userList;}//获取ticketpublic static String getTicket(String access_token) {String ticket = null;String url = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=" + access_token + "&type=jsapi";//这个url链接和参数不能变try {URL urlGet = new URL(url);HttpURLConnection http = (HttpURLConnection) urlGet.openConnection();http.setRequestMethod("GET"); // 必须是get方式请求http.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");http.setDoOutput(true);http.setDoInput(true);System.setProperty("sun.net.client.defaultConnectTimeout", "30000");// 连接超时30秒System.setProperty("sun.net.client.defaultReadTimeout", "30000"); // 读取超时30秒http.connect();InputStream is = http.getInputStream();int size = is.available();byte[] jsonBytes = new byte[size];is.read(jsonBytes);String message = new String(jsonBytes, "UTF-8");JSONObject demoJson = JSONObject.fromObject(message);System.out.println("JSON字符串:" + demoJson);ticket = demoJson.getString("ticket");is.close();} catch (Exception e) {e.printStackTrace();}return ticket;}//获取access_tokenpublic static String getAccessToken(String appid, String secret) {String access_token = "";String grant_type = "client_credential";//获取access_token填写client_credentialString url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=" + grant_type + "&appid=" + appid + "&secret=" + secret;//这个url链接地址和参数皆不能变String requestUrl = "";String oppid = "";JSONObject oppidObj = null;String openid = "";String requestUrl2 = "";String userInfoStr = "";JSONObject wxUserInfo = null;try {//获取code后,请求以下链接获取access_tokenURL urlGet = new URL(url);HttpURLConnection http = (HttpURLConnection) urlGet.openConnection();http.setRequestMethod("GET"); // 必须是get方式请求http.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");http.setDoOutput(true);http.setDoInput(true);System.setProperty("sun.net.client.defaultConnectTimeout", "30000");// 连接超时30秒System.setProperty("sun.net.client.defaultReadTimeout", "30000"); // 读取超时30秒http.connect();InputStream is = http.getInputStream();int size = is.available();byte[] jsonBytes = new byte[size];is.read(jsonBytes);String message = new String(jsonBytes, "UTF-8");JSONObject demoJson = JSONObject.fromObject(message);System.out.println("JSON字符串:" + demoJson);access_token = demoJson.getString("access_token");is.close();} catch (Exception e) {e.printStackTrace();}return access_token;}}

Constants类

package com.cosun.cosunp.tool;import java.util.HashMap;
import java.util.Map;public interface Constants {/*** 异常信息统一头信息<br>* 非常遗憾的通知您,程序发生了异常*/public static final String Exception_Head = "boom。炸了。";/*** 缓存键值*/public static final Map<Class<?>, String> cacheKeyMap = new HashMap<>();/*** 保存文件所在路径的key,eg.FILE_MD5:1243jkalsjflkwaejklgjawe*/public static final String FILE_MD5_KEY = "FILE_MD5:";/*** 保存上传文件的状态*/public static final String FILE_UPLOAD_STATUS = "FILE_UPLOAD_STATUS";public static final String accessToken = "accessToken";public static final String expiresin = "expiresin";public static final String jsapi_ticket = "jsapi_ticket";}
<!DOCTYPE html>
<html lang="zh-CN" xmlns:th="http://www.thymeleaf.org">
<head><meta charset="UTF-8"><title>打卡</title><script src="/lib/jquery-3.3.1.min.js" type="text/javascript"></script><script type="text/javascript" src="../static/lib/bootstrap/js/bootstrap.min.js"></script><script src="http://res.wx.qq.com/open/js/jweixin-1.2.0.js"></script></head>
<script>var l_timestamp;var l_noncestr;var l_signature;var appid;var wx;var openId;$(function () {//自动获取urlvar url = location.href.split('#').toString();//url不能写死var bean = $("#bean").val();var path = "http://homey.nat100.top/weixin/getMobileLocateReal";$.post(path, {wxurl: url, bean: bean}, function (data) {var data = JSON.parse(data);l_timestamp = data[0];l_noncestr = data[1];l_signature = data[2];appid = data[4];openId = data[5];wx.config({debug: false, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。appId: appid, // 必填,公众号的唯一标识timestamp: l_timestamp, // 必填,生成签名的时间戳,上文通过后台获取的nonceStr: l_noncestr, // 必填,生成签名的随机串,上文通过后台获取的signature: l_signature,// 必填,签名,上文通过后台获取的jsApiList: ['getLocation', 'openLocation'] // 必填,需要使用的JS接口列表,就是下文的分享朋友圈和转发给朋友的列表});});});wx.ready(function () {wx.checkJsApi({jsApiList: ['getLocation', 'openLocation'],success: function (res) {// alert(JSON.stringify(res));// alert(JSON.stringify(res.checkResult.getLocation));if (res.checkResult.getLocation == false) {alert('你的微信版本太低,不支持微信JS接口,请升级到最新的微信版本!');return;}}});wx.error(function (res) {alert("接口调取失败")});wx.getLocation({type: 'gcj02',success: function (res) {var locate = JSON.stringify(res);var jsonarray = {"latitude": res.latitude,"longitude": res.longitude,"openId": openId//"id":1};var data = JSON.stringify(jsonarray);$.ajax({data: data,type: "POST",contentType: "application/json",//上传内容格式为json结构url: "http://homey.nat100.top/weixin/punchClock",success: function (msg) {var dataa = eval(msg);//将msg化为数;if (dataa[0].isClock == "0") {wx.openLocation({latitude: res.latitude, // 纬度,浮点数,范围为90 ~ -90longitude: res.longitude, // 经度,浮点数,范围为180 ~ -180。name: '打卡位置(打卡成功)', // 位置名address: dataa[0].address, // 地 址详情说明scale: 15, // 地图缩放级别,整形值,范围从1~28。默认为最大infoUrl: 'http://www.cosunsign.com/page/gyks.html' // 在查看位置界面底部显示的超链接,可点击跳转(测试好像不可用)});} else {alert("已打过卡,不允许重复打卡.")}},error: function (msg) {}});//window.location.href = "http://homey.nat100.top/weixin/punchClock?latitude=" + res.latitude + "&longitude="//   + res.longitude + "&openId=" + openId;},cancel: function (res) {alert('用户拒绝授权获取地理位置');}});});</script>
<body>
<input type="hidden" id="appId" th:value="${appId}">
<input type="hidden" id="l_timestamp" th:value="${l_timestamp}">
<input type="hidden" id="l_noncestr" th:value="${l_noncestr}">
<input type="hidden" id="l_signature" th:value="${l_signature}">
<input type="hidden" id="requestOri" th:value="${requestOri}">
<input type="hidden" id="bean" th:value="${bean}"></body>
</html>

上面是调用的html页面,也可以直接在java里写,这里就不提供了.

下面提供HTML调用的controller

 @ResponseBody@RequestMapping(value = "/getMobileLocateReal")public void getMobileLocateReal(HttpServletRequest request, HttpServletResponse response) throws Exception {String wxMsgXml = IOUtils.toString(request.getInputStream(), "utf-8");String url = request.getParameter("wxurl");String openId = request.getParameter("bean");pool = new JedisPool(new JedisPoolConfig(), "127.0.0.1");jedis = pool.getResource();try {String noncestr = UUID.randomUUID().toString().replace("-", "").substring(0, 16);//随机字符串String timestamp = String.valueOf(System.currentTimeMillis() / 1000);//时间戳System.out.println("accessToken:" + jedis.get(Constants.accessToken) + "\njsapi_ticket:" + jedis.get(Constants.jsapi_ticket) + "\n时间戳:" + timestamp + "\n随机字符串:" + noncestr);String str = "jsapi_ticket=" + jedis.get(Constants.jsapi_ticket) + "&noncestr=" + noncestr + "&timestamp=" + timestamp + "&url=" + url;//6、将字符串进行sha1加密String signature = CheckUtil.getSha1(str);System.out.println("参数:" + str + "\n签名:" + signature);List l_data = new ArrayList();l_data.add(timestamp);l_data.add(noncestr);l_data.add(signature);l_data.add(url);l_data.add(WeiXinConfig.appid);l_data.add(openId);JSONArray l_jsonarrary = JSONArray.fromObject(l_data);//json转的字符串值String l_jsonstring = l_jsonarrary.toString();response.getWriter().print(l_jsonstring);response.getWriter().flush();response.getWriter().close();} catch (Exception e) {e.printStackTrace();}}

下面根据html调用的接口获取打卡位置

  @ResponseBody@RequestMapping(value = "/punchClock")public void punchClock(@RequestBody(required = true) Location location, HttpServletRequest request, HttpServletResponse response) throws Exception {//22.77200698852539//114.3155288696289String code = request.getParameter("code");pool = new JedisPool(new JedisPoolConfig(), "127.0.0.1");jedis = pool.getResource();int isClock = 0;AccessToken accessToken = WeiXinUtil.getTheCode(code, jedis);String addr = null;// Map<String, String> map = WeiXinUtil.xmlToMap(request);Map<String, String> address = MapUtil.getCityByLonLat(location.getLatitude(), location.getLongitude());List<Location> locations = new ArrayList<Location>();if (address != null) {OutClockIn outClockIn = new OutClockIn();Date date = new Date();SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");SimpleDateFormat format1 = new SimpleDateFormat("yyyy-MM-dd");String dateStr = format.format(date);String dateStr1 = format1.format(date);String hourStr = dateStr.split(" ")[1];addr = address.get("province") + address.get("city") + address.get("district") +address.get("street");Integer hour = Integer.valueOf(hourStr.split(":")[0]);outClockIn.setClockInDateStr(dateStr1);outClockIn.setWeixinNo(location.getOpenId());if (hour < 12 && hour >= 6) {//视为上午打卡outClockIn.setClockInDateAMOnStr(dateStr);outClockIn.setClockInAddrAMOn(addr);int isClockInAlready = personServ.isClockInAlready(location.getOpenId(), dateStr1, "clockInDateAMOn");if (isClockInAlready == 0) {personServ.saveOrUpdateOutClockInData(outClockIn);} else {isClock = 1;}} else if (hour >= 12 && hour <= 18) {//视为下午打卡outClockIn.setClockInDatePMOnStr(dateStr);outClockIn.setClockInAddrPMOn(addr);int isClockInAlready = personServ.isClockInAlready(location.getOpenId(), dateStr1, "clockInDatePMOn");if (isClockInAlready == 0) {personServ.saveOrUpdateOutClockInData(outClockIn);} else {isClock = 1;}} else if (hour > 18 && hour <= 24) {//视为晚上打卡outClockIn.setClockInDateNMOnStr(dateStr);outClockIn.setClockInAddNMOn(addr);int isClockInAlready = personServ.isClockInAlready(location.getOpenId(), dateStr1, "clockInDateNMOn");if (isClockInAlready == 0) {personServ.saveOrUpdateOutClockInData(outClockIn);} else {isClock = 1;}} else {isClock = 1;}} else {isClock = 0;}location.setIsClock(isClock);location.setAddress(addr);locations.add(location);String str = null;ObjectMapper x = new ObjectMapper();//ObjectMapper类提供方法将list数据转为json数据try {str = x.writeValueAsString(locations);response.setCharacterEncoding("UTF-8");response.setContentType("text/html;charset=UTF-8");response.getWriter().print(str); //返回前端ajax} catch (IOException e) {e.printStackTrace();logger.debug(e.getMessage());throw e;}}

我这里调用了百度地图API,是因为取的经纬度拿到百度地图里出的地址很准确.

现贴上我调用百度API的类

package com.cosun.cosunp.weixin;import com.alibaba.fastjson.JSONObject;import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;/*** @author:homey Wong* @Date: 2019/9/17 0017 下午 6:49* @Description:* @Modified By:* @Modified-date:*/
public class MapUtil {/*** 百度地图请求秘钥*/private static final String KEY = "你的KEY";/*** 返回值类型*/private static final String OUTPUT = "json";/*** 根据地名获取经纬度*/private static final String GET_LNG_LAT_URL = "http://api.map.baidu.com/reverse_geocoding/v3/";/*** 根据经纬度获取地名*///http://api.map.baidu.com/reverse_geocoding/v3/?ak=你的AK&output=json&coordtype=wgs84ll&location=22.77200698852539,114.3155288696289private static final String GET_ADDRESS_URL = "http://api.map.baidu.com/reverse_geocoding/v3/";private static final String coordtype = "wgs84ll";/*** 根据经纬度获得省市区信息** @param lat 经度* @return*/public static Map<String, String> getCityByLonLat(double lng, double lat) {String location = lng + "," + lat;Map<String, String> params = new HashMap<>();params.put("location", location);params.put("coordtype", coordtype);try {//拼装urlString url = joinUrl(params, OUTPUT, KEY, GET_ADDRESS_URL);JSONObject result = JSONObject.parseObject(JSONObject.parseObject(JSONObject.parseObject(HttpClientUtils.doGet(url)).getString("result")).getString("addressComponent"));Map<String, String> area = new HashMap<>();area.put("province", result.getString("province"));area.put("city", result.getString("city"));area.put("district", result.getString("district"));area.put("street", result.getString("street"));area.put("street_number", result.getString("street_number"));return area;} catch (Exception e) {e.printStackTrace();}return null;}/*** 拼接url字符串** @param params* @param output* @param key* @param url* @return* @throws IOException*/private static String joinUrl(Map<String, String> params, String output, String key, String url) throws IOException {StringBuilder baseUrl = new StringBuilder();baseUrl.append(url);int index = 0;Set<Map.Entry<String, String>> entrys = params.entrySet();for (Map.Entry<String, String> param : entrys) {// 判断是否是第一个参数if (index == 0) {baseUrl.append("?");} else {baseUrl.append("&");}baseUrl.append(param.getKey()).append("=").append(URLEncoder.encode(param.getValue(), "utf-8"));index++;}baseUrl.append("&output=").append(output).append("&ak=").append(key);return baseUrl.toString();}}

这里的百度地图ak,可以去官方百度地图里申请.特于是要注意这个V3和V2版本的问题.然后注意坐标系的问题.

至址地址打卡功能就完成了.

 

我这里的功能是地址打卡取经纬度,然后去百度地图匹配,然后打卡行为完成并成功后回显地图位置,代码全贴上了.