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.

612 lines
14 KiB
Go

package service
import (
"joybuywork/internal/app"
"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/repository/withdefault"
"joybuywork/internal/service/provider/players"
"joybuywork/internal/service/script"
"joybuywork/internal/utils"
"joybuywork/internal/utils/timez"
pb "joybuywork/proto/go_proto/w_script"
"joybuywork/proto/go_proto/workerr"
"strings"
"github.com/rs/xid"
ddevicepb "gits.branchcn.com/backend/deeplink/proto/go_proto/ddevice"
clientv3 "go.etcd.io/etcd/client/v3"
"gorm.io/gen"
)
type WScript struct {
Service
}
// Boot 运行脚本
func (s *WScript) Boot(req *pb.BootReq, res *pb.BootRes) (err error) {
defer s.checkErr()
*res = pb.BootRes{
TaskId: script.Boot(req),
}
return
}
// RefreshDayLimit 刷新每日限制
func (s *WScript) RefreshDayLimit(req *pb.RefreshDayLimitReq, res *pb.RefreshDayLimitRes) (err error) {
defer s.checkErr()
cpn, err := finder.Campaign(s.ctx, req.GetCampaignHashId())
if err != nil {
err = s.BE().CacheError(err)
return
}
if cpn == nil || cpn.Status != mtype.FissionCampaignStatusPubPre {
err = workerr.NotFound("can not do it")
return
}
user, err := finder.FissionUser(s.ctx, cpn.ID, req.GetHashId())
if err != nil {
err = s.BE().CacheError(err)
return
}
if user == nil {
err = workerr.NotFound("not found user")
return
}
ticketM := s.GetDao().FissionCampaignTicket
ticket, err := ticketM.WithContext(s.ctx).Where(
ticketM.CampaignID.Eq(cpn.ID),
ticketM.Mark.Eq(mtype.FissionCampaignTicketCustom),
ticketM.Open.Eq(mtype.Yes),
).Take()
if err = dbcheck.DbError(err); err != nil {
err = s.BE().MysqlError(err)
return
}
if ticket == nil {
err = workerr.NotFound("can not do it")
return
}
m := s.GetDao().FissionUserCond
_, err = m.WithContext(s.ctx).Where(m.UserID.Eq(user.ID)).UpdateSimple(
m.Total.Value(""),
m.CountNum.Value(0),
)
if err != nil {
err = s.BE().MysqlError(err)
return
}
day, start, end := timez.GMTStartAndEndTs(cpn.TOffset)
recordM := s.GetDao().FissionUserCondRecord
_, err = recordM.WithContext(s.ctx).Where(
recordM.UserID.Eq(user.ID),
recordM.BehaviorTime.Gte(start),
recordM.BehaviorTime.Lte(end),
).UpdateSimple(recordM.BehaviorTime.Sub(86400))
if err != nil {
err = s.BE().MysqlError(err)
return
}
taskM := s.GetDao().FissionUserTaskRecord
_, err = taskM.WithContext(s.ctx).Where(
taskM.UserID.Eq(user.ID),
taskM.CreatedAt.Gte(start),
taskM.CreatedAt.Lte(end),
).UpdateSimple(taskM.CreatedAt.Sub(86400))
if err != nil {
err = s.BE().MysqlError(err)
return
}
var condIds []int64
condM := s.GetDao().FissionCampaignCond
err = condM.WithContext(s.ctx).Where(condM.CampaignID.Eq(cpn.ID), condM.IsDel.Eq(mtype.No)).Pluck(condM.ID, &condIds)
if err != nil {
err = s.BE().MysqlError(err)
return
}
var taskIds []int64
ctm := s.GetDao().FissionCampaignTask
err = ctm.WithContext(s.ctx).Where(ctm.CampaignID.Eq(cpn.ID), ctm.IsDel.Eq(mtype.No)).Pluck(ctm.ID, &taskIds)
if err != nil {
err = s.BE().MysqlError(err)
return
}
var keys []string
for _, id := range condIds {
keys = append(keys, ckey.FissionUserCondDayLimit(day, user.ID, id))
}
for _, id := range taskIds {
keys = append(keys, ckey.FissionUserTaskDayLimit(day, user.ID, id))
}
app.Redis.Cache.Del(s.ctx, keys...)
*res = pb.RefreshDayLimitRes{}
return
}
// NotifyList 奖品回调列表
func (s *WScript) NotifyList(req *pb.NotifyListReq, res *pb.NotifyListRes) (err error) {
defer s.checkErr()
cpn, err := finder.Campaign(s.ctx, req.GetCampaignHashId())
if err != nil {
return s.BE().CacheError(err)
}
if cpn == nil || cpn.IsDel == mtype.Yes {
return
}
m := s.GetDao().FissionNotify
var cond = []gen.Condition{
m.CampaignID.Eq(cpn.ID),
}
if req.GetRewardHashId() != "" {
var record *model.FissionRewardRecord
recordM := s.GetDao().FissionRewardRecord.SubTable(cpn.ID)
record, err = recordM.WithContext(s.ctx).Where(recordM.HashID.Eq(req.GetRewardHashId())).Take()
if err = dbcheck.DbError(err); err != nil {
err = s.BE().MysqlError(err)
return
}
if record != nil {
cond = append(cond, m.RecordID.Eq(record.ID))
} else {
cond = append(cond, m.RecordID.Eq(0))
}
}
offset, limit := utils.PpDbLo(req.GetPage(), req.GetPerPage())
list, total, err := m.WithContext(s.ctx).Where(cond...).Order(m.ID.Desc()).FindByPage(offset, limit)
if err != nil {
return s.BE().MysqlError(err)
}
*res = pb.NotifyListRes{
List: make([]*pb.NotifyListRes_One, 0, len(list)),
Total: total,
}
if total == 0 {
return
}
var ids []int64
for _, v := range list {
ids = append(ids, v.ID)
}
respM := s.GetDao().FissionNotifyResp
respList, err := respM.WithContext(s.ctx).Where(respM.NotifyID.In(ids...)).Order(respM.ID.Desc()).Find()
if err != nil {
err = s.BE().MysqlError(err)
return
}
var respMap = make(map[int64][]*model.FissionNotifyResp, len(ids))
for _, v := range respList {
respMap[v.NotifyID] = append(respMap[v.NotifyID], v)
}
for _, v := range list {
one := &pb.NotifyListRes_One{
HashId: v.HashID,
CreatedAt: v.CreatedAt,
Body: v.Body,
NotifyUrl: v.NotifyURL,
Resp: nil,
}
if resp, ok := respMap[v.ID]; ok {
one.Resp = make([]string, 0, len(resp))
for i, v1 := range resp {
if i == 0 {
one.LastPush = v1.CreatedAt
}
one.Resp = append(one.Resp, v1.Resp)
}
}
res.List = append(res.List, one)
}
return
}
// EtcdKey 查看etcd的key
func (s *WScript) EtcdKey(req *pb.EtcdKeyReq, res *pb.EtcdKeyRes) (err error) {
defer s.checkErr()
resp, err := app.EtcdCli.Get(s.ctx, req.GetPrefix(), clientv3.WithPrefix())
if err != nil {
err = s.BE().VerifyError(err.Error())
return
}
*res = pb.EtcdKeyRes{
Kvs: make([]*pb.EtcdKeyRes_KV, 0, len(resp.Kvs)),
}
for _, ev := range resp.Kvs {
res.Kvs = append(res.Kvs, &pb.EtcdKeyRes_KV{
Key: string(ev.Key),
Value: string(ev.Value),
})
}
return
}
// EventFlow 查看事件记录
func (s *WScript) EventFlow(req *pb.EventFlowReq, res *pb.EventFlowRes) (err error) {
defer s.checkErr()
project, err := s.ProjectErrNil(req.GetProjectHashId())
if err != nil {
return
}
m := s.GetDao().ModuleStatisticsEventflow
list, err := m.WithContext(s.ctx).Where(m.ProjectID.Eq(project.ID)).Limit(100).Order(m.CreatedTime.Desc()).Find()
if err != nil {
err = s.BE().MysqlError(err)
return
}
var cpnHashIdMap = make(map[int64]string)
var cpnIds []int64
for _, v := range list {
if _, ok := cpnHashIdMap[v.CampaignID]; !ok && v.CampaignID > 0 {
cpnIds = append(cpnIds, v.CampaignID)
cpnHashIdMap[v.CampaignID] = ""
}
}
if len(cpnIds) > 0 {
cpnM := s.GetDao().FissionCampaign
var cpnList []*model.FissionCampaign
cpnList, err = cpnM.WithContext(s.ctx).Where(cpnM.ID.In(cpnIds...)).Find()
if err != nil {
err = s.BE().MysqlError(err)
return
}
for _, cpn := range cpnList {
cpnHashIdMap[cpn.ID] = cpn.HashID
}
}
*res = pb.EventFlowRes{
List: make([]*pb.EventFlowRes_One, 0, len(list)),
}
for _, v := range list {
res.List = append(res.List, &pb.EventFlowRes_One{
LinkHashId: v.LinkHash,
DeviceId: v.DeviceID,
UserId: v.UserID,
EventTitle: v.EventKey,
IpAddress: v.IPAddress,
Os: v.Os,
OsVersion: v.OsVersion,
DeviceModel: v.DeviceModel,
EventData: v.EventData,
CreatedAt: int64(v.CreatedTime),
Source: utils.Ternary[int32](v.LinkID == 0, 1, utils.Ternary[int32](v.CampaignID == 0, 2, 3)),
CampaignHashId: cpnHashIdMap[v.CampaignID],
})
}
return
}
// ClearDevice 清除设备信息
func (s *WScript) ClearDevice(req *pb.ClearDeviceReq, res *pb.ClearDeviceRes) (err error) {
defer s.checkErr()
project, err := s.ProjectErrNil(req.GetProjectHashId())
if err != nil {
return
}
if project.IsTest == mtype.No {
err = s.BE().VerifyError("not test project")
return
}
cpn, err := finder.Campaign(s.ctx, req.GetCampaignHashId())
if err != nil {
err = s.BE().CacheError(err)
return
}
if cpn == nil {
err = s.BE().VerifyError("not found cpn")
return
}
user, err := finder.FissionUser(s.ctx, cpn.ID, req.GetHashId())
if err != nil {
err = s.BE().CacheError(err)
return
}
if user == nil || strings.HasPrefix(user.SubUserID, consts.TblPrefix) {
return
}
cc := cache.NewFissionUser(s.ctx, cpn.ID)
uid := consts.TblPrefix + xid.New().String()
m := s.GetDao().FissionUser
_, err = m.WithContext(s.ctx).Where(m.ID.Eq(user.ID)).UpdateSimple(
m.DeviceID.Value(""),
m.SubUserID.Value(uid),
m.UserMark.Value(uid),
)
if err != nil {
err = s.BE().MysqlError(err)
return
}
ms := s.GetDao().FissionUser.SubTable(cpn.ID)
_, err = ms.WithContext(s.ctx).Where(ms.ID.Eq(user.ID)).UpdateSimple(
ms.DeviceID.Value(""),
ms.SubUserID.Value(uid),
ms.UserMark.Value(uid),
)
if err != nil {
err = s.BE().MysqlError(err)
return
}
_, _ = app.NewDeepLinkDevice().DeleteDevice(s.ctx, &ddevicepb.DeleteDeviceReq{
Code: user.DeviceID,
ProjectId: project.ID,
UserId: user.SubUserID,
})
_ = cc.Clear(user)
iovdMark := ckey.FissionUserIovdMark(user.ID)
userMark := app.Redis.Cache.Get(s.ctx, iovdMark).Val()
var keys = []string{
ckey.FissionUserUniqMark(user.CampaignID, userMark),
}
if user.DeviceID != "" {
keys = append(keys, cc.IdxKey("campaign_id", user.CampaignID, "device_id", user.DeviceID))
}
if user.SubUserID != "" {
keys = append(keys, cc.IdxKey("campaign_id", user.CampaignID, "sub_user_id", user.SubUserID))
}
app.Redis.Cache.Del(s.ctx, keys...)
*res = pb.ClearDeviceRes{}
return
}
// RefreshView 重新体验玩法
func (s *WScript) RefreshView(req *pb.RefreshViewReq, res *pb.RefreshViewRes) (err error) {
defer s.checkErr()
cpn, err := finder.Campaign(s.ctx, req.GetCampaignHashId())
if err != nil {
err = s.BE().CacheError(err)
return
}
user, err := cache.NewFissionUser(s.ctx, cpn.ID).FindBySubUserId(consts.FissionViewer)
if err != nil {
err = s.BE().CacheError(err)
return
}
if user == nil {
return
}
switch cpn.FissionID {
case consts.IdCash:
var cash *players.Cash
cash, err = players.NewCash(s.ctx, user)
if err != nil {
return
}
err = cash.RefreshView()
if err != nil {
return
}
case consts.IdKeep:
var keep *players.KeepDog
keep, err = players.NewKeepDog(s.ctx, user)
if err != nil {
return
}
err = keep.RefreshView()
if err != nil {
return
}
case consts.IdChop:
var chop *players.Chop
chop, err = players.NewChop(s.ctx, user)
if err != nil {
return
}
err = chop.RefreshView()
if err != nil {
return
}
case consts.IdGold:
var chop *players.Gold
chop, err = players.NewGold(s.ctx, user)
if err != nil {
return
}
err = chop.RefreshView()
if err != nil {
return
}
}
*res = pb.RefreshViewRes{}
return
}
// ErrLog 错误日志记录
func (s *WScript) ErrLog(req *pb.ErrLogReq, res *pb.ErrLogRes) (err error) {
defer s.checkErr()
_ = s.GetDao().ErrLog.WithContext(s.ctx).Create(withdefault.ErrLog(&model.ErrLog{
APIURL: req.GetApiUrl(),
Data: req.GetData(),
LinkURL: req.GetLinkUrl(),
Msg: req.GetMsg(),
}))
*res = pb.ErrLogRes{}
return
}
// PointsLog 领扣积分请求
func (s *WScript) PointsLog(req *pb.PointsLogReq, res *pb.PointsLogRes) (err error) {
defer s.checkErr()
cpn, err := finder.Campaign(s.ctx, req.GetCampaignHashId())
if err != nil {
return s.BE().CacheError(err)
}
if cpn == nil || cpn.IsDel == mtype.Yes {
return
}
m := s.GetDao().FissionPointsLog
var cond = []gen.Condition{
m.CampaignID.Eq(cpn.ID),
}
offset, limit := utils.PpDbLo(req.GetPage(), req.GetPerPage())
list, total, err := m.WithContext(s.ctx).Where(cond...).Order(m.ID.Desc()).FindByPage(offset, limit)
if err != nil {
return s.BE().MysqlError(err)
}
*res = pb.PointsLogRes{
List: make([]*pb.PointsLogRes_One, 0, len(list)),
Total: total,
}
if total == 0 {
return
}
for _, v := range list {
res.List = append(res.List, &pb.PointsLogRes_One{
Id: v.ID,
CreatedAt: v.CreatedAt,
Req: v.Req,
ReqUrl: v.ReqURL,
Token: v.Token,
ReqHeader: v.ReqHeader,
Resp: v.Resp,
ErrMsg: v.ErrMsg,
})
}
return
}
// UserBehavior 用户行为日志
func (s *WScript) UserBehavior(req *pb.UserBehaviorReq, res *pb.UserBehaviorRes) (err error) {
defer s.checkErr()
_ = s.GetDao().UserBehavior.WithContext(s.ctx).Create(withdefault.UserBehavior(&model.UserBehavior{
APIURL: req.GetApiUrl(),
Desc: req.GetDesc(),
CompanyID: req.GetCompanyId(),
UserID: req.GetUserId(),
ProjectID: req.GetProjectHashId(),
IP: req.GetIp(),
UaData: req.GetUaData(),
Req: req.GetReq(),
Res: req.GetRes(),
}))
*res = pb.UserBehaviorRes{}
return
}
// RewardPushLog 奖品推送日志
func (s *WScript) RewardPushLog(req *pb.RewardPushLogReq, res *pb.RewardPushLogRes) (err error) {
defer s.checkErr()
m := s.GetDao().RewardPush
push, err := m.WithContext(s.ctx).Where(
m.Source.Eq(req.GetSource()),
m.FirstID.Eq(req.GetFirstId()),
m.SecondID.Eq(req.GetSecondId()),
m.RelateID.Eq(req.GetRelateId()),
).Take()
if err = dbcheck.DbError(err); err != nil {
return s.BE().CacheError(err)
}
if push == nil {
return
}
logM := s.GetDao().RewardPushLog
offset, limit := utils.PpDbLo(req.GetPage(), req.GetPerPage())
list, total, err := logM.WithContext(s.ctx).Where(logM.PushID.Eq(push.ID)).Order(logM.CreatedAt.Desc()).FindByPage(offset, limit)
if err != nil {
return s.BE().MysqlError(err)
}
*res = pb.RewardPushLogRes{
List: make([]*pb.RewardPushLogRes_One, 0, len(list)),
Total: total,
}
for _, v := range list {
res.List = append(res.List, &pb.RewardPushLogRes_One{
Id: v.ID,
CreatedAt: v.CreatedAt,
Req: v.Req,
ReqUrl: v.ReqURL,
Token: v.Token,
ReqHeader: v.ReqHeader,
Resp: v.Resp,
ErrMsg: v.ErrMsg,
ReqTime: v.ReqTime,
})
}
return
}