| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455 |
- package com.usoftchina.dingtalk.sdk;
- import com.aliyun.dingtalktodo_1_0.models.*;
- import com.aliyun.teaopenapi.models.Config;
- import com.aliyun.teautil.models.RuntimeOptions;
- import com.dingtalk.api.DefaultDingTalkClient;
- import com.dingtalk.api.DingTalkClient;
- import com.dingtalk.api.request.*;
- import com.dingtalk.api.response.*;
- import com.taobao.api.internal.util.StringUtils;
- import com.usoftchina.dingtalk.sdk.config.DingTalkProperties;
- import com.usoftchina.dingtalk.sdk.util.DateUtils;
- import org.springframework.util.CollectionUtils;
- import java.util.ArrayList;
- import java.util.List;
- /**
- * oa
- * 签到、考勤
- *
- * @author yingp
- * @date 2020/2/19
- */
- public class OaSdk extends BaseSdk {
- public OaSdk(DingTalkProperties properties) {
- super(properties);
- }
- /**
- * 获取部门用户签到记录
- * 企业使用此接口可获取部门人员的签到记录,进行统计分析,也可以基于高德地图(http://lbs.amap.com/)API接口开发人员分布图和热力图。
- * <p>
- * 注意:目前最多获取1000人以内的签到数据,如果所传部门ID及其子部门下的user超过1000,会报错。
- * </p>
- *
- * @param agentCode
- * @param departmentId
- * @param startTime 起始时间。Unix时间戳,如:1520956800000
- * @param endTime 结束时间。Unix时间戳,如:1520956800000。开始时间和结束时间的间隔不能大于45天
- * @return
- */
- public List<OapiCheckinRecordResponse.Data> getCheckinData(String agentCode, long departmentId, long startTime, long endTime) {
- List<OapiCheckinRecordResponse.Data> dataList = new ArrayList<>();
- long size = 100;
- int i = 0;
- while (true) {
- List<OapiCheckinRecordResponse.Data> tempList = getCheckinData(agentCode, departmentId, startTime, endTime, i++, size);
- if (null != tempList) {
- dataList.addAll(tempList);
- if (tempList.size() < size) {
- break;
- }
- } else {
- break;
- }
- }
- return dataList;
- }
- /**
- * 分页获取部门用户签到记录
- * 企业使用此接口可获取部门人员的签到记录,进行统计分析,也可以基于高德地图(http://lbs.amap.com/)API接口开发人员分布图和热力图。
- * <p>
- * 注意:目前最多获取1000人以内的签到数据,如果所传部门ID及其子部门下的user超过1000,会报错。
- * </p>
- *
- * @param agentCode
- * @param departmentId
- * @param startTime
- * @param endTime
- * @param offset 支持分页查询,与size 参数同时设置时才生效,此参数代表偏移量,从0、1、2...依次递增
- * @param size 支持分页查询,与offset 参数同时设置时才生效,此参数代表分页大小,最大100
- * @return
- */
- public List<OapiCheckinRecordResponse.Data> getCheckinData(String agentCode, long departmentId, long startTime, long endTime, long offset, long size) {
- DingTalkClient client = new DefaultDingTalkClient(getProperties().getApi() + "/checkin/record");
- OapiCheckinRecordRequest req = new OapiCheckinRecordRequest();
- req.setDepartmentId(String.valueOf(departmentId));
- req.setStartTime(startTime);
- req.setEndTime(endTime);
- req.setOffset(offset);
- req.setOrder("asc");
- req.setSize(size);
- req.setHttpMethod("GET");
- OapiCheckinRecordResponse resp = cached(() -> client.execute(req, getAccessToken(agentCode)));
- assertOK(resp);
- return resp.getData();
- }
- /**
- * 获取用户签到记录
- * 企业使用此接口可获取指定人员的签到记录,进行统计分析,也可以基于高德地图(http://lbs.amap.com)API接口开发人员分布图和热力图。
- *
- * @param agentCode
- * @param userIdList
- * @param startTime 起始时间。Unix时间戳,如:1520956800000
- * @param endTime 结束时间。Unix时间戳,如:1520956800000。如果是取1个人的数据,时间范围最大到10天,如果是取多个人的数据,时间范围最大1天。
- * @return
- */
- public List<OapiCheckinRecordGetResponse.CheckinRecordVo> getCheckinData(String agentCode, List<String> userIdList, long startTime, long endTime) {
- List<OapiCheckinRecordGetResponse.CheckinRecordVo> dataList = new ArrayList<>();
- long size = 100;
- int i = 0;
- while (true) {
- List<OapiCheckinRecordGetResponse.CheckinRecordVo> tempList = getCheckinData(agentCode, userIdList, startTime, endTime, i++, size);
- if (null != tempList) {
- dataList.addAll(tempList);
- if (tempList.size() < size) {
- break;
- }
- } else {
- break;
- }
- }
- return dataList;
- }
- /**
- * 分页获取用户签到记录
- * 企业使用此接口可获取指定人员的签到记录,进行统计分析,也可以基于高德地图(http://lbs.amap.com)API接口开发人员分布图和热力图。
- *
- * @param agentCode
- * @param userIdList
- * @param startTime
- * @param endTime
- * @param cursor 分页查询的游标,最开始可以传0,然后以1、2依次递增
- * @param size 分页查询的每页大小,最大100
- * @return
- */
- public List<OapiCheckinRecordGetResponse.CheckinRecordVo> getCheckinData(String agentCode, List<String> userIdList, long startTime, long endTime, long cursor, long size) {
- DingTalkClient client = new DefaultDingTalkClient(getProperties().getApi() + "/topapi/checkin/record/get");
- OapiCheckinRecordGetRequest req = new OapiCheckinRecordGetRequest();
- req.setStartTime(startTime);
- req.setEndTime(endTime);
- req.setSize(size);
- req.setCursor(cursor);
- req.setUseridList(String.join(",", userIdList));
- OapiCheckinRecordGetResponse resp = cached(() -> client.execute(req, getAccessToken(agentCode)));
- assertOK(resp);
- return resp.getResult().getPageList();
- }
- /**
- * 获取打卡详情
- * 该接口用于返回企业内员工的实际打卡记录。比如,企业给一个员工设定的排班是上午9点和下午6点各打一次卡,但是员工在这期间打了多次,该接口会把所有的打卡记录都返回。
- * <p>
- * 如果只要获取打卡结果数据,不需要详情数据,可使用获取打卡结果接口。
- * </p>
- *
- * @param agentCode
- * @param userIdList 企业内的员工id列表,最多不能超过50个
- * @param startTime 查询考勤打卡记录的起始工作日。格式为“yyyy-MM-dd hh:mm:ss”。
- * @param endTime 查询考勤打卡记录的结束工作日。格式为“yyyy-MM-dd hh:mm:ss”。注意,起始与结束工作日最多相隔7天
- */
- public List<OapiAttendanceListRecordResponse.Recordresult> getAttendanceRecordList(String agentCode, List<String> userIdList, long startTime, long endTime) {
- DingTalkClient client = new DefaultDingTalkClient(getProperties().getApi() + "/attendance/listRecord");
- OapiAttendanceListRecordRequest req = new OapiAttendanceListRecordRequest();
- req.setCheckDateFrom(DateUtils.formatDateTime(startTime));
- req.setCheckDateTo(DateUtils.formatDateTime(endTime));
- req.setUserIds(userIdList);
- OapiAttendanceListRecordResponse resp = cached(() -> client.execute(req, getAccessToken(agentCode)));
- assertOK(resp);
- return resp.getRecordresult();
- }
- /**
- * 获取打卡结果
- * 该接口用于返回企业内员工的实际打卡结果。比如,企业给一个员工设定的排班是上午9点和下午6点各打一次卡,即使员工在这期间打了多次,该接口也只会返回两条记录,包括上午的打卡结果和下午的打卡结果。
- * <p>
- * 如果要获取打卡详细数据,比如打卡位置,可使用获取打卡详情接口。
- * </p>
- *
- * @param agentCode
- * @param userIdList
- * @param startTime 查询考勤打卡记录的起始工作日。格式为“yyyy-MM-dd HH:mm:ss”,HH:mm:ss可以使用00:00:00,将返回此日期从0点到24点的结果
- * @param endTime 查询考勤打卡记录的结束工作日。格式为“yyyy-MM-dd HH:mm:ss”,HH:mm:ss可以使用00:00:00,将返回此日期从0点到24点的结果。注意,起始与结束工作日最多相隔7天
- * @param offset 表示获取考勤数据的起始点,第一次传0,如果还有多余数据,下次获取传的offset值为之前的offset+limit,0、1、2...依次递增
- * @param limit 表示获取考勤数据的条数,最大不能超过50条
- * @return
- */
- public List<OapiAttendanceListResponse.Recordresult> getAttendanceList(String agentCode, List<String> userIdList, long startTime, long endTime, long offset, long limit) {
- DingTalkClient client = new DefaultDingTalkClient(getProperties().getApi() + "/attendance/list");
- OapiAttendanceListRequest req = new OapiAttendanceListRequest();
- req.setWorkDateFrom(DateUtils.formatDateTime(startTime));
- req.setWorkDateTo(DateUtils.formatDateTime(endTime));
- req.setUserIdList(userIdList);
- req.setOffset(offset);
- req.setLimit(limit);
- OapiAttendanceListResponse resp = cached(() -> client.execute(req, getAccessToken(agentCode)));
- assertOK(resp);
- return resp.getRecordresult();
- }
- /**
- * 获取打卡结果
- * 该接口用于返回企业内员工的实际打卡结果。比如,企业给一个员工设定的排班是上午9点和下午6点各打一次卡,即使员工在这期间打了多次,该接口也只会返回两条记录,包括上午的打卡结果和下午的打卡结果。
- * <p>
- * 如果要获取打卡详细数据,比如打卡位置,可使用获取打卡详情接口。
- * </p>
- *
- * @param agentCode
- * @param userIdList
- * @param startTime 查询考勤打卡记录的起始工作日。格式为“yyyy-MM-dd HH:mm:ss”,HH:mm:ss可以使用00:00:00,将返回此日期从0点到24点的结果
- * @param endTime 查询考勤打卡记录的结束工作日。格式为“yyyy-MM-dd HH:mm:ss”,HH:mm:ss可以使用00:00:00,将返回此日期从0点到24点的结果。注意,起始与结束工作日最多相隔7天
- * @return
- */
- public List<OapiAttendanceListResponse.Recordresult> getAttendanceList(String agentCode, List<String> userIdList, long startTime, long endTime) {
- List<OapiAttendanceListResponse.Recordresult> dataList = new ArrayList<>();
- long size = 100;
- int i = 0;
- while (true) {
- List<OapiAttendanceListResponse.Recordresult> tempList = getAttendanceList(agentCode, userIdList, startTime, endTime, i++ * size, size);
- if (null != tempList) {
- dataList.addAll(tempList);
- if (tempList.size() < size) {
- break;
- }
- } else {
- break;
- }
- }
- return dataList;
- }
- //离职、补卡、请假、出差、加班
- /**
- * 获取出差单列表
- * 该接口用于返回企业内员工的出差申请单。
- *
- * @param agentCode
- * @param startTime 查询起始工作日。格式为“yyyy-MM-dd HH:mm:ss”,HH:mm:ss可以使用00:00:00,将返回此日期从0点到24点的结果
- * @param endTime 查询结束工作日。格式为“yyyy-MM-dd HH:mm:ss”,HH:mm:ss可以使用00:00:00,将返回此日期从0点到24点的结果。注意,起始与结束工作日最多相隔7天
- * @param offset 表示获取考勤数据的起始点,第一次传1,如果还有多余数据,下次获取传的offset值为之前的offset+limit 1、2...依次递增
- * @param size 表示获取考勤数据的条数,最大不能超过50条
- * @return
- */
- public List<OapiAlitripBtripApplySearchResponse.OpenApplyRs> getAlitripList(String agentCode, String startTime, String endTime, long offset, long size) {
- DingTalkClient client = new DefaultDingTalkClient(getProperties().getApi() + "/topapi/alitrip/btrip/apply/search");
- OapiAlitripBtripApplySearchRequest req = new OapiAlitripBtripApplySearchRequest();
- OapiAlitripBtripApplySearchRequest.OpenSearchRq rq = new OapiAlitripBtripApplySearchRequest.OpenSearchRq();
- rq.setCorpid(getProperties().getCorpId());
- rq.setStartTime(StringUtils.parseDateTime(startTime));
- rq.setEndTime(StringUtils.parseDateTime(endTime));
- rq.setPage(offset);
- rq.setPageSize(size);
- req.setRq(rq);
- OapiAlitripBtripApplySearchResponse resp = cached(() -> client.execute(req, getAccessToken(agentCode)));
- assertOK(resp);
- return resp.getModule();
- }
- public List<OapiAlitripBtripApplySearchResponse.OpenApplyRs> getAllAlitrip(String agentCode, String startTime, String endTime){
- List<OapiAlitripBtripApplySearchResponse.OpenApplyRs> dataList = new ArrayList<>();
- long i=1,size=50;
- while (true) {
- List<OapiAlitripBtripApplySearchResponse.OpenApplyRs> alitripList = getAlitripList(agentCode, startTime, endTime, i++, size);
- if (null != alitripList) {
- dataList.addAll(alitripList);
- if (alitripList.size() < size) {
- break;
- }
- } else {
- break;
- }
- }
- return dataList;
- }
- /**
- * 员工离职列表
- * @param agentCode
- * @param offset
- * @param size
- */
- public OapiSmartworkHrmEmployeeQuerydimissionResponse.Paginator getEmpLeaveRecords(String agentCode, long offset, long size){
- DingTalkClient client = new DefaultDingTalkClient(getProperties().getApi() + "/topapi/smartwork/hrm/employee/querydimission");
- OapiSmartworkHrmEmployeeQuerydimissionRequest req = new OapiSmartworkHrmEmployeeQuerydimissionRequest();
- req.setOffset(offset);
- req.setSize(size);
- OapiSmartworkHrmEmployeeQuerydimissionResponse resp= cached(() -> client.execute(req, getAccessToken(agentCode)));
- assertOK(resp);
- return resp.getResult();
- }
- /**
- * 员工离职列表
- * @param agentCode
- */
- public List<OapiSmartworkHrmEmployeeListdimissionResponse.EmpDimissionInfoVo> getAllEmpLeaveRecords(String agentCode){
- List<OapiSmartworkHrmEmployeeListdimissionResponse.EmpDimissionInfoVo> list = new ArrayList<>();
- long i=1,size=50;
- while (true) {
- OapiSmartworkHrmEmployeeQuerydimissionResponse.Paginator empLeaveRecords = getEmpLeaveRecords(agentCode, i++, size);
- if (null != empLeaveRecords) {
- Long nextCursor = empLeaveRecords.getNextCursor()==null?0:empLeaveRecords.getNextCursor();
- list.addAll(getEmpLeave(agentCode, empLeaveRecords.getDataList()));
- if (nextCursor<=0) {
- break;
- }
- } else {
- break;
- }
- }
- return list;
- }
- /**
- * 员工离职信息
- *
- * @param agentCode
- * @param userIdList
- */
- public List<OapiSmartworkHrmEmployeeListdimissionResponse.EmpDimissionInfoVo> getEmpLeave(String agentCode, List<String> userIdList){
- DingTalkClient client = new DefaultDingTalkClient(getProperties().getApi() + "/topapi/smartwork/hrm/employee/listdimission");
- OapiSmartworkHrmEmployeeListdimissionRequest req = new OapiSmartworkHrmEmployeeListdimissionRequest();
- req.setUseridList(String.join(",", userIdList));
- OapiSmartworkHrmEmployeeListdimissionResponse resp= cached(() -> client.execute(req, getAccessToken(agentCode)));
- assertOK(resp);
- return resp.getResult();
- }
- /**
- * 员工请假列表
- * @param agentCode
- * @param offset
- * @param size
- */
- public List<OapiAttendanceGetleavestatusResponse.LeaveStatusVO> getLeaves(String agentCode,List<String> userIdList, long startTime, long endTime, long offset, long size){
- DingTalkClient client = new DefaultDingTalkClient(getProperties().getApi() + "/topapi/attendance/getleavestatus");
- OapiAttendanceGetleavestatusRequest req = new OapiAttendanceGetleavestatusRequest();
- req.setUseridList(String.join(",", userIdList));
- req.setStartTime(startTime);
- req.setEndTime(endTime);
- req.setOffset(offset);
- req.setSize(size);
- OapiAttendanceGetleavestatusResponse resp= cached(() -> client.execute(req, getAccessToken(agentCode)));
- assertOK(resp);
- OapiAttendanceGetleavestatusResponse.LeaveStatusListVO leaveStatusListVO = resp.getResult();
- if (leaveStatusListVO!=null){
- return leaveStatusListVO.getLeaveStatus();
- }
- return null;
- }
- public List<OapiAttendanceGetleavestatusResponse.LeaveStatusVO> getAllLeaves(String agentCode, List<String> userIdList, long startTime, long endTime){
- List<OapiAttendanceGetleavestatusResponse.LeaveStatusVO> dataList = new ArrayList<>();
- long i=1,size=20;
- while (true) {
- List<OapiAttendanceGetleavestatusResponse.LeaveStatusVO> leaves = getLeaves(agentCode, userIdList, startTime, endTime, i++, size);
- if (!CollectionUtils.isEmpty(leaves)) {
- dataList.addAll(leaves);
- if (leaves.size() < size) {
- break;
- }
- } else {
- break;
- }
- }
- return dataList;
- }
- /**
- * 使用 Token 初始化账号Client
- * @return Client
- * @throws Exception
- */
- public com.aliyun.dingtalktodo_1_0.Client initClient() throws Exception {
- Config config = new Config();
- config.protocol = "https";
- config.regionId = "central";
- return new com.aliyun.dingtalktodo_1_0.Client(config);
- }
- public void createTodo(String agentCode,String unionId,String creatorId,String appUrl,String pcUrl,String title,String description,int priority,String dingNotify,Boolean isOnlyShow) throws Exception {
- com.aliyun.dingtalktodo_1_0.Client client = initClient();
- CreateTodoTaskHeaders createTodoTaskHeaders = new CreateTodoTaskHeaders();
- createTodoTaskHeaders.xAcsDingtalkAccessToken = getAccessToken(agentCode);
- CreateTodoTaskRequest.CreateTodoTaskRequestNotifyConfigs notifyConfigs = new CreateTodoTaskRequest.CreateTodoTaskRequestNotifyConfigs()
- .setDingNotify(dingNotify);
- CreateTodoTaskRequest.CreateTodoTaskRequestDetailUrl detailUrl = new CreateTodoTaskRequest.CreateTodoTaskRequestDetailUrl()
- .setAppUrl(appUrl)
- .setPcUrl(pcUrl);
- CreateTodoTaskRequest createTodoTaskRequest = new CreateTodoTaskRequest()
- .setSubject(title)
- .setCreatorId(creatorId)
- .setDescription(description)
- .setDueTime(DateUtils.nowDateEnd().getTime())
- .setExecutorIds(java.util.Arrays.asList(
- unionId
- ))
- .setParticipantIds(java.util.Arrays.asList(
- unionId
- ))
- .setDetailUrl(detailUrl)
- .setIsOnlyShowExecutor(isOnlyShow)
- .setPriority(priority)
- .setNotifyConfigs(notifyConfigs);
- client.createTodoTaskWithOptions(unionId, createTodoTaskRequest, createTodoTaskHeaders, new RuntimeOptions());
- }
- public void updateTodo(String agentCode,String creatorId,String unionId,String taskId,String title,String description) throws Exception {
- com.aliyun.dingtalktodo_1_0.Client client = initClient();
- UpdateTodoTaskHeaders updateTodoTaskHeaders = new UpdateTodoTaskHeaders();
- updateTodoTaskHeaders.xAcsDingtalkAccessToken =getAccessToken(agentCode);
- UpdateTodoTaskRequest updateTodoTaskRequest = new UpdateTodoTaskRequest()
- .setOperatorId(creatorId)
- .setSubject(title)
- .setDescription(description)
- .setDueTime(DateUtils.nowDateTime().getTime())
- .setDone(true)
- .setExecutorIds(java.util.Arrays.asList(
- unionId
- ))
- .setParticipantIds(java.util.Arrays.asList(
- unionId
- ));
- client.updateTodoTaskWithOptions(unionId, taskId, updateTodoTaskRequest, updateTodoTaskHeaders, new RuntimeOptions());
- }
- public QueryOrgTodoTasksResponse getTodo(String agentCode,String unionId,String nextToken,Boolean isDone) throws Exception {
- com.aliyun.dingtalktodo_1_0.Client client = initClient();
- QueryOrgTodoTasksHeaders queryOrgTodoTasksHeaders = new QueryOrgTodoTasksHeaders();
- queryOrgTodoTasksHeaders.xAcsDingtalkAccessToken = getAccessToken(agentCode);
- QueryOrgTodoTasksRequest queryOrgTodoTasksRequest = new QueryOrgTodoTasksRequest()
- .setNextToken(nextToken)
- .setIsDone(isDone);
- return client.queryOrgTodoTasksWithOptions(unionId, queryOrgTodoTasksRequest, queryOrgTodoTasksHeaders, new RuntimeOptions());
- }
- public List<QueryOrgTodoTasksResponseBody.QueryOrgTodoTasksResponseBodyTodoCards> getAllTodo(String agentCode,String unionId,String nextToken,Boolean isDone) throws Exception {
- Boolean b=true;
- List<QueryOrgTodoTasksResponseBody.QueryOrgTodoTasksResponseBodyTodoCards> todos = new ArrayList<>();
- while (b){
- QueryOrgTodoTasksResponse todo = getTodo(agentCode, unionId, nextToken, isDone);
- QueryOrgTodoTasksResponseBody body = todo.getBody();
- todos.addAll(body.getTodoCards());
- String token = body.getNextToken();
- if (token!=null&&!"".equals(token)){
- nextToken=token;
- }else {
- b=false;
- }
- }
- return todos;
- }
- public void deleteTodo(String agentCode,String unionId,String taskId) throws Exception {
- com.aliyun.dingtalktodo_1_0.Client client = initClient();
- DeleteTodoTaskHeaders deleteTodoTaskHeaders = new DeleteTodoTaskHeaders();
- deleteTodoTaskHeaders.xAcsDingtalkAccessToken = getAccessToken(agentCode);
- DeleteTodoTaskRequest deleteTodoTaskRequest = new DeleteTodoTaskRequest()
- .setOperatorId(unionId);
- client.deleteTodoTaskWithOptions(unionId, taskId, deleteTodoTaskRequest, deleteTodoTaskHeaders, new RuntimeOptions());
- }
- }
|