钉钉企业内部机器人开发——同步组织架构人员信息到数据库

开发钉钉机器人的过程中,我们不仅需要直接把组织架构用户信息导入数据库,还要不定时的进行同步,因为钉钉里面的人员总是在变动,部门也是不断在调整。

下面是使用递归的方式,调用钉钉接口,同步部门和人员信息,没有的创建,多余的删除

func (d *DingDept) ImportDeptData() (DepartmentList []DingDept, err error) {
    var oldDept []DingDept
    err = global.GLOAB_DB.Find(&oldDept).Error
    if err != nil {

    }
    var dfs func(string, int) (err error)
    dfs = func(token string, id int) (err error) {
        var client *http.Client
        var request *http.Request
        var resp *http.Response
        var body []byte
        URL := "https://oapi.dingtalk.com/topapi/v2/department/listsub?access_token=" + token
        client = &http.Client{Transport: &http.Transport{ //对客户端进行一些配置
            TLSClientConfig: &tls.Config{
                InsecureSkipVerify: true,
            },
        }, Timeout: time.Duration(time.Second * 5)}
        //此处是post请求的请求题,我们先初始化一个对象
        b := struct {
            DeptID int `json:"dept_id"`
        }{
            DeptID: id,
        }
        //然后把结构体对象序列化一下
        bodymarshal, err := json.Marshal(&b)
        if err != nil {
            return
        }
        //再处理一下
        reqBody := strings.NewReader(string(bodymarshal))
        //然后就可以放入具体的request中的
        request, err = http.NewRequest(http.MethodPost, URL, reqBody)
        if err != nil {
            return
        }
        resp, err = client.Do(request)
        if err != nil {
            return
        }
        defer resp.Body.Close()
        body, err = ioutil.ReadAll(resp.Body) //把请求到的body转化成byte[]
        if err != nil {
            return
        }
        r := struct {
            DingResponseCommon
            Result []DingDept `json:"result"`
        }{}
        //把请求到的结构反序列化到专门接受返回值的对象上面
        err = json.Unmarshal(body, &r)
        if err != nil {
            return
        }
        if r.Errcode != 0 {
            return errors.New(r.Errmsg)
        }
        // 此处举行具体的逻辑判断,然后返回即可
        subDepartments := r.Result
        DepartmentList = append(DepartmentList, subDepartments...)
        if len(subDepartments) > 0 {
            for i := range subDepartments {
                departmentList := make([]DingDept, 0)
                dfs(token, subDepartments[i].DeptId)
                if err != nil {
                    return
                }
                DepartmentList = append(DepartmentList, departmentList...)
            }
        }
        return
    }
    err = dfs(d.DingToken.Token, 1)
    if err != nil {
        return
    }
    //取差集查看一下那些部门已经不在来了,进行软删除

    err = global.GLOAB_DB.Clauses(clause.OnConflict{
        Columns:   []clause.Column{{Name: "dept_id"}},
        DoUpdates: clause.AssignmentColumns([]string{"name", "parent_id"}),
    }).Create(&DepartmentList).Error
    //找到不存在的部门进行软删除,同时删除其关系
    Deleted := DiffSilceDept(oldDept, DepartmentList)
    err = global.GLOAB_DB.Select(clause.Associations).Delete(&Deleted).Error
    //根据部门id存储一下部门用户
    for i := 0; i < len(DepartmentList); i++ {
        UserList := make([]DingUser, 0)
        //调用钉钉接口,获取部门中的成员,然后存储进来
        hasMore := true
        for hasMore {
            tempUserList := make([]DingUser, 0)
            d.DeptId = DepartmentList[i].DeptId
            tempUserList, hasMore, err = d.GetUserListByDepartmentID(0, 100)
            if err != nil {
                zap.L().Error("获取部门用户详情失败", zap.Error(err))
            }
            UserList = append(UserList, tempUserList...)
            fmt.Println(i)
            fmt.Println(hasMore)
        }
        //查到用户后,同步到数据库里面,把不在组织架构里面直接删除掉
        //先查一下老的
        oldUserList := make([]DingUser, 0)
        global.GLOAB_DB.Model(&DingDept{DeptId: DepartmentList[i].DeptId}).Association("UserList").Find(&oldUserList)
        //取差集找到需要删除的名单
        userDeleted := DiffSilceUser(oldUserList, UserList)
        err = global.GLOAB_DB.Select(clause.Associations).Delete(&userDeleted).Error
        err = global.GLOAB_DB.Clauses(clause.OnConflict{
            Columns:   []clause.Column{{Name: "user_id"}},
            DoUpdates: clause.AssignmentColumns([]string{"name", "title"}),
        }).Create(&UserList).Error
        //更新用户部门关系,更新的原理是:先把之前该部门的关系全部删除,然后重新添加
        err = global.GLOAB_DB.Model(&DepartmentList[i]).Association("UserList").Replace(UserList)
    }
    return
}

你可能感兴趣的:(golang,算法,钉钉机器人开发,钉钉,机器人)