對接釘釘考勤

總結:

應用場景:公司ERP裏看到釘釘的考勤記錄

一共建了4個實體 ,如果只有單個公司又想簡化的話可以只建實體2和4

  1. 公司ID和公司密匙表(我需要涉及多個公司)
  2. 釘釘用戶與ERP系統用戶的對照表
  3. 釘釘的考勤記錄
  4. 系統的考勤記錄

其中踩了個坑,通過接口傳入userIdList 獲取考勤記錄時,老是不全,後來發現這個用戶ID屬性不能爲Long,改爲String就好了,有什麼問題大家可以多看看文檔,裏面啥都有,就是有點不友好,我以前開發完之後現在釘釘改了接口參數 ,正好以前寫的也不是很好於是重新改了一版,不要再問我要代碼,主要代碼和思路已經寫好分享了,其餘基礎代碼還要問我要你覺得合適嗎?

獲取釘釘的accessToken

/**
 * 獲取釘釘的accessToken
 */
public String getAccessToken(String corpid, String secret) {
    String requestUrl = "https://oapi.dingtalk.com/gettoken?corpid=" + corpid + "&corpsecret=" + secret;
    RequestResult result = SendHttpRequestUtil.doGet(requestUrl);
    String accessToken = null;
    JSONObject jsonObject = JSON.parseObject(result.getResult());
    String msg = jsonObject.get("errmsg").toString();
    if ("ok".equals(msg)) {
        accessToken = (String) jsonObject.get("access_token");
    }
    return accessToken;
}

獲取釘釘的用戶並與自己系統相關聯,人事在上工號的時候需要在釘釘那邊填一下該員工在系統裏的工號(當然,釘釘也有接口你可以自己直接加)

Controller
/**
 * 獲取釘釘用戶並保存
 */
@ResponseBody
@RequestMapping(value = "getDingUser")
public ActionResult<Map<String, Object>> getDingUser() {
    return dingUserService.getDingUser();
}


Service
/**
 * 獲取釘釘的用戶信息
 */
@Transactional(readOnly = false)
public ActionResult<Map<String, Object>> getDingUser() {
    //清空表數據
    dao.deleteTable();
    //兩個公司遍歷
    List<HrmDingCompany> companyList = companyService.findList(new HrmDingCompany());
    for (HrmDingCompany companyEach : companyList) {
        //獲取token
        String accessToken = recordsService.getAccessToken(companyEach.getCorpId(), companyEach.getCorpSecret());
        //獲取子部門ID列表
        String requestUrl = "https://oapi.dingtalk.com/department/list_ids?access_token=" + accessToken + "&id=1";
        RequestResult result = SendHttpRequestUtil.doGet(requestUrl);
        JSONObject jsonObject = JSON.parseObject(result.getResult());
        String msg = (String) jsonObject.get("errmsg");
        List<Integer> departIds = new ArrayList<>();
        if ("ok".equals(msg)) {
            departIds = (List<Integer>) jsonObject.get("sub_dept_id_list");
        } else {
            logger.error(jsonObject.toString());
        }

        //獲取部門用戶userid列表
        List<String> userIds = new ArrayList<>();
        for (Integer departId : departIds) {
            requestUrl = "https://oapi.dingtalk.com/user/getDeptMember?access_token=" + accessToken + "&deptId=" + departId;
            result = SendHttpRequestUtil.doGet(requestUrl);
            jsonObject = JSON.parseObject(result.getResult());
            msg = (String) jsonObject.get("errmsg");
            if ("ok".equals(msg)) {
                List<String> tempList = new ArrayList<>();
                tempList = (List<String>) jsonObject.get("userIds");
                userIds.addAll(tempList);
            } else {
                logger.error(jsonObject.toString());
            }
        }

        //保存用戶對照
        for (String userId : userIds) { 
            HrmDingUser dingUser = getSingleDingUser(userId, accessToken);
            dingUser.setCorpId(companyEach.getCorpId());
            dingUser.setUserId(userId);
            save(dingUser);
        }
    }

    return new ActionResult<Map<String, Object>>(ErpStatusCode.SUCCESS, "操作成功", null);
}


/**
 * 獲取單個釘釘的用戶信息
 */
