Initial commit

This commit is contained in:
Donny
2019-04-22 20:46:32 +08:00
commit 49ab8aadd1
25441 changed files with 4055000 additions and 0 deletions

View File

@@ -0,0 +1,66 @@
load(
"@io_bazel_rules_go//go:def.bzl",
"go_test",
"go_library",
)
go_test(
name = "go_default_test",
srcs = [
"gift_test.go",
"service_test.go",
],
embed = [":go_default_library"],
tags = ["automanaged"],
deps = [
"//app/interface/live/app-room/api/http/v1:go_default_library",
"//app/interface/live/app-room/conf:go_default_library",
"//app/interface/live/app-room/model:go_default_library",
"//library/log:go_default_library",
"//library/net/metadata:go_default_library",
"//vendor/github.com/smartystreets/goconvey/convey:go_default_library",
],
)
go_library(
name = "go_default_library",
srcs = [
"banner.go",
"gift.go",
"roomNotice.go",
],
importpath = "go-common/app/interface/live/app-room/service/v1",
tags = ["automanaged"],
visibility = ["//visibility:public"],
deps = [
"//app/interface/live/app-room/api/http/v1:go_default_library",
"//app/interface/live/app-room/conf:go_default_library",
"//app/interface/live/app-room/dao:go_default_library",
"//app/interface/live/app-room/model:go_default_library",
"//app/service/live/gift/api/grpc/v1:go_default_library",
"//app/service/live/resource/api/grpc/v1:go_default_library",
"//app/service/live/xuserex/api/grpc/v1:go_default_library",
"//library/ecode:go_default_library",
"//library/log:go_default_library",
"//library/net/http/blademaster:go_default_library",
"//library/net/metadata:go_default_library",
"//library/sync/errgroup:go_default_library",
],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [
":package-srcs",
"//app/interface/live/app-room/service/v1/dm:all-srcs",
],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

View File

@@ -0,0 +1,38 @@
package v1
import (
resAPI "go-common/app/interface/live/app-room/api/http/v1"
"go-common/app/interface/live/app-room/conf"
rspb "go-common/app/service/live/resource/api/grpc/v1"
bm "go-common/library/net/http/blademaster"
)
var _rsCli *rspb.Client
// Init -
func Init(c *conf.Config) {
var err error
if _rsCli, err = rspb.NewClient(c.ResourceClient); err != nil {
panic(err)
}
}
// GetBanner -
func GetBanner(context *bm.Context) {
p := new(rspb.GetBannerReq)
if err := context.Bind(p); err != nil {
return
}
respRPC, err := _rsCli.GetBanner(context, p)
if err != nil {
return
}
resp := make([]resAPI.GetBannerResp, len(respRPC.List))
for index, banner := range respRPC.List {
resp[index].Id = banner.Id
resp[index].Title = banner.Title
resp[index].Img = banner.ImageUrl
resp[index].Link = banner.JumpPath
}
context.JSON(resp, err)
}

View File

@@ -0,0 +1,44 @@
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_library",
)
go_library(
name = "go_default_library",
srcs = [
"dM.go",
"data.go",
"validate.go",
],
importpath = "go-common/app/interface/live/app-room/service/v1/dm",
tags = ["automanaged"],
visibility = ["//visibility:public"],
deps = [
"//app/interface/live/app-room/api/http/v1:go_default_library",
"//app/interface/live/app-room/conf:go_default_library",
"//app/interface/live/app-room/model:go_default_library",
"//app/service/live/live-dm/api/grpc/v1:go_default_library",
"//app/service/live/live_riskcontrol/api/grpc/v1:go_default_library",
"//app/service/live/xcaptcha/api/grpc/v1:go_default_library",
"//library/ecode:go_default_library",
"//library/log:go_default_library",
"//library/net/http/blademaster:go_default_library",
"//library/net/metadata:go_default_library",
],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

View File

@@ -0,0 +1,162 @@
package v1
import (
v1pb "go-common/app/interface/live/app-room/api/http/v1"
"go-common/app/interface/live/app-room/conf"
dmrpc "go-common/app/service/live/live-dm/api/grpc/v1"
risk "go-common/app/service/live/live_riskcontrol/api/grpc/v1"
xcaptcha "go-common/app/service/live/xcaptcha/api/grpc/v1"
"go-common/library/ecode"
"go-common/library/log"
bm "go-common/library/net/http/blademaster"
"go-common/library/net/metadata"
"strings"
)
// DMService struct
type DMService struct {
conf *conf.Config
}
var (
//弹幕client
dmClient dmrpc.DMClient
//风控client
riskClient risk.IsForbiddenClient
//验证码client
xcaptchaClient xcaptcha.XCaptchaClient
)
//NewDMService init
func NewDMService(c *conf.Config) (s *DMService) {
s = &DMService{
conf: c,
}
var err error
if dmClient, err = dmrpc.NewClient(c.DM); err != nil {
panic(err)
}
if riskClient, err = risk.NewClient(c.Risk); err != nil {
panic(err)
}
if xcaptchaClient, err = xcaptcha.NewClient(c.VerifyConf); err != nil {
panic(err)
}
return s
}
func sendMsg(ctx *bm.Context, req *v1pb.SendDMReq, uid int64) (resp *v1pb.SendMsgResp, err error) {
resp = &v1pb.SendMsgResp{}
ip := metadata.String(ctx, metadata.RemoteIP)
var ck = make([]string, 0, 10)
for _, v := range ctx.Request.Cookies() {
if v.Name != "SESSDATA" {
ck = append(ck, v.Name+"="+v.Value)
}
}
var dmReq = &dmrpc.SendMsgReq{
Uid: uid,
Roomid: req.Roomid,
Msg: req.Msg,
Rnd: req.Rnd,
Ip: ip,
Fontsize: req.Fontsize,
Mode: req.Mode,
Platform: req.Platform,
Msgtype: 0,
Bubble: req.Bubble,
Lancer: &dmrpc.Lancer{
Build: req.Build,
Buvid: ctx.Request.Header.Get("Buvid"),
UserAgent: ctx.Request.Header.Get("User-Agent"),
Refer: ctx.Request.Header.Get("Referer"),
Cookie: strings.Join(ck, ";"),
},
}
gresp, gerr := dmClient.SendMsg(ctx, dmReq)
if gerr != nil {
log.Error("DM GRPC ERR: %v", gerr)
err = ecode.Error(1003218, "系统正在维护中,请稍后尝试")
return nil, err
}
if gresp.IsLimit {
err = ecode.Error(ecode.Code(gresp.Code), gresp.LimitMsg)
return nil, err
}
return resp, nil
}
//验证码风控
func verifyRisk(ctx *bm.Context, uid int64, req *v1pb.SendDMReq) (resp *v1pb.SendMsgResp, err error) {
//验证码
if req.Anti != "" {
result := checkVerify(ctx, req.Anti, uid, req.Roomid)
if !result {
return nil, ecode.Error(1990001, "验证码验证失败")
}
return sendMsg(ctx, req, uid)
}
//风控校验
ifb, ferr := isriskcontrol(ctx, uid, req)
if ifb {
return nil, ferr
}
return sendMsg(ctx, req, uid)
}
// SendMsg implementation
// `method:"POST"`
func (s *DMService) SendMsg(ctx *bm.Context, req *v1pb.SendDMReq) (resp *v1pb.SendMsgResp, err error) {
//获取UID
uid, ok := ctx.Get("mid")
if !ok {
err = ecode.Error(1003218, "未登录")
return nil, err
}
uid64, ok := uid.(int64)
if !ok {
log.Error("DM: mid error")
err = ecode.Error(1003218, "未登录")
return nil, err
}
device, ok := ctx.Get("device")
if !ok {
log.Error("DM: Get device error")
return sendMsg(ctx, req, uid64)
}
devices, ok := device.(*bm.Device)
if !ok {
log.Error("DM: device error")
return sendMsg(ctx, req, uid64)
}
//验证码版本控制
if (devices.RawMobiApp == "android" && devices.Build >= 5360000) ||
(devices.RawMobiApp == "iphone" && devices.Build >= 8290) {
return verifyRisk(ctx, uid64, req)
}
//发送弹幕
return sendMsg(ctx, req, uid64)
}
// GetHistory implementation
// `method:"POST"`
func (s *DMService) GetHistory(ctx *bm.Context, req *v1pb.HistoryReq) (resp *v1pb.HistoryResp, err error) {
resp = &v1pb.HistoryResp{}
var hreq = &dmrpc.HistoryReq{
Roomid: req.Roomid,
}
gresp, err := dmClient.GetHistory(ctx, hreq)
if err != nil {
log.Error("DM GRPC ERR: %v", err)
return
}
resp.Admin = gresp.Admin
resp.Room = gresp.Room
return
}

View File

@@ -0,0 +1,32 @@
package v1
import (
"encoding/json"
v1pb "go-common/app/interface/live/app-room/api/http/v1"
"go-common/app/interface/live/app-room/model"
)
//HistoryData 历史数据处理
func HistoryData(data *v1pb.HistoryResp) map[string][]*model.History {
var result = make(map[string][]*model.History)
result["admin"] = make([]*model.History, 0, 10)
result["room"] = make([]*model.History, 0, 10)
for i := 0; i < len(data.Admin); i++ {
var h = &model.History{}
err := json.Unmarshal([]byte(data.Admin[i]), h)
if err != nil {
break
}
result["admin"] = append(result["admin"], h)
}
for i := 0; i < len(data.Room); i++ {
var h = &model.History{}
err := json.Unmarshal([]byte(data.Room[i]), h)
if err != nil {
break
}
result["room"] = append(result["room"], h)
}
return result
}

View File

@@ -0,0 +1,78 @@
package v1
import (
"encoding/json"
v1pb "go-common/app/interface/live/app-room/api/http/v1"
risk "go-common/app/service/live/live_riskcontrol/api/grpc/v1"
xcaptcha "go-common/app/service/live/xcaptcha/api/grpc/v1"
"go-common/library/ecode"
"go-common/library/log"
bm "go-common/library/net/http/blademaster"
"go-common/library/net/metadata"
)
type rbody struct {
Roomid int64 `json:"roomid"`
Msg string `json:"msg" `
Rnd string `json:"rnd" `
Fontsize int64 `json:"fontsize"`
Mode int64 `json:"mode" `
Color int64 `json:"color"`
Bubble int64 `json:"bubble"`
}
func isriskcontrol(ctx *bm.Context, uid int64, r *v1pb.SendDMReq) (forbid bool, err *ecode.Status) {
req := &risk.GetForbiddenReq{
Uid: uid,
Uri: "/xlive/app-room/v1/dM/sendmsg",
Ip: metadata.String(ctx, metadata.RemoteIP),
Method: "POST",
Header: make(map[string]string),
}
for k := range ctx.Request.Header {
req.Header[k] = ctx.Request.Header.Get(k)
}
rb := &rbody{
Roomid: r.Roomid,
Msg: r.Msg,
Rnd: r.Rnd,
Fontsize: r.Fontsize,
Mode: r.Mode,
Color: r.Color,
Bubble: r.Bubble,
}
jb, _ := json.Marshal(rb)
req.Body = string(jb)
resp, rerr := riskClient.GetForbidden(ctx, req)
if rerr != nil {
log.Error("DM: riskcontrol err:%+v", rerr)
return false, nil
}
switch resp.IsForbidden {
case 0:
return false, nil
case 1:
return true, ecode.Error(400, "访问被拒绝")
case 2:
return true, ecode.Error(1990000, "need a second time verify")
}
return false, nil
}
func checkVerify(ctx *bm.Context, anti string, uid int64, roomid int64) bool {
req := &xcaptcha.XVerifyReq{
Uid: uid,
ClientIp: metadata.String(ctx, metadata.RemoteIP),
XAnti: anti,
RoomId: roomid,
}
if _, err := xcaptchaClient.Verify(ctx, req); err != nil {
return false
}
return true
}

View File

@@ -0,0 +1,318 @@
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
}

