官方文档
1.首要参数(重要) 1.1 企业ID,应用凭证密钥 2.获取access_token请求方式: GET(HTTPS)
请求地址: https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid=ID&corpsecret=SECRET
获取access_token是调用企业微信API接口的第一步,相当于创建了一个登录凭证,其它的业务API接口,都需要依赖于access_token来鉴权调用者身份。官方调试工具
public String GetWecharAccessToken() {
// TODO Auto-generated method stub
String AccessToken = null;
Map AccessTokenmap = new HashMap();
AccessTokenmap.put("corpid", Corpid);//此处可设置企业ID的全局变量
AccessTokenmap.put("corpsecret", Corpsecret);//此处可设置应用凭证密钥的全局变量
String strParam = JSONObject.toJSONString(AccessTokenmap);
CloseableHttpClient httpClient=null;
String option = "https";
if(option.equals("https")) {
httpClient =(CloseableHttpClient) wrapClient();//此处调用绕过Https证书验证
}else {
httpClient = HttpClients.createDefault();
}
String res = "";
HttpPost httpPost = new HttpPost(RequestUrl);
// RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(200000).setConnectTimeout(200000).build();
// httpPost.setConfig(requestConfig);
try {
if (null != strParam) {
StringEntity entity = new StringEntity(strParam, "UTF-8");
entity.setContentEncoding("UTF-8");
entity.setContentType("application/json");
httpPost.setEntity(entity);
}
CloseableHttpResponse result = httpClient.execute((HttpUriRequest) httpPost);
if (result.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
String str = "";
str = EntityUtils.toString(result.getEntity(), "UTF-8");
res = str;
System.out.println("获取Token时获取到接口的返回值为:"+res);
JSONObject TokenData = JSONObject.parseObject(res);
String Status = TokenData.get("errcode").toString();
if("0".equals(Status)){
System.out.println("获取Token时接口请请求成功,并成功返回!");
AccessToken = TokenData.get("access_token").toString();
System.out.println("获取到的Token为:"+AccessToken);
}
}
} catch (IOException e) {
e.printStackTrace();
logger.error("获取Token IOException 异常为:"+e);
} finally {
//httpPost.releaseConnection();
}
return AccessToken;
}
2.2 绕过Https证书验证代码:
public static HttpClient wrapClient() {
try {
SSLContext ctx = SSLContext.getInstance("TLS");
X509TrustManager tm = new X509TrustManager() {
@Override
public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {}
@Override
public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {}
@Override
public X509Certificate[] getAcceptedIssuers() {
return null;
}
};
ctx.init(null, new TrustManager[] { tm }, null);
SSLConnectionSocketFactory ssf = new SSLConnectionSocketFactory(ctx, NoopHostnameVerifier.INSTANCE);
CloseableHttpClient httpclient = HttpClients.custom().setSSLSocketFactory(ssf).build();
return httpclient;
} catch (Exception e) {
return HttpClients.createDefault();
}
}
3.获取所有人员的userID
本节官方文档以及详细字段信息
请求方式:GET(HTTPS)
请求地址:https://qyapi.weixin.qq.com/cgi-bin/user/list?access_token=ACCESS_TOKEN&department_id=DEPARTMENT_ID&fetch_child=FETCH_CHILD
由于请求打卡数据用户列表不超过100个的限制。则这里就要将获取到的userID按照数量为100个来进行分组
3.1 调用代码如下:
public void GetQiYeAllUserAndGroup(Context ctx, String accessToken) {
// TODO Auto-generated method stub
List AllUserIdData = new ArrayList();
CloseableHttpClient httpClient=null;
String option = "https";
if(option.equals("https")) {
httpClient =(CloseableHttpClient) wrapClient();
}else {
httpClient = HttpClients.createDefault();
}
String res = "";
String BuildUserIdInfoUrl ="https://qyapi.weixin.qq.com/cgi-bin/user/simplelist?access_token="+accessToken+"&department_id=1&fetch_child=1";
HttpPost httpPost = new HttpPost(BuildUserIdInfoUrl);
try {
CloseableHttpResponse result = httpClient.execute((HttpUriRequest) httpPost);
if (result.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
String str = "";
str = EntityUtils.toString(result.getEntity(), "UTF-8");
res = str;
System.out.println("获取到接口的返回值为:"+res);
JSONObject UserInfoData = JSONObject.parseObject(res);
String Status = UserInfoData.get("errcode").toString();
if("0".equals(Status)){
System.out.println("接口请请求成功,并成功返回!");
JSONArray jsonArray = (JSONArray) UserInfoData.get("userlist");
for(int i = 0;i> Group = fixdGrouping2(AllUserIdData,100);
System.out.println(Group);
for(List ListCount : Group){
GetPunchRecordData(ctx,ListCount,accessToken);
}
}
3.1 userID分组代码
public static4.获取打卡记录List > fixdGrouping2(List
source, int n) { // TODO Auto-generated method stub if(null == source || source.size() == 0 || n <= 0) return new ArrayList >(); List
> result = new ArrayList
>();//此处构建分组后的结果 int remainder = source.size() % n;//取余数,因为存在一个组合不足100的情况 int size = (source.size() / n);//取循环次数 for(int i = 0;i < size;i++){ List
subset = null; //即取fromIndex (第一次循环*一组的数量) //即取toIndex (第一次循环+1)*一组的数量 subset = source.subList(i*n, (i+1)* n); result.add(subset); } //这个时候数量不够了,就把剩下的数据全部装进List中。上面取的余数发挥的作用 if(remainder > 0){ List subset = null; subset = source.subList(size * n, size * n +remainder); result.add(subset); } return result; }
官方文档和详细信息
请求方式:POST(HTTPS)
请求地址:https://qyapi.weixin.qq.com/cgi-bin/checkin/getcheckindata?access_token=ACCESS_TOKEN
按照这个请求格式来即可:
{
"endtime": "1650328200",
"opencheckindatatype": "3",
"starttime": "1650326400",
"useridlist": ["ly","XXXX"]
}
4.2 请求代码如下:
(RequestParam为构建Json的get,set方法,采用注解的方式自动构建Json)
此方法在遍历获取userID分组的地方调用,见 3.1
public void GetPunchRecordData(Context ctx,List4.3 这里就会用到一个工具类。将日期字符串转换为时间戳(自行构建即可)listCount, String accessToken) { // TODO Auto-generated method stub JSONObject PunchRecordJsonData = null; RequestParam BuildParam = new RequestParam(); try { SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); Calendar ca = Calendar.getInstance();//得到一个Calendar的实例 ca.setTime(new Date()); //设置时间为当前时间 ca.add(Calendar.HOUR, -4);//前4个小时 Date lastMonth = ca.getTime(); //结果 String StartUnixTimeStamp = String.valueOf(sdf.parse(sdf.format(lastMonth)).getTime() / 1000); String EndUnixTimeStamp = String.valueOf(sdf.parse(sdf.format(new Date())).getTime() / 1000); System.out.println(sdf.format(lastMonth)+",Unix时间戳为:"+StartUnixTimeStamp); System.out.println(sdf.format(new Date())+"Unix时间戳为:"+EndUnixTimeStamp); BuildParam.setType(PunchRecordType); BuildParam.setStarttime(StartUnixTimeStamp); BuildParam.setEndTime(EndUnixTimeStamp); BuildParam.setUseridList(listCount); } catch (ParseException e1) { // TODO Auto-generated catch block e1.printStackTrace(); logger.error("构建请求打卡记录并请求返回Json ParseException时间戳转换异常为:"+e1); } //构建请求 String strParam = JSONObject.toJSONString(BuildParam); CloseableHttpClient httpClient=null; String option = "https"; if(option.equals("https")) { httpClient =(CloseableHttpClient) wrapClient(); }else { httpClient = HttpClients.createDefault(); } String res = ""; StringBuffer PostRequestUrl = new StringBuffer(); PostRequestUrl.append(RequestPunchRecord).append(accessToken); HttpPost httpPost = new HttpPost(PostRequestUrl.toString()); httpPost.setHeader("content-type", "application/json"); //RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(200000).setConnectTimeout(200000).build(); //httpPost.setConfig(requestConfig); try { if (null != strParam) { StringEntity entity; entity = new StringEntity(strParam, "UTF-8"); entity.setContentEncoding("UTF-8"); entity.setContentType("application/json"); httpPost.setEntity(entity); } CloseableHttpResponse result = httpClient.execute((HttpUriRequest) httpPost); if (result.getStatusLine().getStatusCode() == HttpStatus.SC_OK) { String str = ""; str = EntityUtils.toString(result.getEntity(), "UTF-8"); res = str; System.out.println("获取到接口的返回值为:"+res); PunchRecordJsonData = JSONObject.parseObject(res); SyncPunchRecordData(ctx, PunchRecordJsonData,accessToken); }else{ System.out.println("获取打卡数据的时候,接口请求错误!"); return; } } catch (UnsupportedEncodingException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (ClientProtocolException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } }
public static String stampToDate1(String s){
String formats = "yyyy-MM-dd HH:mm:ss";
Long timestamp = Long.parseLong(s) * 1000;
String date = new SimpleDateFormat(formats, Locale.CHINA).format(new Date(timestamp));
return date;
}
public static String stampToDate2(String s){
String formats = "yyyy-MM-dd";
Long timestamp = Long.parseLong(s) * 1000;
String date = new SimpleDateFormat(formats, Locale.CHINA).format(new Date(timestamp));
StringBuffer cc = new StringBuffer();
cc.append(date).append(" ").append("00:00:00");
return cc.toString();
}
4.4 接下来调用SyncPunchRecordData方法,即最终保存打卡数据的方法
(这里自行构建,写自己的保存逻辑即可)
这个方法传入一个userID组别的集合,以及access_token。
根据节点转换成JSONArray,然后遍历你同步打卡数据的逻辑即可完成。
依葫芦画瓢,按照上面请求的代码Copy就行了。
多多参考官方文档,和官方调用工具。很容易就实现了!
这里我用的定时器直接执行主方法,代码中的URL以及接口地址,相关参数都是设置全局变量的。
最终我使用该逻辑用SpringBoot分包分层,用于正式环境上线。就不公布了。
希望Day Day No BUG。
遇到问题也可以在开发者社区进行提问。或者联系我:910380566@qq.com
或者留言,每天都来CSDN巴拉代码,会看见。
索取的同时也做做贡献,和各位一起成长,逐渐成为大佬而不断努力。同时也记录一下开发的经验和思路。