private HrmDingUser getSingleDingUser(String userId, String accessToken) {
    String requestUrl = "https://oapi.dingtalk.com/user/get?access_token=" + accessToken + "&userid=" + userId;
    RequestResult result = SendHttpRequestUtil.doGet(requestUrl);
    HrmDingUser dingUser = new HrmDingUser();
    JSONObject jsonObject = JSON.parseObject(result.getResult());
    String msg = (String) jsonObject.get("errmsg");
    if ("ok".equals(msg)) {
        dingUser.setStaffName(jsonObject.get("name").toString());
        dingUser.setStaffNo(jsonObject.get("jobnumber").toString());
    }
    return dingUser;
}

獲取釘釘的考勤記錄並保存

Controller
@RequestMapping(value = "syncByDays")
public ActionResult<Map<String, Object>> syncByDays(int days) {
    String offset = "0";//分頁獲取數據,0表示第一頁
    String limit = "50";//每頁50條數據
    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");//需要的時間的格式
    String workDateFrom = DateUtils.formatDate(DateUtils.getDestDate(new Date(), -days)) + " 00:00:00";
    String workDateTo = sdf.format(new Date()) + " 23:59:59";
    //多個公司數據合併
    List<HrmDingCompany> companyList = companyService.findList(new HrmDingCompany());
    for (HrmDingCompany companyEach : companyList) {
        String accessToken = recordsService.getAccessToken(companyEach.getCorpId(), companyEach.getCorpSecret());
        recordsService.getUserId(accessToken, workDateFrom, workDateTo, offset, limit, companyEach.getCorpId());
    }

    return new ActionResult<Map<String, Object>>(ErpStatusCode.SUCCESS, "操作成功", null);

}

Service
/**
 * 獲取釘釘用戶的userid
 */
public void getUserId(String accessToken, String workDateFrom, String workDateTo, String offset, String limit, String corpId) {
    List<String> userIdList = dingUserDao.findUserIdList(corpId);
    List<String> userIdListResult = new ArrayList<>();
    if (userIdList.size() > 50) {
        for (int i = 0; 50 * i < userIdList.size(); i++) {
            userIdListResult = userIdList.subList(50 * i, userIdList.size() > 50 * (i + 1) ? 50 * (i + 1) : userIdList.size());
            getDingRecords(accessToken, workDateFrom, workDateTo, offset, limit, corpId, userIdListResult);
        }
    } else {
        userIdListResult = userIdList;
        getDingRecords(accessToken, workDateFrom, workDateTo, offset, limit, corpId, userIdListResult);
    }
}

/**
 * 獲取釘釘的考勤記錄
 */
@Transactional(readOnly = false)
public void getDingRecords(String accessToken, String workDateFrom, String workDateTo, String offset, String limit, String corpId, List<String> userIdList) {
    String requestUrl = "https://oapi.dingtalk.com/attendance/list?access_token=" + accessToken;
    JSONObject jsonObject = new JSONObject();
    jsonObject.put("workDateFrom", workDateFrom);
    jsonObject.put("workDateTo", workDateTo);
    jsonObject.put("offset", offset);
    jsonObject.put("limit", limit);
    jsonObject.put("userIdList", userIdList);
    RequestResult result = SendHttpRequestUtil.doPost(requestUrl, "", jsonObject);
    JSONObject resultJSON = JSONObject.parseObject(result.getResult());
    String msg = (String) resultJSON.get("errmsg");
    String hasMore = resultJSON.get("hasMore").toString();
    List<HrmDingRecords> resultList = new ArrayList<HrmDingRecords>();
    if ("ok".equals(msg)) {
        resultList = JSONObject.parseArray(resultJSON.get("recordresult").toString(), HrmDingRecords.class);
    }
    //保存釘釘的考勤記錄
    saveDingList(resultList);
    //如果還有繼續獲取
    if (resultList.size() == 50) {
        //表示獲取考勤數據的起始點,第一次傳0,如果還有多餘數據,下次獲取傳的offset值爲之前的offset+limit
        offset = String.valueOf(Integer.parseInt(offset) + Integer.parseInt(limit));
        getDingRecords(accessToken, workDateFrom, workDateTo, offset, limit, corpId, userIdList);
    }
}


