From 81ce871b6d67d9010aecd2c156d1e2c355360200 Mon Sep 17 00:00:00 2001 From: denghui <1016848185@qq.com> Date: Mon, 23 Jun 2025 16:07:45 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E6=B8=B8=E6=88=8F=E4=BA=BA?= =?UTF-8?q?=E7=94=9F=E6=8E=A5=E5=8F=A3=E3=80=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- internal/model/user.go | 7 +- utility/gamelife/gamelife.go | 137 +++++++++++++++++++---------------- utility/wechat/wechat.go | 9 ++- 3 files changed, 85 insertions(+), 68 deletions(-) diff --git a/internal/model/user.go b/internal/model/user.go index 1bc02ae..f37a7c3 100644 --- a/internal/model/user.go +++ b/internal/model/user.go @@ -139,10 +139,9 @@ type GetPhoneCodeOut struct { } type UserGamelifeCache struct { - Aes string `json:"aes"` - IV string `json:"iv"` - Token string `json:"token"` - Params string `json:"params"` + Aes string `json:"aes"` + IV string `json:"iv"` + Token string `json:"token"` } type UserBoundResult struct { diff --git a/utility/gamelife/gamelife.go b/utility/gamelife/gamelife.go index 6232eb3..3358aaa 100644 --- a/utility/gamelife/gamelife.go +++ b/utility/gamelife/gamelife.go @@ -178,15 +178,23 @@ func (s *gamelifeClient) GetUrl(ctx context.Context, popenID, appName, nickname if !isBound { rootURL = s.unBoundURLMap[s.config.Mode] } - cache, err := s.ensureUserCacheWithParams(ctx, popenID, appName, nickname, bindType, isBound) + cache, err := s.ensureUserCache(ctx, popenID) if err != nil { return "", err } - - return fmt.Sprintf("%s?%s", rootURL, cache.Params), nil + params, err := s.buildQueryParams(ctx, popenID, cache, appName, nickname, bindType, isBound) + if err != nil { + return "", err + } + return fmt.Sprintf("%s?%s", rootURL, params), nil } -func (s *gamelifeClient) ensureUserCache(ctx context.Context, popenID string) (*model.UserGamelifeCache, error) { - cacheKey := fmt.Sprintf(consts.GameLifeUserKey, popenID) + +// 通用缓存获取函数,只负责获取/刷新 aes、iv、token +func (s *gamelifeClient) ensureUserCacheGeneral( + ctx context.Context, + popenId string, +) (*model.UserGamelifeCache, error) { + cacheKey := fmt.Sprintf(consts.GameLifeUserKey, popenId) cacheData, err := g.Redis().Get(ctx, cacheKey) if err != nil { return nil, ecode.Fail.Sub("从缓存中获取用户信息失败") @@ -194,7 +202,7 @@ func (s *gamelifeClient) ensureUserCache(ctx context.Context, popenID string) (* var cache *model.UserGamelifeCache if cacheData.IsEmpty() { - cache, err = s.GetUserKeyIV(ctx, popenID) + cache, err = s.GetUserKeyIV(ctx, popenId) if err != nil { return nil, err } @@ -206,6 +214,14 @@ func (s *gamelifeClient) ensureUserCache(ctx context.Context, popenID string) (* return cache, nil } +// 只获取基本缓存 +func (s *gamelifeClient) ensureUserCache(ctx context.Context, popenID string) (*model.UserGamelifeCache, error) { + if popenID == "" || popenID == "undefined" { + return nil, ecode.Params.Sub("popenID 不能为空或 undefined") + } + return s.ensureUserCacheGeneral(ctx, popenID) +} + // GetBound retrieves the binding status of a user from the GameLife system. // It uses buildQueryParams to construct the encrypted user data for the POST body. func (s *gamelifeClient) GetBound(ctx context.Context, popenID string) (*model.UserBoundResult, error) { @@ -213,13 +229,10 @@ func (s *gamelifeClient) GetBound(ctx context.Context, popenID string) (*model.U if err != nil { return nil, err } - - // Use default values for appName, nickname, bindType, and isBound - platUserStr, err := s.buildQueryParams(ctx, popenID, cache, s.config.PlatID, "", 1, true) + platUserStr, err := s.buildQueryParams(ctx, popenID, cache, "", "", 1, true) if err != nil { return nil, err } - // Parse platUserStr to extract Token and PlatUserInfoStr queryParams, err := url.ParseQuery(platUserStr) if err != nil { @@ -233,7 +246,6 @@ func (s *gamelifeClient) GetBound(ctx context.Context, popenID string) (*model.U if err := json.Unmarshal([]byte(extplatDataStr), &extplatData); err != nil { return nil, ecode.Fail.Sub("解析 extplat_data 失败") } - postBody := map[string]string{ "plat_id": s.config.PlatID, "plat_user_info": popenID, @@ -247,7 +259,6 @@ func (s *gamelifeClient) GetBound(ctx context.Context, popenID string) (*model.U if err != nil || resp.StatusCode() != 200 { return nil, ecode.Fail.Sub("向游戏人生获取绑定信息出现异常") } - glog.Info(ctx, "Fetched user binding info", map[string]interface{}{ "popen_id": popenID, "result": result, @@ -319,14 +330,21 @@ func (s *gamelifeClient) RequestActivity(ctx context.Context, in *model.QQNetbar if err != nil { return nil, ecode.Fail.Sub("获取游戏编码失败") } - cache, err := s.ensureUserCacheWithParams(ctx, in.PopenId, value.String(), in.NickName, in.BindType, true) + cache, err := s.ensureUserCache(ctx, in.PopenId) + if err != nil { + return nil, err + } + params, err := s.buildQueryParams(ctx, in.PopenId, cache, value.String(), in.NickName, in.BindType, true) + if err != nil { + return nil, err + } in.TaskParam.BrandId = s.config.BrandID var result model.GameTaskResponse resp, err := client.R(). SetContext(ctx). SetBody(in.TaskParam). SetResult(&result). - Post(fmt.Sprintf("%s%s?%s", taskURL, consts.GetTaskList, cache.Params)) + Post(fmt.Sprintf("%s%s?%s", taskURL, consts.GetTaskList, params)) if err != nil || resp.IsError() { return nil, ecode.Fail.Sub("请求出现异常") } @@ -336,13 +354,20 @@ func (s *gamelifeClient) RequestActivity(ctx context.Context, in *model.QQNetbar if err != nil { return nil, ecode.Fail.Sub("获取游戏编码失败") } - cache, err := s.ensureUserCacheWithParams(ctx, in.PopenId, value.String(), in.NickName, in.BindType, true) + cache, err := s.ensureUserCache(ctx, in.PopenId) + if err != nil { + return nil, err + } + params, err := s.buildQueryParams(ctx, in.PopenId, cache, value.String(), in.NickName, in.BindType, true) + if err != nil { + return nil, err + } var result model.UserRoleListResponse resp, err := client.R(). SetContext(ctx). SetBody(in.UserRoleParam). SetResult(&result). - Post(fmt.Sprintf("%s%s?%s", taskURL, consts.QueryUserRoleList, cache.Params)) + Post(fmt.Sprintf("%s%s?%s", taskURL, consts.QueryUserRoleList, params)) if err != nil || resp.IsError() { return nil, ecode.Fail.Sub("请求出现异常") } @@ -353,13 +378,20 @@ func (s *gamelifeClient) RequestActivity(ctx context.Context, in *model.QQNetbar if err != nil { return nil, ecode.Fail.Sub("获取游戏编码失败") } - cache, err := s.ensureUserCacheWithParams(ctx, in.PopenId, value.String(), in.NickName, in.BindType, true) + cache, err := s.ensureUserCache(ctx, in.PopenId) + if err != nil { + return nil, err + } + params, err := s.buildQueryParams(ctx, in.PopenId, cache, value.String(), in.NickName, in.BindType, true) + if err != nil { + return nil, err + } var result model.GiftResponse resp, err := client.R(). SetContext(ctx). SetBody(in.GiftParam). SetResult(&result). - Post(fmt.Sprintf("%s%s?%s", taskURL, consts.GetGift, cache.Params)) + Post(fmt.Sprintf("%s%s?%s", taskURL, consts.GetGift, params)) if err != nil || resp.IsError() { return nil, ecode.Fail.Sub("请求出现异常") } @@ -369,13 +401,20 @@ func (s *gamelifeClient) RequestActivity(ctx context.Context, in *model.QQNetbar if err != nil { return nil, ecode.Fail.Sub("获取游戏编码失败") } - cache, err := s.ensureUserCacheWithParams(ctx, in.PopenId, value.String(), in.NickName, in.BindType, true) + cache, err := s.ensureUserCache(ctx, in.PopenId) + if err != nil { + return nil, err + } + params, err := s.buildQueryParams(ctx, in.PopenId, cache, value.String(), in.NickName, in.BindType, true) + if err != nil { + return nil, err + } var result model.GoodsResponse resp, err := client.R(). SetContext(ctx). SetBody(in.GoodsParam). SetResult(&result). - Post(fmt.Sprintf("%s%s?%s", taskURL, consts.QueryUserGoodsList, cache.Params)) + Post(fmt.Sprintf("%s%s?%s", taskURL, consts.QueryUserGoodsList, params)) if err != nil || resp.IsError() { return nil, ecode.Fail.Sub("请求出现异常") } @@ -385,13 +424,20 @@ func (s *gamelifeClient) RequestActivity(ctx context.Context, in *model.QQNetbar if err != nil { return nil, ecode.Fail.Sub("获取游戏编码失败") } - cache, err := s.ensureUserCacheWithParams(ctx, in.PopenId, value.String(), in.NickName, in.BindType, true) + cache, err := s.ensureUserCache(ctx, in.PopenId) + if err != nil { + return nil, err + } + params, err := s.buildQueryParams(ctx, in.PopenId, cache, value.String(), in.NickName, in.BindType, true) + if err != nil { + return nil, err + } var result model.ExchangeGoodsResponse resp, err := client.R(). SetContext(ctx). SetBody(in.ExchangeGoodsParam). SetResult(&result). - Post(fmt.Sprintf("%s%s?%s", taskURL, consts.ExchangeGoods, cache.Params)) + Post(fmt.Sprintf("%s%s?%s", taskURL, consts.ExchangeGoods, params)) if err != nil || resp.IsError() { return nil, ecode.Fail.Sub("请求出现异常") } @@ -401,7 +447,11 @@ func (s *gamelifeClient) RequestActivity(ctx context.Context, in *model.QQNetbar if err != nil { return nil, ecode.Fail.Sub("获取游戏编码失败") } - cache, err := s.ensureUserCacheWithParams(ctx, in.PopenId, value.String(), in.NickName, in.BindType, true) + cache, err := s.ensureUserCache(ctx, in.PopenId) + if err != nil { + return nil, err + } + params, err := s.buildQueryParams(ctx, in.PopenId, cache, value.String(), in.NickName, in.BindType, true) if err != nil { return nil, err } @@ -410,7 +460,7 @@ func (s *gamelifeClient) RequestActivity(ctx context.Context, in *model.QQNetbar SetContext(ctx). SetBody(in.QueryUserGoodsDetailParam). SetResult(&result). - Post(fmt.Sprintf("%s%s?%s", taskURL, consts.QueryUserGoodsDetail, cache.Params)) + Post(fmt.Sprintf("%s%s?%s", taskURL, consts.QueryUserGoodsDetail, params)) if err != nil || resp.IsError() { return nil, ecode.Fail.Sub("请求出现异常") } @@ -419,42 +469,3 @@ func (s *gamelifeClient) RequestActivity(ctx context.Context, in *model.QQNetbar return nil, ecode.Fail.Sub(fmt.Sprintf("不支持的任务: %s", in.ServiceName)) } } - -// ensureUserCacheWithParams ensures user cache exists and contains a valid Params string. -// It handles cache retrieval, fallback refresh, Params generation, and cache update. -func (s *gamelifeClient) ensureUserCacheWithParams(ctx context.Context, popenId, appname, nickname string, bindType int, isBound bool) (*model.UserGamelifeCache, error) { - cacheKey := fmt.Sprintf(consts.GameLifeUserKey, popenId) - cacheData, err := g.Redis().Get(ctx, cacheKey) - if err != nil { - return nil, ecode.Fail.Sub("从缓存中获取用户信息失败") - } - - var cache *model.UserGamelifeCache - if cacheData.IsEmpty() { - cache, err = s.GetUserKeyIV(ctx, popenId) - if err != nil { - return nil, err - } - } else { - if err := json.Unmarshal(cacheData.Bytes(), &cache); err != nil { - return nil, ecode.Fail.Sub("解析用户信息失败") - } - } - - if cache.Params == "" { - cache.Params, err = s.buildQueryParams(ctx, popenId, cache, appname, nickname, bindType, isBound) - if err != nil { - return nil, err - } - - ttl, err := g.Redis().TTL(ctx, cacheKey) - if err != nil { - return nil, ecode.Fail.Sub("获取缓存过期时间失败") - } - if err := g.Redis().SetEX(ctx, cacheKey, cache, ttl); err != nil { - return nil, ecode.Fail.Sub("更新缓存失败") - } - } - - return cache, nil -} diff --git a/utility/wechat/wechat.go b/utility/wechat/wechat.go index 17cd834..256cfa3 100644 --- a/utility/wechat/wechat.go +++ b/utility/wechat/wechat.go @@ -178,6 +178,7 @@ func (c *weChatClient) GetTicket(sceneId string) (string, error) { }, } result := struct { + Errcode int `json:"errcode"` Ticket string `json:"ticket"` ExpireSeconds int `json:"expire_seconds"` Url string `json:"url"` @@ -197,7 +198,13 @@ func (c *weChatClient) GetTicket(sceneId string) (string, error) { glog.Errorf(ctx, "[GetTicket] 响应错误,状态: %s,内容: %s", resp.Status(), resp.String()) return "", ecode.Fail.Sub("获取微信 ticket 失败") } - + if result.Errcode == 40001 { + if err := c.getAccessToken(); err != nil { + glog.Errorf(ctx, "[GetTicket] 刷新 token 失败: %+v", err) + return "", ecode.Fail.Sub("刷新 access_token 失败") + } + return c.GetTicket(sceneId) + } glog.Infof(ctx, "[GetTicket] 成功获取 ticket: %s, 过期时间: %ds", result.Ticket, result.ExpireSeconds) return result.Ticket, nil }