You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

671 lines
15 KiB
Go

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

package campaign
import (
"joybuywork/internal/consts"
"joybuywork/internal/consts/ckey"
"joybuywork/internal/repository/cache"
"joybuywork/internal/repository/dbcheck"
"joybuywork/internal/repository/finder"
"joybuywork/internal/repository/model"
"joybuywork/internal/repository/mtype"
"joybuywork/internal/service/cmm"
"joybuywork/internal/service/provider"
"joybuywork/internal/service/provider/cachecurd"
"joybuywork/internal/utils"
"joybuywork/internal/utils/logic"
"joybuywork/internal/utils/randext"
pb "joybuywork/proto/go_proto/w_campaign"
"joybuywork/proto/go_proto/workerr"
"fmt"
"math"
"math/rand"
"time"
"gorm.io/gen"
)
type Barrage struct {
logic.Logic
Req *pb.BarrageReq
Res *pb.BarrageRes
}
func (s *Barrage) Run() error {
return logic.Run(s)
}
func (s *Barrage) Exec() (err error) {
cpn, conf, err := s.campaign()
if err != nil {
return
}
return s.barrage(cpn, conf)
}
// 活动数据
func (s *Barrage) campaign() (cpn *model.FissionCampaign, conf *model.FissionCampaignConfig, err error) {
cpn, err = finder.Campaign(s.Ctx, s.Req.GetId(), s.Req.GetHashId())
if err != nil {
err = s.BE().CacheError(err)
return
}
if cpn == nil || cpn.IsDel == mtype.Yes {
err = workerr.NotFound("cpn not found")
return
}
conf, err = cache.NewCampaignConfig(s.Ctx).FindByCampaignId(cpn.ID)
if err != nil {
err = s.BE().CacheError(err)
return
}
return
}
// 奖品处理
func (s *Barrage) barrage(cpn *model.FissionCampaign, conf *model.FissionCampaignConfig) (err error) {
switch cpn.FissionID {
case consts.IdWinTogether, consts.IdReferral: //一起赢
return s._invite(cpn, conf)
case consts.IdCash:
return s._cash(cpn)
case consts.IdGold:
return s._gold(cpn)
case consts.IdChop:
return s._chop(cpn)
case consts.IdKeep:
return s._keep(cpn)
case consts.IdFlip:
return s._flip(cpn)
case consts.IdCoin:
return s._coin(cpn)
}
return
}
func (s *Barrage) _reward(rewardTitle []string) {
for i := 0; i < 15; i++ {
idx := i % len(rewardTitle)
s.Res.Content = append(s.Res.Content, fmt.Sprintf("%s****%s %s", utils.GetRandEnStr(3), utils.GetRandEnStr(3), rewardTitle[idx]))
}
}
func (s *Barrage) _invite(cpn *model.FissionCampaign, conf *model.FissionCampaignConfig) (err error) {
rewardM := s.GetDao().FissionCampaignReward
var conds = []gen.Condition{
rewardM.CampaignID.Eq(cpn.ID),
rewardM.RewardType.Neq(mtype.FissionCampaignRewardTypeNewcomer),
rewardM.IsDel.Eq(mtype.No),
}
// 获取活动对应的用户等级和用户的语言
uct, err := cmm.NewCMM(s.Ctx, s.GetDao()).UserCampaignType(cpn, conf, s.Req.GetLangMark(), s.Req.GetLv(), s.Req.GetCountryMark())
if err != nil {
return
}
userLang, userLevel := uct.LangMark, uct.LevelId
switch conf.RewardGroup {
case mtype.FissionRewardGroupUserLevel:
conds = append(conds, rewardM.LevelID.Eq(userLevel))
case mtype.FissionRewardGroupLangAndUserLevel:
conds = append(conds, rewardM.LevelID.Eq(userLevel), rewardM.LangMark.Eq(userLang))
case mtype.FissionRewardGroupLang:
conds = append(conds, rewardM.LangMark.Eq(userLang))
}
list, err := rewardM.WithContext(s.Ctx).Where(conds...).Find()
if err != nil {
return s.BE().MysqlError(err)
}
if len(list) == 0 {
return
}
var rewardTitle []string
defer func() {
s._reward(rewardTitle)
}()
var ids []int64
for _, v := range list {
ids = append(ids, v.RewardID)
}
preward, err := provider.NewRewards(s.Ctx, cpn.ProjectID, ids...)
if err != nil {
return
}
var showLang = utils.NotExistGetFirst(s.Req.GetShowLang(), cpn.GetLangMarks())
for _, v := range list {
data, _ := preward.InfoAutoLang(v.RewardID, showLang)
rewardTitle = append(rewardTitle, fmt.Sprintf("%d %s", v.RewardNum, data.Title))
}
return
}
func (s *Barrage) _cash(cpn *model.FissionCampaign) (err error) {
var price int32
spl := cpn.GetLangMarks()
lm := utils.NotExistGetFirst(s.Req.GetShowLang(), spl)
if lm == spl[0] {
m := s.GetDao().FissionCampaignCash
var conf *model.FissionCampaignCash
conf, err = m.WithContext(s.Ctx).Where(m.CampaignID.Eq(cpn.ID)).Take()
if err = dbcheck.DbError(err); err != nil {
return
}
if conf == nil {
return
}
price = conf.Price
} else {
var lang *model.FissionCampaignLang
lang, err = cache.NewCampaignLang(s.Ctx).FindByCampaignId(cpn.ID, lm)
if err != nil {
err = s.BE().CacheError(err)
return
}
if lang == nil {
return
}
if cash := lang.GetCash(); cash != nil {
price = cash.Price
}
}
var mark = []string{"victory_tip", "min_won_barrage", "won_barrage", "closer_to_prize", "shine_arrived"}
l := len(mark) * 5
s.Res.TranContent = make([]*pb.BarrageRes_TranContent, 0, l)
for i := 0; i < l; i++ {
key := mark[i%5]
one := &pb.BarrageRes_TranContent{
Mark: fmt.Sprintf("barrage:%s", key),
ReplaceKv: nil,
}
switch key {
case "won_barrage":
one.ReplaceKv = append(one.ReplaceKv, &pb.BarrageRes_KV{
Key: "{{name}}",
Value: fmt.Sprintf("%s***%s", randext.RandLetters(1), randext.RandLetters(1)),
}, &pb.BarrageRes_KV{
Key: "{{cash}}",
Value: fmt.Sprintf("$%d", price),
})
case "min_won_barrage":
one.ReplaceKv = append(one.ReplaceKv, &pb.BarrageRes_KV{
Key: "{{name}}",
Value: fmt.Sprintf("%s***%s", randext.RandLetters(1), randext.RandLetters(1)),
}, &pb.BarrageRes_KV{
Key: "{{cash}}",
Value: fmt.Sprintf("$%d", price),
}, &pb.BarrageRes_KV{
Key: "{{min}}",
Value: fmt.Sprintf("%d", rand.Intn(9)+1),
})
}
s.Res.TranContent = append(s.Res.TranContent, one)
}
return
}
func (s *Barrage) _chop(cpn *model.FissionCampaign) (err error) {
user, err := cache.NewFissionUser(s.Ctx, cpn.ID).FindById(s.Req.GetUserId())
if err != nil {
err = s.BE().CacheError(err)
return
}
rewards, err := cmm.NewCMM(s.Ctx, s.GetDao()).UserAppReward(user)
if err != nil {
return
}
var bIds []int64
var randReward = make(map[int64]*model.FissionCampaignReward)
for _, reward := range rewards {
randReward[reward.ID] = reward
bIds = append(bIds, reward.RewardID)
}
m := s.GetDao().FissionCampaignTicket
ticket, err := m.WithContext(s.Ctx).Where(
m.CampaignID.Eq(cpn.ID),
m.Mark.Eq(mtype.FissionCampaignTicketRewardHelp),
m.Open.Eq(mtype.Yes),
).Take()
if err = dbcheck.DbError(err); err != nil {
err = s.BE().MysqlError(err)
return
}
if ticket == nil {
err = workerr.NotFound("not found reward_help ticket")
return
}
preward, err := provider.NewRewards(s.Ctx, cpn.ProjectID, bIds...)
if err != nil {
return
}
var showLang = utils.NotExistGetFirst(s.Req.GetShowLang(), cpn.GetLangMarks())
var marks = ticket.GetHelpEvent()
var markL = len(marks)
// 20条数据
var randMap = make(map[int]*pb.BarrageRes_TranContent, 20)
var idx int
for i := 1; i <= 20; i++ {
// 5条一组
switch a := i % 5; {
case a < 3: // 3个奖品
var rewardTitle string
for _, reward := range randReward {
info, _ := preward.InfoAutoLang(reward.RewardID, showLang)
rewardTitle = info.Title
}
s.Res.TranContent = append(s.Res.TranContent)
randMap[i] = &pb.BarrageRes_TranContent{
Mark: "barrage:get_reward",
ReplaceKv: []*pb.BarrageRes_KV{
{
Key: "{{name}}",
Value: fmt.Sprintf("%s***%s", randext.RandLetters(1), randext.RandLetters(1)),
},
{
Key: "{{reward_title}}",
Value: rewardTitle,
},
},
}
default: // 1个助力
for j := 0; j < 2; j++ {
randMap[i] = &pb.BarrageRes_TranContent{
Mark: fmt.Sprintf("barrage:%s", marks[idx]),
ReplaceKv: []*pb.BarrageRes_KV{
{
Key: "{{name}}",
Value: fmt.Sprintf("%s***%s", randext.RandLetters(1), randext.RandLetters(1)),
},
},
}
idx++
if idx >= markL {
idx = 0
}
}
}
}
// 打乱一下
for _, content := range randMap {
s.Res.TranContent = append(s.Res.TranContent, content)
}
return
}
func (s *Barrage) _keep(cpn *model.FissionCampaign) (err error) {
randReward, preward, showLang, err := s._rewardDepend(cpn)
if err != nil {
return
}
// 20条数据
s.Res.TranContent = make([]*pb.BarrageRes_TranContent, 20)
for i := 0; i < 20; i++ {
var rewardTitle, imgUrl string
for _, reward := range randReward {
info, _ := preward.InfoAutoLang(reward.RewardID, showLang)
rewardTitle, imgUrl = info.Title, info.ImgUrl
}
s.Res.TranContent[i] = &pb.BarrageRes_TranContent{
Mark: "barrage:get_reward",
ReplaceKv: []*pb.BarrageRes_KV{
{
Key: "{{name}}",
Value: fmt.Sprintf("%s***%s", randext.RandLetters(1), randext.RandLetters(1)),
},
{
Key: "{{reward_title}}",
Value: rewardTitle,
},
},
RewardImg: imgUrl,
}
}
return
}
func (s *Barrage) _gold(cpn *model.FissionCampaign) (err error) {
var price float64
spl := cpn.GetLangMarks()
lm := utils.NotExistGetFirst(s.Req.GetShowLang(), spl)
if lm == spl[0] {
var conf *model.FissionCampaignGold
conf, err = cache.NewCampaignGold(s.Ctx).FindByCampaignId(cpn.ID)
if err != nil {
err = s.BE().CacheError(err)
return
}
if conf == nil {
return
}
price = conf.Price
} else {
var lang *model.FissionCampaignLang
lang, err = cache.NewCampaignLang(s.Ctx).FindByCampaignId(cpn.ID, lm)
if err != nil {
err = s.BE().CacheError(err)
return
}
if lang == nil {
return
}
if gold := lang.GetGold(); gold != nil {
price = gold.Price
}
}
var mark = []string{"victory_tip", "min_won_barrage", "won_barrage", "closer_to_prize", "shine_arrived"}
l := len(mark) * 5
s.Res.TranContent = make([]*pb.BarrageRes_TranContent, 0, l)
for i := 0; i < l; i++ {
key := mark[i%5]
one := &pb.BarrageRes_TranContent{
Mark: fmt.Sprintf("barrage:%s", key),
ReplaceKv: nil,
}
var val = fmt.Sprintf("%.2f", price)
if price == math.Trunc(price) {
val = fmt.Sprintf("%d", int32(price))
}
switch key {
case "won_barrage":
one.ReplaceKv = append(one.ReplaceKv, &pb.BarrageRes_KV{
Key: "{{name}}",
Value: fmt.Sprintf("%s***%s", randext.RandLetters(1), randext.RandLetters(1)),
}, &pb.BarrageRes_KV{
Key: "{{cash}}",
Value: val,
})
case "min_won_barrage":
one.ReplaceKv = append(one.ReplaceKv, &pb.BarrageRes_KV{
Key: "{{name}}",
Value: fmt.Sprintf("%s***%s", randext.RandLetters(1), randext.RandLetters(1)),
}, &pb.BarrageRes_KV{
Key: "{{cash}}",
Value: val,
}, &pb.BarrageRes_KV{
Key: "{{min}}",
Value: fmt.Sprintf("%d", rand.Intn(9)+1),
})
}
s.Res.TranContent = append(s.Res.TranContent, one)
}
return
}
func (s *Barrage) _flip(cpn *model.FissionCampaign) (err error) {
randReward, preward, showLang, err := s._rewardDepend(cpn)
if err != nil {
return
}
var idx = 20
var ids []int64
for _, reward := range randReward {
if (reward.Odds == 0 && reward.IsThank == mtype.Yes) || reward.RewardID < 0 { // 客户设置的概率为0的谢谢参与不显示,默认的谢谢参与奖也不显示
delete(randReward, reward.ID)
continue
}
if reward.Odds == 0 {
ids = append(ids, reward.ID)
idx--
}
}
for _, reward := range randReward {
if reward.Odds == 0 {
continue
}
g := float64(idx) * (float64(reward.Odds) / 1000)
var n = int(g)
if n < 1 {
n = 1
}
for i := 0; i < n; i++ {
ids = append(ids, reward.ID)
}
}
l := len(ids)
idxL := l
for {
if l >= 10 {
break
}
for _, id := range ids[:idxL] {
ids = append(ids, id)
l++
}
}
// 20条数据
s.Res.TranContent = make([]*pb.BarrageRes_TranContent, l)
for i, id := range ids {
reward := randReward[id]
info, _ := preward.InfoAutoLang(reward.RewardID, showLang)
rewardTitle, imgUrl := info.Title, info.ImgUrl
s.Res.TranContent[i] = &pb.BarrageRes_TranContent{
Mark: "barrage:get_reward",
ReplaceKv: []*pb.BarrageRes_KV{
{
Key: "{{name}}",
Value: fmt.Sprintf("%s***%s", randext.RandLetters(1), randext.RandLetters(1)),
},
{
Key: "{{reward_title}}",
Value: rewardTitle,
},
},
RewardImg: imgUrl,
}
}
return
}
func (s *Barrage) _rewardDepend(cpn *model.FissionCampaign) (randReward map[int64]*model.FissionCampaignReward, preward *provider.Rewards, showLang string, err error) {
user, err := cache.NewFissionUser(s.Ctx, cpn.ID).FindById(s.Req.GetUserId())
if err != nil {
err = s.BE().CacheError(err)
return
}
rewards, err := cmm.NewCMM(s.Ctx, s.GetDao()).UserAppReward(user)
if err != nil {
return
}
var bIds []int64
randReward = make(map[int64]*model.FissionCampaignReward)
for _, reward := range rewards {
randReward[reward.ID] = reward
bIds = append(bIds, reward.RewardID)
}
preward, err = provider.NewRewards(s.Ctx, cpn.ProjectID, bIds...)
if err != nil {
return
}
showLang = utils.NotExistGetFirst(s.Req.GetShowLang(), cpn.GetLangMarks())
return
}
func (s *Barrage) _coin(cpn *model.FissionCampaign) (err error) {
conf, err := cache.NewCampaignCoin(s.Ctx).FindByCampaignId(cpn.ID)
if err != nil {
err = s.BE().CacheError(err)
return
}
m := s.GetDao().FissionCoinScene
scenes, err := m.WithContext(s.Ctx).Where(m.CampaignID.Eq(cpn.ID)).Find()
if err != nil {
err = s.BE().CacheError(err)
return
}
var opL int32
for _, scene := range scenes {
if scene.OpenTime <= time.Now().Unix() {
opL++
}
}
num := rand.Intn(int(conf.UseLimit)) + 1
var nm = make(map[int]struct{}, num)
for i := 1; i < num; i++ {
nm[i] = struct{}{}
}
if opL == 0 {
for i := 0; i < 20; i++ {
var n int
for k := range nm {
n = k
}
s.Res.TranContent = append(s.Res.TranContent, &pb.BarrageRes_TranContent{
Mark: "barrage:join_coin_num",
ReplaceKv: []*pb.BarrageRes_KV{
{
Key: "{{name}}",
Value: fmt.Sprintf("%s***%s", randext.RandLetters(1), randext.RandLetters(1)),
},
{
Key: "{{num}}",
Value: fmt.Sprint(n),
},
},
})
}
return
}
var scene *model.FissionCoinScene
if len(scenes) == 1 {
scene = scenes[0]
} else {
scene = scenes[len(scenes)-2]
}
key := ckey.FissionCoinSceneData(scene.ID)
sceneData, err := cachecurd.NewHMap(s.Ctx, key,
cachecurd.SetCoinSceneBuild(cpn.ID, scene.ID),
cachecurd.SetHMapExp(time.Duration(conf.OpenDays+1)*consts.TimeDay),
)
if err != nil {
err = s.BE().CacheError(err)
return
}
userCoin, _ := sceneData.GetInt64(cachecurd.CoinSceneUserCoin)
joinNum, _ := sceneData.GetInt64(cachecurd.CoinSceneJoinNum)
var getNum int64
if joinNum > 0 {
getNum = userCoin / joinNum
}
for i := 0; i < 20; i++ {
var n int
for k := range nm {
n = k
}
if i%2 == 0 {
s.Res.TranContent = append(s.Res.TranContent, &pb.BarrageRes_TranContent{
Mark: "barrage:get_coin",
ReplaceKv: []*pb.BarrageRes_KV{
{
Key: "{{name}}",
Value: fmt.Sprintf("%s***%s", randext.RandLetters(1), randext.RandLetters(1)),
},
{
Key: "{{num}}",
Value: fmt.Sprintf("%d", (getNum+int64(conf.UseCoin))*int64(n)),
},
},
})
continue
}
s.Res.TranContent = append(s.Res.TranContent, &pb.BarrageRes_TranContent{
Mark: "barrage:join_coin_num",
ReplaceKv: []*pb.BarrageRes_KV{
{
Key: "{{name}}",
Value: fmt.Sprintf("%s***%s", randext.RandLetters(1), randext.RandLetters(1)),
},
{
Key: "{{num}}",
Value: fmt.Sprint(n),
},
},
})
}
return
}