go-common/app/interface/main/app-view/service/view/contain.go
2019-04-22 18:49:16 +08:00

1004 lines
25 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package view
import (
"context"
"encoding/json"
"fmt"
"hash/crc32"
"sort"
"time"
"go-common/app/interface/main/app-view/model"
"go-common/app/interface/main/app-view/model/ad"
"go-common/app/interface/main/app-view/model/bangumi"
"go-common/app/interface/main/app-view/model/game"
"go-common/app/interface/main/app-view/model/manager"
"go-common/app/interface/main/app-view/model/tag"
"go-common/app/interface/main/app-view/model/view"
account "go-common/app/service/main/account/model"
"go-common/app/service/main/archive/api"
"go-common/app/service/main/archive/model/archive"
location "go-common/app/service/main/location/model"
thumbup "go-common/app/service/main/thumbup/model"
"go-common/app/service/openplatform/pgc-season/api/grpc/season/v1"
"go-common/library/ecode"
"go-common/library/log"
"go-common/library/sync/errgroup"
)
var (
_rate = map[int]int64{15: 464, 16: 464, 32: 1028, 48: 1328, 64: 2192, 74: 3192, 80: 3192, 112: 6192, 116: 6192, 66: 1820}
)
const (
_dmformat = "http://comment.bilibili.com/%d.xml"
_qn480 = 32
_qnAndroidBuildGt = 5325000
_qnIosBuildGt = 8170
_qnAndroidBuildLt = 5335000
_qnIosBuildLt = 8190
)
// initReqUser init Req User
func (s *Service) initReqUser(c context.Context, v *view.View, mid int64, plat int8, build int) {
const (
_androidOld = 427000
_iosOld = 4000
_ipadOld = 4300
_ipadHD = 10410
)
// owner ext
var (
owners []int64
cards map[int64]*account.Card
fls map[int64]int8
)
g, ctx := errgroup.WithContext(c)
if v.Author.Mid > 0 {
owners = append(owners, v.Author.Mid)
for _, staffInfo := range v.StaffInfo {
owners = append(owners, staffInfo.Mid)
}
g.Go(func() (err error) {
v.OwnerExt.OfficialVerify.Type = -1
cards, err = s.accDao.Cards3(ctx, owners)
if err != nil {
log.Error("%+v", err)
err = nil
return
}
if card, ok := cards[v.Author.Mid]; ok && card != nil {
otp := -1
odesc := ""
if card.Official.Role != 0 {
if card.Official.Role <= 2 {
otp = 0
} else {
otp = 1
}
odesc = card.Official.Title
}
v.OwnerExt.OfficialVerify.Type = otp
v.OwnerExt.OfficialVerify.Desc = odesc
v.OwnerExt.Vip.Type = int(card.Vip.Type)
v.OwnerExt.Vip.VipStatus = int(card.Vip.Status)
v.OwnerExt.Vip.DueDate = card.Vip.DueDate
v.Author.Name = card.Name
v.Author.Face = card.Face
}
if l, ok := s.liveCache[v.Author.Mid]; ok {
v.OwnerExt.Live = l
}
return
})
g.Go(func() (err error) {
stat, err := s.relDao.Stat(c, v.Author.Mid)
if err != nil {
log.Error("%+v", err)
err = nil
return
}
if stat != nil {
v.OwnerExt.Fans = int(stat.Follower)
}
return
})
g.Go(func() error {
if ass, err := s.assDao.Assist(ctx, v.Author.Mid); err != nil {
log.Error("%+v", err)
} else {
v.OwnerExt.Assists = ass
}
return nil
})
}
// req user
v.ReqUser = &view.ReqUser{Favorite: 0, Attention: -999, Like: 0, Dislike: 0}
// check req user
if mid > 0 {
g.Go(func() error {
var is bool
if (model.IsAndroid(plat) && build < _androidOld) || (model.IsIPhone(plat) && build < _iosOld) || ((plat == model.PlatIPad && build < _ipadOld) || (plat == model.PlatIpadHD && build < _ipadHD) || (plat == model.PlatIPadI)) {
is, _ = s.favDao.IsFavDefault(ctx, mid, v.Aid)
} else {
is, _ = s.favDao.IsFav(ctx, mid, v.Aid)
}
if is {
v.ReqUser.Favorite = 1
}
return nil
})
g.Go(func() error {
res, err := s.thumbupDao.HasLike(ctx, mid, _businessLike, []int64{v.Aid})
if err != nil {
log.Error("s.thumbupDao.HasLike err(%+v)", err)
return nil
}
if res.States == nil {
return nil
}
if typ, ok := res.States[v.Aid]; ok {
if typ.State == thumbup.StateLike {
v.ReqUser.Like = 1
} else if typ.State == thumbup.StateDislike {
v.ReqUser.Dislike = 1
}
}
return nil
})
g.Go(func() (err error) {
res, err := s.coinDao.ArchiveUserCoins(ctx, v.Aid, mid, _avTypeAv)
if err != nil {
log.Error("%+v", err)
err = nil
}
if res != nil && res.Multiply > 0 {
v.ReqUser.Coin = 1
}
return
})
if v.Author.Mid > 0 {
g.Go(func() error {
fls = s.accDao.IsAttention(ctx, owners, mid)
if _, ok := fls[v.Author.Mid]; ok {
v.ReqUser.Attention = 1
}
return nil
})
}
}
if err := g.Wait(); err != nil {
log.Error("%+v", err)
}
// fill staff
for _, owner := range owners {
if card, ok := cards[owner]; ok && card != nil {
staff := &view.Staff{Mid: owner}
if owner == v.Author.Mid {
staff.Title = "UP主"
} else {
for _, s := range v.StaffInfo {
if s.Mid == owner {
staff.Title = s.Title
}
}
}
staff.Name = card.Name
staff.Face = card.Face
staff.OfficialVerify.Type = -1
otp := -1
odesc := ""
if card.Official.Role != 0 {
if card.Official.Role <= 2 {
otp = 0
} else {
otp = 1
}
odesc = card.Official.Title
}
staff.OfficialVerify.Type = otp
staff.OfficialVerify.Desc = odesc
staff.Vip.Type = int(card.Vip.Type)
staff.Vip.VipStatus = int(card.Vip.Status)
staff.Vip.DueDate = card.Vip.DueDate
if _, ok := fls[owner]; ok {
staff.Attention = 1
}
v.Staff = append(v.Staff, staff)
}
}
}
func (s *Service) initRelateCMTag(c context.Context, v *view.View, plat int8, build, qn, fnver, fnval, forceHost, parentMode int, mid int64, buvid, mobiApp, device, network, adExtra, from string, now time.Time) {
const (
_iPhoneRelateGame = 6500
_androidRelateGame = 5210000
)
var (
rls []*view.Relate
aidm map[int64]struct{}
mr *manager.Relate
rGameID, cGameID int64
advert *ad.Ad
adm map[int]*ad.AdInfo
relateRsc int64
cmRsc int64
err error
adminfo json.RawMessage
hasDalao int
dalaoExp int
)
tids := s.initTag(c, v, mid, plat)
g, ctx := errgroup.WithContext(c)
g.Go(func() (err error) {
if mid > 0 || buvid != "" {
if rls, v.UserFeature, v.ReturnCode, hasDalao, dalaoExp, err = s.newRcmdRelate(ctx, plat, v.Aid, mid, buvid, mobiApp, from, build, qn, fnver, fnval, forceHost, parentMode); err != nil {
log.Error("s.newRcmdRelate(%d) error(%+v)", v.Aid, err)
}
}
if len(rls) == 0 {
rls, _, err = s.dealRcmdRelate(ctx, plat, v.Aid, build)
log.Warn("s.dealRcmdRelate aid(%d) mid(%d) buvid(%s)", v.Aid, mid, buvid)
} else {
v.IsRec = 1
log.Warn("s.newRcmdRelate returncode(%s) aid(%d) mid(%d) buvid(%s) hasDalao(%d) dalaoExp(%d)", v.ReturnCode, v.Aid, mid, buvid, hasDalao, dalaoExp)
}
err = nil
return
})
if !model.IsIPad(plat) {
g.Go(func() (err error) {
const (
_iphoneRelateRsc = 2029
_androidRelateRsc = 2028
_iphoneCMRsc = 2335
_androidCMRsc = 2337
)
if model.IsIPhone(plat) {
relateRsc = _iphoneRelateRsc
cmRsc = _iphoneCMRsc
} else {
relateRsc = _androidRelateRsc
cmRsc = _androidCMRsc
}
if advert, err = s.adDao.Ad(ctx, mobiApp, device, buvid, build, mid, v.Author.Mid, v.Aid, v.TypeID, tids, []int64{relateRsc, cmRsc}, network, adExtra); err != nil {
log.Error("%+v", err)
err = nil
}
return
})
if v.OrderID > 0 {
g.Go(func() (err error) {
if adminfo, err = s.adDao.MonitorInfo(ctx, v.Aid); err != nil {
log.Error("%+v", err)
err = nil
}
return
})
}
}
if dalaoExp != 1 {
g.Go(func() (err error) {
mr = s.relateCache(ctx, plat, build, now, v.Aid, tids, v.TypeID)
return
})
}
if (plat == model.PlatAndroid && build >= _androidRelateGame) || (plat == model.PlatIPhone && build >= _iPhoneRelateGame) || plat == model.PlatIPhoneB {
if buvid != "" && crc32.ChecksumIEEE([]byte(buvid))%10 == 1 {
g.Go(func() (err error) {
rGameID = s.relateGame(ctx, v.Aid)
return
})
}
if v.AttrVal(archive.AttrBitIsPorder) == archive.AttrYes || v.OrderID > 0 {
g.Go(func() (err error) {
if cGameID, err = s.arcDao.Commercial(ctx, v.Aid); err != nil {
log.Error("%+v", err)
err = nil
}
return
})
}
}
if err = g.Wait(); err != nil {
log.Error("%+v", err)
return
}
//ad config
if advert != nil {
if advert.AdsControl != nil {
v.CMConfig = &view.CMConfig{
AdsControl: advert.AdsControl,
}
}
}
if adminfo != nil {
if v.CMConfig == nil {
v.CMConfig = &view.CMConfig{
MonitorInfo: adminfo,
}
} else {
v.CMConfig.MonitorInfo = adminfo
}
}
//ad
if len(rls) == 0 {
s.prom.Incr("zero_relates")
return
}
var (
r *view.Relate
rm map[int]*view.Relate
)
if advert != nil {
if adm, err = s.dealCM(c, advert, relateRsc); err != nil {
log.Error("%+v", err)
}
initCM(c, v, advert, cmRsc)
}
//ai已经有dalao卡则直接返回没有则看要不要第一位拼接其他卡
if hasDalao == 1 {
v.Relates = rls
return
}
if dalaoExp != 1 {
if r, err = s.dealManagerRelate(c, plat, mr, build); err != nil {
log.Error("%+v", err)
}
}
if r == nil {
if r, err = s.dealGame(c, plat, cGameID, model.FromOrder); err != nil {
log.Error("%+v", err)
}
}
if r == nil {
if r, err = s.dealGame(c, plat, rGameID, model.FromRcmd); err != nil {
log.Error("%+v", err)
}
}
if r != nil {
rm = map[int]*view.Relate{0: r}
aidm = map[int64]struct{}{r.Aid: struct{}{}}
} else if len(adm) != 0 {
rm = make(map[int]*view.Relate, len(adm))
for idx, ad := range adm {
r = &view.Relate{}
r.FromCM(ad)
rm[idx] = r
}
}
if len(rm) != 0 {
var tmp []*view.Relate
for _, rl := range rls {
if _, ok := aidm[rl.Aid]; ok {
continue
}
tmp = append(tmp, rl)
}
v.Relates = make([]*view.Relate, 0, len(tmp)+len(rm))
for _, rl := range tmp {
LABEL:
if r, ok := rm[len(v.Relates)]; ok {
if r.IsAdLoc && r.AdCb == "" {
rel := &view.Relate{}
*rel = *rl
rel.IsAdLoc = r.IsAdLoc
rel.RequestID = r.RequestID
rel.SrcID = r.SrcID
rel.ClientIP = r.ClientIP
rel.AdIndex = r.AdIndex
rel.Extra = r.Extra
rel.CardIndex = r.CardIndex
v.Relates = append(v.Relates, rel)
} else if r.Aid != v.Aid {
v.Relates = append(v.Relates, r)
goto LABEL
} else {
v.Relates = append(v.Relates, rl)
}
} else {
v.Relates = append(v.Relates, rl)
}
}
} else {
v.Relates = rls
}
}
func initCM(c context.Context, v *view.View, advert *ad.Ad, resource int64) {
ads, _ := advert.Convert(resource)
sort.Sort(ad.AdInfos(ads))
if len(ads) == 0 {
return
}
v.CMs = make([]*view.CM, 0, len(ads))
for _, ad := range ads {
cm := &view.CM{}
cm.FromCM(ad)
v.CMs = append(v.CMs, cm)
}
}
func (s *Service) initMovie(c context.Context, v *view.View, mid int64, build int, mobiApp, device string, nMovie bool) (err error) {
s.pHit.Incr("is_movie")
var m *bangumi.Movie
if m, err = s.banDao.Movie(c, v.Aid, mid, build, mobiApp, device); err != nil || m == nil {
log.Error("%+v", err)
err = ecode.NothingFound
s.pMiss.Incr("err_is_PGC")
return
}
if v.Rights.HD5 == 1 && m.PayUser.Status == 0 && !s.checkVIP(c, mid) {
v.Rights.HD5 = 0
}
if len(m.List) == 0 {
err = ecode.NothingFound
return
}
vps := make([]*view.Page, 0, len(m.List))
for _, l := range m.List {
vp := &view.Page{
Page3: &archive.Page3{Cid: l.Cid, Page: int32(l.Page), From: l.Type, Part: l.Part, Vid: l.Vid},
}
vps = append(vps, vp)
}
m.List = nil
// view
v.Pages = vps
v.Rights.Download = int32(m.AllowDownload)
m.AllowDownload = 0
v.Rights.Bp = 0
if nMovie {
v.Movie = m
v.Desc = m.Season.Evaluate
}
return
}
func (s *Service) initPGC(c context.Context, v *view.View, mid int64, build int, mobiApp, device string) (err error) {
s.pHit.Incr("is_PGC")
var season *bangumi.Season
if season, err = s.banDao.PGC(c, v.Aid, mid, build, mobiApp, device); err != nil {
log.Error("%+v", err)
err = ecode.NothingFound
s.pMiss.Incr("err_is_PGC")
return
}
if season != nil {
if season.Player != nil {
if len(v.Pages) != 0 {
if season.Player.Cid != 0 {
v.Pages[0].Cid = season.Player.Cid
}
if season.Player.From != "" {
v.Pages[0].From = season.Player.From
}
if season.Player.Vid != "" {
v.Pages[0].Vid = season.Player.Vid
}
}
season.Player = nil
}
if season.AllowDownload == "1" {
v.Rights.Download = 1
} else {
v.Rights.Download = 0
}
if season.SeasonID != "" {
season.AllowDownload = ""
v.Season = season
}
}
if v.Rights.HD5 == 1 && !s.checkVIP(c, mid) {
v.Rights.HD5 = 0
}
v.Rights.Bp = 0
return
}
func (s *Service) initPages(c context.Context, vs *view.ViewStatic, ap []*archive.Page3) {
pages := make([]*view.Page, 0, len(ap))
for _, v := range ap {
page := &view.Page{}
metas := make([]*view.Meta, 0, 4)
for q, r := range _rate {
meta := &view.Meta{
Quality: q,
Size: int64(float64(r*v.Duration) * 1.1 / 8.0),
}
metas = append(metas, meta)
}
if vs.AttrVal(archive.AttrBitIsBangumi) == archive.AttrYes {
v.From = "bangumi"
}
page.Page3 = v
page.Metas = metas
page.DMLink = fmt.Sprintf(_dmformat, v.Cid)
pages = append(pages, page)
}
vs.Pages = pages
}
func (s *Service) initDownload(c context.Context, v *view.View, mid int64, cdnIP string) (err error) {
var download int64
if v.AttrVal(archive.AttrBitLimitArea) == archive.AttrYes {
if download, err = s.ipLimit(c, mid, v.Aid, cdnIP); err != nil {
return
}
} else {
download = location.AllowDown
}
if download == location.ForbiddenDown {
v.Rights.Download = int32(download)
return
}
for _, p := range v.Pages {
if p.From == "qq" {
download = location.ForbiddenDown
break
}
}
v.Rights.Download = int32(download)
return
}
func (s *Service) initUGCPay(c context.Context, v *view.View, plat int8, mid int64) (err error) {
var (
asset *view.Asset
platform = model.Platform(plat)
)
if asset, err = s.ugcpayDao.AssetRelationDetail(c, mid, v.Aid, platform); err != nil {
log.Error("%+v", err)
return
}
if asset != nil {
v.Asset = asset
}
return
}
func (s *Service) initContributions(c context.Context, v *view.View) {
const _count = 5
if v.ReqUser != nil && v.ReqUser.Attention == 1 {
return
}
var hasAudio bool
for _, page := range v.Pages {
if page.Audio != nil {
hasAudio = true
break
}
}
if hasAudio || v.OwnerExt.Archives < 20 {
return
}
aids, err := s.arcDao.ViewContributeCache(c, v.Author.Mid)
if err != nil {
log.Error("%+v", err)
return
}
if len(aids) < _count+1 {
return
}
as, err := s.arcDao.Archives(c, aids)
if err != nil {
log.Error("%+v", err)
return
}
if len(as) == 0 {
return
}
ctbt := make([]*view.Contribution, 0, len(as))
for _, aid := range aids {
if a, ok := as[aid]; ok && a.IsNormal() {
if a.Aid != v.Aid {
vc := &view.Contribution{Aid: a.Aid, Title: a.Title, Pic: a.Pic, Author: a.Author, Stat: a.Stat, CTime: a.PubDate}
ctbt = append(ctbt, vc)
}
}
}
if len(ctbt) > _count {
ctbt = ctbt[:_count]
}
if len(ctbt) == _count {
v.Contributions = ctbt
}
}
func (s *Service) initAudios(c context.Context, v *view.View) {
pLen := len(v.Pages)
if pLen == 0 || pLen > 100 {
return
}
if pLen > 50 {
pLen = 50
}
cids := make([]int64, 0, len(v.Pages[:pLen]))
for _, p := range v.Pages[:pLen] {
cids = append(cids, p.Cid)
}
vam, err := s.audioDao.AudioByCids(c, cids)
if err != nil {
log.Error("%+v", err)
return
}
if len(vam) != 0 {
for _, p := range v.Pages[:pLen] {
if va, ok := vam[p.Cid]; ok {
p.Audio = va
}
}
if len(v.Pages) == 1 {
if va, ok := vam[v.Pages[0].Cid]; ok {
v.Audio = va
}
}
}
}
func (s *Service) initElec(c context.Context, v *view.View, mid int64) {
if _, ok := s.allowTypeIds[int16(v.TypeID)]; !ok || int8(v.Copyright) != archive.CopyrightOriginal {
return
}
info, err := s.elcDao.Info(c, v.Author.Mid, mid)
if err != nil {
log.Error("%+v", err)
return
}
if info != nil {
v.Rights.Elec = 1
info.Show = true
v.Elec = info
}
}
func (s *Service) initTag(c context.Context, v *view.View, mid int64, plat int8) (tids []int64) {
var (
actTag []*tag.Tag
arcTag []*tag.Tag
actTagName string
)
if v.MissionID > 0 {
protocol, err := s.actDao.ActProtocol(c, v.MissionID)
if err != nil {
log.Error("s.actDao.ActProtocol err(%+v)", err)
err = nil
} else {
if protocol.SubjectItem != nil {
v.ActivityURL = protocol.SubjectItem.AndroidURL
if model.IsIOS(plat) {
v.ActivityURL = protocol.SubjectItem.IosURL
}
}
if protocol.ActSubjectProtocol != nil {
actTagName = protocol.ActSubjectProtocol.Tags
}
}
}
tags, err := s.tagDao.ArcTags(c, v.Aid, mid)
if err != nil {
log.Error("s.tagDao.ArcTags err(%+v)", err)
return
}
tids = make([]int64, 0, len(tags))
for _, t := range tags {
if actTagName == t.Name {
t.IsActivity = 1
actTag = append(actTag, t)
} else {
arcTag = append(arcTag, t)
}
tids = append(tids, t.TagID)
}
//活动稿件tag放在第一位
v.Tag = append(actTag, arcTag...)
return
}
func (s *Service) initDM(c context.Context, v *view.View) {
const (
_dmTypeAv = 1
_dmPlatMobie = 1
)
pLen := len(v.Pages)
if pLen == 0 || pLen > 100 {
return
}
if pLen > 50 {
pLen = 50
}
cids := make([]int64, 0, len(v.Pages[:pLen]))
for _, p := range v.Pages[:pLen] {
cids = append(cids, p.Cid)
}
res, err := s.dmDao.SubjectInfos(c, _dmTypeAv, _dmPlatMobie, cids...)
if err != nil {
log.Error("%+v", err)
return
}
if len(res) == 0 {
return
}
for _, p := range v.Pages[:pLen] {
if r, ok := res[p.Cid]; ok {
p.DM = r
}
}
}
func (s *Service) dealCM(c context.Context, advert *ad.Ad, resource int64) (adm map[int]*ad.AdInfo, err error) {
ads, aids := advert.Convert(resource)
if len(ads) == 0 {
return
}
adm = make(map[int]*ad.AdInfo, len(ads))
for _, ad := range ads {
adm[ad.CardIndex-1] = ad
}
if len(aids) == 0 {
return
}
as, err := s.arcDao.Archives(c, aids)
if err != nil {
log.Error("%+v", err)
err = nil
return
}
for _, ad := range adm {
if ad.Goto == model.GotoAv && ad.CreativeContent != nil {
if a, ok := as[ad.CreativeContent.VideoID]; ok {
ad.View = int(a.Stat.View)
ad.Danmaku = int(a.Stat.Danmaku)
if ad.CreativeContent.Desc == "" {
ad.CreativeContent.Desc = a.Desc
}
ad.URI = model.FillURI(ad.Goto, ad.Param, model.AvHandler(a, "", nil))
}
}
}
return
}
func (s *Service) dealRcmdRelate(c context.Context, plat int8, aid int64, build int) (rls []*view.Relate, aidm map[int64]struct{}, err error) {
if rls, err = s.arcDao.RelatesCache(c, aid); err != nil {
return
}
if len(rls) != 0 {
aidm = make(map[int64]struct{}, len(rls))
for _, rl := range rls {
if rl.Aid != 0 {
aidm[rl.Aid] = struct{}{}
}
}
return
}
s.prom.Incr("need_relates")
var aids []int64
if aids, err = s.arcDao.RelateAids(c, aid); err != nil {
return
}
if len(aids) == 0 {
return
}
var as map[int64]*api.Arc
if as, err = s.arcDao.Archives(c, aids); err != nil {
return
}
aidm = make(map[int64]struct{}, len(as))
for _, aid := range aids {
if a, ok := as[aid]; ok {
if s.overseaCheck(archive.BuildArchive3(a), plat) || !a.IsNormal() {
continue
}
r := &view.Relate{}
var cooperation bool
if (model.IsAndroid(plat) && build > s.c.BuildLimit.CooperationAndroid) || (model.IsIPhone(plat) && build > s.c.BuildLimit.CooperationIOS) {
cooperation = true
}
r.FromAv(a, "", "", nil, cooperation)
rls = append(rls, r)
aidm[aid] = struct{}{}
}
}
if len(rls) != 0 {
s.arcDao.AddRelatesCache(aid, rls)
}
return
}
func (s *Service) dealManagerRelate(c context.Context, plat int8, mr *manager.Relate, build int) (r *view.Relate, err error) {
if mr == nil || mr.Param < 1 {
return
}
var cooperation bool
if (model.IsAndroid(plat) && build > s.c.BuildLimit.CooperationAndroid) || (model.IsIPhone(plat) && build > s.c.BuildLimit.CooperationIOS) {
cooperation = true
}
switch mr.Goto {
case model.GotoAv:
var a *api.Arc
if a, err = s.arcDao.Archive3(c, mr.Param); err != nil {
return
}
if a != nil {
r = &view.Relate{}
r.FromOperateOld(mr, a, nil, nil, model.FromOperation, cooperation)
}
case model.GotoGame:
var info *game.Info
if info, err = s.gameDao.Info(c, mr.Param, plat); err != nil {
return
}
if info != nil && info.IsOnline {
r = &view.Relate{}
r.FromOperateOld(mr, nil, info, nil, model.FromOperation, cooperation)
}
case model.GotoSpecial:
if sp, ok := s.specialCache[mr.Param]; ok {
r = &view.Relate{}
r.FromOperateOld(mr, nil, nil, sp, model.FromOperation, cooperation)
}
}
return
}
func (s *Service) dealGame(c context.Context, plat int8, id int64, from string) (r *view.Relate, err error) {
if id < 1 {
return
}
var info *game.Info
if info, err = s.gameDao.Info(c, id, plat); err != nil {
return
}
if info != nil && info.IsOnline {
r = &view.Relate{}
r.FromGame(info, from)
}
return
}
func (s *Service) newRcmdRelate(c context.Context, plat int8, aid, mid int64, buvid, mobiApp, from string, build, qn, fnver, fnval, forceHost, parentMode int) (rls []*view.Relate, userFeature, returnCode string, hasDalao, dalaoExp int, err error) {
recData, userFeature, returnCode, dalaoExp, err := s.arcDao.NewRelateAids(c, aid, mid, build, parentMode, buvid, from, plat)
if err != nil || len(recData) == 0 {
return
}
var (
aids []int64
ssIDs []int32
gameID int64
specialID int64
arcm map[int64]*api.Arc
banm map[int32]*v1.CardInfoProto
gameInfo *game.Info
)
for _, rec := range recData {
switch rec.Goto {
case model.GotoAv:
aids = append(aids, rec.Oid)
case model.GotoBangumi:
ssIDs = append(ssIDs, int32(rec.Oid))
case model.GotoGame:
gameID = rec.Oid
case model.GotoSpecial:
specialID = rec.Oid
}
}
eg := errgroup.Group{}
if len(aids) > 0 {
eg.Go(func() (err error) {
if arcm, err = s.arcDao.Archives(context.Background(), aids); err != nil {
log.Error("s.arcDao.Archives err(%+v)", err)
}
return
})
}
if len(ssIDs) > 0 {
eg.Go(func() (err error) {
if banm, err = s.banDao.CardsInfoReply(context.Background(), ssIDs); err != nil {
log.Error("s.banDao.CardsInfoReply err(%+v)", err)
}
return
})
}
if gameID > 0 {
eg.Go(func() (err error) {
if gameInfo, err = s.gameDao.Info(c, gameID, plat); err != nil {
log.Error("s.gameDao.Info err(%+v)", err)
}
return
})
}
eg.Wait()
players := make(map[int64]*archive.PlayerInfo)
if (model.IsAndroid(plat) && build > _qnAndroidBuildGt) || (model.IsIOSNormal(plat) && build > _qnIosBuildGt) || model.IsIPhoneB(plat) {
var cids []int64
if aid%100 < s.c.RelateGray {
for k, v := range aids {
if k == s.c.RelateCnt {
break
}
if arcm[v].Rights.Autoplay == 1 {
cids = append(cids, arcm[v].FirstCid)
}
}
}
if len(cids) > 0 {
playerInfo := make(map[uint32]*archive.BvcVideoItem)
if (model.IsAndroid(plat) && build < _qnAndroidBuildLt) || (model.IsIOSNormal(plat) && build <= _qnIosBuildLt) || qn <= 0 {
qn = _qn480
}
if playerInfo, err = s.arcDao.PlayerInfos(c, cids, qn, fnver, fnval, forceHost, mobiApp); err != nil {
log.Error("%+v", err)
err = nil
} else if len(playerInfo) > 0 {
for k, pi := range playerInfo {
cid := int64(k)
players[cid] = new(archive.PlayerInfo)
players[cid].Cid = pi.Cid
players[cid].ExpireTime = pi.ExpireTime
players[cid].FileInfo = make(map[int][]*archive.PlayerFileInfo)
for qn, files := range pi.FileInfo {
for _, f := range files.Infos {
players[cid].FileInfo[int(qn)] = append(players[cid].FileInfo[int(qn)], &archive.PlayerFileInfo{
FileSize: f.Filesize,
TimeLength: f.Timelength,
})
}
}
players[cid].SupportQuality = pi.SupportQuality
players[cid].SupportFormats = pi.SupportFormats
players[cid].SupportDescription = pi.SupportDescription
players[cid].Quality = pi.Quality
players[cid].URL = pi.Url
players[cid].VideoCodecid = pi.VideoCodecid
players[cid].VideoProject = pi.VideoProject
players[cid].Fnver = pi.Fnver
players[cid].Fnval = pi.Fnval
players[cid].Dash = pi.Dash
}
}
}
}
var cooperation bool
if (model.IsAndroid(plat) && build > s.c.BuildLimit.CooperationAndroid) || (model.IsIPhone(plat) && build > s.c.BuildLimit.CooperationIOS) {
cooperation = true
}
for _, rec := range recData {
r := &view.Relate{AvFeature: rec.AvFeature, Source: rec.Source, TrackID: rec.TrackID}
switch rec.Goto {
case model.GotoAv:
arc, ok := arcm[rec.Oid]
if !ok || s.overseaCheck(archive.BuildArchive3(arc), plat) || !arc.IsNormal() {
continue
}
if rec.IsDalao == 1 {
r.FromOperate(rec, arc, nil, nil, model.FromOperation, cooperation)
} else {
r.FromAv(arc, "", rec.TrackID, players[arc.FirstCid], cooperation)
}
case model.GotoBangumi:
ban, ok := banm[int32(rec.Oid)]
if !ok {
continue
}
r.FromBangumi(ban)
case model.GotoGame:
if gameInfo == nil || !gameInfo.IsOnline {
continue
}
r.FromOperate(rec, nil, gameInfo, nil, model.FromOperation, cooperation)
case model.GotoSpecial:
sp, ok := s.specialCache[specialID]
if !ok {
continue
}
r.FromOperate(rec, nil, nil, sp, model.FromOperation, cooperation)
}
if rec.IsDalao == 1 {
hasDalao = 1
}
rls = append(rls, r)
}
return
}