• 钉钉统计部门个人请假次数go


    前言

    最近小组需要统计部门各种请假次数,写了一个方法,第一次实战中用到递归函数,简单记录一下。

    效果展示

    在这里插入图片描述

    这些数据不需要返回json,这里这样是为了方便测试。可以通过这些数据完成其它的操作。

    功能实现

    钉钉服务端调试工具API Explorer

    在这里插入图片描述

    感兴趣的可以在接口里面详细看一下参数,这里就不一 一解释了

    定义model

    请求参数

    package model
    
    type RequestDingLeave struct {
    	UseridList string `json:"userid_list"` // 待查询用户的ID列表,每次最多100个。
    	StartTime  int    `json:"start_time"`  // 开始时间 ,Unix时间戳,支持最多180天的查询。
    	EndTime    int    `json:"end_time"`    // 结束时间,Unix时间戳,支持最多180天的查询。
    	Offset     int    `json:"offset"`      // 支持分页查询,与size参数同时设置时才生效,此参数代表偏移量,偏移量从0开始。
    	Size       int    `json:"size"`        // 支持分页查询,与offset参数同时设置时才生效,此参数代表分页大小,最大20。
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    响应参数

    package model
    
    // DingLeaveStatus 请假状态
    type DingLeaveStatus struct {
    	StartTime       int64  `json:"start_time"`
    	DurationPercent int    `json:"duration_percent"`
    	EndTime         int64  `json:"end_time"`
    	LeaveCode       string `json:"leave_code"` // 请假类型 个人事假:d4edf257-e581-45f9-b9b9-35755b598952  非个人事假:baf811bc-3daa-4988-9604-d68ec1edaf50  病假:a7ffa2e6-872a-498d-aca7-4554c56fbb52
    	DurationUnit    string `json:"duration_unit"`
    	UserID          string `json:"userid"`
    }
    
    // DingLeaveResult 请假列表
    type DingLeaveResult struct {
    	LeaveStatus *[]DingLeaveStatus `json:"leave_status"`
    	HasMore     bool               `json:"has_more"` // 是否有更多数据
    }
    
    // DingResponse 钉钉响应
    type DingResponse struct {
    	ErrCode   int             `json:"errcode"`
    	Result    DingLeaveResult `json:"result"`
    	Success   bool            `json:"success"`
    	ErrMsg    string          `json:"errmsg"`
    	RequestID string          `json:"request_id"`
    }
    
    type DingUser struct {
    	Id   string `json:"id"`
    	Name string `json:"name"`
    	Type map[string]int
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    功能逻辑

    我这里只是想简单的实现一下功能,并没有按照严格标准的mvc分层,还请见谅

    package controller
    
    import (
    	"bytes"
    	"encoding/json"
    	"fmt"
    	"github.com/gin-gonic/gin"
    	"leave/model"
    	"net/http"
    	"time"
    )
    
    var tmp = map[string]string{"d4edf257-e581-45f9-b9b9-35755b598952": "个人事假", "a7ffa2e6-872a-498d-aca7-4554c56fbb52": "病假", "baf811bc-3daa-4988-9604-d68ec1edaf50": "非个人事假"} // code与请假类型对应
    
    // GetDepartmentLeaveStatus 统计部门请假状态
    func GetDepartmentLeaveStatus(c *gin.Context) {
    	userList := "323832232226246897,01320463195324064909,02280849645326263552,01546916272226288917"	// 模拟数据
    	leave := model.RequestDingLeave{
    		UseridList: userList,
    		StartTime:  1698624000000,	
    		EndTime:    int(time.Now().UnixMilli()), // 拿到当前的时间戳
    		Offset:     0,
    		Size:       2,
    	}
    	res := []model.DingLeaveStatus{}
    	res, err := GetLeaveStatus(leave, res)
    	if err != nil {
    		return
    	}
    	statistics := map[string]model.DingUser{}
    	for _, v := range res {
    		_, exist := statistics[v.UserID]
    		if !exist {
    			statistics[v.UserID] = model.DingUser{Type: map[string]int{}}
    		}
    		statistics[v.UserID].Type[tmp[v.LeaveCode]]++
    	}
    
    	c.JSON(http.StatusOK, statistics)
    	fmt.Println(int(time.Now().Weekday()))
    	return
    }
    
    // GetLeaveStatus 获取请假状态
    func GetLeaveStatus(leave model.RequestDingLeave, res []model.DingLeaveStatus) ([]model.DingLeaveStatus, error) {
    	// 将json数据编码为字节数组
    	var send func(leave model.RequestDingLeave) error
    
    	// 切片作为函数参数传递时为值传递,如果每次传入新的切片需要增加返回值接收,这里直接使用的传入的res作为变量并返回
    	send = func(leave model.RequestDingLeave) error {
    		jsonLeave, err := json.Marshal(leave)
    		if err != nil {
    			fmt.Println("json.Marshal(leave) failed:", err)
    			return err
    		}
    		url := fmt.Sprintf("https://oapi.dingtalk.com/topapi/attendance/getleavestatus?%s", "access_token=企业token") // access_token 填企业token
    		buffer := bytes.NewBuffer(jsonLeave)
    		response, err := http.Post(url, "application/json", buffer)
    		if err != nil {
    			fmt.Println("http.Post(\"https://oapi.dingtalk.com/topapi/attendance/getleavestatus\", \"application/json\", buffer) failed:", err)
    			return err
    		}
    		var dingResp model.DingResponse
    		err = json.NewDecoder(response.Body).Decode(&dingResp)	// 将响应的json绑定到dingResp中
    		if err != nil {
    			return err
    		}
    		res = append(res, *dingResp.Result.LeaveStatus...)
    		if dingResp.Result.HasMore {	// 如果有更多的记录,再次请求并添加到切片后面
    			leave.Offset += leave.Size
    			send(leave)					// 递归
    		}
    		return nil
    	}
    	err := send(leave)
    	return res, err
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    其他
    package router
    
    import (
    	"github.com/gin-gonic/gin"
    	"leave/controller"
    )
    
    func SetupRouter() *gin.Engine {
    	r := gin.Default()
    	r.GET("/test", controller.GetDepartmentLeaveStatus)
    	return r
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    package main
    
    import "leave/router"
    
    func main() {
    	router := router.SetupRouter()
    	router.Run()
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
  • 相关阅读:
    TTKEFU在线客服系统:实时交流,更好地理解客户需求
    ROS2与turtlebot4仿真入门教程-测试雷达和相机
    HC小区管理系统组织架构说明
    Vue生命周期
    MySQL--创建,删除,查找,案例
    配置 Pod 以使用 PersistentVolume 作为存储
    项目部署到Linux
    【菜菜的sklearn课堂笔记】支持向量机-关于predict_proba、decision_function
    剑指 Offer 27. 二叉树的镜像
    springMvc整合mybatis-plus
  • 原文地址:https://blog.csdn.net/Wksycxy/article/details/134355382