package weixin 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" urlConvertOpenid = "https://qyapi.weixin.qq.com/cgi-bin/user/convert_to_openid" ) 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) exceptionType := cast.ToString(c["exception_type"]) checkinTime := cast.ToInt64(c["checkin_time"]) if exceptionType != "" { isException = true } exception = append(exception, exceptionType) if checkinTime < startTime { startTime = checkinTime } 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 } func (q *QyWeixin) GetOpenid(userid string) (string, error) { if err := q.refreshToken(); err != nil { return "", err } reqUrl := fmt.Sprintf("%s?access_token=%s", urlConvertOpenid, q.token) rspBody, err := butil.HttpPostJson(reqUrl, nil, []byte(fmt.Sprintf(`{"userid" : "%s"}`, userid))) if err != nil { log.Errorf("httpPost 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)) } return cast.ToString(result["openid"]), nil }