精华内容
下载资源
问答
  • 钉钉考勤数据下载的示例代码,分享给需要的朋友! 本示例是用corpsecret和corpid来获取access_token的,现在钉钉接口改成用appKey和appSecret来获取token了,不过方法大同小异,换一下调用接口的地址和参数就可以...
  • python应用钉钉考勤应用的一个demo供大家参考,如果有那个大神补充可以写在留言去大家一起分享。希望对刚刚入门的朋友有所帮助。
  • PHP获取钉钉考勤信息源代码,PHP获取打卡详情DEMO,钉钉考勤
  • 钉钉突然改接口了,直接获取是被拒绝了,加了分页限制,加了人数限制,头大,之前得方法不能用了,重新写了版,最多一次获取50个人的考勤,并且这些人的考勤记录一次只能获取50条,我想了个办法中心思想就是首先拆分...
  • 钉钉打卡工时统计,表1为原始打卡记录,怎么用Python或者VBA生成表2工时格式。 早上上班时间为7:00,下班时间为11:30,下午上班时间为13:30下班时间为17:30,如果有加班加班时间为18:00-20:30。 中午休息1.5...
  • 同步钉钉考勤.zip

    2020-09-13 18:42:59
    钉钉获取考勤组所有人的打卡记录,存储到简道云平台内,我写的小软件,可以帮忙修改源码,根据个人需要扩展或者缩减
  • 5分钟快速接入钉钉实现钉钉考勤

    千次阅读 2020-07-15 08:00:00
    一、前言由于今年疫情影响,假期的无限延长让大家都不得不进行线上办公,说到线上办公就毫无疑问,钉钉是这个疫情假期最大的赢家,APP的火热程度以及下载量甚至压过了微信,跃居App store...

    一、前言

    由于今年疫情影响,假期的无限延长让大家都不得不进行线上办公,说到线上办公就毫无疑问,钉钉是这个疫情假期最大的赢家,APP的火热程度以及下载量甚至压过了微信,跃居App store免费排行榜第1名的位置。
    最早我们知道钉钉,是因为办公需求,我们主要在人员管理/考勤打卡/日常交流/移动审批等日常工作。但你怎么也想不到,钉钉广泛被大家所知,是因为小学生们的一星差评…..既然钉钉火了,所以就有了这篇文章的到来,让大家快速的接入钉钉,来帮助企业内部线上交流、考勤打卡、移动审批等,这次我先快速简述下对接钉钉组织架构和对接钉钉考勤

    二、对接钉钉组织架构

    废话不多说,直接开撸!
    思路分析:大家都知道对接外部应用肯定需要授权,拿到授权后就基本就可以为所欲为了,所以第一步就是拿授权(令牌token)
    1.登陆钉钉官网:https://ding-doc.dingtalk.com/
    2.进入开发者后台,如图点击后扫码登陆(如何在钉钉上创建企业这里就不说了,直接度娘~我这里已经创建了自己名下的测试企业)


    3.钉钉开发者后台拿CorpId和SSOSecret(写的时候发现企业获取钉钉令牌的方式钉钉已经更新了,所以建议用新的授权方式 )。 我这里就按新的推荐方式拿appKey和appSecret,
    详细获取方法:https://ding-doc.dingtalk.com/doc#/serverapi2/eev437 。如下图就已经拿到

    4.使用appKey和appSecret获取 access_token ,正常情况下access_token有效期为7200秒,有效期内重复获取返回相同结果,并自动续期。
    大家各自用自己的开发语言( php是世界上最好的语言 )进行调用,这里我直接用postman演示:

    请求方式:GET(HTTPS)
    
    请求地址:https://oapi.dingtalk.com/gettoken?appkey=上面拿的;appsecret=上面拿的
    
    

    第二步同步企业部门到钉钉组织架构

    请求方式:POST(HTTPS)
    
    请求地址 :https://oapi.dingtalk.com/department/create?access_token=ACCESS_TOKEN
    
    

    请求包结构体 :

    {
    
    "name": "helloworld",
    
    "parentid": "1",
    
    "order": null,
    
    "createDeptGroup": true,
    
    "deptHiding": false,
    
    "deptPerimits": null,
    
    "userPerimits": null,
    
    "outerDept": false,
    
    "outerPermitDepts": null,
    
    "outerPermitUsers": null,
    
    "soureIdentifier": null,
    
    "id": null
    
    }
    
    

    参数说明:

    这里我创建一个helloworld部门,调用如下:


    创建完后,我们去钉钉的通讯录看看,可以看到钉钉组织架构已经发生了变化,在测试企业下面新增的刚才的helloworld部门,看下图:


    上述,我们就有了钉钉部门新增的接口,那就简单了,写几行代码将企业的部门组织架构读取然后进行依次调用接口创建部门,就完成了部门同步钉钉的目的。

    //部门更新接口
    
    https://oapi.dingtalk.com/department/update?access_token=ACCESS_TOKEN
    
    //部门删除接口
    
    https://oapi.dingtalk.com/department/delete?access_token=ACCESS_TOKEN&id=ID
    
    

    第三步同步企业员工到钉钉通讯录中

    请求方式:POST(HTTPS)
    
    请求地址:https://oapi.dingtalk.com/user/create?access_token=ACCESS_TOKEN
    
    

    请求包结构体:

    {
    
    "userid": "fuleli",
    
    "name": "福乐里",
    
    "orderInDepts" : "",
    
    "department": [371046100],
    
    "position": "狗产品",
    
    "mobile": "15172391968",
    
    "tel" : "xxxx-xxxxxxxx",
    
    "workPlace" :"",
    
    "remark" : "",
    
    "email": "test@xxx.com",
    
    "orgEmail": "test@xxx.com",
    
    "jobnumber": "xxx",
    
    "isHide": false,
    
    "isSenior": false,
    
    "extattr": {
    
    "爱好":"旅游",
    
    "年龄":"24"
    
    }
    
    }
    
    

    参数说明(如果非必须的字段未指定,则钉钉后台不改变该字段之前设置好的值)

    直接用postman进行调用:

    新增完后我们去钉钉组织架构查看,发现已经新增了福乐里的员工


    同理,后面就简单了,写几行代码将员工的信息依次调用员工新增接口即可,下面为需要用到的接口

    //获取部门列表
    
    https://oapi.dingtalk.com/department/list?access_token=ACCESS_TOKEN
    
    //员工更新接口
    
    https://oapi.dingtalk.com/user/update?access_token=ACCESS_TOKEN
    
    //员工删除接口
    
    https://oapi.dingtalk.com/user/delete?access_token=ACCESS_TOKEN&userid=zhangsan
    
    

    三、对接钉钉考勤

    有了员工数据后,就能获取所有员工的考勤数据,在获取考勤数据前,先设置下钉钉后台的打卡设置,这里我就用默认设置,然后勾选了地点打卡和wifi打卡

    然后我们使用手机在钉钉中进行打卡,可以看到29号那天打了2次卡:

    我们直接开始用接口获取:

    请求方式:POST(HTTPS)
    
    请求地址:https://oapi.dingtalk.com/attendance/list?access_token=ACCESS_TOKEN
    
    

    请求包结构体:

    {
    
    "workDateFrom": "2020-06-29 00:00:00",
    
    "workDateTo": "2020-07-03 00:00:00",
    
    "userIdList":["manager962"],
    
    "offset":0,
    
    "limit":50
    
    }
    
    

    参数说明:

    直接使用postman请求

    返回参数说明:

    好了,自此为止,已经可以获取到员工的打卡数据了,那我们就已经实现了接入钉钉实现考勤统计的核心工作了~

    分享几个采坑的问题!

    1. 不能频繁调用钉钉开放平台接口!不能频繁调用!不能频繁调用 。之前发生过一次,接口全部返回错误,查了半天原因,最后发现是因为频繁调用钉钉接口导致触发了限流,直接被禁止调用..

    官方解释如下:

    1. 编辑员工信息同步至钉钉中时,如果入参数据中手机号有修改,则直接同步修改失败。 因为钉钉的主键是手机号,所以通过API去修改员工信息时,如果手机号不一致就会 出现问题,所以如果需要通过钉钉接口去修改员工手机号时,正确顺序是:删除原手机号的员工-》新增新手机号的员工(一开始也是没注意这块,导致老是同步失败)

    结尾

    最后说下:不要想着模拟定位打卡和用其他人手机代打卡,因为这样是会被后台监控到的,所以不要得尝所失 !!!

    下期预告:5分钟快速接入钉钉工作流

    展开全文
  • 钉钉考勤接口调用与OA系统数据对接

    千次阅读 2019-11-18 11:32:10
    钉钉考勤接口调用与OA系统数据对接 公司由原来的指纹打卡更换为钉钉打卡,需要钉钉和现有的OA考勤数据对接(合并钉钉打卡数据和OA上的请假,外出,出差数据) 1.查看钉钉接口文档 ... 2.项目搭建引入钉钉开发SDK ...

    钉钉考勤接口调用与OA系统数据对接

    公司由原来的指纹打卡更换为钉钉打卡,需要钉钉和现有的OA考勤数据对接(合并钉钉打卡数据和OA上的请假,外出,出差数据)

    1.查看钉钉接口文档
    https://ding-doc.dingtalk.com/doc#/serverapi2/gh60vz
    详细接口说明
    2.项目搭建引入钉钉开发SDK
    SDK下载
    3.获取钉钉考勤数据存储服务器数据库(调整存储格式)
    //测试
    public static void main(String[] args) throws Exception {
    Date date = new Date();
    DateFormat format_getHours = new SimpleDateFormat(“HH:mm:ss”);
    String currentDate = new SimpleDateFormat(“yyyy-MM-dd”).format(date);
    String yesterday = getPreDayOrAfterDay(currentDate, -1);
    String workDateFrom = yesterday + " " + “01:00:00”;
    String workDateTo = yesterday + " " + “23:00:00”;
    //新逻辑
    List asList = Arrays.asList(“1”,“2”,“3”);
    List Attendances = new ArrayList();
    for (int i = 0; i < asList.size(); i++) {
    Attendance Attendance = new Attendance();
    Attendance.setUserId(asList.get(i));
    JSONObject getuserinfo = getuserinfo(asList.get(i));//获取用户详情
    String name = getuserinfo.getString(“name”);//姓名
    Attendance.setName(name);
    JSONArray departmentid = getuserinfo.getJSONArray(“department”);//部门id
    Attendance.setDepartment(getdepartment(departmentid.getString(0)));//获取部门名称
    Attendance.setAttendanceTime(yesterday);//设置打卡时间
    JSONObject Json = getattendance(asList.get(i),workDateFrom,workDateTo);//获取打卡结果
    JSONArray recordresult = Json.getJSONArray(“recordresult”);
    for (int j = 0; j < recordresult.size(); j++) {
    JSONObject record = recordresult.getJSONObject(j);
    String checkType = record.getString(“checkType”);//上下班
    String locationResult = record.getString(“locationResult”);//位置结果
    if (null!=locationResult) {
    switch (locationResult) {
    case “Normal”:
    locationResult=DingConstant.locationResult_Normal;
    break;
    case “Outside”:
    locationResult=DingConstant.locationResult_Outside;
    break;
    case “NotSigned”:
    locationResult=DingConstant.locationResult_NotSigned;
    break;
    }
    }

            	  String timeResult = record.getString("timeResult");//打卡结果
            	  if (null!=timeResult) {
    	        		switch (timeResult) {
    	  				case "Normal":
    	  					timeResult=DingConstant.timeResult_Normal;
    	  					break;
    	  				case "Early":
    	  					timeResult=DingConstant.timeResult_Early;
    	  					break;
    	  				case "Late":
    	  					timeResult=DingConstant.timeResult_Late;
    	  				case "NotSigned":
    	  					timeResult=DingConstant.timeResult_NotSigned;
    	  					break;
    	  				}
    	          }
            	  String userCheckTime = getHours(record.getString("userCheckTime"));//打卡时间
            	  String onDuty1checkTime = Attendance.getOnDuty1checkTime();
            	  String onDuty1checkResult = Attendance.getOnDuty1checkResult();
            	  String offDuty1checkResult = Attendance.getOffDuty1checkResult();
            	  String offDuty1checkTime = Attendance.getOffDuty1checkTime();
            	  String offDuty2checkResult = Attendance.getOffDuty2checkResult();
            	  String offDuty2checkTime = Attendance.getOffDuty2checkTime();
            	  String onDuty2checkResult = Attendance.getOnDuty2checkResult();
            	  String onDuty2checkTime = Attendance.getOnDuty2checkTime();
            	  if (checkType!=null) {
            		  if (checkType.equals("OnDuty")) {
            			  if (null==onDuty1checkTime&&null==onDuty1checkResult) {
        	        		  Attendance.setOnDuty1checkTime(userCheckTime);
        	        		  if (null!=locationResult&&locationResult.equals(DingConstant.locationResult_Outside)) {
    							
        	        			  Attendance.setOnDuty1checkResult(locationResult);	        		  
        	        		  }else {
    							
        	        			  Attendance.setOnDuty1checkResult(timeResult);	        		  
        	        		  }
        	        		  continue;
        	        	  }else if (null==onDuty2checkTime&&null==onDuty2checkResult) {
        	        		  if (format_getHours.parse(userCheckTime).getTime()<format_getHours.parse(onDuty1checkTime).getTime()) {
        	        			  Attendance.setOnDuty2checkTime(onDuty1checkTime);
        	        			  Attendance.setOnDuty2checkResult(onDuty1checkResult);	        		  
        	        			  Attendance.setOnDuty1checkTime(userCheckTime);
        	        			  if (null!=locationResult&&locationResult.equals(DingConstant.locationResult_Outside)) {
      								
    	    	        			  Attendance.setOnDuty1checkResult(locationResult);	        		  
    	    	        		  }else {
    								
    	    	        			  Attendance.setOnDuty1checkResult(timeResult);	        		  
    	    	        		  }
        	        		  }else {
        	        			  Attendance.setOnDuty2checkTime(userCheckTime);
    	    	        		  if (null!=locationResult&&locationResult.equals(DingConstant.locationResult_Outside)) {
    									
    	    	        			  Attendance.setOnDuty2checkResult(locationResult);	        		  
    	    	        		  }else {
    								
    	    	        			  Attendance.setOnDuty2checkResult(timeResult);	        		  
    	    	        		  }
        	        		  }
        	        		  continue;
        	        	  }
            		  }else if (checkType.equals("OffDuty")) {
            			  if (null==offDuty1checkTime&&null==offDuty1checkResult) {
        	        		  Attendance.setOffDuty1checkTime(userCheckTime);
        	        		  if (null!=locationResult&&locationResult.equals(DingConstant.locationResult_Outside)) {
    								
        	        			  Attendance.setOffDuty1checkResult(locationResult);	        		  
        	        		  }else {
    							
        	        			  Attendance.setOffDuty1checkResult(timeResult);	        		  
        	        		  }
        	        		  continue;
        	        	  }else if (null==offDuty2checkTime&&null==offDuty2checkResult) {
        	        		  if (format_getHours.parse(userCheckTime).getTime()<format_getHours.parse(offDuty1checkTime).getTime()) {
        	        			  Attendance.setOffDuty2checkTime(offDuty1checkTime);
        	        			  Attendance.setOffDuty2checkResult(offDuty1checkResult);	        		  
        	        			  Attendance.setOffDuty1checkTime(userCheckTime);
        	        			  if (null!=locationResult&&locationResult.equals(DingConstant.locationResult_Outside)) {
    									
    	    	        			  Attendance.setOffDuty1checkResult(locationResult);	        		  
    	    	        		  }else {
    								
    	    	        			  Attendance.setOffDuty1checkResult(timeResult);	        		  
    	    	        		  }
        	        		  }else {
        	        			  Attendance.setOffDuty2checkTime(userCheckTime);
    	    	        		  if (null!=locationResult&&locationResult.equals(DingConstant.locationResult_Outside)) {
    									
    	    	        			  Attendance.setOffDuty2checkResult(locationResult);	        		  
    	    	        		  }else {
    								
    	    	        			  Attendance.setOffDuty2checkResult(timeResult);	        		  
    	    	        		  }
        	        		  }
        	        		  continue;
        	        	  }
            		  }
            	  }
            	  
              }
              System.out.println(Attendance.toString());
              Attendances.add(Attendance);
    	  }
    	  
    	  
    }
    

    4.合并OA数据
    public void run() {
    try {
    AttendanceService attendanceService = (AttendanceService) ApplicationContextUtil.getBean(“attendanceService”);
    OaLeaveService oaLeaveService = (OaLeaveService) ApplicationContextUtil.getBean(“oaLeaveService”);
    OaYearLeaveService oaYearLeaveService = (OaYearLeaveService) ApplicationContextUtil.getBean(“oaYearLeaveService”);
    OaBusinessService oaBusinessService = (OaBusinessService) ApplicationContextUtil.getBean(“oaBusinessService”);
    OaGooutService oaGooutService = (OaGooutService) ApplicationContextUtil.getBean(“oaGooutService”);
    UserService userService = (UserService) ApplicationContextUtil.getBean(“userService”);

    		List<UserBean> list = userService.getuserlist();
    		String flow_data=null;
    		
    		//更新oa信息
    		for (int i = 0; i < list.size(); i++) {
    			UserBean userBean = list.get(i);
    			String oa_id = userBean.getUser_account();//OAID
    			String ding_id = userBean.getDing_id();//dingdingID
    			String user_name = userBean.getUser_name();
    			//判断是否有OA账号
    		if (null!=ding_id) {
    			if (null==oa_id) {
    				continue;
    			}else {
    				//取OA未记录数据
    				Map<String, Object> oaLeaveMap = oaLeaveService.getOaLeaveList("0",oa_id,"values", "", "", "flow_data_507", "批准", "'"+"2019-08-01"+"'", "", 1, 5);
    				Map<String, Object> oaLeaveMap1 = oaLeaveService.getOaLeaveList("0",oa_id,"values", "", "", "flow_data_508", "批准", "'"+"2019-08-01"+"'", "", 1, 5);
    				Map<String, Object> oaLeaveMap2 = oaLeaveService.getOaLeaveList("0",oa_id,"values", "", "", "flow_data_512", "批准", "'"+"2019-08-01"+"'", "", 1, 5);
    				Map<String, Object> oaYearLeaveMap = oaYearLeaveService.getOaYearLeaveList("0",oa_id,"values", "", "", "flow_data_535", "批准", "'"+"2019-08-01"+"'", "", 1, 5);
    				Map<String, Object> oaBusinessMap = oaBusinessService.getOaBusinessList("0",oa_id, "values", "", "", "flow_data_103", "批准", "'"+"2019-08-01"+"'", "", 1, 5);
    				Map<String, Object> oaGooutMap = oaGooutService.getOaGooutList("0",oa_id, "values", "", "", "flow_data_85", "批准", "'"+"2019-08-01"+"'", "", 1, 5);
    				List<OaLeave> oaLeaveList =(List<OaLeave>) oaLeaveMap.get("rows");
    				List<OaLeave> oaLeaveList1 =(List<OaLeave>) oaLeaveMap1.get("rows");
    				List<OaLeave> oaLeaveList2 =(List<OaLeave>) oaLeaveMap2.get("rows");
    				List<OaYearLeave> oaYearLeaveList =(List<OaYearLeave>) oaYearLeaveMap.get("rows");
    				List<OaBusiness> oaBusinessList = (List<OaBusiness>) oaBusinessMap.get("rows");
    				List<OaGoout> oaGooutList = (List<OaGoout>) oaGooutMap.get("rows");
    				
    				//请假信息
    				if (oaLeaveList.isEmpty()&&oaLeaveList1.isEmpty()&&oaLeaveList2.isEmpty()&&
    					oaYearLeaveList.isEmpty()&&oaBusinessList.isEmpty()&&oaGooutList.isEmpty()) {
    					continue;
    				}else {
    					//构造打卡信息
    					  JSONObject getuserinfo = DingRecordSyncController.getuserinfo(ding_id);
    					  JSONArray departmentid = getuserinfo.getJSONArray("department");//部门id
    					  String department=null;
    					  if (null==departmentid) {
    						  continue;
    					  }else {
    						  department = DingRecordSyncController.getdepartment(departmentid.getString(0));
    					  }
    					
    					//遍历请假出差外出信息
    					if (!oaLeaveList.isEmpty()||!oaLeaveList1.isEmpty()||!oaLeaveList2.isEmpty()) {
    						List<OaLeave> list2 = new ArrayList<OaLeave>();
    						
    						if (!oaLeaveList.isEmpty()) {
    							list2=oaLeaveList;
    							flow_data="flow_data_507";
    						}else if (!oaLeaveList1.isEmpty()) {
    							list2=oaLeaveList1;
    							flow_data="flow_data_508";
    						}else if (!oaLeaveList2.isEmpty()) {
    							list2=oaLeaveList2;
    							flow_data="flow_data_512";
    						}
    						for (int j = 0; j < list2.size(); j++) {
    							OaLeave oaLeave = list2.get(j);
    							String id = oaLeave.getId();
    							String begin_date_type = oaLeave.getBegin_date_type();//开始时间的上下午
    							String end_date_type = oaLeave.getEnd_date_type();//结束时间的上下午
    							String begin_date = oaLeave.getBegin_date();//开始日期
    							String end_date = oaLeave.getEnd_date();//结束日期
    							String leave_name = oaLeave.getLeave_name();//请假类别
    							String date_count = oaLeave.getDate_count();//请假时长
    							if (null!=date_count&&date_count.equals("半")) {
    								date_count="0.5";
    							}
    							if (null!=date_count&&date_count.equals("半天")) {
    								date_count="0.5";
    							}
    							float count = Float.parseFloat(date_count);
    							
    							if (begin_date_type.equals("上午")) {
    								if (count==0.5) {
    									Attendance attendance2 = attendanceService.getAttendance(ding_id, begin_date);
    									if (null!=attendance2) {
    										attendance2.setOnDuty1checkResult(leave_name);
    										attendance2.setOffDuty1checkResult(leave_name);
    										attendance2.setLeave_count(0.5f);
    										attendanceService.updateAttendance(attendance2);
    									}else {
    										attendanceService.saveAttendance(new Attendance(ding_id,user_name,department,begin_date,null,leave_name,null,leave_name,null,null,null,null,0.5f,null,null,null));
    									}
    									if (flow_data.equals("flow_data_507")) {
    										oaLeaveService.updateOaLeave(id,1);
    									}else if (flow_data.equals("flow_data_508")) {
    										oaLeaveService.updateOaLeave1(id,1);
    									}else if (flow_data.equals("flow_data_512")) {
    										oaLeaveService.updateOaLeave2(id,1);
    									}
    									continue;
    								}else if (count==1) {
    									Attendance attendance2 = attendanceService.getAttendance(ding_id, begin_date);
    									if (null!=attendance2&&attendance2.getAttendanceTime()!=null) {
    										attendance2.setOnDuty1checkResult(leave_name);
    										attendance2.setOnDuty2checkResult(leave_name);
    										attendance2.setOffDuty1checkResult(leave_name);
    										attendance2.setOffDuty2checkResult(leave_name);
    										attendance2.setLeave_count(1f);
    										attendanceService.updateAttendance(attendance2);
    									}else {
    										attendanceService.saveAttendance(new Attendance(ding_id,user_name,department,begin_date,null,leave_name,null,leave_name,null,leave_name,null,leave_name,1f,null,null,null));
    									}
    									if (flow_data.equals("flow_data_507")) {
    										oaLeaveService.updateOaLeave(id,1);
    									}else if (flow_data.equals("flow_data_508")) {
    										oaLeaveService.updateOaLeave1(id,1);
    									}else if (flow_data.equals("flow_data_512")) {
    										oaLeaveService.updateOaLeave2(id,1);
    									}
    									continue;
    								}else if (count>1) {
    									if (end_date_type.equals("上午")) {
    										String nextDate = DateUtil.getNextDate(begin_date);
    										Attendance attendance2 = attendanceService.getAttendance(ding_id, begin_date);
    										if (null!=attendance2&&attendance2.getAttendanceTime()!=null) {
    											attendance2.setOnDuty1checkResult(leave_name);
    											attendance2.setOnDuty2checkResult(leave_name);
    											attendance2.setOffDuty1checkResult(leave_name);
    											attendance2.setOffDuty2checkResult(leave_name);
    											attendance2.setLeave_count(1f);
    											attendanceService.updateAttendance(attendance2);
    										}else {
    											attendanceService.saveAttendance(new Attendance(ding_id,user_name,department,begin_date,null,leave_name,null,leave_name,null,leave_name,null,leave_name,1f,null,null,null));
    										}
    										if (DateUtil.compateDate(end_date, nextDate)>0) {
    											do {
    												Attendance attendance3 = attendanceService.getAttendance(ding_id, nextDate);
    												if (null!=attendance3&&attendance3.getAttendanceTime()!=null) {
    													attendance3.setOnDuty1checkResult(leave_name);
    													attendance3.setOnDuty2checkResult(leave_name);
    													attendance3.setOffDuty1checkResult(leave_name);
    													attendance3.setOffDuty2checkResult(leave_name);
    													attendance3.setLeave_count(1f);
    													attendanceService.updateAttendance(attendance3);
    												}else {
    													attendanceService.saveAttendance(new Attendance(ding_id,user_name,department,nextDate,null,leave_name,null,leave_name,null,leave_name,null,leave_name,1f,null,null,null));
    												}
    												nextDate=DateUtil.getNextDate(nextDate);
    											} while (DateUtil.compateDate(end_date, nextDate)>0);
    										}
    										
    										Attendance attendance4 = attendanceService.getAttendance(ding_id, end_date);
    										if (null!=attendance4&&attendance4.getAttendanceTime()!=null) {
    											attendance4.setOnDuty1checkResult(leave_name);
    											attendance4.setOffDuty1checkResult(leave_name);
    											attendance4.setLeave_count(0.5f);
    											attendanceService.updateAttendance(attendance4);
    										}else {
    											attendanceService.saveAttendance(new Attendance(ding_id,user_name,department,end_date,null,leave_name,null,leave_name,null,null,null,null,0.5f,null,null,null));
    										}
    										if (flow_data.equals("flow_data_507")) {
    											oaLeaveService.updateOaLeave(id,1);
    										}else if (flow_data.equals("flow_data_508")) {
    											oaLeaveService.updateOaLeave1(id,1);
    										}else if (flow_data.equals("flow_data_512")) {
    											oaLeaveService.updateOaLeave2(id,1);
    										}
    										continue;
    									}else if (end_date_type.equals("下午")) {
    											String nextDate = DateUtil.getNextDate(begin_date);
    											Attendance attendance2 = attendanceService.getAttendance(ding_id, begin_date);
    											if (null!=attendance2&&attendance2.getAttendanceTime()!=null) {
    												attendance2.setOnDuty1checkResult(leave_name);
    												attendance2.setOnDuty2checkResult(leave_name);
    												attendance2.setOffDuty1checkResult(leave_name);
    												attendance2.setOffDuty2checkResult(leave_name);
    												attendance2.setLeave_count(1f);
    												attendanceService.updateAttendance(attendance2);
    											}else {
    												attendanceService.saveAttendance(new Attendance(ding_id,user_name,department,begin_date,null,leave_name,null,leave_name,null,leave_name,null,leave_name,1f,null,null,null));
    											}
    											
    											do {
    												Attendance attendance3 = attendanceService.getAttendance(ding_id, nextDate);
    												if (null!=attendance3&&attendance3.getAttendanceTime()!=null) {
    													attendance3.setOnDuty1checkResult(leave_name);
    													attendance3.setOnDuty2checkResult(leave_name);
    													attendance3.setOffDuty1checkResult(leave_name);
    													attendance3.setOffDuty2checkResult(leave_name);
    													attendance3.setLeave_count(1f);
    													attendanceService.updateAttendance(attendance3);
    												}else {
    													attendanceService.saveAttendance(new Attendance(ding_id,user_name,department,nextDate,null,leave_name,null,leave_name,null,leave_name,null,leave_name,1f,null,null,null));
    												}
    												nextDate=DateUtil.getNextDate(nextDate);
    											} while (DateUtil.compateDate(end_date, nextDate)>=0);
    											if (flow_data.equals("flow_data_507")) {
    												oaLeaveService.updateOaLeave(id,1);
    											}else if (flow_data.equals("flow_data_508")) {
    												oaLeaveService.updateOaLeave1(id,1);
    											}else if (flow_data.equals("flow_data_512")) {
    												oaLeaveService.updateOaLeave2(id,1);
    											}
    											continue;
    									}
    								}//开始时间是上午
    							}else if (begin_date_type.equals("下午")) {
    								if (count==0.5) {
    									Attendance attendance2 = attendanceService.getAttendance(ding_id, begin_date);
    									if (null!=attendance2) {
    										attendance2.setOnDuty2checkResult(leave_name);
    										attendance2.setOffDuty2checkResult(leave_name);
    										attendance2.setLeave_count(0.5f);
    										attendanceService.updateAttendance(attendance2);
    									}else {
    										attendanceService.saveAttendance(new Attendance(ding_id,user_name,department,begin_date,null,null,null,null,null,leave_name,null,leave_name,0.5f,null,null,null));
    									}
    									if (flow_data.equals("flow_data_507")) {
    										oaLeaveService.updateOaLeave(id,1);
    									}else if (flow_data.equals("flow_data_508")) {
    										oaLeaveService.updateOaLeave1(id,1);
    									}else if (flow_data.equals("flow_data_512")) {
    										oaLeaveService.updateOaLeave2(id,1);
    									}
    									continue;
    								}else if (count==1) {
    									Attendance attendance2 = attendanceService.getAttendance(ding_id, begin_date);
    									if (null!=attendance2&&attendance2.getAttendanceTime()!=null) {
    										attendance2.setOnDuty2checkResult(leave_name);
    										attendance2.setOffDuty2checkResult(leave_name);
    										attendance2.setLeave_count(0.5f);
    										attendanceService.updateAttendance(attendance2);
    									}else {
    										attendanceService.saveAttendance(new Attendance(ding_id,user_name,department,begin_date,null,null,null,null,null,leave_name,null,leave_name,0.5f,null,null,null));
    									}
    									Attendance attendance3 = attendanceService.getAttendance(ding_id, DateUtil.getNextDate(begin_date));
    									if (null!=attendance3&&attendance3.getAttendanceTime()!=null) {
    										attendance3.setOnDuty1checkResult(leave_name);
    										attendance3.setOffDuty1checkResult(leave_name);
    										attendance3.setLeave_count(0.5f);
    										attendanceService.updateAttendance(attendance3);
    									}else {
    										attendanceService.saveAttendance(new Attendance(ding_id,user_name,department,DateUtil.getNextDate(begin_date),null,leave_name,null,leave_name,null,null,null,null,0.5f,null,null,null));
    									}
    									if (flow_data.equals("flow_data_507")) {
    										oaLeaveService.updateOaLeave(id,1);
    									}else if (flow_data.equals("flow_data_508")) {
    										oaLeaveService.updateOaLeave1(id,1);
    									}else if (flow_data.equals("flow_data_512")) {
    										oaLeaveService.updateOaLeave2(id,1);
    									}
    									continue;
    								}else if (count>1) {
    									if (end_date_type.equals("下午")) {
    										String nextDate = DateUtil.getNextDate(begin_date);
    										Attendance attendance2 = attendanceService.getAttendance(ding_id, begin_date);
    										if (null!=attendance2&&attendance2.getAttendanceTime()!=null) {
    											attendance2.setOnDuty2checkResult(leave_name);
    											attendance2.setOffDuty2checkResult(leave_name);
    											attendance2.setLeave_count(0.5f);
    											attendanceService.updateAttendance(attendance2);
    										}else {
    											attendanceService.saveAttendance(new Attendance(ding_id,user_name,department,begin_date,null,null,null,null,null,leave_name,null,leave_name,0.5f,null,null,null));
    										}
    										
    										do {
    											Attendance attendance3 = attendanceService.getAttendance(ding_id, nextDate);
    											if (null!=attendance3&&attendance3.getAttendanceTime()!=null) {
    												attendance3.setOnDuty1checkResult(leave_name);
    												attendance3.setOnDuty2checkResult(leave_name);
    												attendance3.setOffDuty1checkResult(leave_name);
    												attendance3.setOffDuty2checkResult(leave_name);
    												attendance3.setLeave_count(1f);
    												attendanceService.updateAttendance(attendance3);
    											}else {
    												attendanceService.saveAttendance(new Attendance(ding_id,user_name,department,nextDate,null,leave_name,null,leave_name,null,leave_name,null,leave_name,1f,null,null,null));
    											}
    											nextDate=DateUtil.getNextDate(nextDate);
    										} while (DateUtil.compateDate(end_date, nextDate)>=0);
    										if (flow_data.equals("flow_data_507")) {
    											oaLeaveService.updateOaLeave(id,1);
    										}else if (flow_data.equals("flow_data_508")) {
    											oaLeaveService.updateOaLeave1(id,1);
    										}else if (flow_data.equals("flow_data_512")) {
    											oaLeaveService.updateOaLeave2(id,1);
    										}
    										continue;
    									}else if (end_date_type.equals("上午")) {
    											String nextDate = DateUtil.getNextDate(begin_date);
    											Attendance attendance2 = attendanceService.getAttendance(ding_id, begin_date);
    											if (null!=attendance2&&attendance2.getAttendanceTime()!=null) {
    												attendance2.setOnDuty2checkResult(leave_name);
    												attendance2.setOffDuty2checkResult(leave_name);
    												attendance2.setLeave_count(0.5f);
    												attendanceService.updateAttendance(attendance2);
    											}else {
    												attendanceService.saveAttendance(new Attendance(ding_id,user_name,department,begin_date,null,null,null,null,null,leave_name,null,leave_name,0.5f,null,null,null));
    											}
    											
    											do {
    												Attendance attendance3 = attendanceService.getAttendance(ding_id, nextDate);
    												if (null!=attendance3&&attendance3.getAttendanceTime()!=null) {
    													attendance3.setOnDuty1checkResult(leave_name);
    													attendance3.setOnDuty2checkResult(leave_name);
    													attendance3.setOffDuty1checkResult(leave_name);
    													attendance3.setOffDuty2checkResult(leave_name);
    													attendance3.setLeave_count(1f);
    													attendanceService.updateAttendance(attendance3);
    												}else {
    													attendanceService.saveAttendance(new Attendance(ding_id,user_name,department,nextDate,null,leave_name,null,leave_name,null,leave_name,null,leave_name,1f,null,null,null));
    												}
    												nextDate=DateUtil.getNextDate(nextDate);
    											} while (DateUtil.compateDate(end_date, nextDate)>0);
    											Attendance attendance4 = attendanceService.getAttendance(ding_id, end_date);
    											if (null!=attendance4&&attendance4.getAttendanceTime()!=null) {
    												attendance4.setOnDuty1checkResult(leave_name);
    												attendance4.setOffDuty1checkResult(leave_name);
    												attendance4.setLeave_count(0.5f);
    												attendanceService.updateAttendance(attendance4);
    											}else {
    												attendanceService.saveAttendance(new Attendance(ding_id,user_name,department,end_date,null,leave_name,null,leave_name,null,null,null,null,0.5f,null,null,null));
    											}
    											if (flow_data.equals("flow_data_507")) {
    												oaLeaveService.updateOaLeave(id,1);
    											}else if (flow_data.equals("flow_data_508")) {
    												oaLeaveService.updateOaLeave1(id,1);
    											}else if (flow_data.equals("flow_data_512")) {
    												oaLeaveService.updateOaLeave2(id,1);
    											}
    											continue;
    									}
    								}//开始时间是下午
    							}
    						}
    					}
    

    5.添加定时任务
    public class TimerManager {
    private static final long PERIOD_DAY = 24 * 60 * 60 * 1000;
    public TimerManager() {
    Calendar calendar = Calendar.getInstance();

    calendar.set(Calendar.HOUR_OF_DAY, 02);
    calendar.set(Calendar.MINUTE, 10);
    calendar.set(Calendar.SECOND, 00);

    Date date = calendar.getTime();
    if (date.before(new Date())) {
    date = this.addDay(date, 1);
    }
    Timer timer = new Timer();
    TimerTaskService task = new TimerTaskService();
    timer.schedule(task, date, PERIOD_DAY);
    }

    private Date addDay(Date date, int num) {
    Calendar startDT = Calendar.getInstance();
    startDT.setTime(date);
    startDT.add(Calendar.DAY_OF_MONTH, num);
    return startDT.getTime();
    }
    }
    Copyright © 2019 shaoyanbin All Rights Reserved

    展开全文
  • 钉钉考勤接口python3.6调用

    千次阅读 2019-05-14 16:48:27
    钉钉考勤接口调用 import requests import json appkey = "appkey" appsecret = "appsecret" def getToken(): url = 'https://oapi.dingtalk.com/gettoken?appkey='+appkey+'&appsecret='+appsecret ...

    钉钉考勤接口调用

    import requests
    import json
    
    
    appkey = "appkey"
    appsecret = "appsecret"
    def getToken():
        url = 'https://oapi.dingtalk.com/gettoken?appkey='+appkey+'&appsecret='+appsecret
        response = requests.get(url=url)
        result = response.json()
        errmsg = result['errmsg']
        print('获取密钥是否成功:',errmsg)
        try:
            access_token = result['access_token']
        except Exception as e:
            print(e)
            access_token = ''
        return access_token
    access_token = getToken()
    
    #------在钉钉考勤应用中,设置考勤组规则后,会生成每天的排班信息,包括工作日、周末、节假日等。如果企业想查询某天的排班情况,可使用此接口查询某天的考勤排班全量信息。注:固定班制只能查到未来15天的排班信息。
    url = 'https://oapi.dingtalk.com/topapi/attendance/listschedule?access_token='+access_token
    # url = 'https: // oapi.dingtalk.com / topapi / processinstance / create?access_token = ' &
    展开全文
  • 钉钉考勤与企业系统对接

    千次阅读 2020-06-22 13:47:31
    公司最近企业系统要与钉钉考勤打卡数据对接,所以需要拿到钉钉上月员工的考勤打卡数据。配置了spring定时任务,任务类步骤如下: 引入钉钉相关JAR包 一:获得tooken 1、需要公司钉钉管理员给开发人员开放考勤权限。...

    公司最近企业系统要与钉钉考勤打卡数据对接,所以需要拿到钉钉上月员工的考勤打卡数据。配置了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());
        }
    
    展开全文
  • C#实现调取钉钉考勤接口的功能

    千次阅读 2020-09-15 16:07:15
    C#实现调取钉钉考勤接口的功能 公司需要做一个钉钉考勤的页面,让我去写这个功能。结果却比我想象的要麻烦一些!具体是怎么个麻烦呢,下面直入正题。 首先我们找到获取钉钉考勤结果的接口。结果发现请求参数里有一...
  • 钉钉考勤报表--工时统计小程序

    千次阅读 2020-09-21 17:32:29
    老婆大人:今天弄一天的公司的考勤报表,看的我眼睛都花了。这工作太难了,老公,我不想干了。。。 我:说说 老婆大人:公司用的钉钉,一个月会导出一份excel报表,让我统计每个人投入工时。你是不知道,我们公司...
  • 对接钉钉考勤

    千次阅读 2018-03-08 10:00:10
    应用场景:公司ERP里看到钉钉考勤记录 一共建了4个实体 ,如果只有单个公司又想简化的话可以只建实体2和4 公司ID和公司密匙表(我需要涉及多个公司) 钉钉用户与ERP系统用户的对照表 钉钉考勤记录 系统的...
  • 基于钉钉的县级公安考勤系统,钉钉考勤方案汇报PPT。含现状及痛点、钉钉考勤的核心价值、钉钉考勤系统介绍和钉钉公安场景应用。
  • 类似钉钉考勤打卡功能,如果遇到有跨天的统计该怎么实现 ,如果有某天的日期和打卡时间该怎么判断他是哪个时间打卡
  • 基于钉钉的县级公安考勤系统,钉钉考勤系统实施方案。含现状及痛点、钉钉考勤的核心价值、钉钉考勤系统介绍和钉钉公安场景应用。
  • 钉钉wifi考勤插件

    2019-01-25 09:45:27
    可修改连接wifi的mac地址,实现进入考勤范围,成功使用钉钉进行打卡。需先安装xposed框架,慎用!!!
  • 钉钉考勤接口调用与OA系统数据对接(多线程版) 公司由原来的指纹打卡更换为钉钉打卡,需要钉钉和现有的OA考勤数据对接(合并钉钉打卡数据和OA上的请假,外出,出差数据),因为人数增减单线程定时任务数据抓取时间...
  • } 原文: List _dayHeaders(TextStyle? headerStyle, MaterialLocalizations localizations) { final List result = []; for (int i = localizations.firstDayOfWeekIndex;... i = (i + 1) % 7) { ...
  • 一个人可以设置为多个部门,通过不同的部门获取到的人员DD_id是一样的,如果此时使用一对多的话,会产生问题,应该设计成多对多。 转载于:https://www.cnblogs.com/zhaogaojian/p/9577527.html...
  • 公司要对接钉钉考勤,于是开始研究钉钉开发文档,其实也不难。 首先,你相应的权限要有,多余的话我也不说了,讲一下,调取打卡结果的接口。 我用的PHP的SDK,贴代码: $dk = new \DingTalkClient('oapi', ...
  • 一、钉钉2021年3月份新增了上传打卡记录的接口,这样就方便集成考勤系统。当然,也方便很多管理员“干坏事了”! 去网站上获取你需要上传的打卡时间。https://tool.lu/timestamp 所有操作都有日志记录:...
  • 仿钉钉考勤统计圆形控件

    千次阅读 2018-02-26 16:31:37
    一、效果图 出于好奇,做了一个模仿钉钉考勤统计的圆形控件,效果如下:二、原理 不感兴趣的可以不往下看,代码已经上传到github,连接:https://github.com/861493711/CircleRatioView 如上图所示,首先我们从最...
  • 魔点D2人脸识别考勤对接钉钉后,从钉钉的api接口下载考勤记录。用到了另外一个上传的日期时间控件,请另外下载,否则请修改。
  • 钉钉API考勤打卡记录获取并存入数据库(python),免去人数限制
  • 解决钉钉导出考勤表统计(加班时长、补贴) 支持自定义格式输出,生成每个人的考勤统计 基于pandas和xlwings对表格进行读写 import pandas as pd import sys import os import numpy as np import xlwings as xw ...
  • 钉钉API考勤打卡记录获取并存入数据库(python)

    万次阅读 热门讨论 2019-07-25 13:00:57
    钉钉有个开发平台,通过API可以开发自己企业内部应用,钉钉开发文档顺序写的有点乱,花了挺长时间才看懂,我写了一个python脚本来获取考勤记录,当然能做的不止这些,可以删除公司成员,修改部门,瞎发通知等等。...
  • } j2m是连接并输出到数据库(百度的,只能实现输入固定值,想要实现将上述读取的钉钉考勤数据写入到数据库) public class j2m { public static void main(String[] args) { try { Class.forName(...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 1,053
精华内容 421
关键字:

钉钉考勤