View File

@@ -0,0 +1,290 @@
package v1
import (
"context"
"go-common/app/interface/live/app-room/api/http/v1"
"go-common/app/interface/live/app-room/model"
"go-common/library/net/metadata"
"strconv"
"testing"
"time"
. "github.com/smartystreets/goconvey/convey"
v1pb "go-common/app/interface/live/app-room/api/http/v1"
"github.com/smartystreets/goconvey/convey"
)
func TestV1DailyBag(t *testing.T) {
convey.Convey("DailyBag", t, func(c convey.C) {
var (
ctx = metadata.NewContext(context.Background(), metadata.MD{
metadata.Mid: int64(88895029),
})
req = &v1pb.DailyBagReq{}
)
c.Convey("When everything gose positive", func(c convey.C) {
resp, err := s.DailyBag(ctx, req)
c.Convey("Then err should be nil.resp should not be nil.", func(c convey.C) {
c.So(err, convey.ShouldBeNil)
c.So(resp, convey.ShouldNotBeNil)
})
})
})
}
func Test_RealGoldRecharge(t *testing.T) {
Convey("normal", t, func() {
So(1000, ShouldEqual, realRechargeGold(1000))
So(2000, ShouldEqual, realRechargeGold(1300))
So(2000, ShouldEqual, realRechargeGold(1700))
So(1000, ShouldEqual, realRechargeGold(1))
So(1000, ShouldEqual, realRechargeGold(233))
So(2000, ShouldEqual, realRechargeGold(1398))
ts, _ := time.Parse("2006-01-02", "2018-12-01")
So(1, ShouldEqual, day(ts))
So(201812, ShouldEqual, yearMonthNum(ts))
ts, _ = time.Parse("2006-01-02", "2018-11-30")
So(30, ShouldEqual, day(ts))
So(201811, ShouldEqual, yearMonthNum(ts))
})
}
func getContextWithMid(mid int64) context.Context {
md := metadata.MD{
metadata.Mid: mid,
}
return metadata.NewContext(context.Background(), md)
}
func TestGiftService_NeedTipRecharge_Silver(t *testing.T) {
Convey("silver", t, func() {
Convey("day empty", func() {
ctx := getContextWithMid(1)
testGiftService.conf.Gift.RechargeTip.SilverTipDays = []int{}
resp, err := testGiftService.NeedTipRecharge(ctx, &v1.NeedTipRechargeReq{
From: v1.From_Silver,
NeedGold: 0,
Platform: "android",
})
So(err, ShouldBeNil)
So(resp.Show, ShouldEqual, 0)
})
Convey("day hit and has coupon", func() {
mid := int64(2)
yearMonth, _ := strconv.ParseInt(time.Now().Format("200601"), 10, 64)
testGiftService.dao.DelUserConf(context.Background(), mid, model.SilverTarget, yearMonth)
testGiftService.dao.DelUserConf(context.Background(), mid, model.SilverTarget, StopPush)
w, _ := testGiftService.dao.PayCenterWallet(context.Background(), mid, "android")
if w.CouponBalance < 1 {
t.Logf("own not enouth: %v", w.CouponBalance)
return
}
testGiftService.conf.Gift.RechargeTip.SilverTipDays = append(testGiftService.conf.Gift.RechargeTip.SilverTipDays, day(time.Now()))
t.Logf("%v", testGiftService.conf.Gift.RechargeTip.SilverTipDays)
ctx := getContextWithMid(mid)
resp, err := testGiftService.NeedTipRecharge(ctx, &v1.NeedTipRechargeReq{
From: v1.From_Silver,
NeedGold: 0,
Platform: "android",
})
So(err, ShouldBeNil)
t.Logf("resp:%+v", resp)
So(resp.Show, ShouldEqual, 1)
})
Convey("day hit and has coupon and set stop push", func() {
mid := int64(2)
yearMonth, _ := strconv.ParseInt(time.Now().Format("200601"), 10, 64)
testGiftService.dao.DelUserConf(context.Background(), mid, model.SilverTarget, yearMonth)
testGiftService.dao.DelUserConf(context.Background(), mid, model.SilverTarget, StopPush)
w, _ := testGiftService.dao.PayCenterWallet(context.Background(), mid, "android")
if w.CouponBalance < 1 {
t.Logf("own not enouth: %v", w.CouponBalance)
return
}
testGiftService.conf.Gift.RechargeTip.SilverTipDays = append(testGiftService.conf.Gift.RechargeTip.SilverTipDays, day(time.Now()))
t.Logf("%v", testGiftService.conf.Gift.RechargeTip.SilverTipDays)
ctx := getContextWithMid(mid)
_, err := testGiftService.TipRechargeAction(ctx, &v1.TipRechargeActionReq{
From: v1.From_Silver,
Action: v1.UserAction_StopPush,
})
So(err, ShouldBeNil)
resp, err := testGiftService.NeedTipRecharge(ctx, &v1.NeedTipRechargeReq{
From: v1.From_Silver,
NeedGold: 0,
Platform: "android",
})
So(err, ShouldBeNil)
t.Logf("resp:%+v", resp)
So(resp.Show, ShouldEqual, 0)
})
})
}
func TestGiftService_NeedTipRecharge_Gold(t *testing.T) {
Convey("normal", t, func() {
mid := int64(2)
ctx := getContextWithMid(mid)
testGiftService.dao.DelUserConf(context.Background(), mid, model.GoldTarget, HasShow)
w, _ := testGiftService.dao.PayCenterWallet(context.Background(), mid, "android")
bpGold := int64(w.BcoinBalance * 1000)
t.Logf("own : %d", bpGold)
if bpGold < 3*1000 {
t.Logf("own not enouth: %d", bpGold)
return
}
lw, _ := testGiftService.dao.LiveWallet(context.Background(), mid, "android")
if lw.GoldPayCnt > 0 {
t.Logf("goldPayCnt enouth: %d", lw.GoldPayCnt)
return
}
req := &v1.NeedTipRechargeReq{
From: v1.From_Gold,
NeedGold: 666,
Platform: "android",
}
resp, err := testGiftService.NeedTipRecharge(ctx, req)
So(err, ShouldBeNil)
t.Logf("resp:%+v", resp)
So(resp.Show, ShouldEqual, 1)
So(resp.Bp, ShouldEqual, w.BcoinBalance)
So(resp.BpCoupon, ShouldEqual, w.CouponBalance)
So(resp.RechargeGold, ShouldEqual, 1000)
})
}
func TestGiftService_NeedTipRecharge(t *testing.T) {
Convey("silver condition", t, func() {
Convey("day empty", func() {
testGiftService.dao.DelUserConf(context.Background(), 1, model.SilverTarget, StopPush)
testGiftService.conf.Gift.RechargeTip.SilverTipDays = []int{}
resp, err := testGiftService.silverNeedTipRecharge(context.Background(), 1, &v1.NeedTipRechargeReq{
From: v1.From_Silver,
NeedGold: 0,
Platform: "android",
})
So(err, ShouldBeNil)
So(resp.Show, ShouldEqual, 0)
})
Convey("day hit and has coupon", func() {
mid := int64(3)
yearMonth, _ := strconv.ParseInt(time.Now().Format("200601"), 10, 64)
testGiftService.dao.DelUserConf(context.Background(), mid, model.SilverTarget, yearMonth)
testGiftService.dao.DelUserConf(context.Background(), mid, model.SilverTarget, StopPush)
time.Sleep(time.Millisecond * 10) // 因为是异步设置所以需要一点时间延迟
w, _ := testGiftService.dao.PayCenterWallet(context.Background(), mid, "android")
if w.CouponBalance < 1 {
t.Logf("own not enouth: %v", w.CouponBalance)
return
}
testGiftService.conf.Gift.RechargeTip.SilverTipDays = append(testGiftService.conf.Gift.RechargeTip.SilverTipDays, day(time.Now()))
t.Logf("%v", testGiftService.conf.Gift.RechargeTip.SilverTipDays)
resp, err := testGiftService.silverNeedTipRecharge(context.Background(), mid, &v1.NeedTipRechargeReq{
From: v1.From_Silver,
NeedGold: 0,
Platform: "android",
})
So(err, ShouldBeNil)
t.Logf("resp:%+v", resp)
So(resp.Show, ShouldEqual, 1)
time.Sleep(time.Millisecond * 20) // 因为是异步设置所以需要一点时间延迟
resp, err = testGiftService.silverNeedTipRecharge(context.Background(), mid, &v1.NeedTipRechargeReq{
From: v1.From_Silver,
NeedGold: 0,
Platform: "android",
})
So(err, ShouldBeNil)
t.Logf("resp:%+v", resp)
So(resp.Show, ShouldEqual, 0)
})
Convey("day hit and has no coupon", func() {
mid := int64(20)
yearMonth, _ := strconv.ParseInt(time.Now().Format("200601"), 10, 64)
testGiftService.dao.DelUserConf(context.Background(), mid, model.SilverTarget, yearMonth)
testGiftService.dao.DelUserConf(context.Background(), mid, model.SilverTarget, StopPush)
w, _ := testGiftService.dao.PayCenterWallet(context.Background(), mid, "android")
if w.CouponBalance > 1 {
t.Logf("own enouth: %v", w.CouponBalance)
return
}
testGiftService.conf.Gift.RechargeTip.SilverTipDays = append(testGiftService.conf.Gift.RechargeTip.SilverTipDays, day(time.Now()))
t.Logf("%v", testGiftService.conf.Gift.RechargeTip.SilverTipDays)
resp, err := testGiftService.silverNeedTipRecharge(context.Background(), mid, &v1.NeedTipRechargeReq{
From: v1.From_Silver,
NeedGold: 0,
Platform: "android",
})
So(err, ShouldBeNil)
t.Logf("resp:%+v", resp)
So(resp.Show, ShouldEqual, 0)
})
})
Convey("gold condition", t, func() {
mid := int64(3)
testGiftService.dao.DelUserConf(context.Background(), mid, model.GoldTarget, HasShow)
w, _ := testGiftService.dao.PayCenterWallet(context.Background(), mid, "android")
bpGold := int64(w.BcoinBalance * 1000)
t.Logf("own : %d", bpGold)
if bpGold < 3*1000 {
t.Logf("own not enouth: %d", bpGold)
return
}
lw, _ := testGiftService.dao.LiveWallet(context.Background(), mid, "android")
if lw.GoldPayCnt > 0 {
t.Logf("goldPayCnt enouth: %d", lw.GoldPayCnt)
return
}
req := &v1.NeedTipRechargeReq{
From: v1.From_Gold,
NeedGold: 1,
Platform: "android",
}
ctx, cancel := context.WithTimeout(context.Background(), time.Millisecond*300)
resp, err := testGiftService.goldNeedTipRecharge(ctx, mid, req)
So(err, ShouldBeNil)
t.Logf("resp:%+v", resp)
So(resp.Show, ShouldEqual, 1)
So(resp.Bp, ShouldEqual, w.BcoinBalance)
So(resp.BpCoupon, ShouldEqual, w.CouponBalance)
So(resp.RechargeGold, ShouldEqual, 1000)
cancel()
time.Sleep(time.Millisecond * 20) // 因为是异步设置所以需要一点时间延迟
testGiftService.dao.DelUserConf(context.Background(), mid, model.GoldTarget, HasShow)
req.NeedGold = 1230
ctx, cancel = context.WithTimeout(context.Background(), time.Millisecond*300)
resp, err = testGiftService.goldNeedTipRecharge(ctx, mid, req)
cancel()
So(err, ShouldBeNil)
t.Logf("resp:%+v", resp)
So(resp.Show, ShouldEqual, 1)
So(resp.Bp, ShouldEqual, w.BcoinBalance)
So(resp.BpCoupon, ShouldEqual, w.CouponBalance)
So(resp.RechargeGold, ShouldEqual, 2000)
time.Sleep(time.Millisecond * 10) // 因为是异步设置所以需要一点时间延迟
testGiftService.dao.DelUserConf(context.Background(), mid, model.GoldTarget, HasShow)
req.NeedGold = bpGold + 1
ctx, cancel = context.WithTimeout(context.Background(), time.Millisecond*300)
resp, err = testGiftService.goldNeedTipRecharge(ctx, mid, req)
cancel()
So(err, ShouldBeNil)
t.Logf("resp:%+v", resp)
So(resp.Show, ShouldEqual, 0)
})
}

