319 lines
8.8 KiB
Go
319 lines
8.8 KiB
Go
package v1
|
|
|
|
import (
|
|
"context"
|
|
v1pb "go-common/app/interface/live/app-room/api/http/v1"
|
|
"go-common/app/interface/live/app-room/conf"
|
|
"go-common/app/interface/live/app-room/dao"
|
|
"go-common/app/interface/live/app-room/model"
|
|
"go-common/app/service/live/gift/api/grpc/v1"
|
|
"go-common/library/ecode"
|
|
"go-common/library/log"
|
|
"go-common/library/net/metadata"
|
|
"go-common/library/sync/errgroup"
|
|
"strconv"
|
|
"time"
|
|
)
|
|
|
|
// GiftService struct
|
|
type GiftService struct {
|
|
conf *conf.Config
|
|
// optionally add other properties here, such as dao
|
|
// dao *dao.Dao
|
|
client v1.GiftClient
|
|
dao *dao.Dao
|
|
}
|
|
|
|
const (
|
|
// HasShow 已经展示
|
|
HasShow = 302
|
|
// StopPush 停止推送
|
|
StopPush = 403
|
|
)
|
|
|
|
//NewGiftService init
|
|
func NewGiftService(c *conf.Config) (s *GiftService) {
|
|
s = &GiftService{
|
|
conf: c,
|
|
dao: dao.New(c),
|
|
}
|
|
cli, err := v1.NewClient(conf.Conf.Warden)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
s.client = cli
|
|
return s
|
|
}
|
|
|
|
// DailyBag implementation
|
|
// `method:"GET" midware:"guest"`
|
|
func (s *GiftService) DailyBag(ctx context.Context, req *v1pb.DailyBagReq) (resp *v1pb.DailyBagResp, err error) {
|
|
resp = &v1pb.DailyBagResp{}
|
|
mid, _ := metadata.Value(ctx, metadata.Mid).(int64)
|
|
if mid <= 0 {
|
|
err = ecode.NoLogin
|
|
return
|
|
}
|
|
//mid = 88895029
|
|
ret, err := s.client.DailyBag(ctx, &v1.DailyBagReq{
|
|
Uid: mid,
|
|
})
|
|
if err != nil {
|
|
err = ecode.Error(-1, "系统错误")
|
|
return
|
|
}
|
|
resp = &v1pb.DailyBagResp{
|
|
BagStatus: ret.BagStatus,
|
|
BagExpireStatus: ret.BagExpireStatus,
|
|
BagToast: &v1pb.DailyBagResp_BagToast{
|
|
ToastStatus: ret.BagToast.ToastStatus,
|
|
ToastMessage: ret.BagToast.ToastMessage,
|
|
},
|
|
BagList: make([]*v1pb.DailyBagResp_BagList, 0),
|
|
}
|
|
for _, v := range ret.BagList {
|
|
s := &v1pb.DailyBagResp_BagList_Source{}
|
|
if v.Source != nil {
|
|
s = &v1pb.DailyBagResp_BagList_Source{
|
|
MedalId: v.Source.MedalId,
|
|
MedalName: v.Source.MedalName,
|
|
Level: v.Source.Level,
|
|
UserLevel: v.Source.UserLevel,
|
|
}
|
|
}
|
|
tmp := &v1pb.DailyBagResp_BagList{
|
|
Type: v.Type,
|
|
BagName: v.BagName,
|
|
Source: s,
|
|
}
|
|
for _, v2 := range v.GiftList {
|
|
tmp.GiftList = append(tmp.GiftList, &v1pb.DailyBagResp_BagList_GiftList{
|
|
GiftId: v2.GiftId,
|
|
GiftNum: v2.GiftNum,
|
|
ExpireAt: v2.ExpireAt,
|
|
})
|
|
}
|
|
resp.BagList = append(resp.BagList, tmp)
|
|
}
|
|
return
|
|
}
|
|
|
|
// 实际充值的金瓜子数 最小单位是1000
|
|
func realRechargeGold(gold int64) (realGold int64) {
|
|
if gold%1000 == 0 {
|
|
realGold = gold
|
|
} else {
|
|
realGold = gold + 1000 - gold%1000
|
|
}
|
|
return
|
|
}
|
|
func day(t time.Time) int {
|
|
s := t.Format("2")
|
|
d, _ := strconv.Atoi(s)
|
|
return d
|
|
}
|
|
func yearMonthNum(t time.Time) int64 {
|
|
yearMonth, _ := strconv.ParseInt(t.Format("200601"), 10, 64)
|
|
return yearMonth
|
|
}
|
|
|
|
// 银瓜子是否提醒
|
|
func (s *GiftService) silverNeedTipRecharge(ctx context.Context, mid int64, req *v1pb.NeedTipRechargeReq) (resp *v1pb.NeedTipRechargeResp, err error) {
|
|
resp = &v1pb.NeedTipRechargeResp{}
|
|
d := day(time.Now())
|
|
dHit := false
|
|
for _, v := range s.conf.Gift.RechargeTip.SilverTipDays {
|
|
if v == d {
|
|
dHit = true
|
|
break
|
|
}
|
|
}
|
|
if !dHit { // 日期
|
|
log.Info("silver not show because day not hit %d mid:%d", d, mid)
|
|
return
|
|
}
|
|
yearMonth := yearMonthNum(time.Now())
|
|
defer func() {
|
|
if resp.Show == 1 {
|
|
s.dao.AsyncSetUserConf(ctx, mid, model.SilverTarget, yearMonth)
|
|
}
|
|
}()
|
|
// 每月只推一次
|
|
userConf, err := s.dao.GetUserConf(ctx, mid, model.SilverTarget, []int64{yearMonth, StopPush})
|
|
if err != nil {
|
|
err = ecode.ServerErr
|
|
return
|
|
}
|
|
if userConf.IsSet(yearMonth) || userConf.IsSet(StopPush) {
|
|
log.Info("silver not show because userConf yearMonth:%v stopPush:%v mid:%d", userConf.IsSet(yearMonth), userConf.IsSet(StopPush), mid)
|
|
return
|
|
}
|
|
|
|
w, err := s.dao.PayCenterWallet(ctx, mid, req.Platform)
|
|
if err != nil {
|
|
return
|
|
}
|
|
if w.CouponBalance < 1 { // bp coupon >= 1
|
|
log.Info("silver not show because couponBalance less than 1 %f mid:%d", w.CouponBalance, mid)
|
|
return
|
|
}
|
|
resp.Bp = w.BcoinBalance
|
|
resp.BpCoupon = w.CouponBalance
|
|
resp.Show = 1
|
|
resp.RechargeGold = 0
|
|
log.Info("SilverShow mid:%d coupon:%f", mid, w.CouponBalance)
|
|
return
|
|
}
|
|
|
|
// 金瓜子是否提醒
|
|
func (s *GiftService) goldNeedTipRecharge(ctx context.Context, mid int64, req *v1pb.NeedTipRechargeReq) (resp *v1pb.NeedTipRechargeResp, err error) {
|
|
resp = &v1pb.NeedTipRechargeResp{}
|
|
defer func() {
|
|
if resp.Show == 1 {
|
|
s.dao.AsyncSetUserConf(ctx, mid, model.GoldTarget, HasShow) // 设置已经展示过
|
|
}
|
|
}()
|
|
userConf, err := s.dao.GetUserConf(ctx, mid, model.GoldTarget, []int64{HasShow}) // 是否已经展示过
|
|
if err != nil {
|
|
err = ecode.ServerErr
|
|
return
|
|
}
|
|
if userConf.IsSet(HasShow) {
|
|
log.Info("gold not show because has show mid:%d", mid)
|
|
return
|
|
}
|
|
|
|
eg, errCtx := errgroup.WithContext(ctx)
|
|
var payCenterWallet *model.Wallet
|
|
var liveWallet *model.LiveWallet
|
|
eg.Go(func() error {
|
|
var pErr error
|
|
payCenterWallet, pErr = s.dao.PayCenterWallet(errCtx, mid, req.Platform)
|
|
return pErr
|
|
})
|
|
eg.Go(func() error {
|
|
var lErr error
|
|
liveWallet, lErr = s.dao.LiveWallet(errCtx, mid, req.Platform)
|
|
return lErr
|
|
})
|
|
err = eg.Wait()
|
|
if err != nil {
|
|
return
|
|
}
|
|
|
|
if liveWallet.GoldPayCnt > 0 { // 历史上没有消费过金瓜子
|
|
log.Info("gold not show because gold pay cnt lt 0 %d mid:%d", liveWallet.GoldPayCnt, mid)
|
|
return
|
|
}
|
|
|
|
if payCenterWallet.BcoinBalance < 1 { // bp余额大于1
|
|
log.Info("gold not show because bcoin lt 1 %f mid:%d", payCenterWallet.BcoinBalance, mid)
|
|
return
|
|
}
|
|
|
|
bpGold := int64(payCenterWallet.BcoinBalance * 1000)
|
|
realRechargeGold := realRechargeGold(req.NeedGold)
|
|
if bpGold < realRechargeGold { // 金瓜子差值
|
|
log.Info("gold not show because bcoin lt gold bcoin:%f gold:%d mid:%d", payCenterWallet.BcoinBalance, realRechargeGold, mid)
|
|
return
|
|
}
|
|
resp.Bp = payCenterWallet.BcoinBalance
|
|
resp.BpCoupon = payCenterWallet.CouponBalance
|
|
resp.Show = 1
|
|
resp.RechargeGold = realRechargeGold
|
|
log.Info("GoldShow mid:%d bp:%f goldPayCnt:%d needGold:%d", mid, payCenterWallet.BcoinBalance, liveWallet.GoldPayCnt, req.NeedGold)
|
|
return
|
|
}
|
|
|
|
// NeedTipRecharge implementation
|
|
//
|
|
// `midware:"auth"`
|
|
func (s *GiftService) NeedTipRecharge(ctx context.Context, req *v1pb.NeedTipRechargeReq) (resp *v1pb.NeedTipRechargeResp, err error) {
|
|
mid := metadata.Value(ctx, metadata.Mid).(int64)
|
|
if req.From == v1pb.From_Gold {
|
|
return s.goldNeedTipRecharge(ctx, mid, req)
|
|
} else if req.From == v1pb.From_Silver {
|
|
return s.silverNeedTipRecharge(ctx, mid, req)
|
|
}
|
|
err = ecode.RequestErr
|
|
resp = &v1pb.NeedTipRechargeResp{}
|
|
return
|
|
}
|
|
|
|
// TipRechargeAction implementation
|
|
//
|
|
// `midware:"auth"`
|
|
// `method:"post"`
|
|
func (s *GiftService) TipRechargeAction(ctx context.Context, req *v1pb.TipRechargeActionReq) (resp *v1pb.TipRechargeActionResp, err error) {
|
|
resp = &v1pb.TipRechargeActionResp{}
|
|
mid := metadata.Value(ctx, metadata.Mid).(int64)
|
|
if req.From == v1pb.From_Silver && req.Action == v1pb.UserAction_StopPush {
|
|
err = s.dao.SetUserConf(ctx, mid, model.SilverTarget, StopPush)
|
|
} else {
|
|
err = ecode.RequestErr
|
|
}
|
|
|
|
return
|
|
}
|
|
|
|
// GiftConfig implementation
|
|
func (s *GiftService) GiftConfig(ctx context.Context, req *v1pb.GiftConfigReq) (resp *v1pb.GiftConfigResp, err error) {
|
|
resp = &v1pb.GiftConfigResp{
|
|
List: make([]*v1pb.GiftConfigResp_Config, 0),
|
|
}
|
|
ret, err := s.client.GiftConfig(ctx, &v1.GiftConfigReq{
|
|
Platform: req.Platform,
|
|
Build: req.Build,
|
|
})
|
|
if err != nil {
|
|
log.Error("get gift config err,%v", err)
|
|
err = ecode.Error(-1, "系统错误")
|
|
return
|
|
}
|
|
for _, v := range ret.Data {
|
|
countMap := make([]*v1pb.GiftConfigResp_CountMap, 0)
|
|
for _, c := range v.CountMap {
|
|
tmp := &v1pb.GiftConfigResp_CountMap{
|
|
Num: c.Num,
|
|
Text: c.Text,
|
|
}
|
|
countMap = append(countMap, tmp)
|
|
}
|
|
d := &v1pb.GiftConfigResp_Config{
|
|
Id: v.Id,
|
|
Name: v.Name,
|
|
Price: v.Price,
|
|
Type: v.Type,
|
|
CoinType: v.CoinType,
|
|
BagGift: v.BagGift,
|
|
Effect: v.Effect,
|
|
CornerMark: v.CornerMark,
|
|
Broadcast: v.Broadcast,
|
|
Draw: v.Draw,
|
|
StayTime: v.StayTime,
|
|
AnimationFrameNum: v.AnimationFrameNum,
|
|
Desc: v.Desc,
|
|
Rule: v.Rule,
|
|
Rights: v.Rights,
|
|
PrivilegeRequired: v.PrivilegeRequired,
|
|
CountMap: countMap,
|
|
ImgBasic: v.ImgBasic,
|
|
ImgDynamic: v.ImgDynamic,
|
|
FrameAnimation: v.FrameAnimation,
|
|
Gif: v.Gif,
|
|
Webp: v.Webp,
|
|
FullScWeb: v.FullScWeb,
|
|
FullScHorizontal: v.FullScHorizontal,
|
|
FullScVertical: v.FullScVertical,
|
|
FullScHorizontalSvga: v.FullScHorizontalSvga,
|
|
FullScVerticalSvga: v.FullScVerticalSvga,
|
|
BulletHead: v.BulletHead,
|
|
BulletTail: v.BulletTail,
|
|
LimitInterval: v.LimitInterval,
|
|
}
|
|
resp.List = append(resp.List, d)
|
|
}
|
|
|
|
return
|
|
}
|