Переглянути джерело

增加了dingtalk oa的自定义方法

ila 4 роки тому
батько
коміт
ba8227459d
1 змінених файлів з 331 додано та 30 видалено
  1. 331 30
      xnet/dingtalk_oa.go

+ 331 - 30
xnet/dingtalk_oa.go

@@ -2,21 +2,33 @@ package xnet
 
 import (
 	"encoding/json"
+	"fmt"
 	"gcore/core"
+	"gcore/xnet"
 	"log"
 	"net/http"
+	"strings"
 )
 
 type DevConf struct {
-	AppKey             string
-	AppSecret          string
-	GetTokenUrl        string
-	GetDeptUserListUrl string
-	Token              string
-	Params             map[string]string
-	Headers            map[string]string
-	Cookie             []*http.Cookie
-	DeptId             int
+	AppKey                                string
+	AppSecret                             string
+	GetTokenUrl                           string
+	GetDeptListUrl                        string
+	GetDeptUserListUrl                    string
+	GetAttendanceGroupUrl                 string
+	GetAttendanceGroupUserIdsUrl          string
+	GetAttendanceClockDataUrl             string
+	GetAttendanceGroupDetailsUrl          string
+	ListAttendanceGroupMenberListByIdsUrl string
+	Token                                 string
+	Params                                map[string]string
+	Headers                               map[string]string
+	Cookie                                []*http.Cookie
+	DeptId                                int64
+	OpUserId                              int64
+	ManageGroupId                         int64
+	EmployeeGroupId                       int64
 }
 
 // @title GetToken
