基本上钉钉(dingding)作为一个远程办公平台来用的话,虽然差强人意,但是奈何市面上没有啥更好的选择,矬子里拔将军,也还是可以凑合用的,不过远程办公有个问题,就是每天需要检查员工的考勤,居家办公虽然灵活,但是大家究竟有没有办公,则是另外一回事。 钉钉提供的解决方案就是考勤在线打卡功能,但是检查出勤钉钉在移动端就有点费劲,需要在钉钉app里点击至少5次,还不能实时刷新,pc端的钉钉oa系统做的更烂,还不如移动端来得方便,另外如果你在一家上千人的企业里,这家企业有大大小小几十个部门,你又非常倒霉的担任这家公司的人事主管,每天按部门来出员工考勤报表就不是一件容易事了,所以利用钉钉开放的接口,使用Django自己打造一套实时监控员工考勤的web平台是我们本次的目的。 项目背景是一家普通科技公司,大概有五个部门,每个部门100人左右 首先进入钉钉开放平台:opendev。dingtalk。com 在企业内部开发中,选择小程序,新建一个小程序应用,这里其实也还有别的选择,比如h5微应用,主要是小程序兼容性更好一点。 填写应用的名称、简介、Logo等基本信息这些按下不表,按照要求填写即可,也不必非得填写真实信息,这里有个坑就是一定不要忘了配置安全域名或者ip,安全域名是当我们的检测平台上线的时候部署的域名,应用可以跟指定的域名进行网络通信,如果不配置的话,请求钉钉接口会报403错误。 另外还有一个坑,也就是钉钉默认开放的接口仅限于基础权限接口 如果需要考勤或者签到接口的话,还得单独点击申请,这就有点让人看不懂了,那么多接口,全都得靠用鼠标点击开通,不开通就用不了,这个用户体验真是让人非常酸爽,产品设计成这样,钉钉的pm难辞其咎。 OK,前置准备工作就已经就绪了,现在我们只要根据官方文档来写接口就可以了,选择服务端api文档:https:dingdoc。dingtalk。comdocserverapi2gh60vz 钉钉考勤打卡的接口说明是这样的: 该接口用于返回企业内员工的实际打卡记录。比如,企业给一个员工设定的排班是上午9点和下午6点各打一次卡,但是员工在这期间打了多次,该接口会把所有的打卡记录都返回。 如果只要获取打卡结果数据,不需要详情数据,可使用获取打卡结果接口。 请求方式:POST(HTTPS) 请求地址:https:oapi。dingtalk。comattendancelistRecord?accesstokenACCESSTOKEN 请求包结构体: { userIds:〔001,002〕, checkDateFrom:yyyyMMddhh:mm:ss, checkDateTo:yyyyMMddhh:mm:ss, isI18n:false } 这里每个接口都需要一个accesstoken用来鉴权,这个token是用id和秘钥通过接口交换回来的,具体在应用详情里可以获取 这里我们封装成方法importrequestsappkey你的keyappsecret你的秘钥apiurlhttps:oapi。dingtalk。comgettoken?appkeysappsecrets(appkey,appsecret)defgettoken():resrequests。get(apiurl)ifres。statuscode200:strresres。texttoken(json。loads(strres))。get(accesstoken)returntoken 搞定了token,还需要获取您的部门下所有员工的员工id,因为考勤接口参数只能接受员工id,而非部门id获取用户idtokengettoken()获取用户idresrequests。get(https:oapi。dingtalk。comusersimplelist?accesstokensdepartmentid235636048token)strresres。textresjson。loads(strres)ids〔〕idname{}forvalinres〔userlist〕:ids。append(val〔userid〕)idname〔val〔userid〕〕val〔name〕n50大列表中几个数据组成一个小列表lidsbiglist〔l〔i:in〕foriinrange(0,len(l),n)〕 最后请求考勤接口即可resultall〔〕请求打卡接口forxinbiglist:resrequests。post(https:oapi。dingtalk。comattendancelist?accesstokenstoken,json{accesstoken:token,workDateFrom:s00:00:00mydate,workDateTo:s10:00:00mydate,userIdList:str(x),offset:0,limit:50})strresres。textprint(strres)resjson。loads(strres)forxyinres〔recordresult〕:resultall。append(xy)slist〔〕forvalinresultall:ifval〔timeResult〕NotSigned:print(val〔timeResult〕)mydic{}mydic〔idname〔val〔userId〕〕〕未打卡slist。append(mydic) 完整的后台Django后台接口importrequestsfromrestframework。responseimportResponsefromrestframework。viewsimportAPIViewimporttimeappkey你的keyappsecret你的秘钥apiurlhttps:oapi。dingtalk。comgettoken?appkeysappsecrets(appkey,appsecret)defgettoken():resrequests。get(apiurl)ifres。statuscode200:strresres。texttoken(json。loads(strres))。get(accesstoken)returntokenclassGetQianHandler(APIView):defget(self,request):mydaterequest。GET。get(date,None)ifmydateNone:returnResponse({message:需要传递日期})dtstarts00:00:00mydatedtends23:59:59mydatetsstartint(time。mktime(time。strptime(dtstart,YmdH:M:S)))1000tsendint(time。mktime(time。strptime(dtend,YmdH:M:S)))1000tokengettoken()获取用户idresrequests。get(https:oapi。dingtalk。comusersimplelist?accesstokensdepartmentid235636048token)strresres。textresjson。loads(strres)ids〔〕idname{}forvalinres〔userlist〕:ids。append(val〔userid〕)idname〔val〔userid〕〕val〔name〕n50大列表中几个数据组成一个小列表lidsbiglist〔l〔i:in〕foriinrange(0,len(l),n)〕resultall〔〕print(workDateFroms00:00:00mydate)请求打卡接口forxinbiglist:resrequests。post(https:oapi。dingtalk。comattendancelist?accesstokenstoken,json{accesstoken:token,workDateFrom:s00:00:00mydate,workDateTo:s10:00:00mydate,userIdList:str(x),offset:0,limit:50})strresres。textprint(strres)resjson。loads(strres)forxyinres〔recordresult〕:resultall。append(xy)slist〔〕forvalinresultall:ifval〔timeResult〕NotSigned:print(val〔timeResult〕)mydic{}mydic〔idname〔val〔userId〕〕〕未打卡slist。append(mydic)returnResponse(slist) 这样,就可以愉快的通过线上平台来实时监测部门员工考勤了,效果是这样的: