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 }