enterprise/common/qyweixin/qyweixin.go

164 lines
4.6 KiB
Go

package qyweixin
import (
"encoding/json"
butil "enterprise/base/util"
"errors"
"fmt"
log "github.com/sirupsen/logrus"
"github.com/smbrave/goutil"
"github.com/spf13/cast"
"gorm.io/gorm/utils"
"math"
"strings"
"time"
)
var (
urlGetToken = "https://qyapi.weixin.qq.com/cgi-bin/gettoken"
urlGetCheckinRlue = "https://qyapi.weixin.qq.com/cgi-bin/checkin/getcorpcheckinoption"
urlGetCheckinData = "https://qyapi.weixin.qq.com/cgi-bin/checkin/getcheckindata"
)
type QyWeixin struct {
corpId string
secret string
token string
tokenExpire int64
}
func NewQyWeixin(corpId, secret string) *QyWeixin {
return &QyWeixin{
corpId: corpId,
secret: secret,
tokenExpire: 0,
}
}
func (q *QyWeixin) refreshToken() error {
if time.Now().Unix() <= q.tokenExpire-600 {
return nil
}
reqUrl := fmt.Sprintf("%s?corpid=%s&corpsecret=%s", urlGetToken, q.corpId, q.secret)
rspBody, err := butil.HttpGet(reqUrl, nil)
if err != nil {
log.Errorf("http url[%s] error :%s", reqUrl, err.Error())
return 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 err
}
if cast.ToInt(result["errcode"]) != 0 {
log.Errorf("http url[%s] result[%s] error ", reqUrl, string(rspBody))
return errors.New(string(rspBody))
}
q.token = cast.ToString(result["access_token"])
q.tokenExpire = time.Now().Unix() + cast.ToInt64(result["expires_in"])
return nil
}
func (q *QyWeixin) GetCheckinEmployee(groupIds []string) ([]string, error) {
if err := q.refreshToken(); err != nil {
return nil, err
}
reqUrl := fmt.Sprintf("%s?access_token=%s", urlGetCheckinRlue, q.token)
rspBody, err := butil.HttpPostJson(reqUrl, nil, []byte("{}"))
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))
}
resultUser := make([]string, 0)
groups := cast.ToSlice(result["group"])
for _, group := range groups {
g := cast.ToStringMap(group)
if !utils.Contains(groupIds, cast.ToString(g["groupid"])) {
continue
}
ranges := cast.ToStringMap(g["range"])
userid := cast.ToStringSlice(ranges["userid"])
resultUser = append(resultUser, userid...)
}
return resultUser, nil
}
func (q *QyWeixin) GetCheckinData(day, userId string) (*UserCheckIn, error) {
if err := q.refreshToken(); err != nil {
return nil, err
}
dayTime, _ := time.ParseInLocation("2006-01-02", day, time.Local)
reqData := make(map[string]interface{})
reqData["opencheckindatatype"] = 1
reqData["starttime"] = dayTime.Unix()
reqData["endtime"] = dayTime.Unix() + 86400
reqData["useridlist"] = []string{userId}
reqUrl := fmt.Sprintf("%s?access_token=%s", urlGetCheckinData, q.token)
rspBody, err := butil.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))
}
checkindatas := cast.ToSlice(result["checkindata"])
userData := new(UserCheckIn)
userData.UserId = userId
exception := make([]string, 0)
isException := false
startTime := int64(math.MaxInt64)
endTime := int64(0)
for _, checkdata := range checkindatas {
c := cast.ToStringMap(checkdata)
checkinType := cast.ToString(c["checkin_type"])
exceptionType := cast.ToString(c["exception_type"])
checkinTime := cast.ToInt64(c["checkin_time"])
if exceptionType != "" {
isException = true
}
exception = append(exception, exceptionType)
if checkinType == "上班打卡" {
if checkinTime < startTime {
startTime = checkinTime
}
} else if checkinType == "下班打卡" {
if checkinTime > endTime {
endTime = checkinTime
}
}
}
if startTime != int64(math.MaxInt64) {
userData.StartTime = startTime
}
userData.EndTime = endTime
userData.Rawdata = goutil.EncodeJSON(checkindatas)
if isException {
userData.Exception = strings.Join(exception, ",")
}
if userData.EndTime == 0 && userData.StartTime == 0 {
return nil, nil
}
return userData, nil
}