当前位置: 首页 > news >正文

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

前言

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

效果展示

在这里插入图片描述

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

功能实现

钉钉服务端调试工具API Explorer

在这里插入图片描述

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

定义model

请求参数

package modeltype 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。
}

响应参数

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-4554c56fbb52DurationUnit    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
}
功能逻辑

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

package controllerimport ("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 填企业tokenbuffer := 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.DingResponseerr = 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.Sizesend(leave)					// 递归}return nil}err := send(leave)return res, err
}
其他
package routerimport ("github.com/gin-gonic/gin""leave/controller"
)func SetupRouter() *gin.Engine {r := gin.Default()r.GET("/test", controller.GetDepartmentLeaveStatus)return r
}
package mainimport "leave/router"func main() {router := router.SetupRouter()router.Run()
}

相关文章:

  • Wpf 使用 Prism 实战开发Day05
  • PyCharm 【unsupported Python 3.1】
  • Vue3与Vue2:前端进化论,从性能到体验的全面革新
  • c语言-数据结构-栈和队列的实现和解析
  • 微信如何设置自动保存图片和视频
  • demo(二)eurekaribbon----服务注册、提供与消费
  • C语言初学3:变量和常量
  • 【数据结构】希尔排序(最小增量排序)
  • java 旋转方阵
  • 【C++面向对象】13. 接口 / 抽象类*
  • C#几种截取字符串的方法
  • cmmlu数据处理
  • 《持续交付:发布可靠软件的系统方法》 - 目录
  • Windows内的Ubuntu虚拟机安装docker
  • Django路由层之有名分组和无名分组、反向解析、路由分发、伪静态的概念、名称空间、虚拟环境、Django1和Django2的区别
  • 时间复杂度分析经典问题——最大子序列和
  • 【刷算法】求1+2+3+...+n
  • Angular Elements 及其运作原理
  • CAP理论的例子讲解
  • CSS实用技巧干货
  • ECMAScript 6 学习之路 ( 四 ) String 字符串扩展
  • JavaScript创建对象的四种方式
  • Laravel Telescope:优雅的应用调试工具
  • Nacos系列:Nacos的Java SDK使用
  • SpriteKit 技巧之添加背景图片
  • 创建一个Struts2项目maven 方式
  • 翻译--Thinking in React
  • 基于HAProxy的高性能缓存服务器nuster
  • 软件开发学习的5大技巧,你知道吗?
  • 最近的计划
  • [Shell 脚本] 备份网站文件至OSS服务(纯shell脚本无sdk) ...
  • ​软考-高级-系统架构设计师教程(清华第2版)【第1章-绪论-思维导图】​
  • #基础#使用Jupyter进行Notebook的转换 .ipynb文件导出为.md文件
  • (4)logging(日志模块)
  • (js)循环条件满足时终止循环
  • (LeetCode 49)Anagrams
  • (webRTC、RecordRTC):navigator.mediaDevices undefined
  • (力扣记录)235. 二叉搜索树的最近公共祖先
  • (四)docker:为mysql和java jar运行环境创建同一网络,容器互联
  • (一)基于IDEA的JAVA基础1
  • (转)jdk与jre的区别
  • (转)VC++中ondraw在什么时候调用的
  • (最优化理论与方法)第二章最优化所需基础知识-第三节:重要凸集举例
  • **Java有哪些悲观锁的实现_乐观锁、悲观锁、Redis分布式锁和Zookeeper分布式锁的实现以及流程原理...
  • .NET Core WebAPI中封装Swagger配置
  • .NET Core WebAPI中使用Log4net 日志级别分类并记录到数据库
  • .net framwork4.6操作MySQL报错Character set ‘utf8mb3‘ is not supported 解决方法
  • .net 按比例显示图片的缩略图
  • .Net 高效开发之不可错过的实用工具
  • .NET/C# 在代码中测量代码执行耗时的建议(比较系统性能计数器和系统时间)...
  • .w文件怎么转成html文件,使用pandoc进行Word与Markdown文件转化
  • @angular/cli项目构建--Dynamic.Form
  • @CacheInvalidate(name = “xxx“, key = “#results.![a+b]“,multi = true)是什么意思
  • @TableLogic注解说明,以及对增删改查的影响
  • []FET-430SIM508 研究日志 11.3.31