Skip to content

Commit c76c4cb

Browse files
feat: feishu用户导入支持指定部门列表open_department_id (opsre#186)
1 parent 7117719 commit c76c4cb

File tree

4 files changed

+163
-36
lines changed

4 files changed

+163
-36
lines changed

config/config.go

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -180,10 +180,11 @@ type WeComConfig struct {
180180
}
181181

182182
type FeiShuConfig struct {
183-
Flag string `mapstructure:"flag" json:"flag"`
184-
AppID string `mapstructure:"app-id" json:"appId"`
185-
AppSecret string `mapstructure:"app-secret" json:"appSecret"`
186-
EnableSync bool `mapstructure:"enable-sync" json:"enableSync"`
187-
DeptSyncTime string `mapstructure:"dept-sync-time" json:"deptSyncTime"`
188-
UserSyncTime string `mapstructure:"user-sync-time" json:"userSyncTime"`
183+
Flag string `mapstructure:"flag" json:"flag"`
184+
AppID string `mapstructure:"app-id" json:"appId"`
185+
AppSecret string `mapstructure:"app-secret" json:"appSecret"`
186+
EnableSync bool `mapstructure:"enable-sync" json:"enableSync"`
187+
DeptSyncTime string `mapstructure:"dept-sync-time" json:"deptSyncTime"`
188+
UserSyncTime string `mapstructure:"user-sync-time" json:"userSyncTime"`
189+
DeptList []string `mapstructure:"dept-list" json:"deptList"`
189190
}

logic/feishu_logic.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ import (
1717
type FeiShuLogic struct {
1818
}
1919

20-
//通过飞书获取部门信息
20+
// 通过飞书获取部门信息
2121
func (d *FeiShuLogic) SyncFeiShuDepts(c *gin.Context, req interface{}) (data interface{}, rspError interface{}) {
2222
// 1.获取所有部门
2323
deptSource, err := feishu.GetAllDepts()
@@ -80,7 +80,7 @@ func (d FeiShuLogic) AddDepts(group *model.Group) error {
8080
return nil
8181
}
8282

83-
//根据现有数据库同步到的部门信息,开启用户同步
83+
// 根据现有数据库同步到的部门信息,开启用户同步
8484
func (d FeiShuLogic) SyncFeiShuUsers(c *gin.Context, req interface{}) (data interface{}, rspError interface{}) {
8585
// 1.获取飞书用户列表
8686
staffSource, err := feishu.GetAllUsers()

public/client/feishu/feishu.go

Lines changed: 121 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -14,35 +14,125 @@ import (
1414
// GetAllDepts 获取所有部门
1515
func GetAllDepts() (ret []map[string]interface{}, err error) {
1616
var (
17-
fetchChild bool = true
18-
pageSize int64 = 50
17+
fetchChild bool = true
18+
pageSize int64 = 50
19+
pageToken string = ""
20+
// DeptID lark.DepartmentIDType = "department_id"
1921
)
2022

21-
req := lark.GetDepartmentListReq{
22-
FetchChild: &fetchChild,
23-
PageSize: &pageSize,
24-
DepartmentID: "0"}
23+
if len(config.Conf.FeiShu.DeptList) == 0 {
24+
req := lark.GetDepartmentListReq{
25+
// DepartmentIDType: &DeptID,
26+
PageToken: &pageToken,
27+
FetchChild: &fetchChild,
28+
PageSize: &pageSize,
29+
DepartmentID: "0",
30+
}
31+
for {
32+
res, _, err := InitFeiShuClient().Contact.GetDepartmentList(context.TODO(), &req)
33+
if err != nil {
34+
return nil, err
35+
}
2536

26-
for {
27-
res, _, err := InitFeiShuClient().Contact.GetDepartmentList(context.TODO(), &req)
28-
if err != nil {
29-
return nil, err
37+
for _, dept := range res.Items {
38+
ele := make(map[string]interface{})
39+
ele["name"] = dept.Name
40+
ele["custom_name_pinyin"] = tools.ConvertToPinYin(dept.Name)
41+
ele["parent_department_id"] = dept.ParentDepartmentID
42+
ele["department_id"] = dept.DepartmentID
43+
ele["open_department_id"] = dept.OpenDepartmentID
44+
ele["leader_user_id"] = dept.LeaderUserID
45+
ele["unit_ids"] = dept.UnitIDs
46+
ret = append(ret, ele)
47+
}
48+
if !res.HasMore {
49+
break
50+
}
51+
pageToken = res.PageToken
3052
}
31-
for _, dept := range res.Items {
32-
ele := make(map[string]interface{})
33-
ele["name"] = dept.Name
34-
ele["custom_name_pinyin"] = tools.ConvertToPinYin(dept.Name)
35-
ele["parent_department_id"] = dept.ParentDepartmentID
36-
ele["department_id"] = dept.DepartmentID
37-
ele["open_department_id"] = dept.OpenDepartmentID
38-
ele["leader_user_id"] = dept.LeaderUserID
39-
ele["unit_ids"] = dept.UnitIDs
40-
ret = append(ret, ele)
53+
} else {
54+
//使用dept-list来一个一个添加部门,开头为^的不添加子部门
55+
isInDeptList := func(id string) bool {
56+
for _, v := range config.Conf.FeiShu.DeptList {
57+
if strings.HasPrefix(v, "^") {
58+
v = v[1:]
59+
}
60+
if id == v {
61+
return true
62+
}
63+
}
64+
return false
4165
}
42-
if !res.HasMore {
43-
break
66+
dep_append_norepeat := func(ret []map[string]interface{}, dept map[string]interface{}) []map[string]interface{} {
67+
for _, v := range ret {
68+
if v["open_department_id"] == dept["open_department_id"] {
69+
return ret
70+
}
71+
}
72+
return append(ret, dept)
73+
}
74+
for _, dep_s := range config.Conf.FeiShu.DeptList {
75+
dept_id := dep_s
76+
no_add_children := false
77+
if strings.HasPrefix(dep_s, "^") {
78+
no_add_children = true
79+
dept_id = dep_s[1:]
80+
}
81+
req := lark.GetDepartmentReq{
82+
DepartmentID: dept_id,
83+
}
84+
res, _, err := InitFeiShuClient().Contact.GetDepartment(context.TODO(), &req)
85+
if err != nil {
86+
return nil, err
87+
}
88+
ele := make(map[string]interface{})
89+
90+
ele["name"] = res.Department.Name
91+
ele["custom_name_pinyin"] = tools.ConvertToPinYin(res.Department.Name)
92+
if isInDeptList(res.Department.ParentDepartmentID) {
93+
ele["parent_department_id"] = res.Department.ParentDepartmentID
94+
} else {
95+
ele["parent_department_id"] = "0"
96+
}
97+
ele["department_id"] = res.Department.DepartmentID
98+
ele["open_department_id"] = res.Department.OpenDepartmentID
99+
ele["leader_user_id"] = res.Department.LeaderUserID
100+
ele["unit_ids"] = res.Department.UnitIDs
101+
ret = dep_append_norepeat(ret, ele)
102+
103+
if !no_add_children {
104+
pageToken = ""
105+
req := lark.GetDepartmentListReq{
106+
// DepartmentIDType: &DeptID,
107+
PageToken: &pageToken,
108+
FetchChild: &fetchChild,
109+
PageSize: &pageSize,
110+
DepartmentID: dept_id,
111+
}
112+
for {
113+
res, _, err := InitFeiShuClient().Contact.GetDepartmentList(context.TODO(), &req)
114+
if err != nil {
115+
return nil, err
116+
}
117+
118+
for _, dept := range res.Items {
119+
ele := make(map[string]interface{})
120+
ele["name"] = dept.Name
121+
ele["custom_name_pinyin"] = tools.ConvertToPinYin(dept.Name)
122+
ele["parent_department_id"] = dept.ParentDepartmentID
123+
ele["department_id"] = dept.DepartmentID
124+
ele["open_department_id"] = dept.OpenDepartmentID
125+
ele["leader_user_id"] = dept.LeaderUserID
126+
ele["unit_ids"] = dept.UnitIDs
127+
ret = dep_append_norepeat(ret, ele)
128+
}
129+
if !res.HasMore {
130+
break
131+
}
132+
pageToken = res.PageToken
133+
}
134+
}
44135
}
45-
req.PageToken = &res.PageToken
46136
}
47137
return
48138
}
@@ -51,23 +141,26 @@ func GetAllDepts() (ret []map[string]interface{}, err error) {
51141
// GetAllUsers 获取所有员工信息
52142
func GetAllUsers() (ret []map[string]interface{}, err error) {
53143
var (
54-
pageSize int64 = 50
144+
pageSize int64 = 50
145+
pageToken string = ""
146+
// deptidtype lark.DepartmentIDType = "department_id"
55147
)
56148
depts, err := GetAllDepts()
57149
if err != nil {
58150
return nil, err
59151
}
60152

61153
deptids := make([]string, 0)
62-
deptids = append(deptids, "0") // 0 代表根部门
154+
// deptids = append(deptids, "0")
63155
for _, dept := range depts {
64156
deptids = append(deptids, dept["open_department_id"].(string))
65157
}
66158

67159
for _, deptid := range deptids {
68160
req := lark.GetUserListReq{
69-
PageSize: &pageSize,
70-
PageToken: new(string),
161+
PageSize: &pageSize,
162+
PageToken: &pageToken,
163+
// DepartmentIDType: &deptidtype,
71164
DepartmentID: deptid,
72165
}
73166
for {
@@ -112,7 +205,7 @@ func GetAllUsers() (ret []map[string]interface{}, err error) {
112205
if !res.HasMore {
113206
break
114207
}
115-
req.PageToken = &res.PageToken
208+
pageToken = res.PageToken
116209
}
117210
}
118211
return

service/ildap/user_ildap.go

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,39 @@ func (x UserService) Update(oldusername string, user *model.User) error {
7474
return nil
7575
}
7676

77+
func (x UserService) Exist(filter map[string]interface{}) (bool, error) {
78+
filter_str := ""
79+
for key, value := range filter {
80+
filter_str += fmt.Sprintf("(%s=%s)", key, value)
81+
}
82+
search_filter := fmt.Sprintf("(&(|(objectClass=inetOrgPerson)(objectClass=simpleSecurityObject))%s)", filter_str)
83+
// Construct query request
84+
searchRequest := ldap.NewSearchRequest(
85+
config.Conf.Ldap.BaseDN, // This is basedn, we will start searching from this node.
86+
ldap.ScopeWholeSubtree, ldap.NeverDerefAliases, 0, 0, false, // Here several parameters are respectively scope, derefAliases, sizeLimit, timeLimit, typesOnly
87+
search_filter, // This is Filter for LDAP query
88+
[]string{"DN"}, // Here are the attributes returned by the query, provided as an array. If empty, all attributes are returned
89+
nil,
90+
)
91+
92+
// 获取 LDAP 连接
93+
conn, err := common.GetLDAPConn()
94+
defer common.PutLADPConn(conn)
95+
if err != nil {
96+
return false, err
97+
}
98+
var sr *ldap.SearchResult
99+
// Search through ldap built-in search
100+
sr, err = conn.Search(searchRequest)
101+
if err != nil {
102+
return false, err
103+
}
104+
if len(sr.Entries) > 0 {
105+
return true, nil
106+
}
107+
return false, nil
108+
}
109+
77110
// Delete 删除资源
78111
func (x UserService) Delete(udn string) error {
79112
del := ldap.NewDelRequest(udn, nil)

0 commit comments

Comments
 (0)