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

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
}
}