776 lines
22 KiB
Go
776 lines
22 KiB
Go
package service
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"strconv"
|
|
"time"
|
|
|
|
dm2mdl "go-common/app/interface/main/dm2/model"
|
|
tagmdl "go-common/app/interface/main/tag/model"
|
|
"go-common/app/interface/main/web/model"
|
|
accmdl "go-common/app/service/main/account/api"
|
|
infomdl "go-common/app/service/main/account/model"
|
|
arcmdl "go-common/app/service/main/archive/api"
|
|
"go-common/app/service/main/archive/model/archive"
|
|
coinmdl "go-common/app/service/main/coin/api"
|
|
favmdl "go-common/app/service/main/favorite/model"
|
|
locmdl "go-common/app/service/main/location/model"
|
|
sharemdl "go-common/app/service/main/share/api"
|
|
thumbup "go-common/app/service/main/thumbup/model"
|
|
ugcmdl "go-common/app/service/main/ugcpay/api/grpc/v1"
|
|
"go-common/library/conf/env"
|
|
"go-common/library/ecode"
|
|
"go-common/library/log"
|
|
"go-common/library/log/infoc"
|
|
"go-common/library/net/metadata"
|
|
"go-common/library/sync/errgroup"
|
|
)
|
|
|
|
var (
|
|
_emptyTags = make([]*tagmdl.Tag, 0)
|
|
_emptyReplyHot = new(model.ReplyHot)
|
|
_emptyArchive3 = make([]*arcmdl.Arc, 0)
|
|
_emptyArc = make([]*arcmdl.Arc, 0)
|
|
)
|
|
|
|
const (
|
|
_japan = "日本"
|
|
_businessAppeal = 1
|
|
_notForward = 0
|
|
_member = 10000
|
|
_viewBakCacheRand = 10
|
|
_shareArcType = 3
|
|
_hasUGCPay = 1
|
|
_ugcOtypeArc = "archive"
|
|
_ugcCurrencyBp = "bp"
|
|
_ugcAssetPaid = "paid"
|
|
_ugcPaidState = 1
|
|
)
|
|
|
|
// View get a view page by aid.
|
|
func (s *Service) View(c context.Context, aid, cid, mid int64, cdnIP, ck string) (rs *model.View, err error) {
|
|
var (
|
|
viewReply *arcmdl.ViewReply
|
|
video *arcmdl.Page
|
|
longDesc string
|
|
pDesc, forward, report bool
|
|
remoteIP = metadata.String(c, metadata.RemoteIP)
|
|
)
|
|
if viewReply, err = s.arcClient.View(c, &arcmdl.ViewRequest{Aid: aid}); err != nil {
|
|
log.Error("s.arcClient.View(%d) error %v", aid, err)
|
|
return
|
|
}
|
|
if viewReply != nil && viewReply.Arc != nil {
|
|
if _, ok := s.specialMids[viewReply.Arc.Author.Mid]; ok && env.DeployEnv == env.DeployEnvProd {
|
|
err = ecode.NothingFound
|
|
log.Warn("aid(%d) mid(%d) can not view on prod", viewReply.Arc.Aid, viewReply.Arc.Author.Mid)
|
|
return
|
|
}
|
|
if viewReply.Arc.FirstCid == 0 {
|
|
if len(viewReply.Pages) > 0 {
|
|
viewReply.Arc.FirstCid = viewReply.Pages[0].Cid
|
|
}
|
|
}
|
|
if viewReply.Arc.State == archive.StateForbidLock && viewReply.Arc.Forward > 0 {
|
|
forward = true
|
|
} else if viewReply.Arc.State == archive.StateForbidRecicle || viewReply.Arc.State == archive.StateForbidLock {
|
|
if viewReply.Arc.ReportResult == "" {
|
|
err = ecode.NothingFound
|
|
return
|
|
}
|
|
report = true
|
|
}
|
|
check := []int32{archive.StateForbidWait, archive.StateForbidFixed, archive.StateForbidLater, archive.StateForbidAdminDelay}
|
|
for _, v := range check {
|
|
if viewReply.Arc.State == v {
|
|
err = ecode.ArchiveChecking
|
|
return
|
|
}
|
|
}
|
|
if viewReply.Arc.State == archive.StateForbidUserDelay {
|
|
err = ecode.ArchivePass
|
|
return
|
|
} else if !viewReply.Arc.IsNormal() && !forward && !report {
|
|
err = ecode.ArchiveDenied
|
|
return
|
|
}
|
|
rs = &model.View{Arc: viewReply.Arc, Pages: viewReply.Pages}
|
|
group, errCtx := errgroup.WithContext(c)
|
|
if !forward && !report {
|
|
group.Go(func() error {
|
|
return s.zlimit(errCtx, rs, mid, remoteIP, cdnIP)
|
|
})
|
|
group.Go(func() error {
|
|
return s.checkAccess(errCtx, mid, rs, ck, remoteIP)
|
|
})
|
|
}
|
|
group.Go(func() error {
|
|
dmCid := cid
|
|
if dmCid == 0 {
|
|
dmCid = viewReply.Arc.FirstCid
|
|
}
|
|
rs.Subtitle = s.dmSubtitle(errCtx, aid, dmCid)
|
|
return nil
|
|
})
|
|
if rs.Arc.Rights.UGCPay == _hasUGCPay {
|
|
rs.Asset = s.ugcPayAsset(errCtx, aid, mid)
|
|
}
|
|
if err = group.Wait(); err != nil {
|
|
return
|
|
}
|
|
if cid > 0 {
|
|
if video, err = s.arc.Video3(c, &archive.ArgVideo2{Aid: aid, Cid: cid, RealIP: remoteIP}); err != nil {
|
|
err = nil
|
|
log.Error("s.arc.Video3(%d,%d,%s) error %v", aid, cid, remoteIP, err)
|
|
}
|
|
if video.Desc != "" {
|
|
rs.Desc = video.Desc
|
|
pDesc = true
|
|
}
|
|
}
|
|
if !pDesc {
|
|
if longDesc, err = s.arc.Description2(c, &archive.ArgAid{Aid: aid, RealIP: remoteIP}); err != nil {
|
|
err = nil
|
|
log.Error("view s.arc.Description2(%d) error(%v)", aid, err)
|
|
} else if longDesc != "" {
|
|
rs.Desc = longDesc
|
|
}
|
|
}
|
|
if rs.AttrVal(archive.AttrBitIsPGC) == archive.AttrNo {
|
|
if err = s.initDownload(c, rs, mid, remoteIP, cdnIP); err != nil {
|
|
log.Error("s.initDownload aid(%d) mid(%d) ip(%s) error(%+v)", rs.Aid, mid, remoteIP, err)
|
|
err = nil
|
|
}
|
|
}
|
|
if !forward {
|
|
rs.Forward = _notForward
|
|
}
|
|
if !report {
|
|
rs.ReportResult = ""
|
|
}
|
|
if rs.AttrVal(archive.AttrBitJumpUrl) == archive.AttrNo {
|
|
rs.RedirectURL = ""
|
|
}
|
|
if rs.Access >= _member {
|
|
rs.Stat.View = -1
|
|
}
|
|
if rs.AttrVal(archive.AttrBitLimitArea) == archive.AttrYes {
|
|
rs.NoCache = true
|
|
}
|
|
s.cache.Do(c, func(c context.Context) {
|
|
if s.r.Intn(_viewBakCacheRand) == 1 {
|
|
s.dao.SetViewBakCache(c, aid, rs)
|
|
}
|
|
})
|
|
} else {
|
|
rs, err = s.dao.ViewBakCache(c, aid)
|
|
}
|
|
return
|
|
}
|
|
|
|
func (s *Service) zlimit(c context.Context, view *model.View, mid int64, remoteIP, cdnIP string) (err error) {
|
|
var data *int64
|
|
if data, err = s.loc.Archive(c, &locmdl.Archive{Aid: view.Aid, Mid: mid, IP: remoteIP, CIP: cdnIP}); err != nil {
|
|
log.Error("s.loc.Archive(%d%d%s%s) error(%v)", view.Aid, mid, remoteIP, cdnIP, err)
|
|
return
|
|
}
|
|
if *data == locmdl.Forbidden {
|
|
log.Warn("s.loc.Archive aid(%d) zlimit.Forbidden", view.Aid)
|
|
err = ecode.NothingFound
|
|
} else {
|
|
err = s.specialLimit(c, view, remoteIP)
|
|
}
|
|
return
|
|
}
|
|
|
|
// specialLimit spacialLimit special type id limit in japan
|
|
func (s *Service) specialLimit(c context.Context, view *model.View, remoteIP string) (err error) {
|
|
var zone *locmdl.Info
|
|
for _, typeID := range model.LimitTypeIDs {
|
|
if int32(typeID) == view.TypeID {
|
|
// TODO all no cache
|
|
view.NoCache = true
|
|
if zone, err = s.loc.Info(c, &locmdl.ArgIP{IP: remoteIP}); err != nil || zone == nil {
|
|
log.Error("s.loc.Info(%s) error(%v) or zone is nil", remoteIP, err)
|
|
err = nil
|
|
} else if zone.Country == _japan {
|
|
err = ecode.NothingFound
|
|
}
|
|
break
|
|
}
|
|
}
|
|
return
|
|
}
|
|
|
|
// checkAccess check mid aid access
|
|
func (s *Service) checkAccess(c context.Context, mid int64, view *model.View, ck, ip string) (err error) {
|
|
var (
|
|
p *accmdl.CardReply
|
|
)
|
|
if view.Access == 0 {
|
|
return
|
|
}
|
|
view.NoCache = true
|
|
if mid <= 0 {
|
|
log.Warn("user not login aid(%d)", view.Aid)
|
|
err = ecode.AccessDenied
|
|
return
|
|
}
|
|
if p, err = s.accClient.Card3(c, &accmdl.MidReq{Mid: mid}); err != nil {
|
|
log.Error("s.accClient.Card3(%d) error(%v)", mid, err)
|
|
return
|
|
}
|
|
if p == nil {
|
|
log.Warn("Info2 result is null aid(%d) state(%d) access(%d)", view.Aid, view.State, view.Access)
|
|
err = ecode.AccessDenied
|
|
return
|
|
}
|
|
card := p.Card
|
|
isVip := (card.Vip.Type > 0) && (card.Vip.Status == 1)
|
|
if view.Access > 0 && card.Rank < view.Access && (!isVip) {
|
|
log.Warn("mid(%d) rank(%d) vip(tp:%d,status:%d) have not access(%d) view archive(%d) ", mid, card.Rank, card.Vip.Type, card.Vip.Status, view.Access, view.Aid)
|
|
if mid > 0 {
|
|
err = ecode.NothingFound
|
|
} else {
|
|
err = ecode.ArchiveNotLogin
|
|
}
|
|
}
|
|
return
|
|
}
|
|
|
|
func (s *Service) initDownload(c context.Context, v *model.View, mid int64, ip, cdnIP string) (err error) {
|
|
var download int64
|
|
if v.AttrVal(archive.AttrBitLimitArea) == archive.AttrYes {
|
|
if download, err = s.downLimit(c, mid, v.Aid, cdnIP); err != nil {
|
|
return
|
|
}
|
|
} else {
|
|
download = locmdl.AllowDown
|
|
}
|
|
if download == locmdl.ForbiddenDown {
|
|
v.Rights.Download = int32(download)
|
|
return
|
|
}
|
|
for _, p := range v.Pages {
|
|
if p.From == "qq" {
|
|
download = locmdl.ForbiddenDown
|
|
break
|
|
}
|
|
}
|
|
v.Rights.Download = int32(download)
|
|
return
|
|
}
|
|
|
|
// downLimit ip limit
|
|
func (s *Service) downLimit(c context.Context, mid, aid int64, cdnIP string) (down int64, err error) {
|
|
var (
|
|
auth *locmdl.Auth
|
|
ip = metadata.String(c, metadata.RemoteIP)
|
|
)
|
|
if auth, err = s.loc.Archive2(c, &locmdl.Archive{Aid: aid, Mid: mid, IP: ip, CIP: cdnIP}); err != nil {
|
|
log.Error("s.loc.Archive2(%d) error(%v)", mid, err)
|
|
return
|
|
}
|
|
if auth.Play == locmdl.Forbidden {
|
|
err = ecode.AccessDenied
|
|
} else {
|
|
down = auth.Down
|
|
}
|
|
return
|
|
}
|
|
|
|
func (s *Service) dmSubtitle(c context.Context, aid, cid int64) (subtitle *model.Subtitle) {
|
|
var (
|
|
dmSub *dm2mdl.VideoSubtitles
|
|
err error
|
|
mids []int64
|
|
infosReply *accmdl.InfosReply
|
|
subs []*model.SubtitleItem
|
|
)
|
|
subtitle = new(model.Subtitle)
|
|
if dmSub, err = s.dm2.SubtitleGet(c, &dm2mdl.ArgSubtitleGet{Aid: aid, Oid: cid, Type: dm2mdl.SubTypeVideo}); err != nil {
|
|
log.Warn("dmSubtitle s.dm2.SubtitleGet aid(%d) cid(%d) warn(%v)", aid, cid, err)
|
|
} else if dmSub != nil {
|
|
subtitle.AllowSubmit = dmSub.AllowSubmit
|
|
if len(dmSub.Subtitles) > 0 {
|
|
for _, v := range dmSub.Subtitles {
|
|
if v.AuthorMid > 0 {
|
|
mids = append(mids, v.AuthorMid)
|
|
}
|
|
}
|
|
infoData := make(map[int64]*infomdl.Info)
|
|
if len(mids) > 0 {
|
|
if infosReply, err = s.accClient.Infos3(c, &accmdl.MidsReq{Mids: mids, RealIp: metadata.String(c, metadata.RemoteIP)}); err != nil {
|
|
log.Error("dmSubtitle aid(%d) cid(%d) s.acc.Infos3 mids(%v) error(%v)", aid, cid, mids, err)
|
|
} else {
|
|
infoData = infosReply.Infos
|
|
}
|
|
}
|
|
for _, v := range dmSub.Subtitles {
|
|
sub := &model.SubtitleItem{VideoSubtitle: v, Author: &infomdl.Info{Mid: v.AuthorMid}}
|
|
if info, ok := infoData[v.AuthorMid]; ok && info != nil {
|
|
sub.Author = info
|
|
}
|
|
subs = append(subs, sub)
|
|
}
|
|
subtitle.List = subs
|
|
}
|
|
}
|
|
if len(subtitle.List) == 0 {
|
|
subtitle.List = make([]*model.SubtitleItem, 0)
|
|
}
|
|
return
|
|
}
|
|
|
|
// ArchiveStat get archive stat data by aid.
|
|
func (s *Service) ArchiveStat(c context.Context, aid int64) (stat *model.Stat, err error) {
|
|
var (
|
|
arcReply *arcmdl.ArcReply
|
|
view interface{}
|
|
)
|
|
if aid == s.c.Bnj2019.LiveAid && s.bnj2019LiveArc != nil {
|
|
arcReply = s.bnj2019LiveArc
|
|
} else {
|
|
if arcReply, err = s.arcClient.Arc(c, &arcmdl.ArcRequest{Aid: aid}); err != nil {
|
|
log.Error("s.arcClient.Arc(%d) error(%v)", aid, err)
|
|
return
|
|
}
|
|
}
|
|
arc := arcReply.Arc
|
|
if !model.CheckAllowState(arc) {
|
|
err = ecode.AccessDenied
|
|
return
|
|
}
|
|
view = arc.Stat.View
|
|
if arc.Access > 0 {
|
|
view = "--"
|
|
}
|
|
stat = &model.Stat{
|
|
Aid: arc.Stat.Aid,
|
|
View: view,
|
|
Danmaku: arc.Stat.Danmaku,
|
|
Reply: arc.Stat.Reply,
|
|
Fav: arc.Stat.Fav,
|
|
Coin: arc.Stat.Coin,
|
|
Share: arc.Stat.Share,
|
|
Like: arc.Stat.Like,
|
|
NowRank: arc.Stat.NowRank,
|
|
HisRank: arc.Stat.HisRank,
|
|
NoReprint: arc.Rights.NoReprint,
|
|
Copyright: arc.Copyright,
|
|
}
|
|
return
|
|
}
|
|
|
|
// AddShare share add count
|
|
func (s *Service) AddShare(c context.Context, aid, mid int64, ua, refer, path, buvid, sid string) (shares int64, err error) {
|
|
var (
|
|
shareReply *sharemdl.AddShareReply
|
|
remoteIP = metadata.String(c, metadata.RemoteIP)
|
|
)
|
|
// add Anti cheat
|
|
if s.CheatInfoc != nil {
|
|
ac := map[string]string{
|
|
"itemType": infoc.ItemTypeAv,
|
|
"action": infoc.ActionShare,
|
|
"ip": remoteIP,
|
|
"mid": strconv.FormatInt(mid, 10),
|
|
"fid": "",
|
|
"aid": strconv.FormatInt(aid, 10),
|
|
"sid": sid,
|
|
"ua": ua,
|
|
"buvid": buvid,
|
|
"refer": refer,
|
|
"url": path,
|
|
}
|
|
s.CheatInfoc.ServiceAntiCheat(ac)
|
|
}
|
|
if shareReply, err = s.shareClient.AddShare(c, &sharemdl.AddShareRequest{Oid: aid, Mid: mid, Type: _shareArcType, Ip: remoteIP}); err != nil {
|
|
log.Error("AddShare s.shareClient.AddShare (oid:%d,mid:%d) warn(%v)", aid, mid, err)
|
|
return
|
|
}
|
|
shares = shareReply.Shares
|
|
return
|
|
}
|
|
|
|
// Description get archive description by aid.
|
|
func (s *Service) Description(c context.Context, aid, page int64) (res string, err error) {
|
|
var (
|
|
viewReply *arcmdl.ViewReply
|
|
video *arcmdl.Page
|
|
cid int64
|
|
longDesc string
|
|
ip = metadata.String(c, metadata.RemoteIP)
|
|
)
|
|
if viewReply, err = s.arcClient.View(c, &arcmdl.ViewRequest{Aid: aid}); err != nil {
|
|
log.Error("s.arcClient.View(%d,%s) error %v", aid, ip, err)
|
|
return
|
|
}
|
|
if viewReply != nil && viewReply.Arc != nil {
|
|
if !viewReply.Arc.IsNormal() {
|
|
err = ecode.ArchiveDenied
|
|
return
|
|
}
|
|
}
|
|
if page > 0 {
|
|
if int(page-1) >= len(viewReply.Pages) || viewReply.Pages[page-1] == nil {
|
|
err = ecode.NothingFound
|
|
return
|
|
}
|
|
cid = viewReply.Pages[page-1].Cid
|
|
if cid > 0 {
|
|
if video, err = s.arc.Video3(c, &archive.ArgVideo2{Aid: aid, Cid: cid, RealIP: ip}); err != nil {
|
|
log.Error("s.arc.Video2(%d,%d,%s) error %v", aid, cid, ip, err)
|
|
}
|
|
if video.Desc != "" {
|
|
res = video.Desc
|
|
return
|
|
}
|
|
}
|
|
} else {
|
|
res = viewReply.Arc.Desc
|
|
}
|
|
if longDesc, err = s.arc.Description2(c, &archive.ArgAid{Aid: aid, RealIP: ip}); err != nil {
|
|
log.Error("s.arc.Description2(%d) error(%v)", aid, err)
|
|
} else if longDesc != "" {
|
|
res = longDesc
|
|
}
|
|
return
|
|
}
|
|
|
|
// ArcReport add archive report
|
|
func (s *Service) ArcReport(c context.Context, mid, aid, tp int64, reason, pics string) (err error) {
|
|
if err = s.dao.ArcReport(c, mid, aid, tp, reason, pics); err != nil {
|
|
log.Error("s.dao.ArcReport(%d,%d,%d,%s,%s) err (%v)", mid, aid, tp, reason, pics, err)
|
|
}
|
|
return
|
|
}
|
|
|
|
// AppealTags get appeal tags
|
|
func (s *Service) AppealTags(c context.Context) (rs json.RawMessage, err error) {
|
|
if rs, err = s.dao.AppealTags(c, _businessAppeal); err != nil {
|
|
log.Error("s.dao.AppealTags(1) error(%v)", err)
|
|
}
|
|
return
|
|
}
|
|
|
|
// ArcAppeal add archive appeal.
|
|
func (s *Service) ArcAppeal(c context.Context, mid int64, data map[string]string) (err error) {
|
|
aid, _ := strconv.ParseInt(data["oid"], 10, 64)
|
|
if err = s.dao.ArcAppealCache(c, mid, aid); err != nil {
|
|
if err == ecode.ArcAppealLimit {
|
|
log.Warn("s.arcAppealLimit mid(%d) aid(%d)", mid, aid)
|
|
return
|
|
}
|
|
err = nil
|
|
}
|
|
if err = s.dao.ArcAppeal(c, mid, data, _businessAppeal); err != nil {
|
|
log.Error("s.dao.ArcAppeal(%d,%v,1) error(%v)", mid, data, err)
|
|
return
|
|
}
|
|
if err = s.dao.SetArcAppealCache(c, mid, aid); err != nil {
|
|
log.Error("s.dao.SetArcAppealCache(%d,%d)", mid, aid)
|
|
err = nil
|
|
}
|
|
return
|
|
}
|
|
|
|
// AuthorRecommend get author recommend data
|
|
func (s *Service) AuthorRecommend(c context.Context, aid int64) (res []*arcmdl.Arc, err error) {
|
|
var (
|
|
arcReply *arcmdl.ArcReply
|
|
aids []int64
|
|
recArcs, upArcs []*arcmdl.Arc
|
|
arcs *arcmdl.ArcsReply
|
|
ip = metadata.String(c, metadata.RemoteIP)
|
|
)
|
|
defer func() {
|
|
if len(res) == 0 {
|
|
res = _emptyArchive3
|
|
}
|
|
}()
|
|
resAids := make(map[int64]int64)
|
|
if arcReply, err = s.arcClient.Arc(c, &arcmdl.ArcRequest{Aid: aid}); err != nil {
|
|
log.Error("s.arcClient.Arc(%d) error(%v)", aid, err)
|
|
return
|
|
}
|
|
resAids[aid] = aid
|
|
if recArcs, err = s.arc.Recommend3(c, &archive.ArgAid2{Aid: aid, RealIP: ip}); err != nil {
|
|
log.Error("s.arc.Recommend3(%d) error(%v)", aid, err)
|
|
err = nil
|
|
} else {
|
|
for _, v := range recArcs {
|
|
res = append(res, v)
|
|
resAids[v.Aid] = v.Aid
|
|
}
|
|
}
|
|
if len(res) < s.c.Rule.AuthorRecCnt {
|
|
if upArcs, err = s.arc.UpArcs3(c, &archive.ArgUpArcs2{Mid: arcReply.Arc.Author.Mid, Pn: _firstPn, Ps: s.c.Rule.AuthorRecCnt, RealIP: ip}); err != nil {
|
|
log.Error("s.arc.UpArcs3(%d) error(%v)", arcReply.Arc.Author.Mid, err)
|
|
err = nil
|
|
} else {
|
|
for _, v := range upArcs {
|
|
if _, ok := resAids[v.Aid]; !ok {
|
|
res = append(res, v)
|
|
resAids[v.Aid] = v.Aid
|
|
if len(res) >= s.c.Rule.AuthorRecCnt {
|
|
return
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if len(res) < s.c.Rule.AuthorRecCnt {
|
|
if aids, err = s.dao.RelatedAids(c, aid); err != nil {
|
|
log.Error("s.dao.RelatedArchives(%d) error(%v)", aid, err)
|
|
err = nil
|
|
} else if len(aids) > 0 {
|
|
ps := s.c.Rule.AuthorRecCnt - len(res)
|
|
if len(aids) > ps {
|
|
aids = aids[0:ps]
|
|
}
|
|
archivesArgLog("AuthorRecommend", aids)
|
|
if arcs, err = s.arcClient.Arcs(c, &arcmdl.ArcsRequest{Aids: aids}); err != nil {
|
|
log.Error("s.arcClient.Arcs(%v) error(%v)", aids, err)
|
|
err = nil
|
|
} else {
|
|
for _, aid := range aids {
|
|
if _, ok := resAids[aid]; !ok {
|
|
if arc, ok := arcs.Arcs[aid]; ok {
|
|
res = append(res, model.FmtArc(arc))
|
|
if len(res) >= s.c.Rule.AuthorRecCnt {
|
|
return
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return
|
|
}
|
|
|
|
// RelatedArcs get related archives
|
|
func (s *Service) RelatedArcs(c context.Context, aid int64) (res []*arcmdl.Arc, err error) {
|
|
var (
|
|
aids []int64
|
|
arcReply *arcmdl.ArcReply
|
|
arcsReply *arcmdl.ArcsReply
|
|
)
|
|
if _, ok := s.noRelAids[aid]; ok {
|
|
res = _emptyArc
|
|
return
|
|
}
|
|
if arcReply, err = s.arcClient.Arc(c, &arcmdl.ArcRequest{Aid: aid}); err != nil {
|
|
log.Error("s.arcClient.Arc(%d) error(%v)", aid, err)
|
|
return
|
|
}
|
|
// StateForbidUpDelete can have related arc
|
|
if !arcReply.Arc.IsNormal() && arcReply.Arc.GetState() != archive.StateForbidUpDelete {
|
|
res = _emptyArc
|
|
return
|
|
}
|
|
if aids, err = s.dao.RelatedAids(c, aid); err != nil {
|
|
log.Error("s.dao.RelatedArchives(%d) error(%v)", aid, err)
|
|
err = nil
|
|
} else if len(aids) > 0 {
|
|
if len(aids) > s.c.Rule.RelatedArcCnt {
|
|
aids = aids[:s.c.Rule.RelatedArcCnt]
|
|
}
|
|
archivesArgLog("RelatedArcs", aids)
|
|
if arcsReply, err = s.arcClient.Arcs(c, &arcmdl.ArcsRequest{Aids: aids}); err != nil {
|
|
log.Error("s.arcClient.Arcs(%v) error(%v)", aids, err)
|
|
err = nil
|
|
} else {
|
|
for _, aid := range aids {
|
|
if arc, ok := arcsReply.Arcs[aid]; ok && arc.IsNormal() {
|
|
res = append(res, arc)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if len(res) == 0 {
|
|
res = _emptyArc
|
|
}
|
|
return
|
|
}
|
|
|
|
// Detail get merge view card tag reply related.
|
|
func (s *Service) Detail(c context.Context, aid, mid int64, cdnIP, ck string) (rs *model.Detail, err error) {
|
|
var (
|
|
view *model.View
|
|
card *model.Card
|
|
tags []*tagmdl.Tag
|
|
reply *model.ReplyHot
|
|
related []*arcmdl.Arc
|
|
group *errgroup.Group
|
|
cardErr, relatedErr error
|
|
)
|
|
if view, err = s.View(c, aid, 0, mid, cdnIP, ck); err != nil {
|
|
log.Error("s.View(%d) error %+v", aid, err)
|
|
return
|
|
}
|
|
group, errCtx := errgroup.WithContext(c)
|
|
group.Go(func() error {
|
|
if card, cardErr = s.Card(c, view.Author.Mid, mid, false, false); cardErr != nil {
|
|
log.Error("s.Card(%d) error %+v", aid, cardErr)
|
|
}
|
|
return nil
|
|
})
|
|
group.Go(func() error {
|
|
tags, _ = s.arcTags(errCtx, aid, mid)
|
|
return nil
|
|
})
|
|
group.Go(func() error {
|
|
reply, _ = s.replyHot(errCtx, aid)
|
|
return nil
|
|
})
|
|
group.Go(func() error {
|
|
if related, relatedErr = s.RelatedArcs(errCtx, aid); relatedErr != nil {
|
|
log.Error("s.RelatedArcs(%d) error %+v", aid, relatedErr)
|
|
}
|
|
return nil
|
|
})
|
|
group.Wait()
|
|
rs = &model.Detail{
|
|
View: view,
|
|
Card: card,
|
|
Tags: tags,
|
|
Reply: reply,
|
|
Related: related,
|
|
}
|
|
return
|
|
}
|
|
|
|
// ArcUGCPay get arc ugc pay relation.
|
|
func (s *Service) ArcUGCPay(c context.Context, mid, aid int64) (data *model.AssetRelation, err error) {
|
|
var relation *ugcmdl.AssetRelationResp
|
|
data = new(model.AssetRelation)
|
|
if arcReply, e := s.arcClient.Arc(c, &arcmdl.ArcRequest{Aid: aid}); e != nil {
|
|
log.Error("s.arcClient.Arc(%d) error(%v)", aid, e)
|
|
} else if arcReply.Arc.Author.Mid == mid {
|
|
data.State = _ugcPaidState
|
|
return
|
|
}
|
|
if relation, err = s.ugcPayClient.AssetRelation(c, &ugcmdl.AssetRelationReq{Mid: mid, Oid: aid, Otype: _ugcOtypeArc}); err != nil {
|
|
log.Error("ArcUGCPay s.ugcPayClient.AssetRelation mid:%d aid:%d error(%v)", mid, aid, err)
|
|
err = nil
|
|
return
|
|
}
|
|
if relation.State == _ugcAssetPaid {
|
|
data.State = _ugcPaidState
|
|
}
|
|
return
|
|
}
|
|
|
|
// ArcRelation .
|
|
func (s *Service) ArcRelation(c context.Context, mid, aid int64) (data *model.ReqUser, err error) {
|
|
var arc *arcmdl.ArcReply
|
|
data = new(model.ReqUser)
|
|
if arc, err = s.arcClient.Arc(c, &arcmdl.ArcRequest{Aid: aid}); err != nil || arc.Arc == nil || !arc.Arc.IsNormal() {
|
|
log.Error("ArcRelation s.arcClient.Arc(%d) error(%v)", aid, err)
|
|
err = nil
|
|
return
|
|
}
|
|
authorMid := arc.Arc.Author.Mid
|
|
ip := metadata.String(c, metadata.RemoteIP)
|
|
group, errCtx := errgroup.WithContext(c)
|
|
// attention
|
|
group.Go(func() error {
|
|
if resp, e := s.accClient.Relation3(errCtx, &accmdl.RelationReq{Mid: mid, Owner: authorMid, RealIp: ip}); e != nil {
|
|
log.Error("ArcRelation s.accClient.Relation3(%d,%d,%s) error(%v)", mid, authorMid, ip, e)
|
|
} else if resp != nil {
|
|
data.Attention = resp.Following
|
|
}
|
|
return nil
|
|
})
|
|
// favorite
|
|
group.Go(func() error {
|
|
if resp, e := s.fav.IsFav(errCtx, &favmdl.ArgIsFav{Type: favmdl.TypeVideo, Mid: mid, Oid: aid, RealIP: ip}); e != nil {
|
|
log.Error("ArcRelation s.fav.IsFav(%d,%d,%s) error(%v)", mid, aid, ip, e)
|
|
} else {
|
|
data.Favorite = resp
|
|
}
|
|
return nil
|
|
})
|
|
// like
|
|
group.Go(func() error {
|
|
if resp, e := s.thumbup.HasLike(errCtx, &thumbup.ArgHasLike{Business: _businessLike, MessageIDs: []int64{aid}, Mid: mid, RealIP: ip}); e != nil {
|
|
log.Error("ArcRelation s.thumbup.HasLike(%d,%d,%s) error %v", aid, mid, ip, e)
|
|
} else if resp != nil {
|
|
if v, ok := resp[aid]; ok {
|
|
switch v {
|
|
case thumbup.StateLike:
|
|
data.Like = true
|
|
case thumbup.StateDislike:
|
|
data.Dislike = true
|
|
}
|
|
}
|
|
}
|
|
return nil
|
|
})
|
|
// coin
|
|
group.Go(func() error {
|
|
if resp, e := s.coinClient.ItemUserCoins(errCtx, &coinmdl.ItemUserCoinsReq{Mid: mid, Aid: aid, Business: model.CoinArcBusiness}); e != nil {
|
|
log.Error("ArcRelation s.coinClient.ItemUserCoins(%d,%d,%s) error %v", mid, aid, ip, e)
|
|
} else if resp != nil {
|
|
data.Coin = resp.Number
|
|
}
|
|
return nil
|
|
})
|
|
group.Wait()
|
|
return
|
|
}
|
|
|
|
func (s *Service) replyHot(c context.Context, aid int64) (res *model.ReplyHot, err error) {
|
|
if res, err = s.dao.Hot(c, aid); err != nil {
|
|
log.Error("s.dao.Hot(%d) error %+v", aid, err)
|
|
}
|
|
if res == nil {
|
|
res = _emptyReplyHot
|
|
}
|
|
return
|
|
}
|
|
|
|
func (s *Service) arcTags(c context.Context, aid, mid int64) (res []*tagmdl.Tag, err error) {
|
|
remoteIP := metadata.String(c, metadata.RemoteIP)
|
|
var (
|
|
arg = &tagmdl.ArgAid{
|
|
Aid: aid,
|
|
Mid: mid,
|
|
RealIP: remoteIP,
|
|
}
|
|
)
|
|
if res, err = s.tag.ArcTags(c, arg); err != nil {
|
|
log.Error("s.tag.ArcTags(%v) error(%v)", arg, err)
|
|
}
|
|
if len(res) == 0 {
|
|
res = _emptyTags
|
|
}
|
|
return
|
|
}
|
|
|
|
func (s *Service) ugcPayAsset(c context.Context, aid, mid int64) (data *ugcmdl.AssetQueryResp) {
|
|
asset, err := s.ugcPayClient.AssetQuery(c, &ugcmdl.AssetQueryReq{Oid: aid, Otype: _ugcOtypeArc, Currency: _ugcCurrencyBp})
|
|
if err != nil {
|
|
log.Error("ugcPayAsset mid(%d) oid(%d) error(%v)", mid, aid, err)
|
|
data = new(ugcmdl.AssetQueryResp)
|
|
return
|
|
}
|
|
data = asset
|
|
return
|
|
}
|
|
func (s *Service) loadManager() {
|
|
for {
|
|
time.Sleep(time.Duration(s.c.WEB.SpecailInterval))
|
|
midsM, err := s.dao.Special(context.Background())
|
|
if err != nil {
|
|
log.Error("loadManager error(%+v)", err)
|
|
continue
|
|
}
|
|
log.Info("load special mids(%+v)", midsM)
|
|
s.specialMids = midsM
|
|
}
|
|
}
|