实现游戏人生获取物品列表、兑换、领取奖品
This commit is contained in:
@ -10,7 +10,11 @@ const (
|
||||
)
|
||||
|
||||
const (
|
||||
GetNonLoginTaskList = "GetNonloginTaskList"
|
||||
GetTaskList = "GetTaskList"
|
||||
QueryUserRoleList = "QueryUserRoleList"
|
||||
GetNonLoginTaskList = "GetNonloginTaskList"
|
||||
GetTaskList = "GetTaskList"
|
||||
QueryUserRoleList = "QueryUserRoleList"
|
||||
GetGift = "GetGift"
|
||||
GetUserGoodsList = "GetUserGoodsList"
|
||||
ExchangeGoods = "ExchangeGoods"
|
||||
QueryUserGoodsDetail = "QueryUserGoodsDetail"
|
||||
)
|
||||
|
||||
@ -69,10 +69,160 @@ type UserRole struct {
|
||||
type UserRoleListResponse struct {
|
||||
RoleList []UserRole `json:"role_list"`
|
||||
}
|
||||
type QQNetbarActivityIn struct {
|
||||
ServiceName string // 服务名称
|
||||
TaskParam TaskParam // 参数体
|
||||
UserRoleParam UserRoleParam
|
||||
PopenId string
|
||||
BindType int
|
||||
type GiftParam struct {
|
||||
TaskId string `json:"task_id"` // 任务ID,必填
|
||||
AreaId int `json:"area_id,omitempty"` // 区域ID,
|
||||
Gid int `json:"gid"` // 游戏ID,必填
|
||||
RoleIdx string `json:"roleIdx,omitempty"` // 角色ID
|
||||
}
|
||||
|
||||
type GoodsParam struct {
|
||||
Gid int `json:"gid"` // 游戏ID,必填
|
||||
AppFilter string `json:"appfilter"` // 按照gid过滤游戏
|
||||
BigTime int64 `json:"big_time"` // 大时间:如果要控制时间范围,大的时间传这里,必填
|
||||
Pageidx string `json:"pageidx"` // 页码, 首页为空
|
||||
Num int `json:"num"` // 数量
|
||||
OrderType string `json:"order_type"` // winningtime:根据获取时间排序 overduetime:根据过期时间排序
|
||||
OrderByDesc bool `json:"orderby_desc"` // 降序
|
||||
GoodsStatus int `json:"goodsstatus"` // 查询的物品状态:0:查所有 2是已发放(成功和失败),4是未发放且未过期,6是未发放且已过期
|
||||
}
|
||||
|
||||
type GoodsResponse struct {
|
||||
Waters []water `json:"waters"` // 兑换流水
|
||||
PageIdx string `json:"pageidx"` // 下一页的页码
|
||||
Total int64 `json:"total"` // 总数
|
||||
}
|
||||
|
||||
type ExchangeGoodsParam struct {
|
||||
Water water // 兑换流水
|
||||
Gid int `json:"gid"` // 游戏ID,必填
|
||||
AreaId int `json:"area_id"` // 区服 id
|
||||
ReloIdx string `json:"reloidx"` //FIXME
|
||||
}
|
||||
type ExchangeGoodsResponse struct {
|
||||
Water water // 兑换流水
|
||||
}
|
||||
type QueryUserGoodsDetailParam struct {
|
||||
Gid int `json:"gid"`
|
||||
WinningTime int64 `json:"winningtime"` // 用户领取礼包时间
|
||||
OrderId string `json:"orderid"` // 户领取流水订单id
|
||||
IsActInfo int64 `json:"is_actinfo"` // 是否需要活动相关信息 0:默认需要 1:不需要
|
||||
IsDocument int64 `json:"is_document"` // 是否需要文案信息,使用限制信息、代金券图片、使用方式 0:默认需要 1:不需要
|
||||
IsDetail int64 `json:"is_detail"` // 是否需要物品详情 0:默认需要 1:不需要
|
||||
}
|
||||
type QueryUserGoodsDetailResponse struct {
|
||||
Water water // 兑换流水
|
||||
}
|
||||
type QQNetbarActivityIn struct {
|
||||
ServiceName string // 服务名称
|
||||
TaskParam TaskParam // 任务参数
|
||||
UserRoleParam UserRoleParam // 查询用户角色
|
||||
GiftParam GiftParam // 领取物品接口使用
|
||||
GoodsParam GoodsParam // 查询物品列表接口使用
|
||||
ExchangeGoodsParam ExchangeGoodsParam // 兑换物品接口使用
|
||||
QueryUserGoodsDetailParam QueryUserGoodsDetailParam // 查询用户物品详情接口使用
|
||||
PopenId string
|
||||
BindType int
|
||||
NickName string
|
||||
}
|
||||
|
||||
type GiftResponse struct {
|
||||
GiftItem giftItem `json:"rst_list"`
|
||||
}
|
||||
|
||||
type gameRoleInfo struct {
|
||||
// FIXME
|
||||
}
|
||||
|
||||
type userAddress struct {
|
||||
// FIXME
|
||||
}
|
||||
|
||||
type waterExtraInfo struct {
|
||||
// FIXME
|
||||
}
|
||||
|
||||
type goodsType struct {
|
||||
// FIXME
|
||||
}
|
||||
|
||||
type goodsDisplayType struct {
|
||||
// FIXME
|
||||
}
|
||||
|
||||
type merchantInfo struct {
|
||||
// FIXME
|
||||
}
|
||||
|
||||
type goodsExtraInfo struct {
|
||||
// FIXME
|
||||
}
|
||||
|
||||
type water struct {
|
||||
Uid string `json:"uid"` // 用户id
|
||||
UidType uint32 `json:"uidtype"` // 用户id的类型(0是openid,1是uin)
|
||||
WinningTime uint32 `json:"winningtime"` // 获奖时间
|
||||
GoodsId uint32 `json:"goodsid"` // 物品id
|
||||
GoodsCfg goodsCfg `json:"goodscfg"` // 物品配置置信息
|
||||
Gid uint32 `json:"gid"` // 活动id,领取的游戏渠道
|
||||
OverdueTime uint32 `json:"overduetime"` // 物品的过期时间
|
||||
Status uint32 `json:"status"` // 领取状态: 0未发放,1已发放,2是已发放且失败(失败),4是未发放且未过期,6物品已过期(未发放)
|
||||
RecvUid string `json:"recvuid"` // 领奖的用户 id (qq号)
|
||||
Role gameRoleInfo `json:"role"` // 游戏角色信息
|
||||
CdKey string `json:"cdkey"` // cdkey,实物的兑换码/游戏道具兑换码
|
||||
WaterType uint32 `json:"watertype"` // 抽奖流水类型, 0是抽奖,1是核销,2是 tgp
|
||||
SrcType uint32 `json:"srctype"` // 抽奖来源类型id
|
||||
SrcName string `json:"srcname"` // 抽奖来源类型名称
|
||||
ActId string `json:"actid"` // 活动id
|
||||
LotteryId uint32 `json:"lotteryid"` // 抽奖区id
|
||||
GiftId uint32 `json:"giftid"` // 礼包id
|
||||
ShopId uint32 `json:"shopid"` // 门店id
|
||||
Extra string `json:"extra"` // 线下O2O相关信息
|
||||
RecvTime uint32 `json:"recvtime"` // 领取时间
|
||||
Code string `json:"code"` // 核销码
|
||||
TransEq string `json:"traneq"` // 交易流水号
|
||||
Filter1 string `json:"filter1"` // 用于筛选流水记录的业务自定义条件1
|
||||
Filter2 string `json:"filter2"` // 用于筛选流水记录的业务自定义条件2
|
||||
UserAddrType uint32 `json:"useraddrtype"` // 用户地址类型 (1是默认地址, 2是用户确认后地址)——仅面向邮寄的物品使用
|
||||
UserAddr userAddress `json:"useraddr"` // 用户地址信息——仅面向类型的物品使用
|
||||
Cltip string `json:"cltip"` // 用户领奖ip
|
||||
Bsave uint32 `json:"bsave"` // 是否保存到物品表
|
||||
SaveType uint32 `json:"savetype"` // 0表示用户积分流水, 1表示用户物品表,2表示折扣券
|
||||
Sid uint32 `json:"sid"` // 用户流水id,和uid1共同确定一个物品
|
||||
NeedPoints uint32 `json:"needpoints"` // 物品消耗的钱
|
||||
ExtraInfo waterExtraInfo `json:"extrainfo"` // 其余信息
|
||||
AppFilter string `json:"appfilter"` // 业务拓展数据,王者人生为空
|
||||
OrderId string `json:"orderid"` // 订单id,唯一标记一条流水
|
||||
MercId string `json:"mercid"` // 商家 id
|
||||
TipOpenId string `json:"tipopenid"` // 游戏人生openid
|
||||
GoodsIdStr string `json:"goods_id_str"` // 字符串类型Goods id
|
||||
GiftIdStr string `json:"gift_id_str"` // 字符串类型Gift id
|
||||
LottIdStr string `json:"lott_id_str"` // 字符串类型Lott id
|
||||
}
|
||||
type goodsCfg struct {
|
||||
GoodsId uint32 `json:"goodsid"` // 物品id
|
||||
Gid uint32 `json:"gid"` // 游戏id
|
||||
GoodsType goodsType `json:"goodstype"` // 物品类型
|
||||
Maid string `json:"maid"` // ma单号
|
||||
Each uint32 `json:"each"` // 每次发奖的数量
|
||||
GoodsName string `json:"goodsname"` // 物品名称
|
||||
GoodsDetail string `json:"goodsdetail"` // 物品说明信息
|
||||
OverdueTime uint32 `json:"overduetime"` // 物品的过期时间
|
||||
Status uint32 `json:"status"` // 物品状态 0-下线 1-上线
|
||||
GoodsIcon string `json:"goodsicon"` // 物品图片地址
|
||||
Provider string `json:"provider"` // 物品提供方名称
|
||||
RecvWay string `json:"recvway"` // 领取方式
|
||||
RecvWayUrl string `json:"recvwayurl"` // 领取方式详情url
|
||||
MailUrl string `json:"mailurl"` // 邮寄地址url
|
||||
DisplayType goodsDisplayType `json:"displaytype"` // 物品展示类型(枚举或自定义类型)
|
||||
Merchant merchantInfo `json:"merchant"` // 商家信息(需另外定义)
|
||||
Extra goodsExtraInfo `json:"extra"` // 其它信息(需另外定义)
|
||||
GoodsIdStr string `json:"goods_id_str"` // 字符串类型的物品ID
|
||||
AppId string `json:"app_id"` // 所属业务ID
|
||||
ActId string `json:"act_id"` // 活动ID
|
||||
}
|
||||
|
||||
type giftItem struct {
|
||||
Result int `json:"result"` // 1-奖励发放成功,2-奖励兑换失败(礼包发放背包环节成功,需要重新引导领奖) 3-针对只需要发背包,然后引导用户到人生应用背包领奖的奖励类型,发奖成功了 4-water错误(一般是orderid),不做兑换操作
|
||||
Water water `json:"water"` // 礼包列表数据
|
||||
}
|
||||
|
||||
@ -166,7 +166,9 @@ type UserUnBoundUrlOut struct {
|
||||
}
|
||||
|
||||
type UserBoundInfoIn struct {
|
||||
PopenId string
|
||||
PopenId string
|
||||
BindType int
|
||||
AppName string
|
||||
}
|
||||
type UserBoundInfoOut struct {
|
||||
IsBound bool
|
||||
|
||||
@ -108,19 +108,19 @@ func newGamelifeClient(ctx context.Context) *gamelifeClient {
|
||||
}
|
||||
|
||||
// GetUserKeyIV retrieves or refreshes the AES key, IV, and token for a user, storing them in cache.
|
||||
func (s *gamelifeClient) GetUserKeyIV(ctx context.Context, popenID string) (model.UserGamelifeCache, error) {
|
||||
func (s *gamelifeClient) GetUserKeyIV(ctx context.Context, popenID string) (*model.UserGamelifeCache, error) {
|
||||
oriData := map[string]string{
|
||||
"PlatId": s.config.PlatID,
|
||||
"PopenId": popenID,
|
||||
}
|
||||
marshaled, err := json.Marshal(oriData)
|
||||
if err != nil {
|
||||
return model.UserGamelifeCache{}, ecode.Fail.Sub("序列化 json 数据出现异常")
|
||||
return nil, ecode.Fail.Sub("序列化 json 数据出现异常")
|
||||
}
|
||||
|
||||
encrypted, err := rsa.GetRsaClient().EncryptWithRsaPublicKey(marshaled)
|
||||
if err != nil {
|
||||
return model.UserGamelifeCache{}, ecode.Fail.Sub("序列化 json 数据出现异常")
|
||||
return nil, ecode.Fail.Sub("序列化 json 数据出现异常")
|
||||
}
|
||||
|
||||
type httpResult struct {
|
||||
@ -136,17 +136,17 @@ func (s *gamelifeClient) GetUserKeyIV(ctx context.Context, popenID string) (mode
|
||||
SetResult(&result).
|
||||
Post(s.keyIVURLMap[s.config.Mode])
|
||||
if err != nil || resp.StatusCode() != 200 {
|
||||
return model.UserGamelifeCache{}, ecode.Fail.Sub("获取用户信息失败")
|
||||
return nil, ecode.Fail.Sub("获取用户信息失败")
|
||||
}
|
||||
|
||||
decoded, err := encrypt.Base64Decode(result.Secret)
|
||||
if err != nil {
|
||||
return model.UserGamelifeCache{}, ecode.Fail.Sub("解密用户信息失败")
|
||||
return nil, ecode.Fail.Sub("解密用户信息失败")
|
||||
}
|
||||
|
||||
plain, err := rsa.GetRsaClient().DecryptWithRsaPrivateKey(decoded)
|
||||
if err != nil {
|
||||
return model.UserGamelifeCache{}, ecode.Fail.Sub("解密用户信息失败")
|
||||
return nil, ecode.Fail.Sub("解密用户信息失败")
|
||||
}
|
||||
|
||||
var aesResult struct {
|
||||
@ -154,17 +154,17 @@ func (s *gamelifeClient) GetUserKeyIV(ctx context.Context, popenID string) (mode
|
||||
IV string `json:"iv"`
|
||||
}
|
||||
if err := json.Unmarshal(plain, &aesResult); err != nil {
|
||||
return model.UserGamelifeCache{}, ecode.Fail.Sub("解密用户信息失败")
|
||||
return nil, ecode.Fail.Sub("解密用户信息失败")
|
||||
}
|
||||
|
||||
cache := model.UserGamelifeCache{
|
||||
cache := &model.UserGamelifeCache{
|
||||
Aes: aesResult.Key,
|
||||
IV: aesResult.IV,
|
||||
Token: result.Key,
|
||||
}
|
||||
cacheKey := fmt.Sprintf(consts.GameLifeUserKey, popenID)
|
||||
if err := g.Redis().SetEX(ctx, cacheKey, cache, int64(consts.GameLifeUserExpire+grand.Intn(1000))); err != nil {
|
||||
return model.UserGamelifeCache{}, ecode.Fail.Sub("设置用户信息失败")
|
||||
return nil, ecode.Fail.Sub("设置用户信息失败")
|
||||
}
|
||||
|
||||
return cache, nil
|
||||
@ -178,33 +178,38 @@ func (s *gamelifeClient) GetUrl(ctx context.Context, popenID, appName, nickname
|
||||
if !isBound {
|
||||
rootURL = s.unBoundURLMap[s.config.Mode]
|
||||
}
|
||||
|
||||
cache, err := s.getOrRefreshCache(ctx, popenID)
|
||||
cache, err := s.ensureUserCacheWithParams(ctx, popenID, appName, nickname, bindType)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
cache.Params, err = s.buildQueryParams(ctx, popenID, cache, appName, nickname, bindType, isBound)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
cacheKey := fmt.Sprintf(consts.GameLifeUserKey, popenID)
|
||||
ttl, err := g.Redis().TTL(ctx, cacheKey)
|
||||
if err != nil {
|
||||
return "", ecode.Fail.Sub("获取缓存过期时间失败")
|
||||
}
|
||||
if err := g.Redis().SetEX(ctx, cacheKey, cache, ttl); err != nil {
|
||||
return "", ecode.Fail.Sub("更新缓存失败")
|
||||
}
|
||||
|
||||
return fmt.Sprintf("%s?%s", rootURL, cache.Params), nil
|
||||
}
|
||||
func (s *gamelifeClient) ensureUserCache(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("从缓存中获取用户信息失败")
|
||||
}
|
||||
|
||||
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("解析用户信息失败")
|
||||
}
|
||||
}
|
||||
return cache, nil
|
||||
}
|
||||
|
||||
// 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) {
|
||||
cache, err := s.getOrRefreshCache(ctx, popenID)
|
||||
cache, err := s.ensureUserCache(ctx, popenID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -252,7 +257,7 @@ func (s *gamelifeClient) GetBound(ctx context.Context, popenID string) (*model.U
|
||||
|
||||
// buildQueryParams constructs URL query parameters for GameLife requests using cached AES, IV, and token.
|
||||
// It encrypts user data and encodes it into a URL query string.
|
||||
func (s *gamelifeClient) buildQueryParams(ctx context.Context, popenID string, cache model.UserGamelifeCache, appName, nickname string, bindType int, isBound bool) (string, error) {
|
||||
func (s *gamelifeClient) buildQueryParams(ctx context.Context, popenID string, cache *model.UserGamelifeCache, appName, nickname string, bindType int, isBound bool) (string, error) {
|
||||
oriData := map[string]interface{}{
|
||||
"PopenId": popenID,
|
||||
"TimeStamp": time.Now().Unix(),
|
||||
@ -310,31 +315,11 @@ func (s *gamelifeClient) RequestActivity(ctx context.Context, in *model.QQNetbar
|
||||
return &result, nil
|
||||
|
||||
case consts.GetTaskList:
|
||||
cache, err := s.getOrRefreshCache(ctx, in.PopenId)
|
||||
value, err := dao.Games.Ctx(ctx).Where(do.Games{GameId: in.QueryUserGoodsDetailParam.Gid}).Fields(dao.Games.Columns().GameCode).Value()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
cacheKey := fmt.Sprintf(consts.GameLifeUserKey, in.PopenId)
|
||||
if cache.Params == "" {
|
||||
// Reconstruct Params with default values
|
||||
value, err := dao.Games.Ctx(ctx).Where(do.Games{GameId: in.TaskParam.Gid}).Fields(dao.Games.Columns().GameCode).Value()
|
||||
if err != nil {
|
||||
return nil, ecode.Fail.Sub("获取游戏名称失败")
|
||||
}
|
||||
|
||||
cache.Params, err = s.buildQueryParams(ctx, in.PopenId, cache, value.String(), "", in.BindType, true)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// Update cache with new Params
|
||||
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 nil, ecode.Fail.Sub("获取游戏编码失败")
|
||||
}
|
||||
cache, err := s.ensureUserCacheWithParams(ctx, in.PopenId, value.String(), in.NickName, in.BindType)
|
||||
in.TaskParam.BrandId = s.config.BrandID
|
||||
var result model.GameTaskResponse
|
||||
resp, err := client.R().
|
||||
@ -347,31 +332,11 @@ func (s *gamelifeClient) RequestActivity(ctx context.Context, in *model.QQNetbar
|
||||
}
|
||||
return &result, nil
|
||||
case consts.QueryUserRoleList:
|
||||
cache, err := s.getOrRefreshCache(ctx, in.PopenId)
|
||||
value, err := dao.Games.Ctx(ctx).Where(do.Games{GameId: in.QueryUserGoodsDetailParam.Gid}).Fields(dao.Games.Columns().GameCode).Value()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
cacheKey := fmt.Sprintf(consts.GameLifeUserKey, in.PopenId)
|
||||
if cache.Params == "" {
|
||||
// Reconstruct Params with default values
|
||||
value, err := dao.Games.Ctx(ctx).Where(do.Games{GameId: in.UserRoleParam.Gid}).Fields(dao.Games.Columns().GameCode).Value()
|
||||
if err != nil {
|
||||
return nil, ecode.Fail.Sub("获取游戏名称失败")
|
||||
}
|
||||
|
||||
cache.Params, err = s.buildQueryParams(ctx, in.PopenId, cache, value.String(), "", in.BindType, true)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// Update cache with new Params
|
||||
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 nil, ecode.Fail.Sub("获取游戏编码失败")
|
||||
}
|
||||
cache, err := s.ensureUserCacheWithParams(ctx, in.PopenId, value.String(), in.NickName, in.BindType)
|
||||
var result model.UserRoleListResponse
|
||||
resp, err := client.R().
|
||||
SetContext(ctx).
|
||||
@ -382,26 +347,113 @@ func (s *gamelifeClient) RequestActivity(ctx context.Context, in *model.QQNetbar
|
||||
return nil, ecode.Fail.Sub("请求出现异常")
|
||||
}
|
||||
return &result.RoleList, nil
|
||||
|
||||
case consts.GetGift:
|
||||
value, err := dao.Games.Ctx(ctx).Where(do.Games{GameId: in.QueryUserGoodsDetailParam.Gid}).Fields(dao.Games.Columns().GameCode).Value()
|
||||
if err != nil {
|
||||
return nil, ecode.Fail.Sub("获取游戏编码失败")
|
||||
}
|
||||
cache, err := s.ensureUserCacheWithParams(ctx, in.PopenId, value.String(), in.NickName, in.BindType)
|
||||
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))
|
||||
if err != nil || resp.IsError() {
|
||||
return nil, ecode.Fail.Sub("请求出现异常")
|
||||
}
|
||||
return &result, nil
|
||||
case consts.GetUserGoodsList:
|
||||
value, err := dao.Games.Ctx(ctx).Where(do.Games{GameId: in.QueryUserGoodsDetailParam.Gid}).Fields(dao.Games.Columns().GameCode).Value()
|
||||
if err != nil {
|
||||
return nil, ecode.Fail.Sub("获取游戏编码失败")
|
||||
}
|
||||
cache, err := s.ensureUserCacheWithParams(ctx, in.PopenId, value.String(), in.NickName, in.BindType)
|
||||
var result model.GoodsResponse
|
||||
resp, err := client.R().
|
||||
SetContext(ctx).
|
||||
SetBody(in.GoodsParam).
|
||||
SetResult(&result).
|
||||
Post(fmt.Sprintf("%s%s?%s", taskURL, consts.GetUserGoodsList, cache.Params))
|
||||
if err != nil || resp.IsError() {
|
||||
return nil, ecode.Fail.Sub("请求出现异常")
|
||||
}
|
||||
return &result, nil
|
||||
case consts.ExchangeGoods:
|
||||
value, err := dao.Games.Ctx(ctx).Where(do.Games{GameId: in.QueryUserGoodsDetailParam.Gid}).Fields(dao.Games.Columns().GameCode).Value()
|
||||
if err != nil {
|
||||
return nil, ecode.Fail.Sub("获取游戏编码失败")
|
||||
}
|
||||
cache, err := s.ensureUserCacheWithParams(ctx, in.PopenId, value.String(), in.NickName, in.BindType)
|
||||
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))
|
||||
if err != nil || resp.IsError() {
|
||||
return nil, ecode.Fail.Sub("请求出现异常")
|
||||
}
|
||||
return &result, nil
|
||||
case consts.QueryUserGoodsDetail:
|
||||
value, err := dao.Games.Ctx(ctx).Where(do.Games{GameId: in.QueryUserGoodsDetailParam.Gid}).Fields(dao.Games.Columns().GameCode).Value()
|
||||
if err != nil {
|
||||
return nil, ecode.Fail.Sub("获取游戏编码失败")
|
||||
}
|
||||
cache, err := s.ensureUserCacheWithParams(ctx, in.PopenId, value.String(), in.NickName, in.BindType)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var result model.QueryUserGoodsDetailResponse
|
||||
resp, err := client.R().
|
||||
SetContext(ctx).
|
||||
SetBody(in.QueryUserGoodsDetailParam).
|
||||
SetResult(&result).
|
||||
Post(fmt.Sprintf("%s%s?%s", taskURL, consts.QueryUserGoodsDetail, cache.Params))
|
||||
if err != nil || resp.IsError() {
|
||||
return nil, ecode.Fail.Sub("请求出现异常")
|
||||
}
|
||||
return &result, nil
|
||||
default:
|
||||
return nil, ecode.Fail.Sub(fmt.Sprintf("不支持的任务: %s", in.ServiceName))
|
||||
}
|
||||
}
|
||||
|
||||
// getOrRefreshCache retrieves user cache or refreshes it if expired.
|
||||
func (s *gamelifeClient) getOrRefreshCache(ctx context.Context, popenID string) (model.UserGamelifeCache, error) {
|
||||
cacheKey := fmt.Sprintf(consts.GameLifeUserKey, popenID)
|
||||
// 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) (*model.UserGamelifeCache, error) {
|
||||
cacheKey := fmt.Sprintf(consts.GameLifeUserKey, popenId)
|
||||
cacheData, err := g.Redis().Get(ctx, cacheKey)
|
||||
if err != nil {
|
||||
return model.UserGamelifeCache{}, ecode.Fail.Sub("从缓存中获取用户信息失败")
|
||||
return nil, ecode.Fail.Sub("从缓存中获取用户信息失败")
|
||||
}
|
||||
|
||||
var cache model.UserGamelifeCache
|
||||
var cache *model.UserGamelifeCache
|
||||
if cacheData.IsEmpty() {
|
||||
return s.GetUserKeyIV(ctx, popenID)
|
||||
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 err := json.Unmarshal(cacheData.Bytes(), &cache); err != nil {
|
||||
return model.UserGamelifeCache{}, ecode.Fail.Sub("解析用户信息失败")
|
||||
|
||||
if cache.Params == "" {
|
||||
cache.Params, err = s.buildQueryParams(ctx, popenId, cache, appname, nickname, bindType, true)
|
||||
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
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user