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.

300 lines
6.8 KiB
Go

package service
import (
"joybuywork/internal/consts/ckey"
"joybuywork/internal/plugins/jsonm"
"joybuywork/internal/repository/cache"
"joybuywork/internal/repository/dbcheck"
"joybuywork/internal/repository/finder"
"joybuywork/internal/repository/model"
"joybuywork/internal/repository/mtype"
"joybuywork/internal/service/containers"
"joybuywork/internal/service/provider"
"joybuywork/internal/service/provider/fissionaction"
"joybuywork/internal/utils/logic"
pb "joybuywork/proto/go_proto/w_fission_web"
"joybuywork/proto/go_proto/workerr"
"time"
"gits.branchcn.com/backend/microcode/plugins/lucky"
)
type WFissionWeb struct {
Service
}
// GetWebReward 抽取站外奖品
func (s *WFissionWeb) GetWebReward(req *pb.GetWebRewardReq, res *pb.GetWebRewardRes) (err error) {
defer s.checkErr()
cpn, err := finder.Campaign(s.ctx, req.GetHashId())
if err != nil {
return s.BE().CacheError(err)
}
if cpn == nil {
return workerr.NotFound("not found cpn")
}
wbuM := s.GetDao().FissionWebUser
wbu, err := wbuM.WithContext(s.ctx).Where(wbuM.CampaignID.Eq(cpn.ID), wbuM.WebID.Eq(req.GetWebId())).Take()
if err != nil {
return s.BE().MysqlError(err)
}
if wbu == nil {
return workerr.NotFound("not found user")
}
*res = pb.GetWebRewardRes{
Id: wbu.RewardID,
}
return
}
// BindWeb 绑定站外活动
func (s *WFissionWeb) BindWeb(req *pb.BindWebReq, res *pb.BindWebRes) (err error) {
defer s.checkErr()
*res = pb.BindWebRes{}
container := new(containers.FissionWebBindWeb)
{
container.Init(s.ctx)
container.Req = req
container.Res = res
}
return container.Run()
}
// WebReward 用户站外奖
func (s *WFissionWeb) WebReward(req *pb.WebRewardReq, res *pb.WebRewardRes) (err error) {
defer s.checkErr()
*res = pb.WebRewardRes{}
container := new(containers.FissionWebWebReward)
{
container.Init(s.ctx, logic.WithOnce(ckey.FissionUserWebRewardOnce(req.GetWebId())))
container.Req = req
container.Res = res
}
return container.Run()
}
// WebAnswer 用户站外答题
func (s *WFissionWeb) WebAnswer(req *pb.WebAnswerReq, res *pb.WebAnswerRes) (err error) {
defer s.checkErr()
cpn, err := finder.Campaign(s.ctx, req)
if err != nil {
return s.BE().CacheError(err)
}
wbuM := s.GetDao().FissionWebUser
wbu, err := wbuM.WithContext(s.ctx).Where(wbuM.CampaignID.Eq(cpn.ID), wbuM.WebID.Eq(req.GetWebId())).Take()
if err = dbcheck.DbError(err); err != nil {
return s.BE().MysqlError(err)
}
if wbu == nil {
return workerr.NotFound("not found webuser")
}
if wbu.RewardID > 0 {
*res = pb.WebAnswerRes{
Id: wbu.RewardID,
}
return
}
//答卷
answer := make(map[int64]map[int64]struct{})
for _, v := range req.GetSubmits() {
answer[v.GetQid()] = map[int64]struct{}{}
for _, v1 := range v.GetAid() {
answer[v.GetQid()][v1] = struct{}{}
}
}
qm := s.GetDao().FissionCampaignQaQuestion
ql, err := qm.WithContext(s.ctx).Where(qm.CampaignID.Eq(cpn.ID), qm.IsDel.Eq(mtype.No)).Find()
if err != nil {
return s.BE().MysqlError(err)
}
var qids []int64
var scoreMap = make(map[int64]int32)
for _, v := range ql {
qids = append(qids, v.ID)
scoreMap[v.ID] = v.Score
}
opm := s.GetDao().FissionCampaignQaOption
opl, err := opm.WithContext(s.ctx).Where(opm.QuestionID.In(qids...), opm.IsRight.Eq(mtype.Yes), opm.IsDel.Eq(mtype.No)).Find()
if err != nil {
return s.BE().MysqlError(err)
}
//问题
question := map[int64][]int64{}
for _, v := range opl {
question[v.QuestionID] = append(question[v.QuestionID], v.ID)
}
// 得分
var score int32
for qid, aid := range question {
sub, ok := answer[qid]
if !ok {
continue
}
var allRight = true
for _, v := range aid {
_, ok1 := sub[v]
if !ok1 {
allRight = false
break
}
}
if allRight {
score += scoreMap[qid]
}
}
rewardM := s.GetDao().FissionCampaignReward
reward, err := rewardM.WithContext(s.ctx).
Where(rewardM.CampaignID.Eq(cpn.ID), rewardM.RewardType.Eq(mtype.FissionCampaignRewardTypeWeb), rewardM.IsDel.Eq(mtype.No)).
Take()
if err = dbcheck.DbError(err); err != nil {
return s.BE().MysqlError(err)
}
var rewardId int64
if reward != nil {
rewardId = reward.ID
}
val, _ := jsonm.MarshalToString(req.GetSubmits())
// 设置他的奖品
_, err = wbuM.WithContext(s.ctx).Where(wbuM.ID.Eq(wbu.ID)).UpdateSimple(wbuM.RewardID.Value(rewardId), wbuM.Score.Value(score), wbuM.Answer.Value(val))
if err != nil {
return s.BE().MysqlError(err)
}
*res = pb.WebAnswerRes{
Id: rewardId,
}
return
}
// AdsUser Ads用户数据
func (s *WFissionWeb) AdsUser(req *pb.AdsUserReq, res *pb.AdsUserRes) (err error) {
defer s.checkErr()
*res = pb.AdsUserRes{}
container := new(containers.FissionWebAdsUser)
{
container.Init(s.ctx)
container.Req = req
container.Res = res
}
return container.Run()
}
// AdsLottery Ads抽奖
func (s *WFissionWeb) AdsLottery(req *pb.AdsLotteryReq, res *pb.AdsLotteryRes) (err error) {
defer s.checkErr()
cc := cache.NewFissionWebUser(s.ctx)
wbu, err := cc.FindById(req.GetId())
if err != nil {
err = s.BE().CacheError(err)
return
}
if wbu == nil {
err = workerr.NotFound("not found web user")
return
}
cpn, err := finder.Campaign(s.ctx, wbu.CampaignID)
if err != nil {
err = s.BE().CacheError(err)
return
}
m := s.dao.FissionCampaignReward
list, err := m.WithContext(s.ctx).Where(
m.CampaignID.Eq(wbu.CampaignID),
m.IsDel.Eq(mtype.No),
).Find()
if err != nil {
err = s.BE().MysqlError(err)
return
}
if len(list) == 0 {
err = workerr.NotFound("not reward select")
return
}
var bIds []int64
var rewardMap = make(map[int64]*model.FissionCampaignReward, len(list))
var prize = make([]lucky.Reward, 0, len(list))
for _, v := range list {
prize = append(prize, lucky.Reward{
Share: int(v.Odds),
Mark: v.ID,
})
rewardMap[v.ID] = v
bIds = append(bIds, v.RewardID)
}
prewards, err := provider.NewRewards(s.ctx, cpn.ProjectID, bIds...)
if err != nil {
return
}
if wbu.RewardID > 0 {
info, _ := prewards.InfoAutoLang(wbu.RewardID, cpn.GetLangMarks()[0])
*res = pb.AdsLotteryRes{
RewardId: wbu.RewardID,
Title: info.Title,
ImgUrl: info.ImgUrl,
}
return
}
dis := lucky.NewDiscrete(s.ctx, prize)
lottery, _ := dis.Lottery()
reward := rewardMap[lottery.Int64()]
wbuM := s.GetDao().FissionWebUser
_, err = wbuM.WithContext(s.ctx).Where(wbuM.ID.Eq(wbu.ID)).UpdateSimple(wbuM.RewardID.Value(reward.ID))
if err != nil {
err = s.BE().MysqlError(err)
return
}
_ = cc.Clear(wbu)
info, _ := prewards.InfoAutoLang(reward.RewardID, cpn.GetLangMarks()[0])
*res = pb.AdsLotteryRes{
RewardId: reward.ID,
Title: info.Title,
ImgUrl: info.ImgUrl,
}
if cpn.ReportType == mtype.FissionCampaignReportTypeNew {
fissionaction.NewMarkPoint(s.ctx).
OutApp(cpn.ID, wbu.ChannelID, 0, wbu.WebID, req.GetPlatform(), cpn.GetLangMarks()[0]).
ClickPlayWeb(time.Now().Unix(), reward.ID)
}
return
}