164 lines
4.6 KiB
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
|
|
}
|