开发钉钉机器人的过程中,我们不仅需要直接把组织架构用户信息导入数据库,还要不定时的进行同步,因为钉钉里面的人员总是在变动,部门也是不断在调整。文章来源:https://www.toymoban.com/news/detail-512353.html
下面是使用递归的方式,调用钉钉接口,同步部门和人员信息,没有的创建,多余的删除文章来源地址https://www.toymoban.com/news/detail-512353.html
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
}
到了这里,关于钉钉企业内部机器人开发——同步组织架构人员信息到数据库的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!