package wechat import ( "encoding/json" "errors" "eta/eta_report/models" "eta/eta_report/services/alarm_msg" "eta/eta_report/utils" "fmt" "io/ioutil" "net/http" "strings" "time" ) type WxTokenResp struct { Ret int Msg string ErrMsg string ErrCode string Data WxTokenData Success bool `description:"true 执行成功,false 执行失败"` IsSendEmail bool `json:"-"` } type WxTokenReq struct { WxAppId string `description:"公众号appId"` WxAppSecret string `description:"公众号appSecret"` } type WxTokenData struct { AccessToken string `description:"微信token"` } // GetAccessToken 获取微信token func GetAccessToken(tokenReq WxTokenReq) (accessToken string, err error, errMsg string) { if utils.EtaPubUrl == `` { // 找不到推送服务 return } url := fmt.Sprintf("%s%s", utils.EtaPubUrl, "v1/wechat/access_token") defer func() { if err != nil { go alarm_msg.SendAlarmMsg(errMsg, 1) } }() postData, err := json.Marshal(tokenReq) if err != nil { errMsg = "SendTemplateMsg json.Marshal Err:" + err.Error() return } body := ioutil.NopCloser(strings.NewReader(string(postData))) client := &http.Client{} req, err := http.NewRequest("POST", url, body) if err != nil { errMsg = "SendTemplateMsg http.NewRequest Err:" + err.Error() return } contentType := "application/json;charset=utf-8" req.Header.Set("Content-Type", contentType) req.Header.Set("Authorization", utils.EtaPubAuthorization) resp, err := client.Do(req) if err != nil { errMsg = "http client.Do Err:" + err.Error() return } defer resp.Body.Close() b, err := ioutil.ReadAll(resp.Body) if err != nil { errMsg = "ioutil.ReadAll Err:" + err.Error() return } result := new(WxTokenResp) err = json.Unmarshal(b, &result) if err != nil { errMsg = "json.Unmarshal Err:" + err.Error() return } if result.Ret != 200 { err = errors.New(string(b)) errMsg = "请求失败:" + err.Error() return } accessToken = result.Data.AccessToken if accessToken == "" { err = errors.New("请求accessToken失败") errMsg = "请求accessToken失败" return } return } // GetWxAccessToken 获取微信token func GetWxAccessToken(wxAppId, wxAppSecret string) (accessToken string, err error, errMsg string) { accessToken, err, errMsg = getWxAccessToken(wxAppId, wxAppSecret) if err != nil { utils.FileLog.Info(fmt.Sprintf("获取Token失败,err:%s,errMsg:%s", err.Error(), errMsg)) return } return } // getWxAccessToken 获取微信token func getWxAccessToken(wxAppId, wxAppSecret string) (accessToken string, err error, errMsg string) { redisKey := getRedisKeyByAppid(wxAppId) if redisKey == `` { errMsg = "未配置缓存key" err = errors.New(errMsg) return } accessToken, err = utils.Rc.RedisString(redisKey) //fmt.Println(err) //fmt.Println(accessToken) //if err != nil { // errMsg = "GetWxAccessToken Err:" + err.Error() // utils.FileLog.Info("获取Token失败,msg:" + errMsg) // return //} //取到数据后就直接返回了,没有后续了 if accessToken != "" { return } //缓存中没有取到数据,那么需要去强制刷新新的accessToken return refreshWxAccessToken(wxAppId, wxAppSecret) } // refreshWxAccessToken 强制刷新微信token func refreshWxAccessToken(wxAppId, wxAppSecret string) (accessToken string, err error, errMsg string) { fmt.Println("强制刷新" + wxAppId + "微信token") defer func() { if errMsg != `` { utils.FileLog.Info(fmt.Sprintf("强制刷新%s微信token异常:%s", wxAppId, errMsg)) } }() if wxAppId == "" || wxAppSecret == "" { errMsg = fmt.Sprintf("必要信息为空, wxAppId: %s, wxAppSecret: %s", wxAppId, wxAppSecret) err = errors.New(errMsg) return } redisKey := getRedisKeyByAppid(wxAppId) if redisKey == `` { errMsg = "未配置缓存key" err = errors.New(errMsg) return } //调用微信官方接口获取新的accessToken wxAccessToken, tmpErr := models.GetWxToken(wxAppId, wxAppSecret) if tmpErr != nil { err = tmpErr errMsg = "通过微信接口获取accessToken失败 Err:" + err.Error() return } //如果没有token数据 if wxAccessToken.AccessToken == "" { errMsg = "微信返回的accessToken异常: Err:" + wxAccessToken.Errmsg err = errors.New(errMsg) return } accessToken = wxAccessToken.AccessToken ////如果是弘则研究的appid,那么需要更新mysql的accessToken //if wxAppId == utils.WxAppId { // expiresIn := time.Now().Add(time.Duration(wxAccessToken.ExpiresIn) * time.Second).Unix() // err = models.ModifyAccessToken(wxAccessToken.AccessToken, expiresIn) // if err != nil { // errMsg = "更新mysql中的accessToken失败 Err:" + err.Error() // return // } //} //更新redis的accessToken(过期时间提前十分钟) redisTimeExpire := time.Duration(wxAccessToken.ExpiresIn-600) * time.Second err = utils.Rc.Put(redisKey, accessToken, redisTimeExpire) if err != nil { errMsg = "更新redis中的accessToken失败 Err:" + err.Error() return } return } // 根据微信appid获取对应的缓存key func getRedisKeyByAppid(wxAppId string) (redisKey string) { redisKey = utils.ETA_WX_ACCESS_TOEKN + wxAppId //switch wxAppId { //case utils.WxAppId: // redisKey = utils.CACHE_WX_ACCESS_TOKEN_HZ //case utils.AdminWxAppId: // redisKey = utils.HZ_ADMIN_WX_ACCESS_TOEKN + wxAppId //default: // redisKey = utils.HZ_ADMIN_WX_ACCESS_TOEKN + wxAppId //} return redisKey }