private void saveDingList(List<HrmStaffDingRecords> list) {
    //保存釘釘數據
    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");//需要的時間的格式
    SimpleDateFormat sdf2 = new SimpleDateFormat("yyyy-MM-dd");//需要的時間的格式
    for (HrmStaffDingRecords hrmStaffDingRecords : list) {
        //如果數據庫裏已經有了就不插入數據
        HrmStaffDingRecords hrmStaffDingRecordsCheck = new HrmStaffDingRecords();
        hrmStaffDingRecordsCheck.setId(hrmStaffDingRecords.getId());
        List<HrmStaffDingRecords> hrmStaffDingRecordsCheckList = findList(hrmStaffDingRecordsCheck);
        if (hrmStaffDingRecordsCheckList.size() > 0) {
            hrmStaffDingRecords.setIsNewRecord(false);
        } else {
            hrmStaffDingRecords.setIsNewRecord(true);
        }
        //轉換獲取到的時間格式
        hrmStaffDingRecords.setBaseCheckTime(sdf.format(new Date(Long.parseLong(String.valueOf(hrmStaffDingRecords.getBaseCheckTime())))));
        hrmStaffDingRecords.setUserCheckTime(sdf.format(new Date(Long.parseLong(String.valueOf(hrmStaffDingRecords.getUserCheckTime())))));
        hrmStaffDingRecords.setWorkDate(sdf2.format(new Date(Long.parseLong(String.valueOf(hrmStaffDingRecords.getWorkDate())))));
        save(hrmStaffDingRecords);

        //保存頁面展示數據
        HrmStaffAttendanceRecords hrmStaffAttendanceRecords = new HrmStaffAttendanceRecords();
        //上班數據保存
        if (hrmStaffDingRecords.getCheckType().equals("OnDuty")) {
            try {
                hrmStaffAttendanceRecords.setAttendanceBeginTime(sdf.parse(hrmStaffDingRecords.getUserCheckTime()));
            } catch (ParseException e) {
                e.printStackTrace();
            }
            hrmStaffAttendanceRecords.setUserId(hrmStaffDingRecords.getUserId());
            hrmStaffAttendanceRecords.setWorkDate(hrmStaffDingRecords.getWorkDate());
            if (hrmStaffDingRecords.getTimeResult().equals("Normal")) {
                hrmStaffAttendanceRecords.setAttendanceStatus("0");
            } else if (hrmStaffDingRecords.getTimeResult().equals("Late")) {
                hrmStaffAttendanceRecords.setAttendanceStatus("5");
            } else if (hrmStaffDingRecords.getTimeResult().equals("SeriousLate")) {
                hrmStaffAttendanceRecords.setAttendanceStatus("5");
            } else if (hrmStaffDingRecords.getTimeResult().equals("Absenteeism")) {
                hrmStaffAttendanceRecords.setAttendanceStatus("2");
            } else if (hrmStaffDingRecords.getTimeResult().equals("NotSigned")) {
                hrmStaffAttendanceRecords.setAttendanceStatus("2");
            }
            //如果數據庫裏有記錄了則更新上班時間
            HrmStaffAttendanceRecords hrmStaffAttendanceRecordsCheck = new HrmStaffAttendanceRecords();
            hrmStaffAttendanceRecordsCheck.setUserId(hrmStaffAttendanceRecords.getUserId());
            hrmStaffAttendanceRecordsCheck.setWorkDate(hrmStaffAttendanceRecords.getWorkDate());
            List<HrmStaffAttendanceRecords> hrmStaffAttendanceRecordsCheckList = hrmStaffAttendanceRecordsService.findList(hrmStaffAttendanceRecordsCheck);
            if (hrmStaffAttendanceRecordsCheckList.size() != 0) {
                hrmStaffAttendanceRecordsCheck = hrmStaffAttendanceRecordsCheckList.get(0);
                hrmStaffAttendanceRecordsCheck.setAttendanceBeginTime(hrmStaffAttendanceRecords.getAttendanceBeginTime());
                hrmStaffAttendanceRecordsService.save(hrmStaffAttendanceRecordsCheck);
            } else {
                hrmStaffAttendanceRecordsService.save(hrmStaffAttendanceRecords);
            }
        }

        //下班數據保存,找到上班記錄並更新
        if (hrmStaffDingRecords.getCheckType().equals("OffDuty")) {
            HrmStaffAttendanceRecords hrmStaffAttendanceRecordsFind = new HrmStaffAttendanceRecords();
            hrmStaffAttendanceRecordsFind.setUserId(hrmStaffDingRecords.getUserId());
            hrmStaffAttendanceRecordsFind.setWorkDate(hrmStaffDingRecords.getWorkDate());
            List<HrmStaffAttendanceRecords> hrmStaffAttendanceRecordsCheckList = hrmStaffAttendanceRecordsService.findList(hrmStaffAttendanceRecordsFind);
            if (hrmStaffAttendanceRecordsCheckList.size() != 0) {
                hrmStaffAttendanceRecordsFind = hrmStaffAttendanceRecordsCheckList.get(0);
                try {
                    hrmStaffAttendanceRecordsFind.setAttendanceEndTime(sdf.parse(hrmStaffDingRecords.getUserCheckTime()));
                    if (StringUtils.isNotBlank(hrmStaffAttendanceRecordsFind.getAttendanceBeginTime().toString()) && StringUtils.isNotBlank(hrmStaffAttendanceRecordsFind.getAttendanceEndTime().toString())) {
                        //午休一個半小時邏輯判斷
                        String restTime = hrmStaffAttendanceRecordsFind.getWorkDate() + " 13:30:00";
                        Date checkDate = DateUtils.parseDate(restTime);
                        long between;
                        if (checkDate.getTime() < hrmStaffAttendanceRecordsFind.getAttendanceEndTime().getTime()) {
                            between = hrmStaffAttendanceRecordsFind.getAttendanceEndTime().getTime() - hrmStaffAttendanceRecordsFind.getAttendanceBeginTime().getTime() - 1000 * 60 * 90;
                        } else {
                            between = hrmStaffAttendanceRecordsFind.getAttendanceEndTime().getTime() - hrmStaffAttendanceRecordsFind.getAttendanceBeginTime().getTime();
                        }
                        hrmStaffAttendanceRecordsFind.setWorkHours(TimeUtils.toTimeString(between));
                    }
                } catch (ParseException e) {
                    e.printStackTrace();
                }
                hrmStaffAttendanceRecordsService.save(hrmStaffAttendanceRecordsFind);
            }
        }
    }
}

