公司最近企业系统要与钉钉考勤打卡数据对接,所以需要拿到钉钉上月员工的考勤打卡数据。配置了spring定时任务,任务类步骤如下:
引入钉钉相关JAR包
一:获得tooken
1、需要公司钉钉管理员给开发人员开放考勤权限。
2、开发人员登录钉钉开放平台(创建小程序–拿到corpId、corpSecret)
private static String accessTokenUrl = "https://oapi.dingtalk.com/gettoken";
private static String corpId = "生成的corpId";
private static String corpSecret = "生成的corpSecret";
//获得token
public static String getAccessToken() {
DefaultDingTalkClient client = new DefaultDingTalkClient(accessTokenUrl);
OapiGettokenRequest request = new OapiGettokenRequest();
request.setAppkey(corpId);
request.setAppsecret(corpSecret);
request.setHttpMethod("GET");
OapiGettokenResponse response=null;
try {
response = client.execute(request);
} catch (ApiException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
String access_token=response.getAccessToken();
return access_token;//获取access_token
}
二:获取所有部门
//获得部门list id
public static List<Department> getDeptId() {
DingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/department/list");
OapiDepartmentListRequest request = new OapiDepartmentListRequest();
request.setId("");
request.setHttpMethod("GET");
OapiDepartmentListResponse response_deptId=null;
try {
response_deptId = client.execute(request, getAccessToken());
} catch (ApiException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
List<Department> deptId_list=response_deptId.getDepartment();
return deptId_list;
}
三:根据部门编号,获得所有员工信息。
(
因为钉钉暂未放开获得所有员工userID的接口,所以目前只能迂回查出所有员工的userID
1、先查到所有部门编号;
2、根据部门编号查出人员。)
//获得人员信息
public static List<Userlist> getUser(){
DingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/user/simplelist");
OapiUserSimplelistRequest request = new OapiUserSimplelistRequest();
OapiUserSimplelistResponse execute=null;
request.setHttpMethod("GET");
//循环部门编号
List<Userlist> allUserlist=new ArrayList<>();
for (Department dept_id : getDeptId()) {
request.setDepartmentId(dept_id.getId());
try {
execute = client.execute(request,getAccessToken());
//循环每一个部门下的user
allUserlist.addAll(execute.getUserlist());
} catch (ApiException e) {
System.out.println(execute.getMsg());
System.out.println(execute.getErrmsg());
// TODO Auto-generated catch block
e.printStackTrace();
}
}
Map <String , Userlist> map =new HashMap<>();
for (Userlist userlist : allUserlist) {
if (map.containsKey(userlist.getUserid())) {
continue;
}else {
map.put(userlist.getUserid(), userlist);
}
}
List<Userlist> person_list=new ArrayList<>();
person_list.addAll(map.values());
return person_list;
}
四:持久化数据。钉钉userID与企业系统的userID,建立企业人员与考勤打卡数据关联关系
//插入员工对应id
public void insertUserId() {
DingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/user/get");
OapiUserGetRequest request = new OapiUserGetRequest();
List<Userlist> list =getUser();
for (Userlist userlist : list) {
request.setUserid(userlist.getUserid());
request.setHttpMethod("GET");
try {
OapiUserGetResponse response = client.execute(request, getAccessToken());
AttendanceQvo dto=new AttendanceQvo();
dto.setUserId(response.getUserid());
dto.setJobnumber(response.getJobnumber());
dto.setCreate_tm(getmonthLastDay().substring(0,7));
t9z_workAttendanceDAO.insertT9z_dd_power(dto);
} catch (ApiException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
五:根据钉钉userID持久化数据,上月每个员工的考勤打卡数据
因为钉钉考勤数据跨度最大为7天,最多只能查7天数据。因此,需要对上月进行拆分
1、获取上月每个7天的开始日期、结束日期。
2、如果最后一个时间跨入不够7天,就拿月末日期。
3、持久化数据
//插入考勤
public void insertCheck() {
DingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/attendance/list");
OapiAttendanceListRequest request = new OapiAttendanceListRequest();
List<Userlist> allUserlist=getUser();
//拿到上个月初的时间
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
Calendar cal = Calendar.getInstance();
cal.setTime(new Date());
cal.add(Calendar.MONTH, -1);
cal.set(Calendar.DAY_OF_MONTH,cal.getActualMinimum(Calendar.DAY_OF_MONTH));
String time_from=sdf.format(cal.getTime());
//上个月天数
int day=Integer.parseInt(getmonthLastDay().substring(8));
//求得一个月有几个7天
int j=0;
if(day%7==0) {
j=day/7;
}else {
j=day/7+1;
}
String time_to="";
for(int i=1;i<=j;i++) {
if(i>1) {
time_from=getDateAfterNDays(time_to,1);
}
time_to=getDateAfterNDays(time_from,6);
//最后一次循环,则time_to=本月最后一天
if(i==j) {
time_to=getmonthLastDay();
}
//循环给日期周期
for (Userlist userlist : allUserlist) {
request.setWorkDateFrom(time_from+" 00:00:00");
request.setWorkDateTo(time_to+" 23:59:59");
request.setOffset(0L);
request.setLimit((long) 50);
request.setUserIdList(Arrays.asList(userlist.getUserid()));
try {
OapiAttendanceListResponse response = client.execute(request,getAccessToken());
List<Recordresult> list= response.getRecordresult();
for (Recordresult recordresult : list) {
t9z_workAttendanceDAO.insertWorkAttendance(new AttendanceQvo(recordresult));
}
} catch (ApiException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
//如果截至日期为月末日期,则插入完毕,跳出循环
if(time_to.compareTo(getmonthLastDay())==0) {
break;
}
}
}
补充:插入考勤数据,第五步用到以下两个方法,直接调用
//获取N天之后日期
public String getDateAfterNDays(String dateTime, int days) {
Calendar calendar = Calendar.getInstance();
String[] dateTimeArray = dateTime.split("-");
int year = Integer.parseInt(dateTimeArray[0]);
int month = Integer.parseInt(dateTimeArray[1]);
int day = Integer.parseInt(dateTimeArray[2]);
calendar.set(year, month - 1, day);
long time = calendar.getTimeInMillis();// 给定时间与1970 年 1 月 1 日的00:00:00.000的差,以毫秒显示
calendar.setTimeInMillis(time + days * 1000 * 60 * 60 * 24);// 用给定的 long值设置此Calendar的当前时间值
//String result_year=calendar.get(Calendar.YEAR)+ "-" + (calendar.get(Calendar.MONTH) + 1)+ "-" + calendar.get(Calendar.DAY_OF_MONTH);
String end_month="";
int result_month=calendar.get(Calendar.MONTH) + 1;
if(result_month<10) {
end_month="0"+result_month+"";
}else {
end_month=result_month+"";
}
String end_day="";
int result_day=calendar.get(Calendar.DAY_OF_MONTH);
if(result_day<10) {
end_day="0"+result_day+"";
}else {
end_day=result_day+"";
}
String end=calendar.get(Calendar.YEAR)+ "-"+end_month+"-"+end_day;
return end;
}
//获取上个月最后一天
public String getmonthLastDay(){
SimpleDateFormat sf=new SimpleDateFormat("yyyy-MM-dd");
Calendar calendar=Calendar.getInstance();
int month=calendar.get(Calendar.MONTH);
calendar.set(Calendar.MONTH, month-1);
calendar.set(Calendar.DAY_OF_MONTH, calendar.getActualMaximum(Calendar.DAY_OF_MONTH));
return sf.format(calendar.getTime());
}