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 } func NewAppCheckin(corpId, secret, agent string) *AppCheckin { return &AppCheckin{ App: *NewApp(corpId, secret, agent), } } 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 }