【功能开发】从钉钉接口同步部门数据

钉钉接口文档地址:

https://developers.dingtalk.com/document/app/queries-the-complete-information-of-a-department-user

我写的思路,是先获取所有的部门ID,再通过部门ID查询用户详情,遍历到一个List集合中,进行批量插入。

先贴代码,然后详细理清思路

SysDeptController.java

/**
     * 同步钉钉子部门数据
     * 此同步方式为全量同步
     */
    @PreAuthorize(hasPermi = "system:dept:sync")
    @Log(title = "同步钉钉部门数据", businessType = BusinessType.SYNC)
    @GetMapping("/syncListDept")
    public AjaxResult syncListDept () throws ApiException {
        long startTime = System.currentTimeMillis();

        SysDDToken token = deptService.getToken();
        if(!DingConstant.SUCCESS_CODE.equals(token.getCode())){
            return AjaxResult.error(token.getMsg());
        }
        // 删除根部门以下的全部数据
        deptService.deleteDeptExceptRoot();

        insertListDeptFromDD(token.getToken(), DingConstant.ROOT_DEPT_ID);
        long EndTime = System.currentTimeMillis();
        return AjaxResult.success("同步数据成功,耗时:"+(EndTime-startTime)/1000+" 秒");
    }
    /**
     * @description: 根据部门ID获取子部门列表
     * @throws ApiException
     */
    public void insertListDeptFromDD(String token,Long deptId) throws ApiException {
        // 当前部门为父部门
        SysDept subDept = deptService.selectDeptById(deptId);
        JSONObject rootObject = deptService.getListDeptFromDD(token, deptId);
        // 判断是否成功
        checkIsSuccess(rootObject);
        JSONArray result = rootObject.getJSONArray("result");
        if(result.size() == 0){
            return;
        }
        if(result.size() > 0){
            int num = 1;
            for (Object o : result) {
                JSONObject s =  (JSONObject)o;
                SysDept sd = new SysDept();
                // 部门ID
                sd.setDeptId(s.getLong("dept_id"));
                // 部门名称
                sd.setDeptName(s.getString("name"));
                // 父级部门名称
                sd.setParentId(s.getLong("parent_id"));
                sd.setStatus("0");
                sd.setDelFlag("0");
                sd.setOrderNum(String.valueOf(num++));
                sd.setCreateBy(SecurityUtils.getUsername());
                //树状列表
                sd.setAncestors(subDept.getAncestors() + "," + sd.getParentId());

                deptService.insertDeptFromDD(sd);
                insertListDeptFromDD(token,sd.getDeptId());
            }
        }
    }
    public void checkIsSuccess(JSONObject rootObject){
        if (!DingConstant.SUCCESS_CODE.equals(rootObject.getString("errcode"))) {
            throw new ServiceException(rootObject.getString("errmsg"));
        }
    }

SysDeptServiceImpl.java

/**
     * 获取子部门详情
     * @param token :钉钉 token
     * @param deptId :部门ID,根部门为1
     */
    public JSONObject getListDeptFromDD(String token, Long deptId) throws ApiException {
        DingTalkClient client = new DefaultDingTalkClient(DingConstant.DEPT_LIST_API);
        OapiV2DepartmentListsubRequest req = new OapiV2DepartmentListsubRequest();
        req.setDeptId(deptId);
        OapiV2DepartmentListsubResponse rsp = client.execute(req, token);
        return JSONObject.parseObject(rsp.getBody());
    }

获取部门列表的接口

在这里插入图片描述
可以看到,Query参数中有个必填的参数:access_token

access_token:(调用服务端API的应用凭证)。

该参数必须要有,否则会报错。

不同的企业应用,获取token的方式并不相同,具体可以参考官网文档—>传送门

获取token的代码如下:

/**
     * 获取钉钉应用的access_token
     * @return SubToken
     * @throws ApiException
     */
    @Override
    public SysDDToken getToken() throws ApiException {
        DingTalkClient client = new DefaultDingTalkClient(DingConstant.TOKEN_API);
        OapiGettokenRequest request = new OapiGettokenRequest();
        request.setAppkey(DingConstant.APP_KEY);
        request.setAppsecret(DingConstant.APP_SECRET);
        request.setHttpMethod(DingConstant.GET_METHOD);
        return JSON.parseObject(client.execute(request).getBody(), SysDDToken.class);
    }

insertListDeptFromDD是采用递归的方式,进行循环插入。

改进

OapiV2DepartmentListsubResponse rsp  = client.execute(req, token);
return JSONObject.parseObject(rsp.getBody());

这里的rsp 已经可以获取数据了,完全没必要转为json,再解析。

JSONObject rootObject = deptService.getListDeptFromDD(token, deptId);
JSONArray result = rootObject.getJSONArray("result");

这里deptService.getListDeptFromDD(token, deptId)不应该返回JSONObject ,而是应该直接返回OapiV2DepartmentListsubResponse对象。

这个OapiV2DepartmentListsubResponse对象它有个rsp.getResult()可以直接获取result

何必多此一举。

这就去改动代码。

posted @ 2021-11-29 09:19  layman~  阅读(563)  评论(0编辑  收藏  举报