@@ -25,7 +37,7 @@ type DevConf struct {
 // @return
 func (m *DevConf) GetToken() error {
 	params := map[string]string{"appkey": m.AppKey, "appsecret": m.AppSecret}
-	content, err := GetX(m.GetTokenUrl, params, m.Headers, m.Cookie)
+	content, err := xnet.GetX(m.GetTokenUrl, params, m.Headers, m.Cookie)
 	if err != nil {
 		log.Printf("GetToken error : %v", err)
 	}
@@ -44,52 +56,341 @@ func (m *DevConf) GetToken() error {
 
 }
 
+// @title GetDeptList
+// @description 获取部门列表,只支持查询下一级子部门 https://developers.dingtalk.com/document/app/obtain-the-department-list-v2
+// @param
+// @return
+func (m *DevConf) GetDeptList(deptId int64) ([]interface{}, error) {
+	result := []interface{}{}
+	PostData := make(map[string]interface{})
+	PostData["dept_id"] = deptId
+	content, err := xnet.PostJson(m.GetDeptListUrl, m.Params, m.Headers, PostData, m.Cookie)
+	if err != nil {
+		log.Printf("GetDeptUserList  PostJson error : %v", err)
+		return result, err
+
+	}
+	ret := map[string]interface{}{}
+	err = json.Unmarshal([]byte(content), &ret)
+	if err != nil {
+		log.Printf("Unmarshal error : %v", err)
+		return result, err
+	}
+
+	//fmt.Printf("ret===>%v\n", ret)
+	result = ret["result"].([]interface{})
+	/*
+		{
+		    "errcode": 0,
+		    "errmsg":"ok",
+		    "result": [
+		        {
+		            "auto_add_user": true,
+		            "create_dept_group": true,
+		            "dept_id": 37xxxx95,
+		            "name": "市场部",
+		            "parent_id": 1
+		        },
+		        {
+		            "auto_add_user": true,
+		            "create_dept_group": true,
+		            "dept_id": 399xxxx96,
+		            "name": "财务部",
+		            "parent_id": 1
+		        }
+		    ],
+		    "request_id": "5um7ykyaalsj"
+		}
+	*/
+	return result, nil
+}
+
 // @title GetDeptUserList
-// @description 获取部门成员的姓名和userid
+// @description 获取部门成员的姓名和userid https://developers.dingtalk.com/document/app/queries-the-simple-information-of-a-department-user
 // @param
 // @return
-func (m *DevConf) GetDeptUserList() (deptUserList []map[string]string, err error) {
-	cursor := 0
+func (m *DevConf) GetDeptUserList(deptId int64) (map[string]string, error) {
+	cursor := 0.0
 	size := 100
-
+	PostData := make(map[string]interface{})
+	PostData["dept_id"] = deptId
+	PostData["size"] = size
+	deptUserList := make(map[string]string)
+	//外层循环,翻页
 	for {
-		data := map[string]interface{}{
-			"dept_id": m.DeptId,
-			"cursor":  cursor,
-			"size":    size,
-		}
-		content, err := PostJson(m.GetDeptUserListUrl, m.Params, m.Headers, data, m.Cookie)
+		PostData["cursor"] = cursor
+
+		//fmt.Printf("%v\n", cursor)
+		//请求APi
+		content, err := xnet.PostJson(m.GetDeptUserListUrl, m.Params, m.Headers, PostData, m.Cookie)
 		if err != nil {
-			log.Printf("GetToken error : %v", err)
-			continue
+			log.Printf("GetDeptUserList  PostJson error : %v", err)
+
 		}
 
 		ret := map[string]interface{}{}
 		err = json.Unmarshal([]byte(content), &ret)
 		if err != nil {
 			log.Printf("Unmarshal error : %v", err)
-			continue
+
 		}
+		/*
+			{
+			    "errcode": 0,
+			    "errmsg": "ok",
+			    "result": {
+			        "has_more": false,
+			        "list": [
+			            {
+			                "name": "测试用户2",
+			                "userid": "user100"
+			            },
+			            {
+			                "name": "李思",
+			                "userid": "user1"
+			            }
+			        ]
+			    },
+			    "request_id": "x4p6arvi0fzj"
+			}
+		*/
 		result := ret["result"]
+		//遍历用户信息list
 		for _, i := range result.(map[string]interface{})["list"].([]interface{}) {
-			tmpData := core.StringInterfaceToStringString(i.(map[string]interface{}))
-			deptUserList = append(deptUserList, tmpData)
+			deptUserList[i.(map[string]interface{})["userid"].(string)] = i.(map[string]interface{})["name"].(string)
+
 		}
 		//当前请求返回数据量小于size,跳出循环
 		if len(result.(map[string]interface{})["list"].([]interface{})) < size {
 			break
 		}
+		if result.(map[string]interface{})["next_cursor"] == nil {
+			break
+		}
+		cursor = result.(map[string]interface{})["next_cursor"].(float64)
+	}
+
+	return deptUserList, nil
+}
+
+// @title GetAttendanceGroup
+// @description 批量获取考勤组摘要 https://developers.dingtalk.com/document/app/batch-query-of-simple-information-of-the-attendance-group
+// @param
+// @return
+func (m *DevConf) GetAttendanceGroup() ([]map[string]interface{}, error) {
+	groupData := []map[string]interface{}{}
+
+	PostData := make(map[string]interface{})
+	cursor := 1
+	PostData["op_user_id"] = m.OpUserId
+	PostData["cursor"] = cursor
+
+	content, err := xnet.PostJson(m.GetAttendanceGroupUrl, m.Params, m.Headers, PostData, m.Cookie)
+	if err != nil {
+		log.Printf("GetAttendanceClockData PostJson error : %v", err)
+		return groupData, err
+	}
+
+	ret := map[string]interface{}{}
+	err = json.Unmarshal([]byte(content), &ret)
+	if err != nil {
+		log.Printf("Unmarshal error : %v", err)
+		return groupData, err
+	}
+	/*
+		{
+		    "errcode": 0,
+		    "result": {
+		        "cursor": 685935028,
+		        "has_more": false,
+		        "result": [
+		            {
+		                "id": 677765054,
+		                "name": "周末加班"
+		            },
+		            {
+		                "id": 685935028,
+		                "name": "考勤"
+		            }
+		        ]
+		    },
+		    "success": true,
+		    "request_id": "wv9973jntamw"
+		}
+	*/
+	//fmt.Printf("%v\n", ret)
+
+	result := ret["result"]
+	for _, group := range result.(map[string]interface{})["result"].([]interface{}) {
+		group_id := int64(group.(map[string]interface{})["id"].(float64))
+		group_name := group.(map[string]interface{})["name"].(string)
+		groupData = append(groupData, map[string]interface{}{"group_id": group_id, "group_name": group_name})
+
+	}
+	return groupData, err
+}
+
+// @title GetAttendanceClockData
+// @description 获取7天内的指定时间段成员的打卡记录, https://developers.dingtalk.com/document/app/open-attendance-clock-in-data
+// @param days获取多少天内的考勤数据
+// @return
+func (m *DevConf) GetAttendanceClockData(days int, userIdList []string) (map[string][]int, error) {
+
+	limit := 50      //表示获取考勤数据的条数,最大不能超过50条。
+	userIdStep := 50 //单次请求传入的userId数量
+	//最近30天日期数组
+	workData, _ := core.GetWorkDate(days)
+	fmt.Printf("workData lenght %v\n", len(workData))
+	//post请求的body
+	PostData := make(map[string]interface{})
+
+	PostData["dept_id"] = m.DeptId
+	PostData["limit"] = limit
+
+	//当前部门每个人的考勤数据
+	attendanceData := make(map[string][]int)
+
+	userIdIndex := 0
+	//userId的遍历
+	for {
+
+		if userIdIndex+1 > len(userIdList) {
+			break
+		}
+		fmt.Printf("=================第%v位至第%v位user开始遍历\n", userIdIndex+1, userIdIndex+userIdStep)
+
+		if userIdIndex+userIdStep > len(userIdList) {
+			PostData["userIdList"] = userIdList[userIdIndex+1:]
+		} else {
+			PostData["userIdList"] = userIdList[userIdIndex+1 : userIdIndex+userIdStep]
+		}
+
+		//外面的for是日期遍历,间隔6天
+		date := 0
+		dateStep := 6
+		for {
+
+			if date >= len(workData) {
+				break
+			}
+			fmt.Printf("---------------%v开始的考勤\n", workData[date+1])
+			fmt.Printf("date==>%v\n", date+1)
+			splits := strings.Split(workData[date+1], "/")
+			PostData["workDateFrom"] = fmt.Sprintf("%s-%s-%s 00:00:00", splits[0], splits[1], splits[2])
+			if date+1+dateStep < len(workData) {
+				splits = strings.Split(workData[date+1+dateStep], "/")
+			} else {
+				splits = strings.Split(workData[len(workData)-1], "/")
+			}
+
+			PostData["workDateTo"] = fmt.Sprintf("%s-%s-%s 00:00:00", splits[0], splits[1], splits[2])
+			//分页遍历
+			offset := 0 //获取考勤数据的起始点。第一次传0,如果还有多余数据,下次获取传的offset值为之前的offset+limit,
+			for {
+				fmt.Printf("---------------从%v条到%v条的数据\n", offset, offset+limit)
+				PostData["offset"] = offset
+
+				//fmt.Printf("offset %v\n", offset)
+				//fmt.Printf("data %v\n", data)
+				content, err := xnet.PostJson(m.GetAttendanceClockDataUrl, m.Params, m.Headers, PostData, m.Cookie)
+				if err != nil {
+					log.Printf("GetAttendanceClockData PostJson error : %v", err)
 
-		data["curosr"] = result.(map[string]interface{})["next_cursor"].(int64)
+				}
+
+				ret := map[string]interface{}{}
+				err = json.Unmarshal([]byte(content), &ret)
+				if err != nil {
+					log.Printf("Unmarshal error : %v", err)
+
+				}
+				//fmt.Printf("%v\n", ret)
+				//开始解析本次请求的考勤数据,添加到attendanceData
+				for _, i := range ret["recordresult"].([]interface{}) {
+
+					userId := i.(map[string]interface{})["userId"].(string)
+					userCheckTime := i.(map[string]interface{})["userCheckTime"].(float64)
+					//把考勤数据加到个人的slice里
+					attendanceData[userId] = append(attendanceData[userId], int(userCheckTime))
+
+				}
+
+				//当前请求返回数据量小于size,跳出循环
+				if len(ret["recordresult"].([]interface{})) < limit {
+					break
+				}
+
+				offset += limit
+				//time.Sleep(1*time.Second)
+			}
+			date += dateStep
+		}
+		userIdIndex += userIdStep
 	}
+	return attendanceData, nil
+}
+
+// @title GetAttendanceGroupDetails
+// @description 获取考勤组列表,  https://developers.dingtalk.com/document/app/queries-attendance-group-list-details
+// @param
+// @return map[5.5天制管理人员:753150009 5天制:761355305 6天制员工:667040040 合肥1:721640063 合肥6天制:795345194 清洁:854690013 音乐:761855162]
+func (m *DevConf) GetAttendanceGroupDetails() (map[int64]string, error) {
+	PostData := make(map[string]interface{})
+	PostData["offset"] = 0
+	PostData["size"] = 10
+
+	content, err := xnet.PostJson(m.GetAttendanceGroupDetailsUrl, m.Params, m.Headers, PostData, m.Cookie)
+	if err != nil {
+		log.Printf("GetAttendanceClockData PostJson error : %v", err)
 
-	return
+	}
+
+	ret := map[string]interface{}{}
+	err = json.Unmarshal([]byte(content), &ret)
+	if err != nil {
+		log.Printf("Unmarshal error : %v", err)
+
+	}
+	attendaceGroups := make(map[int64]string)
+	groups := ret["result"].(map[string]interface{})["groups"]
+	for _, i := range groups.([]interface{}) {
+		attendaceGroups[int64(i.(map[string]interface{})["group_id"].(float64))] = i.(map[string]interface{})["group_name"].(string)
+	}
+
+	return attendaceGroups, nil
 }
 
-// @title GetDeptAttendanceData
-// @description 30天内部门考勤数据
+// @title ListAttendanceGroupMenberListByIds
+// @description 考勤组成员校验 , https://developers.dingtalk.com/document/app/query-members-by-id
 // @param
 // @return
-func GetDeptAttendanceData() {
+func (m *DevConf) ListAttendanceGroupMenberListByIds(groupId int64, userIdList []string) ([]string, error) {
+	PostData := make(map[string]interface{})
+	PostData["op_user_id"] = m.OpUserId
+	PostData["group_id"] = groupId
+	userids := strings.Join(userIdList, ",")
+	//fmt.Printf("userids=======>%v\n", userids)
+	PostData["member_ids"] = userids
+	PostData["member_type"] = 0
+
+	content, err := xnet.PostJson(m.ListAttendanceGroupMenberListByIdsUrl, m.Params, m.Headers, PostData, m.Cookie)
+	if err != nil {
+		log.Printf("GetAttendanceClockData PostJson error : %v", err)
+
+	}
+
+	ret := map[string]interface{}{}
+	err = json.Unmarshal([]byte(content), &ret)
+	if err != nil {
+		log.Printf("Unmarshal error : %v", err)
+	}
+	//fmt.Printf("%v\n", ret)
+
+	userIds := []string{}
+
+	for _, i := range ret["result"].([]interface{}) {
+		userIds = append(userIds, i.(string))
+	}
 
+	return userIds, nil
 }