實體

HrmDingCompany
private String corpId;			// 企業ID
private String corpSecret;		// 企業密匙


HrmDingUser 
private String corpId;			// 企業ID
private String groupId;			// 考勤組ID
private String userId;			// 用戶ID
private String staffNo;			// 員工工號
private String staffName;		// 員工姓名
private String officeName;		// 部門名稱


HrmDingRecords
private String baseCheckTime;		// 計算遲到和早退,基準時間
private String checkType;		// 考勤類型(OnDuty:上班,OffDuty:下班)
private String corpId;			// 企業ID
private String groupId;			// 考勤組ID
private String locationResult;		// 上班打卡時間
private String planId;			// 排班ID
private String recordId;		// 打卡記錄ID
private String timeResult;		// 時間結果(Normal:正常;Early:早退; Late:遲到;SeriousLate:嚴重遲到;Absenteeism:曠工遲到; NotSigned:未打卡)
private String userCheckTime;		// 實際打卡時間
private String userId;			// 用戶ID
private String workDate;		// 工作日
private String procInstId;		// 關聯的審批實例id
//用於頁面展示
private String staffNo;			// 員工工號
private String staffName;		// 員工姓名
private String officeName;		// 部門名稱


HrmDingAttendance
private String userId;			// 釘釘用戶ID
private String corpId;			// 企業ID
private String staffNo;			// 員工工號
private String staffName;		// 員工姓名
private String officeName;		// 部門名稱
private String attendanceStatus;	// 考勤狀態0正常1補勤2缺勤3請假4放假5遲到
private String workDate;		// 考勤日期
private Date attendanceBeginTime;	// 上班打卡時間
private Date attendanceEndTime;		// 下班打卡時間
private String workHours;		// 當日上班時長
private String zhengChangDays;		// 正常天數
private String queQinDays;		// 缺勤天數
private String qingJiaDays;		// 請假天數
private String fangJiaDays;		// 放假天數

private String beginDate;		// 時間查詢
private String endDate;			// 時間查詢
private String time;                    // 統計用

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章