View File

@@ -0,0 +1,63 @@
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/service/live/xuserex/api/grpc/v1"
"go-common/library/ecode"
)
// RoomNoticeService struct
type RoomNoticeService struct {
conf *conf.Config
// optionally add other properties here, such as dao
dao *dao.Dao
}
//NewRoomNoticeService init
func NewRoomNoticeService(c *conf.Config) (s *RoomNoticeService) {
s = &RoomNoticeService{
conf: c,
dao: dao.New(c),
}
return s
}
// 房间提示 相关服务
// BuyGuard implementation
// 是否弹出大航海购买提示
func (s *RoomNoticeService) BuyGuard(ctx context.Context, req *v1pb.RoomNoticeBuyGuardReq) (resp *v1pb.RoomNoticeBuyGuardResp, err error) {
resp = &v1pb.RoomNoticeBuyGuardResp{}
UID := req.GetUid()
targetID := req.GetTargetId()
if UID <= 0 || targetID <= 0 {
err = ecode.ParamInvalid
return
}
ret, err := s.dao.XuserexAPI.BuyGuard(ctx, &v1.RoomNoticeBuyGuardReq{
Uid: UID,
TargetId: targetID,
})
if err != nil {
return
}
if ret == nil {
return
}
resp = &v1pb.RoomNoticeBuyGuardResp{
ShouldNotice: ret.GetShouldNotice(),
Begin: ret.GetBegin(),
End: ret.GetEnd(),
Now: ret.GetNow(),
Title: ret.GetTitle(),
Content: ret.GetContent(),
Button: ret.GetButton(),
}
return
}

View File

@@ -0,0 +1,25 @@
package v1
import (
"go-common/app/interface/live/app-room/conf"
"go-common/library/log"
"os"
"testing"
)
var (
testGiftService *GiftService
s *GiftService
)
func TestMain(m *testing.M) {
conf.ConfPath = "../../cmd/test.toml"
if err := conf.Init(); err != nil {
panic(err)
}
log.Init(conf.Conf.Log)
defer log.Close()
testGiftService = NewGiftService(conf.Conf)
s = testGiftService
os.Exit(m.Run())
}