package services import ( "context" "encoding/json" "fmt" "go-policy-service/models" "go-policy-service/structs" "go-policy-service/utils" "log" "time" "github.com/go-redis/redis/v8" ) type TokenManager struct { rdb *redis.Client hgConfig *models.HgConfig httpClient utils.HTTPClient // 自己请求 token apiUrl string // 自己请求 token 的接口 } // 修复构造函数参数声明 func NewTokenManager( rdb *redis.Client, hgConfig *models.HgConfig, httpClient utils.HTTPClient, // 明确参数类型 apiUrl string, // 添加类型声明 ) *TokenManager { return &TokenManager{ rdb: rdb, hgConfig: hgConfig, httpClient: httpClient, apiUrl: apiUrl, } } func (t *TokenManager) GetAccessToken() (string, error) { tokenKey := fmt.Sprintf("60s-hgapi-%s", t.hgConfig.Account) ctx := context.Background() // 重试机制 const maxRetries = 10 for i := 0; i < maxRetries; i++ { token, err := t.rdb.Get(ctx, tokenKey).Result() if err == nil { return token, nil } log.Printf("获取hgApi token失败,剩余重试次数: %d, 错误: %v", maxRetries-i-1, err) if i < maxRetries-1 { time.Sleep(5 * time.Second) } } log.Println("hgApi token获取彻底失败,请检查接口状态") return "", fmt.Errorf("failed to get token after %d attempts", maxRetries) } func (t *TokenManager) RefreshAccessToken() error { tokenKey := fmt.Sprintf("60s-hgapi-%s", t.hgConfig.Account) ctx := context.Background() // 尝试从 Redis 获取现有 token _, err := t.rdb.Get(ctx, tokenKey).Result() if err == nil { return nil } // 重试机制 const maxRetries = 3 for i := 0; i < maxRetries; i++ { token, err := t.requestToken() if err == nil { // 成功获取 token 后存入 Redis if setErr := t.rdb.SetEX(ctx, tokenKey, token, 3600*time.Second).Err(); setErr != nil { log.Printf("Failed to set token in Redis: %v", setErr) } return nil } log.Printf("获取hgApi token失败,剩余重试次数: %d, 错误: %v", maxRetries-i-1, err) if i < maxRetries-1 { time.Sleep(1 * time.Second) } } log.Println("hgApi token获取彻底失败,请检查接口状态") return fmt.Errorf("failed to get token after %d attempts", maxRetries) } func (t *TokenManager) requestToken() (string, error) { url := fmt.Sprintf("%s/gateway/oauth/token?grant_type=client_credentials&client_id=%s&client_secret=%s", t.apiUrl, t.hgConfig.Account, t.hgConfig.Password) respBytes, err := t.httpClient.PostJSON(context.Background(), url, nil) if err != nil { return "", fmt.Errorf("HTTP请求失败: %w", err) } var tokenResp structs.TokenResponse if err := json.Unmarshal(respBytes, &tokenResp); err != nil { return "", fmt.Errorf("JSON解析失败: %w", err) } if !tokenResp.Success || tokenResp.Data.AccessToken == "" { return "", fmt.Errorf("接口返回无效响应") } return tokenResp.Data.AccessToken, nil }