Create & Init Project...

This commit is contained in:
2019-04-22 18:49:16 +08:00
commit fc4fa37393
25440 changed files with 4054998 additions and 0 deletions

View File

@@ -0,0 +1,100 @@
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_test",
"go_library",
)
go_test(
name = "go_default_test",
srcs = ["show_test.go"],
embed = [":go_default_library"],
rundir = ".",
tags = ["automanaged"],
deps = [
"//app/interface/main/app-show/conf:go_default_library",
"//app/interface/main/app-show/model:go_default_library",
"//vendor/github.com/smartystreets/goconvey/convey:go_default_library",
],
)
go_library(
name = "go_default_library",
srcs = [
"ad.go",
"audit.go",
"banner.go",
"cache.go",
"feed.go",
"feed2.go",
"infoc.go",
"manager.go",
"service.go",
"show.go",
],
importpath = "go-common/app/interface/main/app-show/service/show",
tags = ["automanaged"],
visibility = ["//visibility:public"],
deps = [
"//app/interface/main/app-card/model:go_default_library",
"//app/interface/main/app-card/model/card:go_default_library",
"//app/interface/main/app-card/model/card/ai:go_default_library",
"//app/interface/main/app-card/model/card/live:go_default_library",
"//app/interface/main/app-card/model/card/operate:go_default_library",
"//app/interface/main/app-card/model/card/rank:go_default_library",
"//app/interface/main/app-show/conf:go_default_library",
"//app/interface/main/app-show/dao/account:go_default_library",
"//app/interface/main/app-show/dao/activity:go_default_library",
"//app/interface/main/app-show/dao/ad:go_default_library",
"//app/interface/main/app-show/dao/archive:go_default_library",
"//app/interface/main/app-show/dao/audit:go_default_library",
"//app/interface/main/app-show/dao/bangumi:go_default_library",
"//app/interface/main/app-show/dao/card:go_default_library",
"//app/interface/main/app-show/dao/databus:go_default_library",
"//app/interface/main/app-show/dao/dynamic:go_default_library",
"//app/interface/main/app-show/dao/live:go_default_library",
"//app/interface/main/app-show/dao/location:go_default_library",
"//app/interface/main/app-show/dao/recommend:go_default_library",
"//app/interface/main/app-show/dao/region:go_default_library",
"//app/interface/main/app-show/dao/relation:go_default_library",
"//app/interface/main/app-show/dao/resource:go_default_library",
"//app/interface/main/app-show/dao/show:go_default_library",
"//app/interface/main/app-show/dao/tag:go_default_library",
"//app/interface/main/app-show/model:go_default_library",
"//app/interface/main/app-show/model/banner:go_default_library",
"//app/interface/main/app-show/model/card:go_default_library",
"//app/interface/main/app-show/model/feed:go_default_library",
"//app/interface/main/app-show/model/recommend:go_default_library",
"//app/interface/main/app-show/model/region:go_default_library",
"//app/interface/main/app-show/model/show:go_default_library",
"//app/interface/main/creative/api:go_default_library",
"//app/service/main/account/model:go_default_library",
"//app/service/main/archive/api:go_default_library",
"//app/service/main/archive/model/archive:go_default_library",
"//app/service/main/location/model:go_default_library",
"//app/service/main/relation/model:go_default_library",
"//app/service/main/resource/model:go_default_library",
"//app/service/openplatform/pgc-season/api/grpc/season/v1:go_default_library",
"//library/ecode:go_default_library",
"//library/log:go_default_library",
"//library/log/infoc:go_default_library",
"//library/net/http/blademaster:go_default_library",
"//library/stat/prom:go_default_library",
"//library/sync/errgroup:go_default_library",
],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

View File

@@ -0,0 +1,95 @@
package show
import (
"context"
"strconv"
"go-common/app/interface/main/app-show/model"
"go-common/app/interface/main/app-show/model/show"
locmdl "go-common/app/service/main/location/model"
"go-common/library/log"
)
// cpmRecommend
func (s *Service) cpmRecommend(c context.Context, mid int64, build int, buvid, resource, network, mobiApp, device, ipaddr string) (sis map[int]*show.Item) {
if _, ok := s.cpmRcmmndMid[mid]; !ok && (mid == 0 || int(mid)%100 >= s.cpmRcmmndNum) && !s.cpmRcmmndAll {
return
}
var (
info *locmdl.Info
country, province, city string
err error
)
if info, err = s.loc.Info(c, ipaddr); err != nil {
log.Warn("s.loc.Info(%v) error(%v)", ipaddr, err)
err = nil
}
if info != nil {
country = info.Country
province = info.Province
city = info.Province
}
adr, err := s.ad.ADRequest(c, mid, build, buvid, resource, ipaddr, country, province, city, network, mobiApp, device, s.adIsPost)
if err != nil {
log.Error("s.ad.ADRequest error(%v)", err)
return
}
sis = map[int]*show.Item{}
sAdis := adr.ADIndexs[resource]
if len(sAdis) == 0 {
log.Info("mobi_app:%v-build:%v-resource:%v-is_ad_loc:%v", mobiApp, build, resource, false)
return
}
var aids []int64
for sidStr, adi := range sAdis {
sid, _ := strconv.Atoi(sidStr)
var si = &show.Item{
IsAdLoc: true,
IsAd: adi.IsAd,
IsAdReplace: false,
CmMark: adi.CmMark,
Rank: adi.Index,
SrcId: sid,
RequestId: adr.RequestID,
ClientIp: ipaddr,
}
if adInfo := adi.Info; adInfo != nil {
aids = append(aids, adInfo.CreativeContent.VideoID)
// si
si.Goto = model.GotoAv
si.Param = strconv.FormatInt(adInfo.CreativeContent.VideoID, 10)
si.URI = model.FillURI(model.GotoAv, si.Param, nil)
si.Title = adInfo.CreativeContent.Title
si.Cover = model.CoverURL(adInfo.CreativeContent.ImageURL)
si.IsAdReplace = true
si.AdCb = adInfo.AdCb
si.CreativeId = adInfo.CreativeID
si.ShowUrl = adInfo.CreativeContent.ShowURL
si.ClickUrl = adInfo.CreativeContent.ClickURL
}
sis[si.Rank] = si
log.Info("mobi_app:%v-build:%v-resource:%v-is_ad_loc:%v", mobiApp, build, resource, true)
}
if len(aids) == 0 {
return
}
as, err := s.arc.ArchivesPB(c, aids)
if err != nil {
log.Error("s.arc.ArchivesPB(%v) error(%v)", aids, err)
return
}
for _, si := range sis {
aid, _ := strconv.ParseInt(si.Param, 10, 64)
if a, ok := as[aid]; ok && a != nil {
si.Play = int(a.Stat.View)
si.Danmaku = int(a.Stat.Danmaku)
if si.Title == "" {
si.Title = a.Title
}
if si.Cover == "" {
si.Cover = model.CoverURL(a.Pic)
}
}
}
return
}

View File

@@ -0,0 +1,299 @@
package show
import (
"context"
"strconv"
cdm "go-common/app/interface/main/app-card/model"
cardm "go-common/app/interface/main/app-card/model/card"
"go-common/app/interface/main/app-card/model/card/ai"
operate "go-common/app/interface/main/app-card/model/card/operate"
"go-common/app/interface/main/app-show/model"
"go-common/app/interface/main/app-show/model/banner"
"go-common/app/interface/main/app-show/model/feed"
"go-common/app/interface/main/app-show/model/show"
"go-common/app/service/main/archive/api"
"go-common/app/service/main/archive/model/archive"
"go-common/library/log"
)
var (
_auditBanner = &banner.Banner{
Title: "充电",
Image: "http://i0.hdslb.com/bfs/archive/9ce8f6cdf76e6cbd50ce7db76262d5a35e594c79.png",
Hash: "3c4990d06c46de0080e3821fca6bedca",
URI: "bilibili://video/813060",
}
_auditRids = map[int8]map[string]struct{}{
model.PlatIPhone: map[string]struct{}{
"13": struct{}{},
"167": struct{}{},
"177": struct{}{},
"23": struct{}{},
"11": struct{}{},
},
}
)
// GetAudit check audit plat and ip, then return audit data.
func (s *Service) Audit(c context.Context, mobiApp string, plat int8, build int) (ss []*show.Show, ok bool) {
if plats, ok := s.auditCache[mobiApp]; ok {
if _, ok = plats[build]; ok {
return s.auditData(c, plat), true
}
}
return nil, false
}
func (s *Service) AuditChild(c context.Context, mobiApp string, plat int8, build int) (res []*show.Item, ok bool) {
if plats, ok := s.auditCache[mobiApp]; ok {
if _, ok = plats[build]; ok {
res = s.auditList(c)
return res, true
}
}
return nil, false
}
// AuditFeed check audit plat and ip, then return audit data.
func (s *Service) AuditFeed(c context.Context, mobiApp string, plat int8, build int) (res []*feed.Item, ok bool) {
if plats, ok := s.auditCache[mobiApp]; ok {
if _, ok = plats[build]; ok {
return s.auditFeed(c), true
}
}
return nil, false
}
// AuditFeed check audit plat and ip, then return audit data.
func (s *Service) AuditFeed2(c context.Context, mobiApp string, plat int8, build int) (res []cardm.Handler, ok bool) {
if plats, ok := s.auditCache[mobiApp]; ok {
if _, ok = plats[build]; ok {
return s.auditFeed2(c, plat), true
}
}
return nil, false
}
// Audit region data list.
func (s *Service) auditRegion(mobiApp string, plat int8, build int, rid string) (isAudit bool) {
if plats, ok := s.auditCache[mobiApp]; ok {
if _, ok = plats[build]; ok {
if params, ok := _auditRids[plat]; ok {
if _, ok = params[rid]; ok {
return true
}
}
}
}
return false
}
func (s *Service) loadAuditCache() {
as, err := s.adt.Audits(context.TODO())
if err != nil {
log.Error("s.adt.Audits error(%v)", err)
return
}
s.auditCache = as
}
// auditData some data for audit.
func (s *Service) auditData(c context.Context, p int8) (ss []*show.Show) {
ss = []*show.Show{
&show.Show{
Head: &show.Head{
Param: "",
Type: "recommend",
Style: "medium",
Title: "热门推荐",
},
},
&show.Show{
Head: &show.Head{
Param: "3",
Type: "region",
Style: "medium",
Title: "音乐区",
},
},
&show.Show{
Head: &show.Head{
Param: "129",
Type: "region",
Style: "medium",
Title: "舞蹈区",
},
},
&show.Show{
Head: &show.Head{
Param: "4",
Type: "region",
Style: "medium",
Title: "游戏区",
},
},
&show.Show{
Head: &show.Head{
Param: "36",
Type: "region",
Style: "medium",
Title: "游戏区",
},
},
}
aids := []int64{308040, 2431658, 2432648, 2427553, 539600, 1968681, 850424, 887861, 1960912, 1935680, 1406019, 1985297, 1977493, 2312184, 2316891, 864845, 1986932, 2314237, 880857, 875624}
n := 4
if p == model.PlatIPad {
aids = []int64{2455179, 2473608, 1711253, 2476389, 0, 0, 0, 0, 308040, 360940, 482844, 221107, 539600, 1968681, 850424, 887861, 936016, 1773160, 886841, 1958897, 1960912, 1935680,
1406019, 1985297, 1635344, 572952, 2316655, 2317928, 1977493, 2312184, 2316891, 864845, 2313588, 875076, 2312249, 842756, 1986932, 2314237, 880857, 875624}
n = 8
// ss[0].Head.Type = ""
// banner
ss[0].Banner = map[string][]*banner.Banner{
"top": []*banner.Banner{_auditBanner, _auditBanner},
}
} else if p == model.PlatIPhone {
aids = []int64{308040, 2431658, 2432648, 2427553, 2455179, 2473608, 539600, 1968681, 850424, 887861, 0, 0, 1960912, 1935680, 1406019, 1985297, 0, 0, 1977493, 2312184, 2316891, 864845, 0, 0,
1986932, 2314237, 880857, 875624, 0, 0}
n = 6
// banner
ss[0].Banner = map[string][]*banner.Banner{
"top": []*banner.Banner{_auditBanner},
}
}
as, err := s.arc.ArchivesPB(c, aids)
if err != nil {
log.Error("s.arc.ArchivesPB error(%v)", err)
as = map[int64]*api.Arc{}
}
for i, aid := range aids {
if aid == 0 {
continue
}
item := &show.Item{}
item.Goto = model.GotoAv
item.Param = strconv.FormatInt(aid, 10)
item.URI = model.FillURI(item.Goto, item.Param, nil)
if a, ok := as[aid]; ok {
item.Title = a.Title
item.Cover = a.Pic
item.Play = int(a.Stat.View)
item.Danmaku = int(a.Stat.Danmaku)
}
ss[i/n].Body = append(ss[i/n].Body, item)
}
return
}
func (s *Service) auditList(c context.Context) (ss []*show.Item) {
aids := []int64{308040, 2431658, 2432648, 2427553, 2455179, 2473608, 539600, 1968681, 850424, 887861, 1960912, 1935680, 1406019, 1985297, 1977493, 2312184, 2316891, 864845,
1986932, 2314237, 880857, 875624}
as, err := s.arc.ArchivesPB(c, aids)
if err != nil {
log.Error("s.arc.ArchivesPB error(%v)", err)
as = map[int64]*api.Arc{}
}
for _, aid := range aids {
if aid == 0 {
continue
}
item := &show.Item{}
item.Goto = model.GotoAv
item.Param = strconv.FormatInt(aid, 10)
item.URI = model.FillURI(item.Goto, item.Param, nil)
if a, ok := as[aid]; ok {
item.Title = a.Title
item.Cover = a.Pic
item.Play = int(a.Stat.View)
item.Danmaku = int(a.Stat.Danmaku)
}
ss = append(ss, item)
}
return
}
func (s *Service) auditFeed(c context.Context) (res []*feed.Item) {
var (
aids = []int64{2455179, 2473608, 1711253, 2476389, 0, 0, 0, 0, 308040, 360940, 482844, 221107, 539600, 1968681, 850424, 887861, 936016, 1773160, 886841, 1958897, 1960912, 1935680,
1406019, 1985297, 1635344, 572952, 2316655, 2317928, 1977493, 2312184, 2316891, 864845, 2313588, 875076, 2312249, 842756, 1986932, 2314237, 880857, 875624}
as map[int64]*api.Arc
err error
)
if as, err = s.arc.ArchivesPB(c, aids); err != nil {
log.Error("hottab s.arc.ArchivesPB aids(%v) error(%v)", aids, err)
return
}
if len(as) == 0 {
log.Warn("hottab s.arc.ArchivesPB(%v) length is 0", aids)
return
}
for i, aid := range aids {
item := &feed.Item{}
item.Idx = int64(i + 1)
item.Pos = i + 1
if aid == 0 {
continue
}
if a, ok := as[aid]; ok {
item.FromPlayerAv(a, "")
// if tag, ok := s.hotArcTag[a.Aid]; ok {
// item.Tag = &feed.Tag{TagID: tag.ID, TagName: tag.Name}
// }
item.Goto = model.GotoAv
res = append(res, item)
}
}
if len(res) == 0 {
res = _emptyList
return
}
return
}
func (s *Service) auditFeed2(c context.Context, plat int8) (res []cardm.Handler) {
var (
aids = []int64{2455179, 2473608, 1711253, 2476389, 0, 0, 0, 0, 308040, 360940, 482844, 221107, 539600, 1968681, 850424, 887861, 936016, 1773160, 886841, 1958897, 1960912, 1935680,
1406019, 1985297, 1635344, 572952, 2316655, 2317928, 1977493, 2312184, 2316891, 864845, 2313588, 875076, 2312249, 842756, 1986932, 2314237, 880857, 875624}
as map[int64]*api.Arc
err error
)
if as, err = s.arc.ArchivesPB(c, aids); err != nil {
log.Error("hottab s.arc.ArchivesPB aids(%v) error(%v)", aids, err)
return
}
if len(as) == 0 {
log.Warn("hottab s.arc.ArchivesPB(%v) length is 0", aids)
return
}
for i, aid := range aids {
if aid == 0 {
continue
}
var (
r = &ai.Item{Goto: model.GotoAv, ID: aid}
h = cardm.Handle(plat, cdm.CardGt(r.Goto), "", 1, r, nil, nil, nil, nil)
main interface{}
)
if h == nil {
continue
}
op := &operate.Card{}
op.From(cdm.CardGt(r.Goto), r.ID, 0, model.PlatIPhone, 0)
if a, ok := as[aid]; ok && (a.AttrVal(archive.AttrBitOverseaLock) == 0) {
main = map[int64]*archive.ArchiveWithPlayer{a.Aid: &archive.ArchiveWithPlayer{Archive3: archive.BuildArchive3(a)}}
}
if main != nil {
h.From(main, op)
}
h.Get().Idx = int64(i + 1)
if h.Get().Right {
res = append(res, h)
}
}
if len(res) == 0 {
res = _emptyList2
return
}
return
}

View File

@@ -0,0 +1,891 @@
package show
import (
"context"
"go-common/app/interface/main/app-show/model"
"go-common/app/interface/main/app-show/model/banner"
resource "go-common/app/service/main/resource/model"
"go-common/library/log"
)
var (
_banners = map[string]map[int8]map[string]int{
"-1": map[int8]map[string]int{
model.PlatIPhone: map[string]int{
"bottom": 467,
},
model.PlatAndroid: map[string]int{
"bottom": 631,
},
model.PlatIPad: map[string]int{
"bottom": 771,
},
model.PlatIPhoneI: map[string]int{
"bottom": 947,
},
model.PlatAndroidG: map[string]int{
"bottom": 1285,
},
model.PlatAndroidI: map[string]int{
"bottom": 1707,
},
model.PlatIPadI: map[string]int{
"bottom": 1117,
},
},
"0": map[int8]map[string]int{
model.PlatIPhone: map[string]int{
"top": 467,
"center": 468,
"bottom": 469,
},
model.PlatAndroid: map[string]int{
"top": 631,
"center": 632,
"bottom": 633,
},
model.PlatIPad: map[string]int{
"top": 771,
"center": 772,
"bottom": 773,
},
model.PlatIPhoneI: map[string]int{
"top": 947,
"center": 952,
"bottom": 957,
},
model.PlatAndroidG: map[string]int{
"top": 1285,
"center": 1290,
"bottom": 1295,
},
model.PlatAndroidI: map[string]int{
"top": 1707,
"center": 1712,
"bottom": 1717,
},
model.PlatIPadI: map[string]int{
"top": 1117,
"center": 1122,
"bottom": 1127,
},
},
"65537": map[int8]map[string]int{
model.PlatIPhone: map[string]int{
"bottom": 482,
},
model.PlatAndroid: map[string]int{
"bottom": 646,
},
model.PlatIPad: map[string]int{
"bottom": 786,
},
model.PlatIPhoneI: map[string]int{
"bottom": 1013,
},
model.PlatAndroidG: map[string]int{
"bottom": 1351,
},
model.PlatAndroidI: map[string]int{
"bottom": 1773,
},
model.PlatIPadI: map[string]int{
"bottom": 1183,
},
},
"13": map[int8]map[string]int{
model.PlatIPhone: map[string]int{
"bottom": 471,
},
model.PlatAndroid: map[string]int{
"bottom": 635,
},
model.PlatIPad: map[string]int{
"bottom": 775,
},
model.PlatIPhoneI: map[string]int{
"bottom": 967,
},
model.PlatAndroidG: map[string]int{
"bottom": 1305,
},
model.PlatAndroidI: map[string]int{
"bottom": 1727,
},
model.PlatIPadI: map[string]int{
"bottom": 1137,
},
},
"1": map[int8]map[string]int{
model.PlatIPhone: map[string]int{
"bottom": 470,
},
model.PlatAndroid: map[string]int{
"bottom": 634,
},
model.PlatIPad: map[string]int{
"bottom": 774,
},
model.PlatIPhoneI: map[string]int{
"bottom": 962,
},
model.PlatAndroidG: map[string]int{
"bottom": 1300,
},
model.PlatAndroidI: map[string]int{
"bottom": 1722,
},
model.PlatIPadI: map[string]int{
"bottom": 1132,
},
},
"3": map[int8]map[string]int{
model.PlatIPhone: map[string]int{
"bottom": 472,
},
model.PlatAndroid: map[string]int{
"bottom": 636,
},
model.PlatIPad: map[string]int{
"bottom": 776,
},
model.PlatIPhoneI: map[string]int{
"bottom": 971,
},
model.PlatAndroidG: map[string]int{
"bottom": 1309,
},
model.PlatAndroidI: map[string]int{
"bottom": 1731,
},
model.PlatIPadI: map[string]int{
"bottom": 1141,
},
},
"129": map[int8]map[string]int{
model.PlatIPhone: map[string]int{
"bottom": 473,
},
model.PlatAndroid: map[string]int{
"bottom": 637,
},
model.PlatIPad: map[string]int{
"bottom": 777,
},
model.PlatIPhoneI: map[string]int{
"bottom": 975,
},
model.PlatAndroidG: map[string]int{
"bottom": 1313,
},
model.PlatAndroidI: map[string]int{
"bottom": 1735,
},
model.PlatIPadI: map[string]int{
"bottom": 1145,
},
},
"4": map[int8]map[string]int{
model.PlatIPhone: map[string]int{
"bottom": 474,
},
model.PlatAndroid: map[string]int{
"bottom": 638,
},
model.PlatIPad: map[string]int{
"bottom": 778,
},
model.PlatIPhoneI: map[string]int{
"bottom": 979,
},
model.PlatAndroidG: map[string]int{
"bottom": 1317,
},
model.PlatAndroidI: map[string]int{
"bottom": 1739,
},
model.PlatIPadI: map[string]int{
"bottom": 1149,
},
},
"36": map[int8]map[string]int{
model.PlatIPhone: map[string]int{
"bottom": 475,
},
model.PlatAndroid: map[string]int{
"bottom": 639,
},
model.PlatIPad: map[string]int{
"bottom": 779,
},
model.PlatIPhoneI: map[string]int{
"bottom": 983,
},
model.PlatAndroidG: map[string]int{
"bottom": 1321,
},
model.PlatAndroidI: map[string]int{
"bottom": 1706,
},
model.PlatIPadI: map[string]int{
"bottom": 1153,
},
},
"160": map[int8]map[string]int{
model.PlatIPhone: map[string]int{
"bottom": 476,
},
model.PlatAndroid: map[string]int{
"bottom": 640,
},
model.PlatIPad: map[string]int{
"bottom": 780,
},
model.PlatIPhoneI: map[string]int{
"bottom": 987,
},
model.PlatAndroidG: map[string]int{
"bottom": 1325,
},
model.PlatAndroidI: map[string]int{
"bottom": 1747,
},
model.PlatIPadI: map[string]int{
"bottom": 1157,
},
},
"119": map[int8]map[string]int{
model.PlatIPhone: map[string]int{
"bottom": 477,
},
model.PlatAndroid: map[string]int{
"bottom": 641,
},
model.PlatIPad: map[string]int{
"bottom": 781,
},
model.PlatIPhoneI: map[string]int{
"bottom": 992,
},
model.PlatAndroidG: map[string]int{
"bottom": 1330,
},
model.PlatAndroidI: map[string]int{
"bottom": 1752,
},
model.PlatIPadI: map[string]int{
"bottom": 1162,
},
},
"155": map[int8]map[string]int{
model.PlatIPhone: map[string]int{
"bottom": 478,
},
model.PlatAndroid: map[string]int{
"bottom": 642,
},
model.PlatIPad: map[string]int{
"bottom": 782,
},
model.PlatIPhoneI: map[string]int{
"bottom": 997,
},
model.PlatAndroidG: map[string]int{
"bottom": 1335,
},
model.PlatAndroidI: map[string]int{
"bottom": 1757,
},
model.PlatIPadI: map[string]int{
"bottom": 1167,
},
},
"5": map[int8]map[string]int{
model.PlatIPhone: map[string]int{
"bottom": 479,
},
model.PlatAndroid: map[string]int{
"bottom": 643,
},
model.PlatIPad: map[string]int{
"bottom": 783,
},
model.PlatIPhoneI: map[string]int{
"bottom": 1001,
},
model.PlatAndroidG: map[string]int{
"bottom": 1339,
},
model.PlatAndroidI: map[string]int{
"bottom": 1761,
},
model.PlatIPadI: map[string]int{
"bottom": 1171,
},
},
"23": map[int8]map[string]int{
model.PlatIPhone: map[string]int{
"bottom": 480,
},
model.PlatAndroid: map[string]int{
"bottom": 644,
},
model.PlatIPad: map[string]int{
"bottom": 784,
},
model.PlatIPhoneI: map[string]int{
"bottom": 1005,
},
model.PlatAndroidG: map[string]int{
"bottom": 1343,
},
model.PlatAndroidI: map[string]int{
"bottom": 1765,
},
model.PlatIPadI: map[string]int{
"bottom": 1175,
},
},
"11": map[int8]map[string]int{
model.PlatIPhone: map[string]int{
"bottom": 481,
},
model.PlatAndroid: map[string]int{
"bottom": 645,
},
model.PlatIPad: map[string]int{
"bottom": 785,
},
model.PlatIPhoneI: map[string]int{
"bottom": 1009,
},
model.PlatAndroidG: map[string]int{
"bottom": 1347,
},
model.PlatAndroidI: map[string]int{
"bottom": 1769,
},
model.PlatIPadI: map[string]int{
"bottom": 1179,
},
},
"165": map[int8]map[string]int{
model.PlatIPhone: map[string]int{
"bottom": 1643,
},
model.PlatAndroid: map[string]int{
"bottom": 1639,
},
model.PlatIPad: map[string]int{
"bottom": 1647,
},
model.PlatIPhoneI: map[string]int{
"bottom": 1643,
},
model.PlatAndroidG: map[string]int{
"bottom": 1639,
},
model.PlatIPadI: map[string]int{
"bottom": 1647,
},
},
"167": map[int8]map[string]int{
model.PlatIPhone: map[string]int{
"bottom": 1950,
},
model.PlatAndroid: map[string]int{
"bottom": 1952,
},
model.PlatIPad: map[string]int{
"bottom": 1951,
},
},
"181": map[int8]map[string]int{
model.PlatIPhone: map[string]int{
"bottom": 2245,
},
model.PlatAndroid: map[string]int{
"bottom": 2249,
},
model.PlatIPad: map[string]int{
"bottom": 2253,
},
},
"177": map[int8]map[string]int{
model.PlatIPhone: map[string]int{
"bottom": 2295,
},
model.PlatAndroid: map[string]int{
"bottom": 2299,
},
model.PlatIPad: map[string]int{
"bottom": 2303,
},
},
}
_bannersIndex = map[string]map[int8]map[string]int{
"-1": map[int8]map[string]int{
model.PlatIPhone: map[string]int{
"top": 467,
},
model.PlatAndroid: map[string]int{
"top": 631,
},
model.PlatIPad: map[string]int{
"top": 771,
},
model.PlatIPhoneI: map[string]int{
"top": 947,
},
model.PlatAndroidG: map[string]int{
"top": 1285,
},
model.PlatAndroidI: map[string]int{
"top": 1707,
},
model.PlatIPadI: map[string]int{
"top": 1117,
},
},
"0": map[int8]map[string]int{
model.PlatIPhone: map[string]int{
"top": 467,
"center": 468,
"bottom": 469,
},
model.PlatAndroid: map[string]int{
"top": 631,
"center": 632,
"bottom": 633,
},
model.PlatIPad: map[string]int{
"top": 771,
"center": 772,
"bottom": 773,
},
model.PlatIPhoneI: map[string]int{
"top": 947,
"center": 952,
"bottom": 957,
},
model.PlatAndroidG: map[string]int{
"top": 1285,
"center": 1290,
"bottom": 1295,
},
model.PlatAndroidI: map[string]int{
"top": 1707,
"center": 1712,
"bottom": 1717,
},
model.PlatIPadI: map[string]int{
"top": 1117,
"center": 1122,
"bottom": 1127,
},
},
"65537": map[int8]map[string]int{
model.PlatIPhone: map[string]int{
"top": 482,
},
model.PlatAndroid: map[string]int{
"top": 646,
},
model.PlatIPad: map[string]int{
"top": 786,
},
model.PlatIPhoneI: map[string]int{
"top": 1013,
},
model.PlatAndroidG: map[string]int{
"top": 1351,
},
model.PlatAndroidI: map[string]int{
"top": 1773,
},
model.PlatIPadI: map[string]int{
"top": 1183,
},
},
"13": map[int8]map[string]int{
model.PlatIPhone: map[string]int{
"top": 471,
},
model.PlatAndroid: map[string]int{
"top": 635,
},
model.PlatIPad: map[string]int{
"top": 775,
},
model.PlatIPhoneI: map[string]int{
"top": 967,
},
model.PlatAndroidG: map[string]int{
"top": 1305,
},
model.PlatAndroidI: map[string]int{
"top": 1727,
},
model.PlatIPadI: map[string]int{
"top": 1137,
},
},
"1": map[int8]map[string]int{
model.PlatIPhone: map[string]int{
"top": 470,
},
model.PlatAndroid: map[string]int{
"top": 634,
},
model.PlatIPad: map[string]int{
"top": 774,
},
model.PlatIPhoneI: map[string]int{
"top": 962,
},
model.PlatAndroidG: map[string]int{
"top": 1300,
},
model.PlatAndroidI: map[string]int{
"top": 1722,
},
model.PlatIPadI: map[string]int{
"top": 1132,
},
},
"3": map[int8]map[string]int{
model.PlatIPhone: map[string]int{
"top": 472,
},
model.PlatAndroid: map[string]int{
"top": 636,
},
model.PlatIPad: map[string]int{
"top": 776,
},
model.PlatIPhoneI: map[string]int{
"top": 971,
},
model.PlatAndroidG: map[string]int{
"top": 1309,
},
model.PlatAndroidI: map[string]int{
"top": 1731,
},
model.PlatIPadI: map[string]int{
"top": 1141,
},
},
"129": map[int8]map[string]int{
model.PlatIPhone: map[string]int{
"top": 473,
},
model.PlatAndroid: map[string]int{
"top": 637,
},
model.PlatIPad: map[string]int{
"top": 777,
},
model.PlatIPhoneI: map[string]int{
"top": 975,
},
model.PlatAndroidG: map[string]int{
"top": 1313,
},
model.PlatAndroidI: map[string]int{
"top": 1735,
},
model.PlatIPadI: map[string]int{
"top": 1145,
},
},
"4": map[int8]map[string]int{
model.PlatIPhone: map[string]int{
"top": 474,
},
model.PlatAndroid: map[string]int{
"top": 638,
},
model.PlatIPad: map[string]int{
"top": 778,
},
model.PlatIPhoneI: map[string]int{
"top": 979,
},
model.PlatAndroidG: map[string]int{
"top": 1317,
},
model.PlatAndroidI: map[string]int{
"top": 1739,
},
model.PlatIPadI: map[string]int{
"top": 1149,
},
},
"36": map[int8]map[string]int{
model.PlatIPhone: map[string]int{
"top": 475,
},
model.PlatAndroid: map[string]int{
"top": 639,
},
model.PlatIPad: map[string]int{
"top": 779,
},
model.PlatIPhoneI: map[string]int{
"top": 983,
},
model.PlatAndroidG: map[string]int{
"top": 1321,
},
model.PlatAndroidI: map[string]int{
"top": 1706,
},
model.PlatIPadI: map[string]int{
"top": 1153,
},
},
"160": map[int8]map[string]int{
model.PlatIPhone: map[string]int{
"top": 476,
},
model.PlatAndroid: map[string]int{
"top": 640,
},
model.PlatIPad: map[string]int{
"top": 780,
},
model.PlatIPhoneI: map[string]int{
"top": 987,
},
model.PlatAndroidG: map[string]int{
"top": 1325,
},
model.PlatAndroidI: map[string]int{
"top": 1747,
},
model.PlatIPadI: map[string]int{
"top": 1157,
},
},
"119": map[int8]map[string]int{
model.PlatIPhone: map[string]int{
"top": 477,
},
model.PlatAndroid: map[string]int{
"top": 641,
},
model.PlatIPad: map[string]int{
"top": 781,
},
model.PlatIPhoneI: map[string]int{
"top": 992,
},
model.PlatAndroidG: map[string]int{
"top": 1330,
},
model.PlatAndroidI: map[string]int{
"top": 1752,
},
model.PlatIPadI: map[string]int{
"top": 1162,
},
},
"155": map[int8]map[string]int{
model.PlatIPhone: map[string]int{
"top": 478,
},
model.PlatAndroid: map[string]int{
"top": 642,
},
model.PlatIPad: map[string]int{
"top": 782,
},
model.PlatIPhoneI: map[string]int{
"top": 997,
},
model.PlatAndroidG: map[string]int{
"top": 1335,
},
model.PlatAndroidI: map[string]int{
"top": 1757,
},
model.PlatIPadI: map[string]int{
"top": 1167,
},
},
"5": map[int8]map[string]int{
model.PlatIPhone: map[string]int{
"top": 479,
},
model.PlatAndroid: map[string]int{
"top": 643,
},
model.PlatIPad: map[string]int{
"top": 783,
},
model.PlatIPhoneI: map[string]int{
"top": 1001,
},
model.PlatAndroidG: map[string]int{
"top": 1339,
},
model.PlatAndroidI: map[string]int{
"top": 1761,
},
model.PlatIPadI: map[string]int{
"top": 1171,
},
},
"23": map[int8]map[string]int{
model.PlatIPhone: map[string]int{
"top": 480,
},
model.PlatAndroid: map[string]int{
"top": 644,
},
model.PlatIPad: map[string]int{
"top": 784,
},
model.PlatIPhoneI: map[string]int{
"top": 1005,
},
model.PlatAndroidG: map[string]int{
"top": 1343,
},
model.PlatAndroidI: map[string]int{
"top": 1765,
},
model.PlatIPadI: map[string]int{
"top": 1175,
},
},
"11": map[int8]map[string]int{
model.PlatIPhone: map[string]int{
"top": 481,
},
model.PlatAndroid: map[string]int{
"top": 645,
},
model.PlatIPad: map[string]int{
"top": 785,
},
model.PlatIPhoneI: map[string]int{
"top": 1009,
},
model.PlatAndroidG: map[string]int{
"top": 1347,
},
model.PlatAndroidI: map[string]int{
"top": 1769,
},
model.PlatIPadI: map[string]int{
"top": 1179,
},
},
"165": map[int8]map[string]int{
model.PlatIPhone: map[string]int{
"top": 1643,
},
model.PlatAndroid: map[string]int{
"top": 1639,
},
model.PlatIPad: map[string]int{
"top": 1647,
},
model.PlatIPhoneI: map[string]int{
"top": 1643,
},
model.PlatAndroidG: map[string]int{
"top": 1639,
},
model.PlatIPadI: map[string]int{
"top": 1647,
},
},
"167": map[int8]map[string]int{
model.PlatIPhone: map[string]int{
"top": 1950,
},
model.PlatAndroid: map[string]int{
"top": 1952,
},
model.PlatIPad: map[string]int{
"top": 1951,
},
},
"181": map[int8]map[string]int{
model.PlatIPhone: map[string]int{
"top": 2245,
},
model.PlatAndroid: map[string]int{
"top": 2249,
},
model.PlatIPad: map[string]int{
"top": 2253,
},
},
"177": map[int8]map[string]int{
model.PlatIPhone: map[string]int{
"top": 2295,
},
model.PlatAndroid: map[string]int{
"top": 2299,
},
model.PlatIPad: map[string]int{
"top": 2303,
},
},
}
_bannersPlat = map[int8]string{
model.PlatIPhone: "467,482,471,470,472,473,474,475,476,477,478,479,480,481,1643,1950,2245,2295",
model.PlatAndroid: "631,646,635,634,636,637,638,639,640,641,642,643,644,645,1639,1952,2249,2299",
model.PlatIPad: "771,786,775,774,776,777,778,779,780,781,782,783,784,785,1647,1951,2253,2303",
model.PlatIPhoneI: "947,1013,967,962,971,975,979,983,987,992,997,1001,1005,1009,1643",
model.PlatAndroidG: "1285,1351,1305,1300,1309,1313,1317,1321,1325,1330,1335,1339,1343,1347,1639",
model.PlatAndroidI: "1707,1773,1727,1722,1731,1735,1739,1706,1747,1752,1757,1761,1765,1769,1639",
model.PlatIPadI: "1117,1183,1137,1132,1141,1145,1149,1153,1157,1162,1167,1171,1175,1179,1647",
}
)
// getBanners get banners by plat, build channel, ip.
func (s *Service) getBanners(c context.Context, plat int8, build int, module, channel, ip string, resbs map[int][]*resource.Banner, isIndex bool) (res map[string][]*banner.Banner) {
var (
bannerIds = _banners
)
if isIndex {
bannerIds = _bannersIndex
}
res = map[string][]*banner.Banner{}
for pos, bID := range bannerIds[module][plat] {
if rbs, ok := resbs[bID]; ok {
var bs []*banner.Banner
for _, rb := range rbs {
b := &banner.Banner{}
b.ResChangeBanner(rb)
bs = append(bs, b)
}
res[pos] = bs
}
}
return
}
// resBannersplat
func (s *Service) resBanners(c context.Context, plat int8, build int, mid int64, resIDStr, channel, ip, buvid, network, mobiApp, device, adExtra string) (res map[int][]*resource.Banner) {
var (
plm = s.bannerCache[plat] // operater banner
err error
isAd = true
)
if plat == model.PlatAndroid && build <= 430000 {
isAd = false
}
if res, err = s.res.ResBanner(c, plat, build, mid, resIDStr, channel, ip, buvid, network, mobiApp, device, adExtra, isAd); err != nil || len(res) == 0 {
log.Error("s.res.ResBanner is null or err(%v)", err)
res = plm
return
}
return
}

View File

@@ -0,0 +1,920 @@
package show
import (
"context"
"fmt"
"math/rand"
"runtime"
"strconv"
"strings"
"time"
clive "go-common/app/interface/main/app-card/model/card/live"
"go-common/app/interface/main/app-card/model/card/operate"
"go-common/app/interface/main/app-card/model/card/rank"
"go-common/app/interface/main/app-show/model"
"go-common/app/interface/main/app-show/model/card"
recmod "go-common/app/interface/main/app-show/model/recommend"
"go-common/app/interface/main/app-show/model/region"
"go-common/app/interface/main/app-show/model/show"
creativeAPI "go-common/app/interface/main/creative/api"
"go-common/app/service/main/archive/api"
resource "go-common/app/service/main/resource/model"
seasongrpc "go-common/app/service/openplatform/pgc-season/api/grpc/season/v1"
"go-common/library/log"
)
const (
_blackUrl = "http://172.18.7.208/privatedata/reco-deny-arcs.json"
)
var (
// 动画,音乐,舞蹈,游戏,科技,娱乐,鬼畜,电影,时尚, 生活,广告,国漫,影视,纪录片
_tids = []string{"1", "3", "129", "4", "36", "5", "119", "23", "155", "160", "11", "165", "167", "181", "177"}
_emptyItems = []*show.Item{&show.Item{}, &show.Item{}, &show.Item{}, &show.Item{}}
)
// loadRcmmndCache load recommend cahce.
func (s *Service) loadRcmmndCache(now time.Time) {
aids, err := s.rcmmnd.Hots(context.TODO())
if err != nil {
log.Error("s.rcmmnd.Hots(%v) error(%v)", now, err)
return
}
if len(aids) > 200 {
aids = aids[:200]
}
if len(aids) < 60 {
return
}
tmp, tmpOsea := s.fromAids(context.TODO(), aids)
if len(tmp) > 0 {
s.rcmmndCache = tmp
}
if len(tmpOsea) > 0 {
s.rcmmndOseaCache = tmpOsea
}
log.Info("loadRcmmndCache success")
}
// loadRegionCache load region cahce.
func (s *Service) loadRegionCache(now time.Time) {
var (
tmp = map[string][]*show.Item{}
tmpOsea = map[string][]*show.Item{}
tmpBg = map[string][]*show.Item{}
tmpBgOsea = map[string][]*show.Item{}
tmpBgEp = map[string][]*show.Item{}
tmpBgEpOsea = map[string][]*show.Item{}
sids = map[int32]*seasongrpc.CardInfoProto{}
)
for _, tid := range _tids {
rs, err := s.rcmmnd.Region(context.TODO(), tid)
if len(rs) > 8 {
rs = rs[:8]
}
tidInt, _ := strconv.Atoi(tid)
if err != nil || len(rs) < 4 {
log.Error("s.rcmmnd.Region(%v) error(%v)", now, err)
res, aids, err := s.dyn.RegionDynamic(context.TODO(), tidInt, 1, 8)
if err != nil || len(res) < 4 {
log.Error("s.dyn.RegionDynamic(%v) error(%v)", now, err)
continue
}
if len(res) > 8 {
res = res[:8]
}
if _, isBangumi := _bangumiReids[tidInt]; isBangumi {
sids, _ = s.fromSeasonID(context.TODO(), aids)
}
tmp[tid], tmpOsea[tid] = s.fromArchivesPB(res)
tmpBg[tid], tmpBgOsea[tid] = s.fromArchivesBangumi(context.TODO(), res, aids, sids, _bangumiSeasonID)
tmpBgEp[tid], tmpBgEpOsea[tid] = s.fromArchivesBangumi(context.TODO(), res, aids, sids, _bangumiEpisodeID)
} else {
if _, isBangumi := _bangumiReids[tidInt]; isBangumi {
sids, _ = s.fromSeasonID(context.TODO(), rs)
}
tmp[tid], tmpOsea[tid], tmpBg[tid], tmpBgOsea[tid], tmpBgEp[tid], tmpBgEpOsea[tid] =
s.fromBgAids(context.TODO(), rs, sids, _bangumiSeasonID)
}
log.Info("load show index region(%s) success", tid)
}
if len(tmp) > 0 {
s.regionCache = tmp
}
if len(tmpOsea) > 0 {
s.regionOseaCache = tmpOsea
}
if len(tmpBg) > 0 {
s.regionBgCache = tmpBg
}
if len(tmpBgOsea) > 0 {
s.regionBgOseaCache = tmpBgOsea
}
if len(tmpBgEp) > 0 {
s.regionBgEpCache = tmpBgEp
}
if len(tmpBgEpOsea) > 0 {
s.regionBgEpOseaCache = tmpBgEpOsea
}
log.Info("loadRegionCache success")
}
// loadBannerCahce load banner cache.
func (s *Service) loadBannerCahce() {
var (
resbs = map[int8]map[int][]*resource.Banner{}
)
for plat, resIDStr := range _bannersPlat {
mobiApp := model.MobiApp(plat)
res, err := s.res.ResBanner(context.TODO(), plat, 515007, 0, resIDStr, "master", "", "", "", mobiApp, "", "", false)
if err != nil || len(res) == 0 {
log.Error("s.res.ResBanner is null or err(%v)", err)
return
}
resbs[plat] = res
}
if len(resbs) > 0 {
s.bannerCache = resbs
}
log.Info("loadBannerCahce success")
}
// loadBgmCache load bangumi cache
func (s *Service) loadBgmCache(now time.Time) {
bgms, err := s.bgm.Recommend(now)
if err != nil {
log.Error("s.bgm.Recommend(%v) error(%v)", now, err)
return
}
if len(bgms) < 8 {
return
}
var (
tmp = map[int8][]*show.Item{}
si *show.Item
)
for _, bgm := range bgms {
si = &show.Item{}
si.FromBangumi(bgm)
tmp[model.PlatAndroid] = append(tmp[model.PlatAndroid], si)
tmp[model.PlatIPhone] = append(tmp[model.PlatIPhone], si)
tmp[model.PlatAndroidG] = append(tmp[model.PlatAndroidG], si)
tmp[model.PlatAndroidI] = append(tmp[model.PlatAndroidI], si)
tmp[model.PlatIPhoneI] = append(tmp[model.PlatIPhoneI], si)
si = &show.Item{}
si.FromBangumi(bgm)
si.Cover = bgm.Cover // pad hd get bangumi cover
tmp[model.PlatIPad] = append(tmp[model.PlatIPad], si)
tmp[model.PlatIPadI] = append(tmp[model.PlatIPadI], si)
tmp[model.PlatAndroidTV] = append(tmp[model.PlatAndroidTV], si)
}
s.bgmCache = tmp
log.Info("loadBgmCache success")
}
// loadLiveCache load live cache .
func (s *Service) loadLiveCache(now time.Time) {
lrs, err := s.lv.Recommend(now)
if err != nil {
log.Error("s.live.Recommend(%v) error(%v)", now, err)
return
}
if lrs == nil {
return
}
s.liveCount = lrs.Count
if subLen := len(lrs.Lives.Subject); subLen > 0 {
tmp := make([]*show.Item, 0, subLen)
for _, l := range lrs.Lives.Subject {
si := &show.Item{}
si.FromLive(l)
tmp = append(tmp, si)
}
s.liveMoeCache = tmp
}
if hotLen := len(lrs.Lives.Hot); hotLen >= 4 {
tmp := make([]*show.Item, 0, hotLen)
for _, l := range lrs.Lives.Hot {
si := &show.Item{}
si.FromLive(l)
tmp = append(tmp, si)
}
s.liveHotCache = tmp
}
log.Info("loadLiveCache success")
}
// loadShowCache load all show cache
func (s *Service) loadShowCache() {
hdm, err := s.dao.Heads(context.TODO())
if err != nil {
log.Error("s.dao.Heads error(%v)", err)
return
}
itm, err := s.dao.Items(context.TODO())
if err != nil {
log.Error("s.dao.Items error(%v)", err)
return
}
tmp, tmpbg, tmpbgep := s.mergeShow(hdm, itm)
if len(tmp) > 0 {
s.cache = tmp
}
if len(tmpbg) > 0 {
s.cacheBg = tmpbg
}
if len(tmpbgep) > 0 {
s.cacheBgEp = tmpbgep
}
log.Info("loadShowCache success")
}
// loadShowTempCache load all show temp cache
func (s *Service) loadShowTempCache() {
hdm, err := s.dao.TempHeads(context.TODO())
if err != nil {
log.Error("s.dao.TempHeads error(%v)", err)
return
}
itm, err := s.dao.TempItems(context.TODO())
if err != nil {
log.Error("s.dao.TempItems error(%v)", err)
return
}
s.tempCache, _, _ = s.mergeShow(hdm, itm)
log.Info("loadShowTempCache success")
}
// loadRegionListCache
func (s *Service) loadRegionListCache() {
res, err := s.rg.RegionPlat(context.TODO())
if err != nil {
log.Error("s.rg.RegionPlat error(%v)", err)
return
}
tmpRegion := map[int]*region.Region{}
tmp := map[int]*region.Region{}
for _, v := range res {
// region list map
tmpRegion[v.Rid] = v
}
for _, r := range res {
if r.Reid != 0 {
if rerg, ok := tmpRegion[r.Reid]; ok {
tmp[r.Rid] = rerg
}
}
}
s.reRegionCache = tmp
}
// loadRankAllCache
func (s *Service) loadRankAllCache() {
var (
rankAids []int64
err error
as map[int64]*api.Arc
c = context.TODO()
trankCache = []*rank.Rank{}
)
aids, others, scores, err := s.rcmmnd.RankAppAll(c)
if err != nil {
log.Error("s.rcmmnd.RankAppAll error(%v)", err)
return
}
for _, aid := range aids {
if _, ok := others[aid]; !ok {
rankAids = append(rankAids, aid)
}
}
if len(rankAids) == 0 {
return
}
s.rankAidsCache = rankAids
s.rankScoreCache = scores
if as, err = s.arc.ArchivesPB(c, rankAids); err != nil {
log.Error("s.arc.ArchivesPB aids(%v) error(%v)", aids, err)
return
}
if len(as) == 0 {
log.Warn("s.arc.ArchivesPB(%v) length is 0", rankAids)
return
}
s.rankArchivesCache = as
tmp, tmpOsea := s.fromRankAids(c, rankAids, scores, as)
if len(tmp) > 0 {
s.rankCache = tmp
}
if len(tmpOsea) > 0 {
s.rankOseaCache = tmpOsea
}
log.Info("loadRankAllCache success")
// new cache
for _, aid := range rankAids {
r := &rank.Rank{
Aid: aid,
Score: int32(scores[aid]),
}
trankCache = append(trankCache, r)
}
s.rankCache2 = trankCache
}
// loadColumnListCache
func (s *Service) loadColumnListCache(now time.Time) {
var (
tmpChild = map[int]*card.ColumnList{}
)
columns, err := s.cdao.ColumnList(context.TODO(), now)
if err != nil {
log.Error("s.cdao.ColumnList error(%v)", err)
return
}
for _, column := range columns {
tmpChild[column.Cid] = column
}
s.columnListCache = tmpChild
}
// loadCardCache load all card cache
func (s *Service) loadCardCache(now time.Time) {
hdm, err := s.cdao.PosRecs(context.TODO(), now)
if err != nil {
log.Error("s.cdao.PosRecs error(%v)", err)
return
}
itm, aids, err := s.cdao.RecContents(context.TODO(), now)
if err != nil {
log.Error("s.cdao.RecContents error(%v)", err)
return
}
tmpItem := map[int]map[int64]*show.Item{}
for recid, aid := range aids {
tmpItem[recid] = s.fromCardAids(context.TODO(), aid)
}
tmp := s.mergeCard(context.TODO(), hdm, itm, tmpItem, now)
s.cardCache = tmp
}
func (s *Service) mergeCard(c context.Context, hdm map[int8]map[int][]*card.Card, itm map[int][]*card.Content, tmpItems map[int]map[int64]*show.Item, now time.Time) (res map[string][]*show.Show) {
var (
_topic = 1
_activity = 0
)
res = map[string][]*show.Show{}
for plat, phds := range hdm {
hds, ok := phds[0]
if !ok {
continue
}
for _, hd := range hds {
key := fmt.Sprintf(_initCardKey, plat)
var (
sis []*show.Item
)
its, ok := itm[hd.ID]
if !ok {
its = []*card.Content{}
}
tmpItem, ok := tmpItems[hd.ID]
if !ok {
tmpItem = map[int64]*show.Item{}
}
// 1 daily 2 topic 3 activity 4 rank 5 polymeric_card
switch hd.Type {
case 1:
for _, ci := range its {
si := s.fillCardItem(ci, tmpItem)
if si.Title != "" {
sis = append(sis, si)
}
}
case 2:
if topicID, err := strconv.ParseInt(hd.Rvalue, 10, 64); err == nil {
if actm, err := s.act.Activitys(c, []int64{topicID}, _topic, ""); err != nil {
} else {
if act, ok := actm[topicID]; ok && act.H5Cover != "" && act.H5URL != "" {
si := &show.Item{}
si.FromTopic(act)
sis = []*show.Item{si}
}
}
}
case 3:
if topicID, err := strconv.ParseInt(hd.Rvalue, 10, 64); err == nil {
if actm, err := s.act.Activitys(c, []int64{topicID}, _activity, ""); err != nil {
} else {
if act, ok := actm[topicID]; ok && act.H5Cover != "" && act.H5URL != "" {
si := &show.Item{}
si.FromActivity(act, now)
sis = []*show.Item{si}
}
}
}
case 4:
if len(s.rankCache) > 3 {
sis = s.rankCache[:3]
} else {
sis = s.rankCache
}
case 5, 6, 8:
for _, ci := range its {
si := s.fillCardItem(ci, tmpItem)
if si.Title != "" {
sis = append(sis, si)
}
}
case 7:
si := &show.Item{
Title: hd.Title,
Cover: hd.Cover,
Desc: hd.Desc,
Goto: hd.Goto,
Param: hd.Param,
}
if hd.Goto == model.GotoColumnStage {
paramInt, _ := strconv.Atoi(hd.Param)
if c, ok := s.columnListCache[paramInt]; ok {
cidStr := strconv.Itoa(c.Ceid)
si.URI = model.FillURICategory(hd.Goto, cidStr, hd.Param)
}
} else {
si.URI = hd.URi
}
sis = append(sis, si)
default:
continue
}
if len(sis) == 0 {
continue
}
sw := &show.Show{}
sw.Head = &show.Head{
CardID: hd.ID,
Title: hd.Title,
Type: hd.TypeStr,
Build: hd.Build,
Condition: hd.Condition,
Plat: hd.Plat,
Style: "small",
}
if hd.Cover != "" {
sw.Head.Cover = hd.Cover
}
switch sw.Head.Type {
case model.GotoDaily:
sw.Head.Date = now.Unix()
sw.Head.Param = hd.Rvalue
case model.GotoCard:
sw.Head.URI = hd.URi
sw.Head.Goto = hd.Goto
sw.Head.Param = hd.Param
case model.GotoRank:
sw.Head.Param = "all"
case model.GotoTopic, model.GotoActivity:
if sw.Head.Title == "" {
if len(sis) > 0 {
sw.Head.Title = sis[0].Title
}
}
case model.GotoVeidoCard:
sw.Head.Param = hd.Param
if hd.Goto == model.GotoColumnStage {
paramInt, _ := strconv.Atoi(hd.Param)
if c, ok := s.columnListCache[paramInt]; ok {
cidStr := strconv.Itoa(c.Ceid)
sw.Head.URI = model.FillURICategory(hd.Goto, cidStr, hd.Param)
}
sw.Head.Goto = model.GotoColumn
} else {
sw.Head.Goto = hd.Goto
sw.Head.URI = hd.URi
}
if sisLen := len(sis); sisLen > 1 {
if sisLen%2 != 0 {
sis = sis[:sisLen-1]
}
} else {
continue
}
case model.GotoSpecialCard:
sw.Head.Cover = ""
case model.GotoTagCard:
if hd.TagID > 0 {
var tagIDInt int64
sw.Head.Title, tagIDInt = s.fromTagIDByName(c, hd.TagID, now)
sw.Head.Param = strconv.FormatInt(tagIDInt, 10)
sw.Head.Goto = model.GotoTagID
}
}
if len(sis) == 0 {
sis = _emptyShowItems
}
sw.Body = sis
res[key] = append(res[key], sw)
}
}
return
}
func (s *Service) fillCardItem(csi *card.Content, tsi map[int64]*show.Item) (si *show.Item) {
si = &show.Item{}
switch csi.Type {
case model.CardGotoAv:
si.Goto = model.GotoAv
si.Param = csi.Value
}
si.URI = model.FillURI(si.Goto, si.Param, nil)
if si.Goto == model.GotoAv {
aid, err := strconv.ParseInt(si.Param, 10, 64)
if err != nil {
log.Error("strconv.ParseInt(%s) error(%v)", si.Param, err)
} else {
if it, ok := tsi[aid]; ok {
si = it
if csi.Title != "" {
si.Title = csi.Title
}
} else {
si = &show.Item{}
}
}
}
return
}
// fromTagIDByName from tag_id by tag_name
func (s *Service) fromTagIDByName(ctx context.Context, tagID int, now time.Time) (tagName string, tagIDInt int64) {
tag, err := s.tag.TagInfo(ctx, 0, tagID, now)
if err != nil {
log.Error("s.tag.TagInfo(%d) error(%v)", tagID, err)
return
}
tagName = tag.Name
tagIDInt = tag.Tid
return
}
// mergeShow merge heads and items
func (s *Service) mergeShow(hdm map[int8][]*show.Head, itm map[int][]*show.Item) (res, resbg, resbgep map[string][]*show.Show) {
res = map[string][]*show.Show{}
resbg = map[string][]*show.Show{}
resbgep = map[string][]*show.Show{}
for plat, hds := range hdm {
for _, hd := range hds {
key := fmt.Sprintf(_initShowKey, plat, hd.Language)
its, ok := itm[hd.ID]
if !ok {
continue
}
var (
sis []*show.Item
sisbg []*show.Item
sisbgep []*show.Item
ext *show.Ext
)
switch hd.Type {
case "recommend":
for _, si := range its {
if si.IsRandom() {
continue
}
s.fillItem(plat, si)
sis = append(sis, si)
}
sisbg = sis
sisbgep = sis
case "live":
if plat == model.PlatAndroidTV {
continue
}
ext = &show.Ext{
LiveCnt: s.liveCount,
}
case "bangumi":
sis = s.sliceCache(plat, s.bgmCache[plat])
sisbg = sis
sisbgep = sis
case "region":
if model.IsOverseas(plat) {
sis = s.sliceCache(plat, s.regionOseaCache[hd.Param])
sisbg = s.sliceCache(plat, s.regionBgOseaCache[hd.Param])
sisbgep = s.sliceCache(plat, s.regionBgEpOseaCache[hd.Param])
} else {
sis = s.sliceCache(plat, s.regionCache[hd.Param])
sisbg = s.sliceCache(plat, s.regionBgCache[hd.Param])
sisbgep = s.sliceCache(plat, s.regionBgEpCache[hd.Param])
}
case "sp":
for _, si := range its {
spidIdx := strings.Split(si.Param, ",")
si.Goto = model.GotoSp
si.Param = spidIdx[0]
si.URI = model.FillURI(model.GotoSp, spidIdx[0], nil)
if len(spidIdx) == 2 {
si.Index = spidIdx[1]
}
sis = append(sis, si)
}
sisbg = sis
sisbgep = sis
case "activity":
for _, si := range its {
if si.IsRandom() {
continue
}
si.Goto = model.GotoWeb
si.URI = model.FillURI(model.GotoWeb, si.Param, nil)
sis = append(sis, si)
}
sisbg = sis
sisbgep = sis
case "topic":
for _, si := range its {
si.Goto = model.GotoWeb
si.URI = model.FillURI(model.GotoWeb, si.Param, nil)
sis = append(sis, si)
}
sisbg = sis
sisbgep = sis
case "focus":
for _, si := range its {
if si.IsRandom() {
continue
}
pp := strings.Split(si.Param, ",")
si.Param = pp[0]
if len(pp) == 2 {
si.Goto = pp[1]
} else {
si.Goto = model.GotoAv
}
si.URI = model.FillURI(si.Goto, si.Param, nil)
sisbg = append(sisbg, si)
}
sisbgep = sisbg
default:
continue
}
sw := &show.Show{}
sw.Head = hd
sw.Body = sis
sw.Ext = ext
swbg := &show.Show{}
swbg.Head = hd
swbg.Body = sisbg
swbg.Ext = ext
swbgep := &show.Show{}
swbgep.Head = hd
swbgep.Body = sisbgep
swbgep.Ext = ext
// append show.Show
res[key] = append(res[key], sw)
resbg[key] = append(resbg[key], swbg)
resbgep[key] = append(resbgep[key], swbgep)
}
}
return
}
// fillItem used by loadShowCache
func (s *Service) fillItem(plat int8, si *show.Item) {
pp := strings.Split(si.Param, ",")
si.Param = pp[0]
if len(pp) == 2 {
si.Goto = pp[1]
} else {
si.Goto = model.GotoAv
}
si.URI = model.FillURI(si.Goto, si.Param, nil)
if si.Goto == model.GotoAv {
aid, err := strconv.ParseInt(si.Param, 10, 64)
if err != nil {
log.Error("strconv.ParseInt(%s) error(%v)", si.Param, err)
} else {
a, err := s.arc.Archive(context.TODO(), aid)
if err != nil || a == nil {
log.Error("s.arc.Archive(%d) error(%v)", aid, err)
} else {
si.Play = int(a.Stat.View)
si.Danmaku = int(a.Stat.Danmaku)
if si.Title == "" {
si.Title = a.Title
}
if si.Cover == "" {
si.Cover = a.Pic
}
}
}
} else {
si.Play = rand.Intn(1000)
si.Danmaku = rand.Intn(1000)
}
}
// sliceCache used by loadShowCache
func (s *Service) sliceCache(plat int8, chc []*show.Item) []*show.Item {
if len(chc) == 0 {
return _emptyItems
}
cnt := 4
if plat == model.PlatIPad {
cnt = 8
}
if len(chc) < cnt {
cnt = len(chc)
}
return chc[:cnt]
}
func (s *Service) loadBlackCache() {
var res []int64
if err := s.client.Get(context.TODO(), _blackUrl, "", nil, &res); err != nil {
log.Error("recommend ranking url(%s) error(%v)", _blackUrl, err)
return
}
if len(res) == 0 {
return
}
tmp := map[int64]struct{}{}
for _, aid := range res {
tmp[aid] = struct{}{}
}
s.blackCache = tmp
log.Info("reBlackList success")
}
// rcmmndproc get recommend aids and add into cache.
func (s *Service) rcmmndproc() {
var ctx = context.TODO()
for i := 0; i < runtime.NumCPU(); i++ {
go func() {
for {
r := <-s.rcmmndCh
s.dao.AddRcmmndCache(ctx, r.key, r.aids...)
}
}()
}
}
// // loadPopularCard load popular card
// func (s *Service) loadPopularCard(now time.Time) {
// var (
// c = context.TODO()
// err error
// tmp, tmpcache []*card.PopularCard
// tmpPlat = map[int64]map[int8][]*card.PopularCardPlat{}
// )
// if tmp, err = s.cdao.Card(c, now); err != nil {
// log.Error("popular card s.cd.Card error(%v)", err)
// return
// }
// if tmpPlat, err = s.cdao.CardPlat(c); err != nil {
// log.Error("popular card s.cd.CardPlat error(%v)", err)
// return
// }
// for _, t := range tmp {
// tc := &card.PopularCard{}
// *tc = *t
// if pconfig, ok := tmpPlat[t.ID]; ok {
// tc.PopularCardPlat = pconfig
// }
// tmpcache = append(tmpcache, tc)
// }
// s.hotCache = tmpcache
// log.Info("hotCache success")
// }
func (s *Service) loadHotTenTabAids() {
var tmpList = make(map[int][]*recmod.CardList)
for i := 0; i < 10; i++ {
var (
c = context.TODO()
err error
hottabAids []*recmod.CardList
flowResp *creativeAPI.FlowResponse
oids []int64
forbidAids = make(map[int64]struct{})
)
if hottabAids, err = s.rcmmnd.HotHeTongTabCard(c, i); err != nil {
log.Error("%+v", err)
continue
}
for _, hot := range hottabAids {
if hot.Goto == model.GotoAv {
oids = append(oids, hot.ID)
}
}
if flowResp, err = s.creativeClient.FlowJudge(context.Background(), &creativeAPI.FlowRequest{
Oids: oids,
Business: 4,
Gid: 24,
}); err != nil {
log.Error("s.creativeClient.FlowJudge error(%v)", err)
tmpList[i] = hottabAids
} else {
for _, oid := range flowResp.Oids {
forbidAids[oid] = struct{}{}
}
for _, list := range hottabAids {
if list.Goto == model.GotoAv {
if _, ok := forbidAids[list.ID]; ok {
log.Info("aid(%d) is flowJundged", list.ID)
continue
}
}
tmpList[i] = append(tmpList[i], list)
}
}
log.Info("buildHotSuccess(%d) len(%d)", i, len(tmpList[i]))
}
if len(tmpList) == 10 {
s.hotTenTabCardCache = tmpList
}
}
func (s *Service) loadHotTopicCache() {
var (
c = context.TODO()
err error
topics []*clive.TopicHot
)
if topics, err = s.lv.TopicHots(c); err != nil {
log.Error("topichots s.lv.TopicHots error(%v)", err)
return
}
if len(topics) > 8 {
s.hottopicsCache = topics[:8]
} else {
s.hottopicsCache = topics
}
log.Info("loadHotTopicCache success")
}
func (s *Service) loadHotTenMergeRcmdCache(i int) {
// mc
var (
c = context.TODO()
hcards []*recmod.CardList
rcmdcard []*card.PopularCard
ok bool
err error
)
if hcards, ok = s.hotTenTabCardCache[i]; ok {
for _, hcard := range hcards {
rcmdcard = append(rcmdcard, hcard.CardListChange())
}
if err = s.cdao.AddPopularCardTenCache(c, i, rcmdcard); err != nil {
log.Error("cards mc s.cdao.AddPopularCardCache error(%v)", err)
return
}
}
}
// PopularCardList cards
func (s *Service) PopularCardTenList(c context.Context, i int) (res []*card.PopularCard) {
var err error
if res, err = s.cdao.PopularCardTenCache(c, i); err != nil {
log.Error("%+v", err)
return
}
return
}
func (s *Service) loadCardSetCache() {
var (
cards map[int64]*operate.CardSet
err error
)
if cards, err = s.cdao.CardSet(context.TODO()); err != nil {
log.Error("%+v", err)
return
}
s.cardSetCache = cards
}
func (s *Service) loadDynamicHotCache() {
var (
liveList []*clive.DynamicHot
err error
)
if liveList, err = s.lv.DynamicHot(context.TODO()); err != nil {
log.Error("s.lv.dynamichot error(%v)", err)
return
}
s.dynamicHotCache = liveList
}
func (s *Service) loadEventTopicCache() {
var (
eventtopic map[int64]*operate.EventTopic
err error
)
if eventtopic, err = s.cdao.EventTopic(context.TODO()); err != nil {
log.Error("s.cdao.eventtopic error(%v)", err)
return
}
s.eventTopicCache = eventtopic
}

View File

@@ -0,0 +1,150 @@
package show
import (
"context"
"hash/crc32"
"strconv"
"time"
"go-common/app/interface/main/app-show/model"
"go-common/app/interface/main/app-show/model/card"
"go-common/app/interface/main/app-show/model/feed"
"go-common/app/service/main/archive/api"
"go-common/app/service/main/archive/model/archive"
)
var (
_emptyList = []*feed.Item{}
)
// FeedIndex feed index
func (s *Service) FeedIndex(c context.Context, mid, idx int64, plat int8, build, loginEvent int, lastParam, mobiApp, device, buvid string, now time.Time) (res []*feed.Item) {
var (
ps = 10
isIpad = plat == model.PlatIPad
cards, cardCache []*card.PopularCard
)
if isIpad {
ps = 20
}
var key int
if mid > 0 {
key = int((mid / 1000) % 10)
} else {
key = int((crc32.ChecksumIEEE([]byte(buvid)) / 1000) % 10)
}
cardCache = s.PopularCardTenList(c, key)
if len(cardCache) > int(idx) {
cards = cardCache[idx:]
} else {
res = _emptyList
return
}
res = s.dealItem(c, plat, build, ps, cards, idx, lastParam, now)
if len(res) == 0 {
res = _emptyList
return
}
//infoc
infoc := &feedInfoc{
mobiApp: mobiApp,
device: device,
build: strconv.Itoa(build),
now: now.Format("2006-01-02 15:04:05"),
loginEvent: strconv.Itoa(loginEvent),
mid: strconv.FormatInt(mid, 10),
buvid: buvid,
page: strconv.Itoa((int(idx) / ps) + 1),
feed: res,
}
s.infocfeed(infoc)
return
}
// dealItem feed item
func (s *Service) dealItem(c context.Context, plat int8, build, ps int, cards []*card.PopularCard, idx int64, lastParam string, now time.Time) (is []*feed.Item) {
const _rankCount = 3
var (
uri map[int64]string
// key
max = int64(100)
_fTypeOperation = "operation"
aids []int64
am map[int64]*api.Arc
feedcards []*card.PopularCard
err error
)
LOOP:
for pos, ca := range cards {
var cardIdx = idx + int64(pos+1)
if cardIdx > max && ca.FromType != _fTypeOperation {
continue
}
if config, ok := ca.PopularCardPlat[plat]; ok {
for _, l := range config {
if model.InvalidBuild(build, l.Build, l.Condition) {
continue LOOP
}
}
} else if ca.FromType == _fTypeOperation {
continue LOOP
}
tmp := &card.PopularCard{}
*tmp = *ca
tmp.Idx = cardIdx
feedcards = append(feedcards, tmp)
switch ca.Type {
case model.GotoAv:
aids = append(aids, ca.Value)
}
if len(feedcards) == ps {
break
}
}
if len(aids) != 0 {
if am, err = s.arc.ArchivesPB(c, aids); err != nil {
s.pMiss.Incr("popularcard_Archives")
err = nil
} else {
s.pHit.Incr("popularcard_Archives")
}
}
for _, ca := range feedcards {
i := &feed.Item{}
i.FromType = ca.FromType
i.Idx = ca.Idx
i.Pos = ca.Pos
switch ca.Type {
case model.GotoAv:
a := am[ca.Value]
isOsea := model.IsOverseas(plat)
if a != nil && a.IsNormal() && (!isOsea || (isOsea && a.AttrVal(archive.AttrBitOverseaLock) == 0)) {
i.FromPlayerAv(a, uri[a.Aid])
i.FromRcmdReason(ca)
// if tag, ok := s.hotArcTag[a.Aid]; ok {
// i.Tag = &feed.Tag{TagID: tag.ID, TagName: tag.Name}
// }
i.Goto = ca.Type
is = append(is, i)
}
case model.GotoRank:
if rankAids := s.rankAidsCache; len(rankAids) >= _rankCount {
i.FromRank(rankAids, s.rankScoreCache, s.rankArchivesCache)
// i.Param = strconv.FormatInt(ca.ID, 10)
if i.Goto != "" {
is = append(is, i)
}
}
case model.GotoHotTopic:
if hotTopics := s.hottopicsCache; len(hotTopics) > 0 {
i.FromHotTopic(hotTopics)
is = append(is, i)
}
}
}
if rl := len(is); rl == 0 {
is = _emptyList
return
}
return
}

View File

@@ -0,0 +1,306 @@
package show
import (
"context"
"hash/crc32"
"strconv"
"time"
cdm "go-common/app/interface/main/app-card/model"
cardm "go-common/app/interface/main/app-card/model/card"
operate "go-common/app/interface/main/app-card/model/card/operate"
"go-common/app/interface/main/app-card/model/card/rank"
"go-common/app/interface/main/app-show/model"
"go-common/app/interface/main/app-show/model/card"
"go-common/app/interface/main/app-show/model/feed"
account "go-common/app/service/main/account/model"
"go-common/app/service/main/archive/api"
"go-common/app/service/main/archive/model/archive"
relation "go-common/app/service/main/relation/model"
"go-common/library/ecode"
"go-common/library/log"
"go-common/library/sync/errgroup"
)
var (
_emptyList2 = []cardm.Handler{}
)
// FeedIndex feed index
func (s *Service) FeedIndex2(c context.Context, mid, idx int64, plat int8, build, loginEvent int, lastParam, mobiApp, device, buvid string, now time.Time) (res []cardm.Handler, ver string, err error) {
var (
ps = 10
isIpad = plat == model.PlatIPad
cards, cardCache []*card.PopularCard
infocs []*feed.Item
style int8
)
if isIpad {
ps = 20
}
var key int
if mid > 0 {
key = int((mid / 1000) % 10)
} else {
key = int((crc32.ChecksumIEEE([]byte(buvid)) / 1000) % 10)
}
cardCache = s.PopularCardTenList(c, key)
if len(cardCache) > int(idx) {
cards = cardCache[idx:]
} else {
err = ecode.AppNotData
res = _emptyList2
return
}
// HotDynamic====================
// cards = append(cards[:0], append([]*card.PopularCard{&card.PopularCard{Type: model.GotoHotDynamic, ReasonType: 0, FromType: "recommend"}}, cards[0:]...)...)
// HotDynamic====================
//build
if plat == model.PlatIPhone && build > 8230 || plat == model.PlatAndroid && build > 5345000 {
// switch key {
// // case 0, 3:
// // style = cdm.HotCardStyleShowUp
// case 2, 5:
// style = cdm.HotCardStyleHideUp
// default:
// style = cdm.HotCardStyleOld
// }
style = cdm.HotCardStyleHideUp
} else {
style = cdm.HotCardStyleOld
}
//build
res, infocs = s.dealItem2(c, plat, build, ps, cards, mid, idx, lastParam, now, style)
ver = strconv.FormatInt(now.Unix(), 10)
if len(res) == 0 {
err = ecode.AppNotData
res = _emptyList2
return
}
//infoc
infoc := &feedInfoc{
mobiApp: mobiApp,
device: device,
build: strconv.Itoa(build),
now: now.Format("2006-01-02 15:04:05"),
loginEvent: strconv.Itoa(loginEvent),
mid: strconv.FormatInt(mid, 10),
buvid: buvid,
page: strconv.Itoa((int(idx) / ps) + 1),
feed: infocs,
}
s.infocfeed(infoc)
return
}
// dealItem feed item
func (s *Service) dealItem2(c context.Context, plat int8, build, ps int, cards []*card.PopularCard, mid, idx int64, lastParam string, now time.Time, style int8) (is []cardm.Handler, infocs []*feed.Item) {
var (
max = int64(100)
_fTypeOperation = "operation"
aids, avUpIDs, upIDs, rnUpIDs []int64
am map[int64]*archive.ArchiveWithPlayer
feedcards []*card.PopularCard
err error
rank *operate.Card
accountm map[int64]*account.Card
isAtten map[int64]int8
statm map[int64]*relation.Stat
)
cardSet := map[int64]*operate.Card{}
eventTopic := map[int64]*operate.Card{}
LOOP:
for pos, ca := range cards {
var cardIdx = idx + int64(pos+1)
if cardIdx > max && ca.FromType != _fTypeOperation {
continue
}
if config, ok := ca.PopularCardPlat[plat]; ok {
for _, l := range config {
if model.InvalidBuild(build, l.Build, l.Condition) {
continue LOOP
}
}
} else if ca.FromType == _fTypeOperation {
continue LOOP
}
tmp := &card.PopularCard{}
*tmp = *ca
if plat == model.PlatIPhone && build > 8290 || plat == model.PlatAndroid && build > 5365000 {
switch ca.Type {
case model.GotoUpRcmdNew:
tmp.Type = model.GotoUpRcmdNewV2
}
}
tmp.Idx = cardIdx
feedcards = append(feedcards, tmp)
switch ca.Type {
case model.GotoAv:
aids = append(aids, ca.Value)
case model.GotoRank:
rank = &operate.Card{}
rank.FromRank(s.rankCache2)
case model.GotoUpRcmdNew, model.GotoUpRcmdNewV2:
cardm, as, upid := s.cardSetChange(c, ca.Value)
aids = append(aids, as...)
for id, card := range cardm {
cardSet[id] = card
}
rnUpIDs = append(rnUpIDs, upid)
case model.GotoEventTopic:
eventTopic = s.eventTopicChange(c, ca.Value)
}
if len(feedcards) == ps {
break
}
}
if len(aids) != 0 {
var as map[int64]*api.Arc
if as, err = s.arc.ArchivesPB(c, aids); err != nil {
log.Error("%+v", err)
err = nil
} else {
am = map[int64]*archive.ArchiveWithPlayer{}
for _, a := range as {
avUpIDs = append(avUpIDs, a.Author.Mid)
am[a.Aid] = &archive.ArchiveWithPlayer{Archive3: archive.BuildArchive3(a)}
}
}
}
switch style {
case cdm.HotCardStyleShowUp, cdm.HotCardStyleHideUp:
upIDs = append(upIDs, avUpIDs...)
}
upIDs = append(upIDs, rnUpIDs...)
avUpIDs = append(avUpIDs, rnUpIDs...)
g, ctx := errgroup.WithContext(c)
if len(avUpIDs) > 0 {
g.Go(func() (err error) {
if accountm, err = s.acc.Cards3(ctx, avUpIDs); err != nil {
log.Error("%+v", err)
err = nil
}
return nil
})
}
if len(upIDs) > 0 {
g.Go(func() (err error) {
if statm, err = s.reldao.Stats(ctx, upIDs); err != nil {
log.Error("%+v", err)
err = nil
}
return nil
})
if mid != 0 {
g.Go(func() error {
isAtten = s.acc.IsAttention(ctx, upIDs, mid)
return nil
})
}
}
g.Wait()
for _, ca := range feedcards {
var (
r = ca.PopularCardToAiChange()
main interface{}
cardType cdm.CardType
)
r.Style = style
op := &operate.Card{}
op.From(cdm.CardGt(r.Goto), r.ID, 0, plat, build)
switch r.Style {
case cdm.HotCardStyleShowUp, cdm.HotCardStyleHideUp:
switch r.Goto {
case model.GotoAv:
cardType = cdm.SmallCoverV5
}
}
switch r.Goto {
case model.GotoAv:
if a, ok := am[r.ID]; ok && (a.AttrVal(archive.AttrBitOverseaLock) == 0 || !model.IsOverseas(plat)) {
main = map[int64]*archive.ArchiveWithPlayer{a.Aid: a}
// op.Tid = a.Aid
r.HideButton = true
if (plat == model.PlatIPhone && build > 8290 || plat == model.PlatAndroid && build > 5365000) && cardType == cdm.SmallCoverV5 {
op.Switch = cdm.SwitchCooperationShow
} else {
op.Switch = cdm.SwitchCooperationHide
}
}
case model.GotoRank:
ams := map[int64]*archive.ArchiveWithPlayer{}
for aid, a := range s.rankArchivesCache {
ams[aid] = &archive.ArchiveWithPlayer{Archive3: archive.BuildArchive3(a)}
}
main = map[cdm.Gt]interface{}{cdm.GotoAv: ams}
op = rank
case model.GotoHotTopic:
main = s.hottopicsCache
case model.GotoUpRcmdNew, model.GotoUpRcmdNewV2:
main = am
op = cardSet[r.ID]
case model.GotoHotDynamic:
main = s.dynamicHotCache
case model.GotoEventTopic:
op = eventTopic[r.ID]
}
h := cardm.Handle(plat, cdm.CardGt(r.Goto), cardType, cdm.ColumnSvrSingle, r, nil, isAtten, statm, accountm)
if h == nil {
continue
}
h.From(main, op)
h.Get().FromType = ca.FromType
h.Get().Idx = ca.Idx
if h.Get().Right {
h.Get().ThreePointWatchLater()
is = append(is, h)
}
// infoc
tinfo := &feed.Item{
Goto: ca.Type,
Param: strconv.FormatInt(ca.Value, 10),
URI: h.Get().URI,
FromType: ca.FromType,
Idx: h.Get().Idx,
CornerMark: ca.CornerMark,
CardStyle: r.Style,
}
if r.RcmdReason != nil {
tinfo.RcmdContent = r.RcmdReason.Content
}
if op != nil {
switch r.Goto {
case model.GotoEventTopic:
tinfo.Item = append(tinfo.Item, &feed.Item{Param: op.URI, Goto: string(op.Goto)})
default:
for _, tmp := range op.Items {
tinfo.Item = append(tinfo.Item, &feed.Item{Param: strconv.FormatInt(tmp.ID, 10), Goto: string(tmp.Goto)})
}
}
}
infocs = append(infocs, tinfo)
if len(is) == ps {
break
}
}
rl := len(is)
if rl == 0 {
is = _emptyList2
return
}
return
}
func (s *Service) RankCard() (ranks []*rank.Rank, aids []int64) {
const _limit = 3
ranks = make([]*rank.Rank, 0, _limit)
aids = make([]int64, 0, _limit)
for _, rank := range s.rankCache2 {
ranks = append(ranks, rank)
aids = append(aids, rank.Aid)
if len(ranks) == _limit {
break
}
}
return
}

View File

@@ -0,0 +1,178 @@
package show
import (
"bytes"
"strconv"
"time"
"go-common/app/interface/main/app-show/conf"
"go-common/app/interface/main/app-show/model"
"go-common/app/interface/main/app-show/model/feed"
"go-common/app/interface/main/app-show/model/show"
"go-common/library/log"
binfoc "go-common/library/log/infoc"
)
type infoc struct {
mid string
client string
buvid string
disid string
ip string
api string
now string
isRcmmnd string
items []*show.Item
}
type feedInfoc struct {
mobiApp string
device string
build string
now string
loginEvent string
mid string
buvid string
page string
feed []*feed.Item
}
// Infoc write data for Hadoop do analytics
func (s *Service) Infoc(mid int64, plat int8, buvid, disid, ip, api string, items []*show.Item, now time.Time) {
select {
case s.logCh <- infoc{strconv.FormatInt(mid, 10), strconv.Itoa(int(plat)), buvid, disid, ip, api, strconv.FormatInt(now.Unix(), 10), "1", items}:
default:
log.Warn("infoc log buffer is full")
}
}
func (s *Service) infocfeed(i interface{}) {
select {
case s.logFeedCh <- i:
default:
log.Warn("infocfeed chan full")
}
}
// writeInfoc
func (s *Service) infocproc() {
const (
// infoc format {"section":{"id":"热门推荐","pos":1,"items":[{"id":%s,"pos":%d,"type":1,"url":""}]}}
noItem = `{"section":{"id":"热门推荐","pos":1,"items":[""]}}`
)
var (
msg1 = []byte(`{"section":{"id":"热门推荐","pos":1,"items":[`)
msg2 = []byte(`{"id":`)
msg3 = []byte(`,"pos":`)
msg4 = []byte(`,"type":1,"url":""},`)
inf2 = binfoc.New(conf.Conf.Infoc2)
buf bytes.Buffer
list string
)
for {
i := <-s.logCh
if len(i.items) > 0 {
buf.Write(msg1)
for i, v := range i.items {
if v.Goto != model.GotoAv {
continue
}
buf.Write(msg2)
buf.WriteString(v.Param)
buf.Write(msg3)
buf.WriteString(strconv.Itoa(i + 1))
buf.Write(msg4)
}
buf.Truncate(buf.Len() - 1)
buf.WriteString(`]}}`)
list = buf.String()
buf.Reset()
} else {
list = noItem
}
inf2.Info(i.ip, i.now, i.api, i.buvid, i.mid, i.client, "1", list, i.disid, i.isRcmmnd)
}
}
func (s *Service) infocfeedproc() {
const (
noItem = `[]`
)
var (
msg1 = []byte(`[`)
msg2 = []byte(`{"goto":"`)
msg3 = []byte(`","param":"`)
msg4 = []byte(`","uri":"`)
msg5 = []byte(`","r_pos":`)
msg6 = []byte(`,"from_type":"`)
msg9 = []byte(`","corner_mark":`)
msg10 = []byte(`,"rcmd_content":"`)
msg11 = []byte(`","card_style":`)
msg12 = []byte(`,"items":[`)
msg13 = []byte(`{"goto":"`)
msg14 = []byte(`","param":"`)
msg17 = []byte(`","pos":`)
msg15 = []byte(`},`)
msg16 = []byte(`]`)
msg7 = []byte(`},`)
msg8 = []byte(`]`)
buf bytes.Buffer
list string
feedInf = binfoc.New(s.c.FeedTabInfoc)
)
for {
i, ok := <-s.logFeedCh
if !ok {
log.Warn("infoc proc exit")
return
}
switch l := i.(type) {
case *feedInfoc:
if f := l.feed; len(f) == 0 {
list = noItem
} else {
buf.Write(msg1)
for _, item := range f {
buf.Write(msg2)
buf.WriteString(item.Goto)
buf.Write(msg3)
buf.WriteString(item.Param)
buf.Write(msg4)
buf.WriteString(item.URI)
buf.Write(msg5)
buf.WriteString(strconv.FormatInt(item.Idx, 10))
buf.Write(msg6)
buf.WriteString(item.FromType)
buf.Write(msg9)
buf.WriteString(strconv.Itoa(int(item.CornerMark)))
buf.Write(msg10)
buf.WriteString(item.RcmdContent)
buf.Write(msg11)
buf.WriteString(strconv.Itoa(int(item.CardStyle)))
if len(item.Item) > 0 {
buf.Write(msg12)
for pos, it := range item.Item {
buf.Write(msg13)
buf.WriteString(it.Goto)
buf.Write(msg14)
buf.WriteString(it.Param)
buf.Write(msg17)
buf.WriteString(strconv.Itoa(pos + 1))
buf.Write(msg15)
}
buf.Truncate(buf.Len() - 1)
buf.Write(msg16)
}
buf.Write(msg7)
}
buf.Truncate(buf.Len() - 1)
buf.Write(msg8)
list = buf.String()
buf.Reset()
}
log.Info("showtab_infoc_index(%s,%s,%s,%s,%s,%s,%s,%s)_list(%s)", l.mobiApp, l.device, l.build, l.now, l.loginEvent, l.mid, l.buvid, l.page, list)
feedInf.Info(l.mobiApp, l.device, l.build, l.now, l.loginEvent, l.mid, l.buvid, list, l.page)
}
}
}

View File

@@ -0,0 +1,44 @@
package show
import (
"context"
"go-common/app/interface/main/app-card/model/card/operate"
)
func (s *Service) cardSetChange(c context.Context, ids ...int64) (cardm map[int64]*operate.Card, aids []int64, upid int64) {
if len(ids) == 0 {
return
}
cardm = make(map[int64]*operate.Card, len(ids))
for _, id := range ids {
if cs, ok := s.cardSetCache[id]; ok {
card := &operate.Card{}
card.FromCardSet(cs)
cardm[id] = card
upid = card.ID
for _, item := range card.Items {
switch cs.Type {
case "up_rcmd_new":
aids = append(aids, item.ID)
}
}
}
}
return
}
func (s *Service) eventTopicChange(c context.Context, ids ...int64) (cardm map[int64]*operate.Card) {
if len(ids) == 0 {
return
}
cardm = make(map[int64]*operate.Card, len(ids))
for _, id := range ids {
if st, ok := s.eventTopicCache[id]; ok {
card := &operate.Card{}
card.FromEventTopic(st)
cardm[id] = card
}
}
return
}

View File

@@ -0,0 +1,443 @@
package show
import (
"strconv"
"time"
clive "go-common/app/interface/main/app-card/model/card/live"
"go-common/app/interface/main/app-card/model/card/operate"
"go-common/app/interface/main/app-card/model/card/rank"
"go-common/app/interface/main/app-show/conf"
accdao "go-common/app/interface/main/app-show/dao/account"
actdao "go-common/app/interface/main/app-show/dao/activity"
addao "go-common/app/interface/main/app-show/dao/ad"
arcdao "go-common/app/interface/main/app-show/dao/archive"
adtdao "go-common/app/interface/main/app-show/dao/audit"
bgmdao "go-common/app/interface/main/app-show/dao/bangumi"
carddao "go-common/app/interface/main/app-show/dao/card"
dbusdao "go-common/app/interface/main/app-show/dao/databus"
dyndao "go-common/app/interface/main/app-show/dao/dynamic"
livedao "go-common/app/interface/main/app-show/dao/live"
locdao "go-common/app/interface/main/app-show/dao/location"
rcmmdao "go-common/app/interface/main/app-show/dao/recommend"
regiondao "go-common/app/interface/main/app-show/dao/region"
reldao "go-common/app/interface/main/app-show/dao/relation"
resdao "go-common/app/interface/main/app-show/dao/resource"
showdao "go-common/app/interface/main/app-show/dao/show"
tagdao "go-common/app/interface/main/app-show/dao/tag"
"go-common/app/interface/main/app-show/model/card"
recmod "go-common/app/interface/main/app-show/model/recommend"
"go-common/app/interface/main/app-show/model/region"
"go-common/app/interface/main/app-show/model/show"
creativeAPI "go-common/app/interface/main/creative/api"
"go-common/app/service/main/archive/api"
resource "go-common/app/service/main/resource/model"
httpx "go-common/library/net/http/blademaster"
"go-common/library/stat/prom"
)
type recommend struct {
key string
aids []int64
}
type rcmmndCfg struct {
Aid int64 `json:"aid"`
Goto string `json:"goto"`
Title string `json:"title"`
Cover string `json:"cover"`
}
// Service is show service.
type Service struct {
c *conf.Config
creativeClient creativeAPI.CreativeClient
dao *showdao.Dao
rcmmnd *rcmmdao.Dao
ad *addao.Dao // cptbanner
bgm *bgmdao.Dao
lv *livedao.Dao
// bnnr *bnnrdao.Dao
adt *adtdao.Dao
tag *tagdao.Dao
arc *arcdao.Dao
dbus *dbusdao.Dao
dyn *dyndao.Dao
res *resdao.Dao
// artic *articledao.Dao
client *httpx.Client
rg *regiondao.Dao
cdao *carddao.Dao
act *actdao.Dao
acc *accdao.Dao
// relation
reldao *reldao.Dao
loc *locdao.Dao
tick time.Duration
rcmmndCache []*show.Item
rcmmndOseaCache []*show.Item
regionCache map[string][]*show.Item
regionOseaCache map[string][]*show.Item
regionBgCache map[string][]*show.Item
regionBgOseaCache map[string][]*show.Item
regionBgEpCache map[string][]*show.Item
regionBgEpOseaCache map[string][]*show.Item
bgmCache map[int8][]*show.Item
liveCount int
liveMoeCache []*show.Item // TODO change to liveMoeCache
liveHotCache []*show.Item // TODO change to liveHotCache
bannerCache map[int8]map[int][]*resource.Banner
cache map[string][]*show.Show
cacheBg map[string][]*show.Show
cacheBgEp map[string][]*show.Show
tempCache map[string][]*show.Show
auditCache map[string]map[int]struct{} // audit mobi_app builds
blackCache map[int64]struct{} // black aids
logCh chan infoc
logFeedCh chan interface{}
rcmmndCh chan recommend
logPath string
// loadfile
jsonOn bool
// cpm percentage 0~100
cpmNum int
cpmMid map[int64]struct{}
cpmAll bool
cpmRcmmndNum int
cpmRcmmndMid map[int64]struct{}
cpmRcmmndAll bool
adIsPost bool
// recommend api
rcmmndOn bool
rcmmndGroup map[int64]int // mid -> group
rcmmndHosts map[int][]string // group -> hosts
// region
reRegionCache map[int]*region.Region
// ranking
rankCache []*show.Item
rankOseaCache []*show.Item
// card
cardCache map[string][]*show.Show
columnListCache map[int]*card.ColumnList
cardSetCache map[int64]*operate.CardSet
eventTopicCache map[int64]*operate.EventTopic
// hot card
hotTenTabCardCache map[int][]*recmod.CardList
rankAidsCache []int64
rankScoreCache map[int64]int64
rankArchivesCache map[int64]*api.Arc
// hotCache []*card.PopularCard
rcmdCache []*card.PopularCard
hottopicsCache []*clive.TopicHot
rankCache2 []*rank.Rank
dynamicHotCache []*clive.DynamicHot
// prom
pHit *prom.Prom
pMiss *prom.Prom
}
// New new a show service.
func New(c *conf.Config) (s *Service) {
rcmmndHosts := make(map[int][]string, len(c.Recommend.Host))
for k, v := range c.Recommend.Host {
key, err := strconv.Atoi(k)
if err != nil {
continue
}
rcmmndHosts[key] = v
}
rcmmndGroup := make(map[int64]int, len(c.Recommend.Group))
for k, v := range c.Recommend.Group {
key, err := strconv.Atoi(k)
if err != nil {
continue
}
rcmmndGroup[int64(key)] = v
}
s = &Service{
c: c,
dao: showdao.New(c),
rcmmnd: rcmmdao.New(c),
ad: addao.New(c),
bgm: bgmdao.New(c),
lv: livedao.New(c),
// bnnr: bnnrdao.New(c),
adt: adtdao.New(c),
tag: tagdao.New(c),
arc: arcdao.New(c),
dbus: dbusdao.New(c),
dyn: dyndao.New(c),
res: resdao.New(c),
// artic: articledao.New(c),
rg: regiondao.New(c),
cdao: carddao.New(c),
act: actdao.New(c),
acc: accdao.New(c),
// relation
reldao: reldao.New(c),
loc: locdao.New(c),
client: httpx.NewClient(c.HTTPData),
tick: time.Duration(c.Tick),
jsonOn: false,
logCh: make(chan infoc, 1024),
logFeedCh: make(chan interface{}, 1024),
rcmmndCh: make(chan recommend, 1024),
logPath: c.ShowLog,
rcmmndOn: false,
rcmmndGroup: rcmmndGroup,
rcmmndHosts: rcmmndHosts,
// cpm percentage 0~100
cpmNum: 0,
cpmMid: map[int64]struct{}{},
cpmAll: true,
cpmRcmmndNum: 0,
cpmRcmmndMid: map[int64]struct{}{},
cpmRcmmndAll: true,
adIsPost: false,
// region
reRegionCache: map[int]*region.Region{},
// ranking
rankCache: []*show.Item{},
rankOseaCache: []*show.Item{},
//card
cardCache: map[string][]*show.Show{},
columnListCache: map[int]*card.ColumnList{},
cardSetCache: map[int64]*operate.CardSet{},
eventTopicCache: map[int64]*operate.EventTopic{},
// hot card
hotTenTabCardCache: make(map[int][]*recmod.CardList),
rankAidsCache: []int64{},
rankScoreCache: map[int64]int64{},
rankArchivesCache: map[int64]*api.Arc{},
// hotCache: []*card.PopularCard{},
rcmdCache: []*card.PopularCard{},
hottopicsCache: []*clive.TopicHot{},
rankCache2: []*rank.Rank{},
dynamicHotCache: []*clive.DynamicHot{},
// prom
pHit: prom.CacheHit,
pMiss: prom.CacheMiss,
}
var err error
if s.creativeClient, err = creativeAPI.NewClient(nil); err != nil {
panic("creativeGRPC not found!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!")
}
now := time.Now()
s.loadCache(now)
go s.cacheproc()
go s.infocproc()
go s.rcmmndproc()
go s.infocfeedproc()
return s
}
// cacheproc load all cache.
func (s *Service) cacheproc() {
for {
time.Sleep(s.tick)
now := time.Now()
s.loadCache(now)
}
}
func (s *Service) loadCache(now time.Time) {
s.loadRcmmndCache(now)
s.loadRegionCache(now)
s.loadBgmCache(now)
s.loadLiveCache(now)
s.loadBannerCahce()
s.loadShowCache()
s.loadShowTempCache()
s.loadBlackCache()
s.loadAuditCache()
s.loadRegionListCache()
s.loadRankAllCache()
s.loadColumnListCache(now)
s.loadCardCache(now)
s.loadCardSetCache()
// hot
// s.loadPopularCard(now)
s.loadHotTenTabAids()
s.loadHotTopicCache()
for i := 0; i < 10; i++ {
s.loadHotTenMergeRcmdCache(i)
}
s.loadDynamicHotCache()
s.loadEventTopicCache()
}
// SetRcmmndOn
func (s *Service) SetRcmmndOn(on bool) {
s.rcmmndOn = on
}
// GetRcmmndOn
func (s *Service) RcmmndOn() bool {
return s.rcmmndOn
}
// Close dao
func (s *Service) Close() error {
return s.dao.Close()
}
// SetRcmmndGroup set rcmmnd group data.
func (s *Service) SetRcmmndGroup(m int64, g int) {
tmp := map[int64]int{}
tmp[m] = g
for k, v := range s.rcmmndGroup {
if k != m {
tmp[k] = v
}
}
s.rcmmndGroup = tmp
}
// GetRcmmndGroup get rcmmnd group data.
func (s *Service) GetRcmmndGroup() map[string]int {
tmp := map[string]int{}
for k, v := range s.rcmmndGroup {
tmp[strconv.FormatInt(k, 10)] = v
}
return tmp
}
// SetRcmmndHost set rcmmnd host data.
func (s *Service) SetRcmmndHost(g int, hosts []string) {
tmp := map[int][]string{}
tmp[g] = hosts
for k, v := range s.rcmmndHosts {
if k != g {
tmp[k] = v
}
}
s.rcmmndHosts = tmp
}
// GetRcmmndHost get rcmmnd host data.
func (s *Service) GetRcmmndHost() map[string][]string {
tmp := map[string][]string{}
for k, v := range s.rcmmndHosts {
tmp[strconv.Itoa(k)] = v
}
return tmp
}
// SetCpm percentage 0~100
func (s *Service) SetCpmNum(num int) {
s.cpmNum = num
if s.cpmNum < 0 {
s.cpmNum = 0
} else if s.cpmNum > 100 {
s.cpmNum = 100
}
}
// GetCpm percentage
func (s *Service) CpmNum() int {
return s.cpmNum
}
// SetCpm percentage 0~100
func (s *Service) SetCpmMid(mid int64) {
var mids = map[int64]struct{}{}
mids[mid] = struct{}{}
for mid, _ := range s.cpmMid {
if _, ok := mids[mid]; !ok {
mids[mid] = struct{}{}
}
}
s.cpmMid = mids
}
// GetCpm percentage
func (s *Service) CpmMid() []int {
var mids []int
for mid, _ := range s.cpmMid {
mids = append(mids, int(mid))
}
return mids
}
// SetCpm All
func (s *Service) SetCpmAll(isAll bool) {
s.cpmAll = isAll
}
// GetCpm All
func (s *Service) CpmAll() int {
if s.cpmAll {
return 1
}
return 0
}
// RcmmndNum percentage
func (s *Service) RcmmndNum() int {
return s.cpmRcmmndNum
}
// SetRcmmndNum percentage 0~100
func (s *Service) SetRcmmndNum(num int) {
s.cpmRcmmndNum = num
if s.cpmRcmmndNum < 0 {
s.cpmRcmmndNum = 0
} else if s.cpmRcmmndNum > 100 {
s.cpmRcmmndNum = 100
}
}
// CpmRcmmndMid Mid
func (s *Service) CpmRcmmndMid() []int {
var mids []int
for mid, _ := range s.cpmRcmmndMid {
mids = append(mids, int(mid))
}
return mids
}
// SetCpmRcmmndMid Mid
func (s *Service) SetCpmRcmmndMid(mid int64) {
var mids = map[int64]struct{}{}
mids[mid] = struct{}{}
for mid, _ := range s.cpmRcmmndMid {
if _, ok := mids[mid]; !ok {
mids[mid] = struct{}{}
}
}
s.cpmRcmmndMid = mids
}
// CpmRcmmnd All
func (s *Service) CpmRcmmndAll() int {
if s.cpmRcmmndAll {
return 1
}
return 0
}
// SetCpmRcmmnd All
func (s *Service) SetCpmRcmmndAll(isAll bool) {
s.cpmRcmmndAll = isAll
}
// SetIsPost Get or Post
func (s *Service) SetAdIsPost(isPost bool) {
s.adIsPost = isPost
}
// IsPost Get or Post
func (s *Service) AdIsPost() int {
if s.adIsPost {
return 1
}
return 0
}

View File

@@ -0,0 +1,918 @@
package show
import (
"context"
"fmt"
"math/rand"
"net/url"
"strconv"
"time"
"go-common/app/interface/main/app-show/conf"
"go-common/app/interface/main/app-show/model"
"go-common/app/interface/main/app-show/model/show"
"go-common/app/service/main/archive/api"
"go-common/app/service/main/archive/model/archive"
resource "go-common/app/service/main/resource/model"
seasongrpc "go-common/app/service/openplatform/pgc-season/api/grpc/season/v1"
"go-common/library/log"
"go-common/library/sync/errgroup"
)
const (
_cnt = 4
_initShowKey = "show_key_%d_%v"
_initCardKey = "card_key_%d"
_initlanguage = "hans"
_bangumiSeasonID = 1
_bangumiEpisodeID = 2
)
var (
_emptyShow = []*show.Show{}
_emptyItem = &show.Item{}
_emptyShowItems = []*show.Item{}
// ad
_recommend = map[int8]string{
model.PlatIPhone: "1508",
model.PlatAndroid: "1515",
model.PlatIPad: "1522",
model.PlatIPhoneI: "1529",
model.PlatAndroidG: "1543",
model.PlatAndroidI: "1777",
model.PlatIPadI: "1536",
}
_bangumiReids = map[int]struct{}{
167: struct{}{},
}
)
// Display display show data.
func (s *Service) Display(c context.Context, mid int64, plat int8, build int, buvid, channel, ip, ak, network, mobiApp,
device, language, adExtra string, isTmp bool, now time.Time) (res []*show.Show) {
res = s.showDisplay(c, mid, plat, build, buvid, channel, ip, ak, network, mobiApp, device, language, adExtra, isTmp, false, false, now)
return
}
// RegionDisplay display region show data.
func (s *Service) RegionDisplay(c context.Context, mid int64, plat int8, build int, buvid, channel, ip, ak, network, mobiApp,
device, language, adExtra string, isTmp bool, now time.Time) (res []*show.Show) {
res = s.showDisplay(c, mid, plat, build, buvid, channel, ip, ak, network, mobiApp, device, language, adExtra, isTmp, true, false, now)
return
}
func (s *Service) Index(c context.Context, mid int64, plat int8, build int, buvid, channel, ip, ak, network, mobiApp,
device, language, adExtra string, isTmp bool, now time.Time) (res []*show.Show) {
res = s.showDisplay(c, mid, plat, build, buvid, channel, ip, ak, network, mobiApp, device, language, adExtra, isTmp, true, true, now)
if cards := s.showCardDisplay(plat, build); len(cards) > 0 {
cards = append(cards, res...)
res = cards
}
return
}
// Display display show data.
func (s *Service) showDisplay(c context.Context, mid int64, plat int8, build int, buvid, channel, ip, ak, network, mobiApp,
device, language, adExtra string, isTmp, isRegion, isIndex bool, now time.Time) (res []*show.Show) {
var (
bnr string
banners map[int][]*resource.Banner
showRec []*show.Item
showLive []*show.Item
isBangumi = false
isRegionBanner = false
ss []*show.Show
resIDStr = _bannersPlat[plat]
)
if language == "" {
language = _initlanguage
}
key := fmt.Sprintf(_initShowKey, plat, language)
if (plat == model.PlatIPhone && build > 6050) || (plat == model.PlatAndroid && build > 512007) {
ss = s.cacheBgEp[key]
} else if ((mobiApp == "iphone" && build > 5600) || (mobiApp == "android" && build > 507000)) && isIndex {
ss = s.cacheBg[key]
} else {
ss = s.cache[key]
}
if isTmp {
ss = s.tempCache[key]
}
if len(ss) == 0 {
res = _emptyShow
return
}
res = make([]*show.Show, 0, len(ss))
if (mobiApp == "iphone" && build > 4310) || (mobiApp == "android" && build > 502000) || isIndex {
isBangumi = true
}
if (mobiApp == "iphone" && build > 4350) || (mobiApp == "android" && build > 503000) {
isRegionBanner = true
}
g, ctx := errgroup.WithContext(c)
g.Go(func() error {
banners = s.resBanners(ctx, plat, build, mid, resIDStr, channel, ip, buvid, network, mobiApp, device, adExtra)
return nil
})
if !isRegion {
g.Go(func() error {
showRec = s.getRecommend(ctx, mid, build, plat, buvid, network, mobiApp, device, ip)
return nil
})
g.Go(func() error {
showLive = s.getLive(ctx, mid, ak, ip, 0, now)
return nil
})
}
if err := g.Wait(); err != nil {
log.Error("showDisplay errgroup.WithContext error(%v)", err)
}
for i, sw := range ss {
if mobiApp == "white" && 101220 >= build && sw.Param == "165" { // 165 ad region
continue
} else if sw.Param != "165" || ((mobiApp != "iphone" || device != "pad") || build <= 3590) {
if model.InvalidBuild(build, sw.Build, sw.Condition) {
continue
}
}
if sw.Type == "recommend" {
if isRegion {
continue
}
sw = s.dealRecommend(c, sw, plat, mid, build, buvid, network, mobiApp, device, ip, showRec)
bnr = "0"
} else if sw.Type == "live" {
if isRegion {
continue
}
sw = s.dealLive(c, sw, showLive)
bnr = "65537"
} else if sw.Type == "bangumi" {
if ok := s.auditRegion(mobiApp, plat, build, "13"); ok {
continue
}
if isRegion && isBangumi && !isRegionBanner {
bnr = "-1"
} else if isRegion && !isBangumi && !isRegionBanner {
continue
} else {
bnr = "13"
}
} else {
bnr = sw.Param
if isRegion {
if ok := s.auditRegion(mobiApp, plat, build, sw.Param); ok {
continue
}
if !isRegionBanner {
if sw.Param == "1" && !isBangumi {
bnr = "-1"
}
if sw.Type == "topic" && i > 0 && (ss[i-1].Type == "bangumi" || ss[i-1].Type == "1") {
continue
}
}
}
}
sw.Banner = s.getBanners(c, plat, build, bnr, channel, ip, banners, isIndex)
res = append(res, sw)
}
return
}
// showCardDisplay
func (s *Service) showCardDisplay(plat int8, build int) (res []*show.Show) {
var ss []*show.Show
key := fmt.Sprintf(_initCardKey, plat)
ss = s.cardCache[key]
if len(ss) == 0 {
res = _emptyShow
return
}
res = []*show.Show{}
for _, sw := range ss {
if model.InvalidBuild(build, sw.Build, sw.Condition) {
continue
}
tmp := &show.Show{}
*tmp = *sw
tmp.FillBuildURI(plat, build)
res = append(res, tmp)
}
return
}
// Change change display show data.
func (s *Service) Change(c context.Context, mid int64, build int, plat int8, rand int, buvid, ip, network, mobiApp, device string) (sis []*show.Item) {
cnt := s.itemNum(plat)
// first get recommend data.
tmp := s.userRecommend(c, mid, build, plat, buvid, network, mobiApp, device, ip, cnt)
if len(tmp) == cnt {
sis = append(sis, tmp...)
}
if len(sis) < cnt {
start := cnt * rand
end := start + cnt
rcLen := len(s.rcmmndCache)
if rcLen < end {
rand = 0
start = cnt * rand
end = start + cnt
}
if rcLen > end {
sis = s.rcmmndCache[start:end]
}
}
return
}
// RegionChange change show region data.
func (s *Service) RegionChange(c context.Context, rid, rand int, plat int8, build int, mobiApp string) (sis []*show.Item) {
if rand < 0 {
rand = 0
}
var (
cnt = 4
pn = rand + 1
isOsea = model.IsOverseas(plat)
bangumiType = 0
tmp []*show.Item
)
if (mobiApp == "iphone" && build > 5600) || (mobiApp == "android" && build > 507000) {
if _, isBangumi := _bangumiReids[rid]; isBangumi {
if (plat == model.PlatIPhone && build > 6050) || (plat == model.PlatAndroid && build > 512007) {
bangumiType = _bangumiEpisodeID
} else {
bangumiType = _bangumiSeasonID
}
}
}
if model.IsIPad(plat) {
cnt = 8
}
as, aids, err := s.dyn.RegionDynamic(c, rid, pn, cnt)
if err != nil {
log.Error("s.rcmmnd.RegionDynamic(%d, %d, %d) error(%v)", rid, pn, cnt, err)
sis = []*show.Item{}
return
}
if bangumiType != 0 {
tmp = s.fromArchivesBangumiOsea(c, as, aids, isOsea, bangumiType)
} else {
tmp = s.fromArchivesOsea(as, isOsea)
}
sis = append(sis, tmp...)
return
}
// BangumiChange change show bangumi data.
func (s *Service) BangumiChange(c context.Context, rand int, plat int8) (sis []*show.Item) {
if rand < 0 {
rand = 0
}
rand = rand + 1
var (
cnt = 4
)
if model.IsIPad(plat) {
cnt = 8
}
start := cnt * rand
end := start + cnt
if bgms, ok := s.bgmCache[plat]; ok {
bcLen := len(bgms)
if bcLen < end {
rand = 0
start = cnt * rand
end = start + cnt
}
if bcLen > end {
sis = bgms[start:end]
}
}
return
}
// Dislike dislike show data
func (s *Service) Dislike(c context.Context, mid int64, plat int8, id int64, buvid, mobiApp, device, gt, ip string) (si *show.Item) {
var (
cnt = 1
changeAid string
port string
)
// first get recommend data.
tmp := s.userRecommend(c, mid, 0, plat, buvid, "", mobiApp, device, ip, cnt)
if len(tmp) > 0 {
si = tmp[0]
port = "userRecommend"
} else {
si = s.rcmmndCache[0]
port = "loadRcmmndCache"
}
if si != nil {
changeAid = si.Param
}
if err := s.dbus.Pub(c, buvid, gt, id, mid); err != nil {
log.Error("s.dbus.Pub(%s,%s,%d,%d) error(%v)", buvid, gt, id, mid, err)
log.Error("dbus_Pub_dislike error mid:%v , dislike_aid:%v , change_aid:%v , interface_name:%v", mid, id, changeAid, port)
return
}
log.Info("dbus_Pub_dislike success mid:%v , dislike_aid:%v , change_aid:%v , interface_name:%v", mid, id, changeAid, port)
return
}
// Widget
func (s *Service) Widget(c context.Context, plat int8) (res []*show.Item) {
var (
isOsea = model.IsOverseas(plat) //is overseas
resCache []*show.Item
randID int
)
if isOsea {
resCache = s.rcmmndOseaCache
} else {
resCache = s.rcmmndCache
}
resCacheLen := len(resCache)
if resCacheLen >= 3 {
for {
if len(res) >= 3 || len(resCache) == 0 {
log.Info("Widget len 3")
break
}
if randInt := rand.Intn(resCacheLen); randInt != randID && resCache[randInt] != nil {
randID = randInt
res = append(res, resCache[randInt])
}
}
} else if resCacheLen > 0 {
log.Info("Widget resCache")
res = resCache
} else {
log.Info("Widget is null")
res = _emptyShowItems
}
return
}
// LiveChange live change.
func (s *Service) LiveChange(c context.Context, mid int64, ak, ip string, rand int, now time.Time) (sis []*show.Item) {
return s.getLive(c, mid, ak, ip, rand, now)
}
// dealRecommend deal recommend.
func (s *Service) dealRecommend(c context.Context, sw *show.Show, plat int8, mid int64, build int, buvid, network, mobiApp, device, ipaddr string, showRec []*show.Item) (rs *show.Show) {
cnt := s.itemNum(plat)
sis := make([]*show.Item, 0, cnt)
// first get recommend data.
if len(showRec) == cnt {
sis = append(sis, showRec...)
}
// if recommend data not enough, get from @hetongzi.
if len(sis) < cnt {
rcLen := len(s.rcmmndCache)
if rcLen < cnt {
sis = s.rcmmndCache[0:rcLen]
} else {
sis = s.rcmmndCache[0:cnt]
}
if rcLen > 0 {
sis = s.adVideo(c, mid, build, plat, buvid, network, mobiApp, device, ipaddr, sis)
}
}
if len(sis) == 0 {
sis = []*show.Item{}
}
rs = &show.Show{
Head: sw.Head,
Body: sis,
}
return
}
// getRecommend user recommend data
func (s *Service) getRecommend(c context.Context, mid int64, build int, plat int8, buvid, network, mobiApp, device, ipaddr string) (sis []*show.Item) {
cnt := s.itemNum(plat)
// first get recommend data.
sis = s.userRecommend(c, mid, build, plat, buvid, network, mobiApp, device, ipaddr, cnt)
return
}
// userRecommend user recommend data.
func (s *Service) userRecommend(ctx context.Context, mid int64, build int, plat int8, buvid, network, mobiApp, device, ipaddr string, cnt int) (sis []*show.Item) {
// get redis seed whether or not hit
if !s.rcmmndOn {
return
}
var (
key = buvid
i int
aids []int64
rcs []*rcmmndCfg
err error
)
if mid > 0 {
key = strconv.FormatInt(mid, 10)
}
if key == "" {
return
}
Retry:
for i = 0; i < 2; i++ {
if aids, err = s.dao.PopRcmmndCache(ctx, key, cnt); err != nil {
log.Error("s.dao.PopRcmmndCache(%d) error(%v)", key, err)
return
}
if len(aids) < cnt {
break
}
for _, aid := range aids {
if _, ok := s.blackCache[aid]; ok {
continue Retry
}
}
var isOsea = model.IsOverseas(plat)
if sis = s.fromAidsOsea(ctx, aids, isOsea); len(sis) < cnt {
log.Warn("recommend aids(%v) get from archive have not normal(%v)", aids, sis)
continue Retry
}
return
}
// if i==2, mean retry two counts, else if i<2, means break and recommend not enough.
if i == 2 {
return
}
if host := s.rcmmndHost(mid); host != "" {
rcs, aids = s.apiRecommend(ctx, plat, key, host, mid)
}
var (
clen = len(rcs)
caids = make([]int64, 0, cnt)
fill = cnt - clen
)
if clen+len(aids) < cnt {
return
}
if cnt < clen {
fill = 0
}
for _, rc := range rcs {
if rc.Goto == "" || rc.Goto == model.GotoAv {
caids = append(caids, rc.Aid)
if len(caids) == cnt {
break
}
}
}
if fill > 0 {
caids = append(caids, aids[:fill]...)
}
if aids = aids[fill:]; len(aids) >= cnt {
select {
case s.rcmmndCh <- recommend{key: key, aids: aids[fill:]}:
default:
log.Warn("recommendProc chan full")
}
}
var isOsea = model.IsOverseas(plat) //is overseas
if sis = s.fromAidsOsea(ctx, caids, isOsea); len(sis) < clen { // NOTE: if cnt=1 means dislike change one
for {
var (
over = cnt - len(sis)
start = 0
)
if over == 0 || start+over > len(aids) {
break
}
if tmp := s.fromAidsOsea(ctx, aids[start:over], isOsea); len(tmp) > 0 {
sis = append(sis, tmp...)
}
}
return
}
for i, rc := range rcs {
if rc.Goto != "" && rc.Goto != model.GotoAv {
sis[i].Param = strconv.FormatInt(rc.Aid, 10)
sis[i].Goto = rc.Goto
sis[i].URI = model.FillURI(rc.Goto, sis[i].Param, nil)
}
if rc.Title != "" {
sis[i].Title = rc.Title
}
if rc.Cover != "" {
sis[i].Cover = rc.Cover
}
}
sis = s.adVideo(ctx, mid, build, plat, buvid, network, mobiApp, device, ipaddr, sis)
return
}
// rcmmndHost get recommend host
func (s *Service) rcmmndHost(mid int64) (host string) {
// if mid=0, let host is 1: base recommend
yu := mid % 20
g := s.rcmmndGroup[yu]
if hosts, ok := s.rcmmndHosts[g]; ok {
if len(hosts) == 1 {
host = hosts[0]
} else {
host = hosts[rand.Intn(len(hosts))]
}
}
return
}
// apiRecommend get recommend fron big data.
func (s *Service) apiRecommend(ctx context.Context, plat int8, key, host string, mid int64) (rcs []*rcmmndCfg, aids []int64) {
var (
uri string
recURL = conf.Conf.Host.Data + "/mobile/home/%s"
)
uri = fmt.Sprintf(recURL, key)
params := url.Values{}
params.Set("plat", strconv.Itoa(int(plat)))
params.Set("v2", "1")
var res struct {
Code int `json:"code"`
Data []int64 `json:"data"`
Configs []*rcmmndCfg `json:"config"`
}
if err := s.client.Post(ctx, uri, "", params, &res); err != nil {
log.Error("recommend url(%s) error(%v)", uri+"?"+params.Encode(), err)
return
}
if res.Code != 0 {
log.Error("url(%s) res code(%d) or res.result(%v,%v)", uri, res.Code, res.Data, res.Configs)
return
}
aids = res.Data
rcs = res.Configs
return
}
// itemNum get item number by plat.
func (s *Service) itemNum(plat int8) int {
// cnt is items number
cnt := 6
if plat == model.PlatAndroid || plat == model.PlatAndroidI || plat == model.PlatAndroidG {
cnt = 4
} else if plat == model.PlatIPad || plat == model.PlatIPadI {
cnt = 8
} else if plat == model.PlatAndroidTV {
cnt = 16
}
return cnt
}
// dealLive dela live data
func (s *Service) dealLive(c context.Context, sw *show.Show, sis []*show.Item) (rs *show.Show) {
rs = &show.Show{
Head: sw.Head,
Body: sis,
Ext: sw.Ext,
}
return
}
// getLive get lives: feed, moe, hot.
func (s *Service) getLive(c context.Context, mid int64, ak, ip string, rand int, now time.Time) (sis []*show.Item) {
const (
_halfCnt = 2
)
sis = make([]*show.Item, _cnt) // _cnt=4 [0,1,2,3]: 0 1 feed and hot, 2 3 moe and hot
feed, err := s.lv.Feed(c, mid, ak, ip, now)
if err != nil {
log.Error("s.live.Feed(%d) error(%d)", mid, err)
}
var have int
// get two feed
if feed != nil {
for i := 0; i < _halfCnt && i < len(feed.Lives); i++ {
si := &show.Item{}
si.FromLive(feed.Lives[i])
sis[i] = si
have++
}
}
// get two moe
fdCnt := have
start := _halfCnt * rand
if len(s.liveMoeCache) < start+_halfCnt {
start = 0
}
index := _halfCnt
MOENEXT:
for _, l := range s.liveMoeCache[start:] {
for i := 0; i < fdCnt; i++ {
if sis[i].Param == l.Param {
continue MOENEXT
}
}
sis[index] = l
index++
have++
if index >= _cnt {
break
}
}
// if feed and moe not enough, get hot
yu := _cnt - have
if yu > 0 {
start := yu * rand
if len(s.liveHotCache) < start+yu {
start = 0
}
var nilI int
HOTNEXT:
for _, l := range s.liveHotCache[start:] {
nilI = -1
for i := len(sis) - 1; i >= 0; i-- {
if sis[i] == nil {
nilI = i
} else if sis[i].Param == l.Param {
continue HOTNEXT
}
}
if nilI != -1 {
sis[nilI] = l
have++
} else {
return
}
}
}
if have < _cnt {
for k, v := range sis {
if v == nil {
sis[k] = _emptyItem
}
}
}
return
}
// fromArchives return region show items from archive archives.
func (s *Service) fromArchivesPB(as []*api.Arc) (sis, sisOsea []*show.Item) {
var asLen = len(as)
if asLen == 0 {
sis = []*show.Item{}
return
}
sis = make([]*show.Item, 0, asLen)
for _, a := range as {
i := &show.Item{}
i.FromArchivePB(a)
if a.AttrVal(archive.AttrBitOverseaLock) == 0 {
sisOsea = append(sisOsea, i)
}
sis = append(sis, i)
}
return
}
// fromArchivesBangumi aid to sid
func (s *Service) fromArchivesBangumi(c context.Context, as []*api.Arc, aids []int64, sids map[int32]*seasongrpc.CardInfoProto, bangumiType int) (sis, sisOsea []*show.Item) {
var (
asLen = len(as)
err error
// bangumi
)
if asLen == 0 {
sis = []*show.Item{}
return
}
if sids == nil {
if sids, err = s.fromSeasonID(c, aids); err != nil {
log.Error("s.fromSeasonID error(%v)", err)
return
}
}
sis = make([]*show.Item, 0, asLen)
for _, a := range as {
i := &show.Item{}
if sid, ok := sids[int32(a.Aid)]; ok && sid.SeasonId != 0 {
i.FromArchivePBBangumi(a, sid, bangumiType)
} else {
i.FromArchivePB(a)
}
sis = append(sis, i)
if a.AttrVal(archive.AttrBitOverseaLock) == 0 {
sisOsea = append(sisOsea, i)
}
}
return
}
// fromArchivesOsea isOverseas
func (s *Service) fromArchivesOsea(as []*api.Arc, isOsea bool) (sis []*show.Item) {
tmp, tmpOsea := s.fromArchivesPB(as)
if isOsea {
sis = tmpOsea
} else {
sis = tmp
}
return
}
// fromArchivesOsea isOverseas
func (s *Service) fromArchivesBangumiOsea(c context.Context, as []*api.Arc, aids []int64, isOsea bool, bangumiType int) (sis []*show.Item) {
tmp, tmpOsea := s.fromArchivesBangumi(c, as, aids, nil, bangumiType)
if isOsea {
sis = tmpOsea
} else {
sis = tmp
}
return
}
// fromAids get Aids.
func (s *Service) fromAids(ctx context.Context, aids []int64) (sis, sisOsea []*show.Item) {
as, err := s.arc.ArchivesPB(ctx, aids)
if err != nil {
log.Error("s.arc.ArchivesPB aids(%v) error(%v)", aids, err)
return
}
if len(as) == 0 {
log.Warn("s.arc.ArchivesPB(%v) length is 0", aids)
return
}
sis = make([]*show.Item, 0, len(aids))
for _, aid := range aids {
var isOverseas int32
si := &show.Item{}
si.Goto = model.GotoAv
si.Param = strconv.FormatInt(aid, 10)
si.URI = model.FillURI(si.Goto, si.Param, nil)
if v, ok := as[aid]; ok {
isOverseas = v.AttrVal(archive.AttrBitOverseaLock)
si.Danmaku = int(v.Stat.Danmaku)
si.Play = int(v.Stat.View)
si.Title = v.Title
si.Duration = v.Duration
si.Rname = v.TypeName
si.Name = v.Author.Name
si.Like = int(v.Stat.Like)
si.Cover = model.CoverURL(v.Pic)
}
if isOverseas == 0 {
sisOsea = append(sisOsea, si)
}
sis = append(sis, si)
}
return
}
// fromCardAids get Aids.
func (s *Service) fromCardAids(ctx context.Context, aids []int64) (sis map[int64]*show.Item) {
as, err := s.arc.ArchivesPB(ctx, aids)
if err != nil {
log.Error("s.arc.ArchivesPB aids(%v) error(%v)", aids, err)
return
}
if len(as) == 0 {
log.Warn("s.arc.ArchivesPB(%v) length is 0", aids)
return
}
sis = map[int64]*show.Item{}
for _, aid := range aids {
si := &show.Item{}
si.Goto = model.GotoAv
si.Param = strconv.FormatInt(aid, 10)
si.URI = model.FillURI(si.Goto, si.Param, nil)
if v, ok := as[aid]; ok {
if !v.IsNormal() {
continue
}
si.Danmaku = int(v.Stat.Danmaku)
si.Play = int(v.Stat.View)
si.Title = v.Title
si.Duration = v.Duration
if region, ok := s.reRegionCache[int(v.TypeID)]; ok {
si.Desc = region.Name
si.Reid = region.Rid
}
si.Rid = int(v.TypeID)
si.Rname = v.TypeName
si.Name = v.Author.Name
si.Like = int(v.Stat.Like)
si.Cover = model.CoverURL(v.Pic)
}
sis[aid] = si
}
return
}
// fromRankAids
func (s *Service) fromRankAids(ctx context.Context, aids []int64, scores map[int64]int64, as map[int64]*api.Arc) (sis, sisOsea []*show.Item) {
var (
aid int64
arc *api.Arc
ok bool
)
for _, aid = range aids {
if arc, ok = as[aid]; ok {
i := &show.Item{}
if region, ok := s.reRegionCache[int(arc.TypeID)]; ok {
i.Desc = region.Name
}
i.FromArchiveRank(arc, scores)
if arc.AttrVal(archive.AttrBitOverseaLock) == 0 {
sisOsea = append(sisOsea, i)
}
sis = append(sis, i)
}
}
return
}
// fromAids get Aids.
func (s *Service) fromBgAids(ctx context.Context, aids []int64, sids map[int32]*seasongrpc.CardInfoProto, bangumiType int) (sis, sisOsea, sisbg, sisbgOsea, sisbgep, sisbgepOsea []*show.Item) {
var (
err error
)
as, err := s.arc.ArchivesPB(ctx, aids)
if err != nil {
log.Error("s.arc.ArchivesPB aids(%v) error(%v)", aids, err)
return
}
if len(as) == 0 {
log.Warn("s.arc.ArchivesPB(%v) length is 0", aids)
return
}
sis = make([]*show.Item, 0, len(aids))
if sids == nil {
if sids, err = s.fromSeasonID(ctx, aids); err != nil {
log.Error("s.fromSeasonID error(%v)", err)
return
}
}
for _, aid := range aids {
var isOverseas int32
si := &show.Item{}
sibg := &show.Item{}
sibgep := &show.Item{}
if v, ok := as[aid]; ok {
isOverseas = v.AttrVal(archive.AttrBitOverseaLock)
if sid, ok := sids[int32(aid)]; ok && sid.SeasonId != 0 {
sibg.FromArchivePBBangumi(v, sid, _bangumiSeasonID)
sibgep.FromArchivePBBangumi(v, sid, _bangumiEpisodeID)
} else {
sibg.FromArchivePB(v)
sibgep.FromArchivePB(v)
}
si.FromArchivePB(v)
if isOverseas == 0 {
sisOsea = append(sisOsea, si)
sisbgOsea = append(sisbgOsea, sibg)
sisbgepOsea = append(sisbgepOsea, sibg)
}
sis = append(sis, si)
sisbg = append(sisbg, sibg)
sisbgep = append(sisbgep, sibgep)
}
}
return
}
// fromSeasonID
func (s *Service) fromSeasonID(c context.Context, arcAids []int64) (seasonID map[int32]*seasongrpc.CardInfoProto, err error) {
if seasonID, err = s.bgm.CardsByAids(c, arcAids); err != nil {
log.Error("s.bgm.Seasonid CardsByAids %v", err)
}
return
}
// isOverseas
func (s *Service) fromAidsOsea(ctx context.Context, aids []int64, isOsea bool) (sis []*show.Item) {
tmp, tmpOsea := s.fromAids(ctx, aids)
if isOsea {
sis = tmpOsea
} else {
sis = tmp
}
return
}
// adVideo
func (s *Service) adVideo(ctx context.Context, mid int64, build int, plat int8, buvid, network, mobiApp, device, ipaddr string, sis []*show.Item) (res []*show.Item) {
var cpmsis map[int]*show.Item
if resID, ok := _recommend[plat]; ok {
cpmsis = s.cpmRecommend(ctx, mid, build, buvid, resID, network, mobiApp, device, ipaddr)
}
for rank, ad := range cpmsis {
if len(sis) >= rank {
if ad.IsAdReplace {
sis[rank-1] = ad
} else {
sis[rank-1].IsAdLoc = true
sis[rank-1].IsAd = ad.IsAd
sis[rank-1].CmMark = ad.CmMark
sis[rank-1].SrcId = ad.SrcId
sis[rank-1].RequestId = ad.RequestId
sis[rank-1].ClientIp = ad.ClientIp
}
}
}
res = sis
return
}

View File

@@ -0,0 +1,66 @@
package show
import (
"context"
"flag"
"go-common/app/interface/main/app-show/conf"
"go-common/app/interface/main/app-show/model"
"path/filepath"
"testing"
"time"
. "github.com/smartystreets/goconvey/convey"
)
var (
s *Service
)
func WithService(f func(s *Service)) func() {
return func() {
f(s)
}
}
func init() {
dir, _ := filepath.Abs("../../cmd/app-show-test.toml")
flag.Set("conf", dir)
conf.Init()
s = New(conf.Conf)
time.Sleep(time.Second)
}
func TestIndex(t *testing.T) {
Convey("get Index data", t, WithService(func(s *Service) {
res := s.Index(context.TODO(), 0, model.PlatIPhone, 0, "", "", "", "", "", "iphone", "phone", _initlanguage, "", false, time.Now())
So(res, ShouldNotBeEmpty)
}))
}
func TestChange(t *testing.T) {
Convey("get Change data", t, WithService(func(s *Service) {
res := s.Change(context.TODO(), 1, 1, 1, 1, "", "", "", "", "")
So(res, ShouldNotBeEmpty)
}))
}
func TestRegionChange(t *testing.T) {
Convey("get RegionChange data", t, WithService(func(s *Service) {
res := s.RegionChange(context.TODO(), 1, 1, 1, 1, "")
So(res, ShouldNotBeEmpty)
}))
}
func TestBangumiChange(t *testing.T) {
Convey("get BangumiChange data", t, WithService(func(s *Service) {
res := s.BangumiChange(context.TODO(), 1, 1)
So(res, ShouldNotBeEmpty)
}))
}
func TestFeedIndex(t *testing.T) {
Convey("get FeedIndex data", t, WithService(func(s *Service) {
res := s.FeedIndex(context.TODO(), 1, 1, 1, 1, 1, "", "", "", "", time.Now())
So(res, ShouldNotBeEmpty)
}))
}