2024-01-22 22:34:59 +08:00
|
|
|
package qyweixin
|
|
|
|
|
|
|
|
import (
|
|
|
|
"encoding/json"
|
|
|
|
"errors"
|
|
|
|
"fmt"
|
|
|
|
log "github.com/sirupsen/logrus"
|
|
|
|
"github.com/smbrave/goutil"
|
|
|
|
"github.com/spf13/cast"
|
|
|
|
"gitlab.batiao8.com/open/gosdk/util"
|
|
|
|
"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
|
|
|
|
}
|
|
|
|
|
2024-01-22 22:47:35 +08:00
|
|
|
func NewAppCheckin(cfg *AppConfig) *AppCheckin {
|
2024-01-22 22:34:59 +08:00
|
|
|
return &AppCheckin{
|
2024-01-22 22:47:35 +08:00
|
|
|
App: *NewApp(cfg),
|
2024-01-22 22:34:59 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
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
|
|
|
|
}
|