Untitled

mail@pastecode.io avatar
unknown
golang
2 years ago
1.6 kB
1
Indexable
Never

const (
	LotteryBlackAction = "7d25738f55772d1d0b5a89fd5210cc6f" // 抽奖用户黑名单
)

func (s *Service) Buy(ctx context.Context, uid int64, req model.BuyReq) (res model.BuyResp, err error) {
	var (
		count = req.Count // 已校验
		log   = logging.For(ctx, "func", "Buy", zap.Int64("uid", uid), zap.Any("req", req))
	)

	// 幂等, 每个用户购买未结束之前, 都定义为相同的请求
	lock, err := s.dao.LockBuy(ctx, uid)
	if err != nil {
		log.Warnf("get lock failed, err: %v", err)
		return
	}
	defer func() {
		if err = s.dao.UnlockBuy(ctx, uid, lock); err != nil {
			log.Warnf("unlock failed, err: %v, lock: %s", err, lock)
		}
	}()

	blackReq := &blackSdk.GetIsBlackByActionReq{
		Names:  []string{strconv.FormatInt(uid, 10)},
		Action: LotteryBlackAction,
	}
	blackResp, err := blackSdk.GetIsBlackByAction(ctx, blackReq)
	if err != nil {
		log.Errorf("get black by action failed, err: %v", err)
	} else {
		// 只有明确请求成功, 且在黑名单, 才拦截
		if len(blackResp.Data) > 0 {
			err = code.LotteryBlackErr // todo caiyi 透传
			log.Info("lottery black user")
			return
		}
	}

	got, err := s.mgr.QueryGold(ctx, uid, s.c.ChargeGold)
	if err != nil {
		return
	}

	gold := int64(count * 10)
	if got < gold {
		err = code.GoldNotEnough
		log.Debugf("11111111111")
		return
	}

	if err = s.mgr.UpdateGold(ctx, uid, -gold, s.c.ChargeGold); err != nil {
		return
	}

	coin := gold // 扭蛋币:钻石 = 1:1
	coin, err = s.mgr.UpdateGameCoin(ctx, uid, coin, s.c.GameCoin.Add)
	if err != nil {
		// todo caiyi 补偿
		return
	}

	res.CapsuleToyCoin = coin
	return
}