package tasks import ( "time" "git.rosy.net.cn/jx-callback/globals/globals2" "git.rosy.net.cn/baseapi/utils" "git.rosy.net.cn/jx-callback/globals" "git.rosy.net.cn/jx-callback/business/models" "github.com/astaxie/beego/orm" ) const ( weixinTokenExpires = 7200 * time.Second elmTokenExpires = 20 * 24 * 3600 * time.Second maxRefreshGap = 5 * 60 * time.Second ) type ElmTokenForCompatible struct { Error string `json:"error"` ErrorDescription string `json:"error_description"` AccessToken string `json:"accessToken"` TokenType string `json:"tokenType"` Expires int `json:"expires"` RefreshToken string `json:"refreshToken"` Success bool `json:"success"` } func RefreshConfig(configKey string, expiresTime time.Duration, configGetter func() string, configSetter func(value string) bool) { go func() { sleepGap := expiresTime / 10 needRefreshGap := expiresTime * 8 / 10 if sleepGap > maxRefreshGap { sleepGap = maxRefreshGap } for { curConfig := &models.Config{ Thirdparty: configKey, } db := orm.NewOrm() // 0: don't refresh, 1 update, 2 insert handleType := 0 if err := db.Read(curConfig, "Thirdparty"); err != nil { if err != orm.ErrNoRows { globals.SugarLogger.Error("db error:%v", err) } else { curConfig.Token = configGetter() handleType = 2 } } else { latestTimeStr := utils.Time2Str(time.Now().Add(-needRefreshGap)) if curConfig.Date <= latestTimeStr { curConfig.Token = configGetter() handleType = 1 } else { configSetter(curConfig.Token) } } if handleType != 0 { globals.SugarLogger.Debugf("refresh %s, value:%s", configKey, curConfig.Token) curConfig.Date = utils.GetCurTimeStr() var num int64 var err error if handleType == 1 { num, err = db.Update(curConfig, "Token", "Date") } else { num, err = db.Insert(curConfig) } if err != nil || num == 0 { globals.SugarLogger.Errorf("db error:%v, num:%d", err, num) } else { if configKey == "wechat" { globals2.FreshFoodAPI.AccessFreshFood("weixin/accesstoken/update", nil) } else if configKey == "eleme" { globals2.FreshFoodAPI.AccessFreshFood("eleme/token/update", nil) } } } time.Sleep(sleepGap) } }() } func RefreshWeixinToken() { RefreshConfig("wechat", weixinTokenExpires, func() string { if tokenInfo, err := globals2.WeixinAPI.RefreshToken(); err == nil { return tokenInfo.AccessToken } return "" }, func(value string) bool { return globals2.WeixinAPI.SetToken(value) }) } func RefreshElmToken() { RefreshConfig("eleme", elmTokenExpires, func() string { if tokenInfo, err := globals2.ElmAPI.RefreshTokenIndividual(); err == nil { tokenInfo2 := &ElmTokenForCompatible{ Error: "", ErrorDescription: "", AccessToken: tokenInfo.AccessToken, TokenType: tokenInfo.TokenType, Expires: tokenInfo.ExpiresIn, RefreshToken: "", Success: true, } return string(utils.MustMarshal(tokenInfo2)) } return "" }, func(value string) bool { var tokenInfo ElmTokenForCompatible err := utils.UnmarshalUseNumber([]byte(value), &tokenInfo) if err == nil { return globals2.ElmAPI.SetToken(tokenInfo.AccessToken) } return false }) }