获取员工的考勤记录,利用钉钉签到功能,每天晚上定时任务获取员工的签到记录并保存到数据库
可在手机上直接操作
需要以管理员的账号登录钉钉开发者中心:https://open-dev.dingtalk.com/#/

创建企业应用,填好以下信息

3.创建好之后获取appKey和appSecret

4.在权限管理面申请相关的权限
1. 个人手机号信息
2.获取签到数据的权限

1.引入所需jar包
<dependency>
<groupId>com.aliyungroupId>
<artifactId>dingtalkartifactId>
<version>1.3.41version>
dependency>
<dependency>
<groupId>org.apache.httpcomponentsgroupId>
<artifactId>httpclientartifactId>
<version>4.5.7version>
dependency>
2.Http请求工具类 HttpUtils
/**
* @ClassName HttpUtils
* @description:
* @author: lsq
* @create: 2022-04-25 14:05
* @Version 1.0
**/
import com.alibaba.fastjson.JSONObject;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.NameValuePair;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.util.EntityUtils;
import java.util.ArrayList;
import java.util.List;
/**
* http请求工具类
* @author lcs
*/
public class HttpUtils {
public static String doPost(String url, JSONObject jsonObject, String charset){
HttpClient httpClient = null;
HttpPost httpPost = null;
String result = null;
try{
httpClient = new DefaultHttpClient();
httpPost = new HttpPost(url);
//设置参数
List<NameValuePair> list = new ArrayList<NameValuePair>();
StringEntity entity = new StringEntity(jsonObject.toString(),charset);
entity.setContentEncoding("UTF-8");
entity.setContentType("application/json");
httpPost.setEntity(entity);
HttpResponse response = httpClient.execute(httpPost);
if(response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
HttpEntity resEntity = response.getEntity();
if(resEntity != null){
result = EntityUtils.toString(resEntity,charset);
}
}
}catch(Exception ex){
ex.printStackTrace();
}
return result;
}
public static String doGet(String url){
String result = null;
HttpGet request = new HttpGet(url);
HttpClient httpClient = new DefaultHttpClient();
try {
HttpResponse response = httpClient.execute(request);
if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
result= EntityUtils.toString(response.getEntity(),"utf-8");
}
}catch (Exception e){
e.printStackTrace();
}
return result;
}
}
3.DingDingSignUtil
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.jr.rdp.commons.util.HttpClientUtil;
import org.springframework.stereotype.Component;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* @ClassName DingDingSignUtil
* @description:
* @author: lsq
* @create: 2022-08-22 14:24
* @Version 1.0
**/
@Component
public class DingDingSignUtil {
// 应用的appKey 自己补充
public static String appKey = "";
// 应用的appSecret
public static String appSecret = "";
private static String accessTokenUrl = "https://oapi.dingtalk.com/gettoken";//通用
private static String userUrl = "https://oapi.dingtalk.com/topapi/v2/user/get";
private static String mobileUrl = "https://oapi.dingtalk.com/topapi/v2/user/getbymobile";
private static String checkInUrl = "https://oapi.dingtalk.com/topapi/checkin/record/get";
/**
* 获取钉钉的accessToken
*
* @param url
* @param corpid
* @param secret
* @return
*/
public static String getAccessToken(String url, String corpid, String secret) {
String requestUrl = url + "?corpid=" + corpid + "&corpsecret=" + secret;
String result = HttpClientUtil.get(requestUrl);
String accessToken = null;
JSONObject jsonObject = new JSONObject();
jsonObject = JSON.parseObject(result);
String msg = (String) jsonObject.get("errmsg");
if ("ok".equals(msg)) {
accessToken = (String) jsonObject.get("access_token");
}
return accessToken;
}
//通过手机号查询用户信息:{"errcode":0,"errmsg":"ok","result":{"userid":"114658655020896248"},"request_id":"16m94nctmwc3n"}
public static String getUserByMobile(String accessToken, String phone) {
try {
JSONObject jsonObject = new JSONObject();
jsonObject.put("mobile", phone);
String url = mobileUrl + "?access_token=" + accessToken;
String result = HttpUtils.doPost(url, jsonObject, "utf-8");
System.out.println("通过手机号查询用户信息:" + result);
return result;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* 获取用户签到记录
*
* @param accessToken
* @param startTime
* @param endTime
* @param userIdStr
* @return
*/
public static JSONObject getCheckinList(String accessToken, Long startTime, Long endTime, String userIdStr) {
String recordUrl = checkInUrl + "?access_token=" + accessToken;
Map<String, String> jsonObject = new HashMap<>();
jsonObject.put("start_time", startTime.toString());
jsonObject.put("end_time", endTime.toString());
jsonObject.put("cursor", "0");
jsonObject.put("size", "100");
List<String> userIdList = new ArrayList<>();
userIdList.add("114658655020896248");
// jsonObject.put("useridList", userIdList.toString());
jsonObject.put("userid_list", userIdStr);
String result = HttpClientUtil.post(recordUrl, jsonObject, "utf-8");
JSONObject resutJSON = JSONObject.parseObject(result);
Integer errcode = resutJSON.getInteger("errcode");
System.out.println(errcode);
JSONObject jsonArray = null;
if (errcode == 0) {
jsonArray = (JSONObject) resutJSON.get("result");
}
return jsonArray;
}
public static String accessToken;
//{"page_list":[{"checkin_time":1650874231000,"detail_place":"","image_list":[],"place":"","remark":"再次测试","userid":"114658655020896248"},{"checkin_time":1650872311000,"detail_place":"","image_list":["https://static.dingtalk.com/media/lQDPDhtdTEGAPxnNBQDNAlCwxtQwnhpswDcCaYhNXgDFAA_592_1280.jpg"],"place":"","remark":"测试签到","userid":"114658655020896248"}]}
public static List<Checkin> getUserCheckinList(Map<String, String> phones, Long startTime, Long endTime) {
String offset = "0";//分页获取数据,0表示第一页
String limit = "100";//每页100条数据
String accessTokenUrl = "https://oapi.dingtalk.com/gettoken";
String corpid = appKey;//替换成自己的corpid
String secret = appSecret;//替换成自己的corpsecret
if (StringUtils.isBlank(accessToken)) {
accessToken = getAccessToken(accessTokenUrl, corpid, secret);
}
Map<String, String> puMap = new HashMap<>();
List<String> userIds = new ArrayList<>();
for (String phone : phones.keySet()) {
String userId = phones.get(phone);
if (StringUtils.isBlank(userId)) {
String userInfo = getUserByMobile(accessToken, phone);
JSONObject jsonObject = JSONObject.parseObject(userInfo);
if (jsonObject.getInteger("errcode") == 0) {
JSONObject result = jsonObject.getJSONObject("result");
userId = result.getString("userid");
}
}
puMap.put(userId, phone);//将用户手机号和钉钉返回的用户id进行关联
userIds.add(userId);
}
if (accessToken != null) {
JSONObject jsonArray = getCheckinList(accessToken, startTime, endTime, StringUtils.join(userIds, ","));
System.out.println(jsonArray);
String pageList = JSONArray.toJSONString(jsonArray.get("page_list"));
List<Checkin> checkins = JSON.parseArray(pageList, Checkin.class);
//为了将缺失的userid补全,返回的数据便于进行处理
for (Checkin checkin : checkins) {
checkin.setPhone(puMap.get(checkin.getUserid()));
}
return checkins;
}
return null;
}
public static void main(String args[]) {
String workDateFrom="2022-08-24 00:00:00";
String workDateTo="2022-08-25 00:00:00";
long startTime = DateUtils.parse(workDateFrom).getTime();
long endTime = DateUtils.parse(workDateTo).getTime();
Map<String, String> map = new HashMap<>();
//我这里兼容部分用户意见获取了用户id进行保存了就不再进行获取用户id,直接获取签到记录
map.put("手机号", "114658655020896248");
map.put("手机号", "");
List<Checkin> userCheckinList = getUserCheckinList(map, startTime, endTime);
}
}
4.结果处理 Checkin
/**
* @program:
* @ClassName Checkin
* @description:
* @author: lsq
* @create: 2022-08-24 14:09
* @Version 1.0
**/
public class Checkin {
private String checkin_time; // 考勤时间
private String detail_place;//详细地址
private String image_list;//图片
private String place;//简要地址
private String remark;//备注
private String userid;//用户id
private String phone;//用户手机号
public String getCheckin_time() {
return checkin_time;
}
public void setCheckin_time(String checkin_time) {
this.checkin_time = checkin_time;
}
public String getDetail_place() {
return detail_place;
}
public void setDetail_place(String detail_place) {
this.detail_place = detail_place;
}
public String getImage_list() {
return image_list;
}
public void setImage_list(String image_list) {
this.image_list = image_list;
}
public String getPlace() {
return place;
}
public void setPlace(String place) {
this.place = place;
}
public String getRemark() {
return remark;
}
public void setRemark(String remark) {
this.remark = remark;
}
public String getUserid() {
return userid;
}
public void setUserid(String userid) {
this.userid = userid;
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
}