gosdk/qyweixin/app_checkin.go

151 lines
4.7 KiB
Go

package qyweixin
import (
"encoding/json"
"errors"
"fmt"
"git.u8t.cn/open/gosdk/util"
log "github.com/sirupsen/logrus"
"github.com/smbrave/goutil"
"github.com/spf13/cast"
"gorm.io/gorm/utils"
"time"
)
type UserCheckIn struct {
Day string
Month string
UserId string
Exception string
Rawdata string
StartTime int64
EndTime int64
}
func (u *UserCheckIn) String() string {
return fmt.Sprintf("[%s][%s][%s~%s][%s]", u.UserId, u.Day,
goutil.TimeToDateTime(u.StartTime), goutil.TimeToDateTime(u.EndTime), u.Exception)
}
type AppCheckin struct {
App
}
func NewAppCheckin(cfg *AppConfig) *AppCheckin {
return &AppCheckin{
App: *NewApp(cfg),
}
}
func (q *AppCheckin) GetCheckinEmployee(groupIds []string) ([]string, error) {
reqUrl := fmt.Sprintf("https://qyapi.weixin.qq.com/cgi-bin/checkin/getcorpcheckinoption?access_token=%s", q.GetToken())
rspBody, err := util.HttpPostJson(reqUrl, nil, []byte("{}"))
if err != nil {
return nil, err
}
result, err := q.GetResult(rspBody)
if err != nil {
log.Errorf("q.GetResult error :%s ", err.Error())
return nil, errors.New(string(rspBody))
}
resultUser := make([]string, 0)
groups := cast.ToSlice(result["group"])
for _, group := range groups {
g := cast.ToStringMap(group)
if len(groupIds) != 0 && !utils.Contains(groupIds, cast.ToString(g["groupid"])) {
continue
}
ranges := cast.ToStringMap(g["range"])
userid := cast.ToStringSlice(ranges["userid"])
//包含部门获取部门下的员工
departmentIds := cast.ToIntSlice(ranges["party_id"])
if len(departmentIds) != 0 {
for _, did := range departmentIds {
uids, err := q.GetDepartmentUserid(did)
if err != nil {
log.Errorf(" q.GetDepartmentUserid did[%d] error :%s", did, err.Error())
continue
}
resultUser = append(resultUser, uids...)
}
}
resultUser = append(resultUser, userid...)
}
return resultUser, nil
}
func (q *AppCheckin) GetCheckinData(startDay, endDay string, userIds []string) ([]*UserCheckIn, error) {
dayTime, _ := time.ParseInLocation("2006-01-02", startDay, time.Local)
endTime, _ := time.ParseInLocation("2006-01-02", endDay, time.Local)
reqData := make(map[string]interface{})
reqData["opencheckindatatype"] = 1
reqData["starttime"] = dayTime.Unix()
reqData["endtime"] = endTime.Unix() + 86400
reqData["useridlist"] = userIds
reqUrl := fmt.Sprintf("https://qyapi.weixin.qq.com/cgi-bin/checkin/getcheckindata?access_token=%s", q.GetToken())
rspBody, err := util.HttpPostJson(reqUrl, nil, []byte(goutil.EncodeJSON(reqData)))
if err != nil {
return nil, err
}
result := make(map[string]interface{})
if err := json.Unmarshal(rspBody, &result); err != nil {
log.Errorf("http url[%s] result[%s] error :%s", reqUrl, string(rspBody), err.Error())
return nil, err
}
if cast.ToInt(result["errcode"]) != 0 {
log.Errorf("http url[%s] result[%s] error ", reqUrl, string(rspBody))
return nil, errors.New(string(rspBody))
}
datas := cast.ToSlice(result["checkindata"])
checkData := make(map[string]*UserCheckIn)
for _, dat := range datas {
c := cast.ToStringMap(dat)
exceptionType := cast.ToString(c["exception_type"])
checkinType := cast.ToString(c["checkin_type"])
userid := cast.ToString(c["userid"])
checkinTime := cast.ToInt64(c["checkin_time"])
schCheckinTime := cast.ToInt64(c["sch_checkin_time"])
if schCheckinTime == 0 {
schCheckinTime = checkinTime
}
checkDay := time.Unix(schCheckinTime, 0).Format("2006-01-02")
checkMonth := time.Unix(schCheckinTime, 0).Format("200601")
key := fmt.Sprintf("%s_%s", userid, checkDay)
var userData *UserCheckIn = nil
var ok bool
if userData, ok = checkData[key]; !ok {
userData = new(UserCheckIn)
userData.UserId = userid
userData.Day = checkDay
userData.Month = checkMonth
checkData[key] = userData
}
if exceptionType != "" {
userData.Exception += goutil.If(userData.Exception != "", ",", "")
userData.Exception += checkinType + ":" + exceptionType
}
userData.Rawdata = goutil.If(userData.Rawdata == "", "", "\n") + goutil.EncodeJSON(dat)
if checkinType == "上班打卡" {
userData.StartTime = goutil.If(userData.StartTime == 0 || checkinTime < userData.StartTime, checkinTime, userData.StartTime)
} else if checkinType == "下班打卡" {
userData.EndTime = goutil.If(checkinTime > userData.EndTime, checkinTime, userData.EndTime)
} else {
log.Errorf("不支持的打卡类型:%s %s", checkinType, goutil.EncodeJSON(dat))
}
}
userDatas := make([]*UserCheckIn, 0)
for _, v := range checkData {
if v.StartTime > v.EndTime {
log.Errorf("user[%s][%s] checkin time error[%s~%s]", v.UserId, v.Day, goutil.TimeToDateTime(v.StartTime), goutil.TimeToDateTime(v.EndTime))
}
userDatas = append(userDatas, v)
}
return userDatas, nil
}