package campaignuser import ( "joybuywork/internal/app" "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/repository/withdefault" "joybuywork/internal/service/cmm" "joybuywork/internal/service/queue/producer" "joybuywork/internal/service/queue/types" "joybuywork/internal/utils/blink" "joybuywork/internal/utils/logic" pb "joybuywork/proto/go_proto/w_campaign_user" "joybuywork/proto/go_proto/workerr" linkpb "gits.branchcn.com/backend/shortlink/proto/go_proto/link" ) type DynamicLink struct { logic.Logic Req *pb.DynamicLinkReq Res *pb.DynamicLinkRes } func (s *DynamicLink) Run() error { return logic.Run(s) } func (s *DynamicLink) Exec() (err error) { project, cpn, channel, err := s.related() if err != nil { return } user, err := s.user(cpn, channel) if err != nil { return } err = s.link(cpn, user, project, channel) if err != nil { return } return } func (s *DynamicLink) related() (project *model.Project, cpn *model.FissionCampaign, channel *model.FissionCampaignChannel, err error) { project, err = finder.Project(s.Ctx, s.Req.GetProjectHashId()) if err != nil { err = s.BE().CacheError(err) return } if project == nil || project.IsDel == mtype.Yes { err = workerr.DynamicNotRelatedError return } if s.Req.GetCampaignHashId() != "" { cpn, err = finder.Campaign(s.Ctx, s.Req.GetCampaignHashId()) if err != nil { err = s.BE().CacheError(err) return } } else { var conf *model.FissionConfig conf, err = cmm.NewCMM(s.Ctx, s.GetDao()).GetFissionConfig(project.ID) if err != nil { return } cpn, err = finder.Campaign(s.Ctx, conf.DynamicCampaign) if err != nil { err = s.BE().CacheError(err) return } } if cpn == nil || cpn.IsDel == mtype.Yes { err = workerr.DynamicNotRelatedError return } channelM := s.GetDao().FissionCampaignChannel channel, err = channelM.WithContext(s.Ctx).Where( channelM.CampaignID.Eq(cpn.ID), channelM.CType.Eq(mtype.FissionCampaignChannelTypeApp), channelM.IsDefault.Eq(mtype.Yes), channelM.IsDel.Eq(mtype.No), ).Take() return } func (s *DynamicLink) user(cpn *model.FissionCampaign, channel *model.FissionCampaignChannel) (user *model.FissionUser, err error) { if s.Req.GetSubUserId() == "" { err = s.BE().VerifyError("sub_user_id empty") return } user, err = cache.NewFissionUser(s.Ctx, cpn.ID).FindBySubUserId(s.Req.GetSubUserId()) if err != nil { err = s.BE().CacheError(err) return } if user != nil { return } lc := app.NewRedisLock(s.Ctx, ckey.FissionUserStoreOnce(cpn.ID, s.Req.GetSubUserId())).Lock() defer lc.Release() if lc.Error() != nil { err = workerr.BusyError return } user, err = cache.NewFissionUser(s.Ctx, cpn.ID).FindBySubUserId(s.Req.GetSubUserId()) if err != nil { err = s.BE().CacheError(err) return } if user != nil { return } user = withdefault.FissionUser(&model.FissionUser{ CampaignID: cpn.ID, ChannelID: channel.ID, ParentID: 0, Deep: 0, IsNew: 0, SubUserID: s.Req.GetSubUserId(), DeviceID: "", UserMark: s.Req.GetSubUserId(), UserType: mtype.FissionUserTypePlay, ParentIds: "", IsView: 0, ShareLink: "", Source: mtype.FissionUserSourceDynamic, IsHelp: 0, }) m := s.GetDao().FissionUser if err = m.WithContext(s.Ctx).Create(user); err != nil { err = s.BE().MysqlError(err) return } ms := s.GetDao().FissionUser.SubTable(cpn.ID) if err = ms.WithContext(s.Ctx).Create(user); err != nil { err = s.BE().MysqlError(err) return } producer.NewCampaignNotice(s.Ctx).ProjectUser(types.ProjectUser{ ProjectId: cpn.ProjectID, UserId: user.SubUserID, }) return } func (s *DynamicLink) link(cpn *model.FissionCampaign, user *model.FissionUser, project *model.Project, channel *model.FissionCampaignChannel) (err error) { params := &mtype.FissionUserDyLinkParams{ MediaType: s.Req.GetMediaType(), ImageText: nil, } switch s.Req.GetMediaType() { case mtype.FissionUserDyLinkMediaTypeImgText: for _, v := range s.Req.GetImageText() { params.ImageText = append(params.ImageText, &mtype.ImageText{ NickName: v.GetNickName(), Avatar: v.GetAvatar(), Title: v.GetTitle(), Desc: v.GetDesc(), Image: v.GetImage(), }) } } b, err := jsonm.Marshal(params) if err != nil { err = workerr.ServerError return } mark, _ := b.ToMd5() m := s.GetDao().FissionUserDylink lk, err := m.WithContext(s.Ctx).Where(m.UserID.Eq(user.ID), m.LinkMark.Eq(mark)).Take() if err = dbcheck.DbError(err); err != nil { err = s.BE().MysqlError(err) return } defer func() { if err != nil { return } s.Res.LinkUrl = lk.LinkURL }() if lk != nil { return } lc := app.NewRedisLock(s.Ctx, ckey.FissionUserDyLinkOnce(user.ID, mark)).Lock() defer lc.Release() if err != nil { err = workerr.BusyError return } lk, err = m.WithContext(s.Ctx).Where(m.UserID.Eq(user.ID), m.LinkMark.Eq(mark)).Take() if err = dbcheck.DbError(err); err != nil { err = s.BE().MysqlError(err) return } if lk != nil { return } lk = withdefault.FissionUserDylink(&model.FissionUserDylink{ CampaignID: cpn.ID, UserID: user.ID, LinkMark: mark, Params: b.ToString(), }) link := blink.NewCampaignLink(project.Domain, cpn.HashID, channel.Mark, blink.SetSubUserId(user.SubUserID), blink.SetDyLinkId(lk.HashID)).CampaignDynamicLink() res, err := app.NewShortLinkNameLink().CreateShortLink(s.Ctx, &linkpb.CreateShortLinkReq{ LongLink: link, Domain: project.Domain, }) if err != nil { return } lk.LinkURL = res.GetShortLink() if err = m.WithContext(s.Ctx).Create(lk); err != nil { err = s.BE().MysqlError(err) return } return }