Create & Init Project...
This commit is contained in:
87
app/interface/main/app-show/service/region/BUILD
Normal file
87
app/interface/main/app-show/service/region/BUILD
Normal file
@ -0,0 +1,87 @@
|
||||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
load(
|
||||
"@io_bazel_rules_go//go:def.bzl",
|
||||
"go_test",
|
||||
"go_library",
|
||||
)
|
||||
|
||||
go_test(
|
||||
name = "go_default_test",
|
||||
srcs = [
|
||||
"region_test.go",
|
||||
"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 = [
|
||||
"audit.go",
|
||||
"banner.go",
|
||||
"cache.go",
|
||||
"infoc.go",
|
||||
"region.go",
|
||||
"service.go",
|
||||
"show.go",
|
||||
],
|
||||
importpath = "go-common/app/interface/main/app-show/service/region",
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
"//app/interface/main/app-show/conf: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/dynamic: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/resource:go_default_library",
|
||||
"//app/interface/main/app-show/dao/search: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/bangumi: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/region:go_default_library",
|
||||
"//app/interface/main/app-show/model/tag: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/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/metadata:go_default_library",
|
||||
"//library/stat/prom:go_default_library",
|
||||
"//library/time:go_default_library",
|
||||
"//vendor/github.com/dgryski/go-farm: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"],
|
||||
)
|
391
app/interface/main/app-show/service/region/audit.go
Normal file
391
app/interface/main/app-show/service/region/audit.go
Normal file
@ -0,0 +1,391 @@
|
||||
package region
|
||||
|
||||
import (
|
||||
"context"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"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/region"
|
||||
"go-common/app/service/main/archive/api"
|
||||
"go-common/library/log"
|
||||
)
|
||||
|
||||
var (
|
||||
_auditRids = map[int8]map[int]struct{}{
|
||||
model.PlatIPad: map[int]struct{}{
|
||||
153: struct{}{},
|
||||
168: struct{}{},
|
||||
169: struct{}{},
|
||||
170: struct{}{},
|
||||
33: struct{}{},
|
||||
32: struct{}{},
|
||||
51: struct{}{},
|
||||
152: struct{}{},
|
||||
37: struct{}{},
|
||||
178: struct{}{},
|
||||
179: struct{}{},
|
||||
180: struct{}{},
|
||||
147: struct{}{},
|
||||
145: struct{}{},
|
||||
146: struct{}{},
|
||||
83: struct{}{},
|
||||
185: struct{}{},
|
||||
187: struct{}{},
|
||||
13: struct{}{},
|
||||
167: struct{}{},
|
||||
177: struct{}{},
|
||||
23: struct{}{},
|
||||
1: struct{}{},
|
||||
160: struct{}{},
|
||||
119: struct{}{},
|
||||
155: struct{}{},
|
||||
165: struct{}{},
|
||||
5: struct{}{},
|
||||
181: struct{}{},
|
||||
},
|
||||
model.PlatIPhone: map[int]struct{}{
|
||||
153: struct{}{},
|
||||
168: struct{}{},
|
||||
169: struct{}{},
|
||||
170: struct{}{},
|
||||
33: struct{}{},
|
||||
32: struct{}{},
|
||||
51: struct{}{},
|
||||
152: struct{}{},
|
||||
37: struct{}{},
|
||||
178: struct{}{},
|
||||
179: struct{}{},
|
||||
180: struct{}{},
|
||||
147: struct{}{},
|
||||
145: struct{}{},
|
||||
146: struct{}{},
|
||||
83: struct{}{},
|
||||
185: struct{}{},
|
||||
187: struct{}{},
|
||||
1: struct{}{},
|
||||
160: struct{}{},
|
||||
119: struct{}{},
|
||||
155: struct{}{},
|
||||
165: struct{}{},
|
||||
5: struct{}{},
|
||||
181: struct{}{},
|
||||
},
|
||||
}
|
||||
)
|
||||
|
||||
// Audit region data list.
|
||||
func (s *Service) auditRegion(mobiApp string, plat int8, build, rid int) (isAudit bool) {
|
||||
if plats, ok := s.auditCache[mobiApp]; ok {
|
||||
if _, ok = plats[build]; ok {
|
||||
if rids, ok := _auditRids[plat]; ok {
|
||||
if _, ok = rids[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
|
||||
}
|
||||
|
||||
// Audit check audit plat and ip, then return audit data.
|
||||
func (s *Service) Audit(c context.Context, mobiApp string, plat int8, build, rid int, isShow bool) (res *region.Show, ok bool) {
|
||||
if plats, ok := s.auditCache[mobiApp]; ok {
|
||||
if _, ok = plats[build]; ok {
|
||||
res = s.auditData(c, plat, rid, auditShowAids)
|
||||
if isShow {
|
||||
res.Banner = audirRegionBanners[rid]
|
||||
}
|
||||
return res, true
|
||||
}
|
||||
}
|
||||
return nil, false
|
||||
}
|
||||
|
||||
// AuditChild check audit plat and ip, then return audit data.
|
||||
func (s *Service) AuditChild(c context.Context, mobiApp, order string, plat int8, build, rid, tid int) (res *region.Show, ok bool) {
|
||||
if plats, ok := s.auditCache[mobiApp]; ok {
|
||||
if _, ok = plats[build]; ok {
|
||||
res = s.auditData(c, plat, rid, auditChildShowAids)
|
||||
res.New = s.auditRegionRPCList(c, rid, 1, 8)
|
||||
return res, true
|
||||
}
|
||||
}
|
||||
return nil, false
|
||||
}
|
||||
|
||||
// AuditChildList check audit plat and ip, then return audit data.
|
||||
func (s *Service) AuditChildList(c context.Context, mobiApp, order string, plat int8, build, rid, tid, pn, ps int) (res []*region.ShowItem, ok bool) {
|
||||
if plats, ok := s.auditCache[mobiApp]; ok {
|
||||
if _, ok = plats[build]; ok {
|
||||
res = s.auditRegionChildList(c, rid, tid, pn, ps)
|
||||
return res, true
|
||||
}
|
||||
}
|
||||
return nil, false
|
||||
}
|
||||
|
||||
// auditData some data for audit.
|
||||
func (s *Service) auditData(c context.Context, p int8, rid int, auditAids map[int][]int64) (res *region.Show) {
|
||||
aids := auditAids[rid]
|
||||
// archive
|
||||
as, err := s.arc.ArchivesPB(c, aids)
|
||||
if err != nil {
|
||||
log.Error("s.arc.ArchivesPB error(%v)", err)
|
||||
as = map[int64]*api.Arc{}
|
||||
}
|
||||
res = ®ion.Show{}
|
||||
for _, aid := range aids {
|
||||
if aid == 0 {
|
||||
continue
|
||||
}
|
||||
item := ®ion.ShowItem{}
|
||||
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.Name = a.Author.Name
|
||||
item.Play = int(a.Stat.View)
|
||||
item.Danmaku = int(a.Stat.Danmaku)
|
||||
item.Reply = int(a.Stat.Reply)
|
||||
item.Fav = int(a.Stat.Fav)
|
||||
}
|
||||
res.Recommend = append(res.Recommend, item)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (s *Service) auditRegionChildList(c context.Context, rid, tid, pn, ps int) (res []*region.ShowItem) {
|
||||
if tid == 0 {
|
||||
arcs, _, err := s.arc.RanksArcs(c, rid, pn, ps)
|
||||
if err != nil {
|
||||
log.Error("s.rcmmnd.RegionArcList(%d, %d, %d, %d) error(%v)", rid, pn, ps, err)
|
||||
return
|
||||
}
|
||||
res = s.fromArchivesPBOsea(arcs, false)
|
||||
} else {
|
||||
as, err := s.tag.NewArcs(c, rid, tid, pn, ps, time.Now())
|
||||
if err != nil {
|
||||
log.Error("s.tag.NewArcs(%d, %d) error(%v)", rid, tid, err)
|
||||
return
|
||||
}
|
||||
res = s.fromAidsOsea(c, as, false, false, 0)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (s *Service) auditRegionRPCList(c context.Context, rid, pn, ps int) (res []*region.ShowItem) {
|
||||
arcs, err := s.arc.RankTopArcs(c, rid, pn, ps)
|
||||
if err != nil {
|
||||
log.Error("s.arc.RankTopArcs(%d) error(%v)", rid, err)
|
||||
return
|
||||
}
|
||||
res, _ = s.fromArchivesPB(arcs)
|
||||
return
|
||||
}
|
||||
|
||||
var (
|
||||
auditShowAids = map[int][]int64{
|
||||
// rid
|
||||
1: []int64{575891, 744286, 663583, 666946, 559050, 744299},
|
||||
3: []int64{881693, 756287, 785484, 402851, 887618, 853895},
|
||||
4: []int64{861290, 861306, 861410, 861538, 861711, 861945},
|
||||
5: []int64{791621, 795406, 797933, 800658, 832103, 833520},
|
||||
11: []int64{1961205, 2028734},
|
||||
13: []int64{2434272, 7408756, 2222558, 845204, 862063, 845034},
|
||||
36: []int64{834839, 838077, 872364, 852955, 877423, 881182},
|
||||
119: []int64{638240, 1959692, 78287, 1979757},
|
||||
129: []int64{966192, 936016, 1958897, 886841},
|
||||
}
|
||||
|
||||
auditChildShowAids = map[int][]int64{
|
||||
20: []int64{936016, 886841, 1773160, 1958897, 1406019, 1935680, 1976153, 1985297, 1984555, 1964367, 29013765, 27379226, 25886650, 27684044, 20203945},
|
||||
21: []int64{689694, 829135, 743922, 876565, 690522, 686220, 286616, 339727, 668054, 288602},
|
||||
22: []int64{1911041, 1976535, 913421},
|
||||
24: []int64{258271, 462832, 430248},
|
||||
25: []int64{190257, 432195},
|
||||
26: []int64{638240, 1959692, 78287, 1979757},
|
||||
27: []int64{775898, 199852, 539880, 2469560, 306718, 2460323, 851414, 2471090, 591021, 286678},
|
||||
28: []int64{221107, 221106, 884789, 364379, 465230, 26437, 29009413, 28965015, 28087847, 27837553, 24691347},
|
||||
29: []int64{1984330, 1966586, 1984971, 28935962, 28818825, 26514923, 23288906, 18043554},
|
||||
30: []int64{308040, 850424, 360940, 482844, 887861, 539600, 869576, 400161, 644935, 333069, 28659609, 24929108, 23068834, 26659364, 25386207},
|
||||
31: []int64{1968681, 1986904, 1986802, 2473751, 2473083, 24910218, 25409335, 25043881, 27384682, 23474776},
|
||||
37: []int64{1968901, 1969254, 1971484},
|
||||
47: []int64{364103, 621797, 557774, 620545, 291630, 853831, 627451, 789570, 582598, 666971},
|
||||
54: []int64{2294239, 2210977, 21297755, 21678914, 22000250, 19929241, 18039794},
|
||||
59: []int64{1969748, 1966643, 1964781, 1969527, 25814802, 25991412, 26577780, 23922472, 28934467},
|
||||
71: []int64{1986816, 1985288, 1986516, 1985717},
|
||||
75: []int64{200595, 721477, 668533, 803294, 708986, 581574, 588820, 718877, 6336, 592586},
|
||||
76: []int64{800617, 817625, 853774, 808176, 810174, 737783, 792994, 811825, 794302, 817814},
|
||||
95: []int64{880857, 26317616, 26697725, 24670946, 13562204, 24136940},
|
||||
96: []int64{2313588, 2314237, 2316089, 28917042, 20177394, 27839524, 25866526, 22021244},
|
||||
98: []int64{875076, 873174, 580862, 289024, 28868117, 26404621, 17229132, 28810408, 27710623},
|
||||
122: []int64{1986932, 1985610, 22034719, 19980487, 19841525, 23328696, 29249512},
|
||||
124: []int64{842756, 875624, 880558, 862316, 876708, 883418, 403120, 855131, 876867, 833785, 29064835, 27464818, 28055879, 18081681, 22968172},
|
||||
126: []int64{1636345, 1985956, 1975358, 1982533},
|
||||
127: []int64{1743126, 1625784, 1986533, 1727650},
|
||||
128: []int64{2031210, 2034983, 1916941, 2030610, 2015734, 2016150, 1982576, 2039658, 1981156, 1964927},
|
||||
130: []int64{1984887, 1985685, 1985886, 25276379, 17119215, 24949925, 25058065, 2929013},
|
||||
131: []int64{1980280, 1975409},
|
||||
137: []int64{2316922, 2318219},
|
||||
138: []int64{2317125, 2317283, 2315385, 2317914, 2317194},
|
||||
153: []int64{2429129, 7408756, 2426501, 2425990, 2387429, 2425770, 2219211, 878914, 880182, 2240189},
|
||||
154: []int64{1960912, 1984928, 29240625, 26192654, 24211477, 23746281, 23871787},
|
||||
156: []int64{28960012, 26624032, 25520347, 23567968, 23706035},
|
||||
17: []int64{28989880, 25158325, 23947116, 27052563, 24237900},
|
||||
171: []int64{29027059, 26486853, 19641793, 26432920, 27107785},
|
||||
172: []int64{28280704, 28667051, 27462689, 22870782, 17703340},
|
||||
65: []int64{28386938, 28832756, 27894258, 23401066, 24434703},
|
||||
173: []int64{28938351, 28945212, 28149415, 17717106, 26227357},
|
||||
121: []int64{27148774, 24729449, 24544576, 23651344, 21672258},
|
||||
136: []int64{26033272, 26422598, 26804826, 25773023, 22961192},
|
||||
19: []int64{28942929, 26325161, 24502096, 22364954, 19289951},
|
||||
39: []int64{29120624, 26300313, 25504214, 9447066, 20786390},
|
||||
176: []int64{28811447, 27569816, 11984355, 10788852, 29346662},
|
||||
}
|
||||
|
||||
audirRegionBanners = map[int]map[string][]*banner.Banner{
|
||||
1: map[string][]*banner.Banner{
|
||||
"top": []*banner.Banner{
|
||||
&banner.Banner{
|
||||
Title: "四月再见",
|
||||
Image: "http://i0.hdslb.com/bfs/archive/8bbc82a30720f8c2cdcca1576e25917f7bbdfb96.jpg",
|
||||
Hash: "db6e4dcc120fcd954a5c2d454b618f09",
|
||||
URI: "http://www.bilibili.com/video/av2471080/",
|
||||
},
|
||||
},
|
||||
},
|
||||
3: map[string][]*banner.Banner{
|
||||
"top": []*banner.Banner{
|
||||
&banner.Banner{
|
||||
Title: "【洛天依原创】夜寂",
|
||||
Image: "http://i0.hdslb.com/bfs/archive/6fa8a51c9adf6eeda36636ed7fffae5b1888c154.jpg",
|
||||
Hash: "c925b57dbaa1198e8cdedc84c4781313",
|
||||
URI: "http://www.bilibili.com/video/av2126431/",
|
||||
},
|
||||
},
|
||||
},
|
||||
4: map[string][]*banner.Banner{
|
||||
"top": []*banner.Banner{
|
||||
&banner.Banner{
|
||||
Title: "释放内心中的熊孩子吧",
|
||||
Image: "http://i0.hdslb.com/bfs/archive/b94d053b289184d498236de100af383bd25cfb13.jpg",
|
||||
Hash: "f246e2f10d19e30dc7311c9f1ee8385e",
|
||||
URI: "http://www.bilibili.com/video/av2459834/",
|
||||
},
|
||||
},
|
||||
},
|
||||
5: map[string][]*banner.Banner{
|
||||
"top": []*banner.Banner{
|
||||
&banner.Banner{
|
||||
Title: "巅峰料理对决~~~",
|
||||
Image: "http://i0.hdslb.com/bfs/archive/a91501598fb180f61f234e31f94731b74235b461.jpg",
|
||||
Hash: "8664c0bd979f62c02cf6711ac0a55219",
|
||||
URI: "http://www.bilibili.com/video/av2607073/?br",
|
||||
},
|
||||
&banner.Banner{
|
||||
Title: "首轮淘汰赛,谁将会离开",
|
||||
Image: "http://i0.hdslb.com/bfs/archive/ae6d1ef420a5bfdca969a31ecd7449384cfcd580.jpg",
|
||||
Hash: "346b456dea567a32a11a9427ebe3246f",
|
||||
URI: "http://www.bilibili.com/video/av2609994/?br",
|
||||
},
|
||||
&banner.Banner{
|
||||
Title: "孙红雷罗志祥乡村女装秀",
|
||||
Image: "http://i0.hdslb.com/bfs/archive/3ea355584e26376df6cccbb1a2574f03f7e0a41d.jpg",
|
||||
Hash: "45e70e0f72dd1fa4621e13986df03b30",
|
||||
URI: "http://www.bilibili.com/video/av2598211/?br",
|
||||
},
|
||||
&banner.Banner{
|
||||
Title: "帅哥萌妹齐驾到 HK君强势出境!",
|
||||
Image: "http://i0.hdslb.com/bfs/archive/ae6d1ef420a5bfdca969a31ecd7449384cfcd580.jpg",
|
||||
Hash: "7e7f8fa57dfffa0ca141e12f43088851",
|
||||
URI: "http://www.bilibili.com/video/av2598658/?br",
|
||||
},
|
||||
&banner.Banner{
|
||||
Title: "林丹谢霆锋上演锅铲大战 容祖儿情绪崩溃大哭",
|
||||
Image: "http://i0.hdslb.com/bfs/archive/959930c687c172a28d9f24e6a53aceb7fca4f728.jpg",
|
||||
Hash: "512a11b81e053d52c2ad836c453c18ad",
|
||||
URI: "http://www.bilibili.com/video/av2588446/?br",
|
||||
},
|
||||
&banner.Banner{
|
||||
Title: "【绅士大概一分钟】尽情舞蹈吧少年",
|
||||
Image: "http://i0.hdslb.com/bfs/archive/40878881827105f576e0346932cf693c3033e1ca.jpg",
|
||||
Hash: "147763f8003e6f88385cd438e8b6c7e4",
|
||||
URI: "http://www.bilibili.com/video/av2614367/?br",
|
||||
},
|
||||
},
|
||||
},
|
||||
11: map[string][]*banner.Banner{
|
||||
"top": []*banner.Banner{
|
||||
&banner.Banner{
|
||||
Title: "亚瑟王",
|
||||
Image: "http://i0.hdslb.com/bfs/archive/60b1339a3eeb8d0de287b7c305e0671082946bfc.jpg",
|
||||
Hash: "634684fe0fd4fb3b7501daf9a9b4ab5d",
|
||||
URI: "http://www.bilibili.com/video/av2128802/",
|
||||
},
|
||||
},
|
||||
},
|
||||
13: map[string][]*banner.Banner{
|
||||
"top": []*banner.Banner{
|
||||
&banner.Banner{
|
||||
Title: "少女终末旅行",
|
||||
Image: "http://i0.hdslb.com/bfs/archive/c0c33be60527c377277048c04ee222c9ec76a82c.jpg",
|
||||
Hash: "2e772627851aa7da8a75f7b5403a5ed3",
|
||||
URI: "http://bangumi.bilibili.com/anime/6463",
|
||||
},
|
||||
},
|
||||
},
|
||||
23: map[string][]*banner.Banner{
|
||||
"top": []*banner.Banner{
|
||||
&banner.Banner{
|
||||
Title: "像素大战",
|
||||
Image: "http://i0.hdslb.com/bfs/archive/0c8f1e05dfdba3b58fc15159523d0ccceed1e9ac.jpg",
|
||||
Hash: "f62bbb0578beb4bc63550d5632960480",
|
||||
URI: "http://www.bilibili.com/video/av2124091/",
|
||||
},
|
||||
},
|
||||
},
|
||||
36: map[string][]*banner.Banner{
|
||||
"top": []*banner.Banner{
|
||||
&banner.Banner{
|
||||
Title: "梦回仙剑",
|
||||
Image: "http://i0.hdslb.com/bfs/archive/76145de97ff917a6e603009376f4ca174dd4ed51.jpg",
|
||||
Hash: "6334c8c08ffa8eaa6c13f8c14bd0fae0",
|
||||
URI: "http://www.bilibili.com/video/av2448057/",
|
||||
},
|
||||
},
|
||||
},
|
||||
119: map[string][]*banner.Banner{
|
||||
"top": []*banner.Banner{
|
||||
&banner.Banner{
|
||||
Title: "魔都地铁偷走了重要的东西",
|
||||
Image: "http://i0.hdslb.com/bfs/archive/f84dd391351a00d69cfb44616c1a64419ad4611c.jpg",
|
||||
Hash: "5de70c2b24a155d7958943b85bf8facc",
|
||||
URI: "http://www.bilibili.com/video/av2106417/",
|
||||
},
|
||||
},
|
||||
},
|
||||
129: map[string][]*banner.Banner{
|
||||
"top": []*banner.Banner{
|
||||
&banner.Banner{
|
||||
Title: "元气少女",
|
||||
Image: "http://i0.hdslb.com/bfs/archive/014c0793bdaf5930e0edca54755da3c25eafcb2e.jpg",
|
||||
Hash: "46e48cee8d5b344af3a41636e96a60ca",
|
||||
URI: "http://www.bilibili.com/video/av2448328/",
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
)
|
254
app/interface/main/app-show/service/region/banner.go
Normal file
254
app/interface/main/app-show/service/region/banner.go
Normal file
@ -0,0 +1,254 @@
|
||||
package region
|
||||
|
||||
import (
|
||||
"context"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"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[int]map[int8]int{
|
||||
13: map[int8]int{
|
||||
model.PlatIPhone: 454,
|
||||
model.PlatIPad: 788,
|
||||
model.PlatAndroid: 617,
|
||||
model.PlatIPhoneI: 1022,
|
||||
model.PlatAndroidG: 1360,
|
||||
model.PlatAndroidI: 1791,
|
||||
model.PlatIPadI: 1192,
|
||||
},
|
||||
1: map[int8]int{
|
||||
model.PlatIPhone: 453,
|
||||
model.PlatIPad: 787,
|
||||
model.PlatAndroid: 616,
|
||||
model.PlatIPhoneI: 1017,
|
||||
model.PlatAndroidG: 1355,
|
||||
model.PlatAndroidI: 1785,
|
||||
model.PlatIPadI: 1187,
|
||||
},
|
||||
3: map[int8]int{
|
||||
model.PlatIPhone: 455,
|
||||
model.PlatIPad: 789,
|
||||
model.PlatAndroid: 618,
|
||||
model.PlatIPhoneI: 1028,
|
||||
model.PlatAndroidG: 1366,
|
||||
model.PlatAndroidI: 1798,
|
||||
model.PlatIPadI: 1198,
|
||||
},
|
||||
129: map[int8]int{
|
||||
model.PlatIPhone: 456,
|
||||
model.PlatIPad: 790,
|
||||
model.PlatAndroid: 619,
|
||||
model.PlatIPhoneI: 1033,
|
||||
model.PlatAndroidG: 1371,
|
||||
model.PlatAndroidI: 1804,
|
||||
model.PlatIPadI: 1203,
|
||||
},
|
||||
4: map[int8]int{
|
||||
model.PlatIPhone: 457,
|
||||
model.PlatIPad: 791,
|
||||
model.PlatAndroid: 620,
|
||||
model.PlatIPhoneI: 1038,
|
||||
model.PlatAndroidG: 1376,
|
||||
model.PlatAndroidI: 1810,
|
||||
model.PlatIPadI: 1208,
|
||||
},
|
||||
36: map[int8]int{
|
||||
model.PlatIPhone: 458,
|
||||
model.PlatIPad: 792,
|
||||
model.PlatAndroid: 621,
|
||||
model.PlatIPhoneI: 1043,
|
||||
model.PlatAndroidG: 1381,
|
||||
model.PlatAndroidI: 1816,
|
||||
model.PlatIPadI: 1213,
|
||||
},
|
||||
160: map[int8]int{
|
||||
model.PlatIPhone: 459,
|
||||
model.PlatIPad: 793,
|
||||
model.PlatAndroid: 622,
|
||||
model.PlatIPhoneI: 1048,
|
||||
model.PlatAndroidG: 1386,
|
||||
model.PlatAndroidI: 1822,
|
||||
model.PlatIPadI: 1218,
|
||||
},
|
||||
119: map[int8]int{
|
||||
model.PlatIPhone: 460,
|
||||
model.PlatIPad: 794,
|
||||
model.PlatAndroid: 623,
|
||||
model.PlatIPhoneI: 1053,
|
||||
model.PlatAndroidG: 1391,
|
||||
model.PlatAndroidI: 1828,
|
||||
model.PlatIPadI: 1223,
|
||||
},
|
||||
155: map[int8]int{
|
||||
model.PlatIPhone: 462,
|
||||
model.PlatIPad: 795,
|
||||
model.PlatAndroid: 624,
|
||||
model.PlatIPhoneI: 1058,
|
||||
model.PlatAndroidG: 1396,
|
||||
model.PlatAndroidI: 1834,
|
||||
model.PlatIPadI: 1228,
|
||||
},
|
||||
5: map[int8]int{
|
||||
model.PlatIPhone: 463,
|
||||
model.PlatIPad: 796,
|
||||
model.PlatAndroid: 625,
|
||||
model.PlatIPhoneI: 1063,
|
||||
model.PlatAndroidG: 1401,
|
||||
model.PlatAndroidI: 1840,
|
||||
model.PlatIPadI: 1233,
|
||||
},
|
||||
23: map[int8]int{
|
||||
model.PlatIPhone: 464,
|
||||
model.PlatIPad: 797,
|
||||
model.PlatAndroid: 626,
|
||||
model.PlatIPhoneI: 1068,
|
||||
model.PlatAndroidG: 1406,
|
||||
model.PlatAndroidI: 1846,
|
||||
model.PlatIPadI: 1238,
|
||||
},
|
||||
11: map[int8]int{
|
||||
model.PlatIPhone: 465,
|
||||
model.PlatIPad: 798,
|
||||
model.PlatAndroid: 627,
|
||||
model.PlatIPhoneI: 1073,
|
||||
model.PlatAndroidG: 1411,
|
||||
model.PlatAndroidI: 1852,
|
||||
model.PlatIPadI: 1243,
|
||||
},
|
||||
655: map[int8]int{
|
||||
model.PlatIPhone: 466,
|
||||
model.PlatIPad: 799,
|
||||
model.PlatAndroid: 628,
|
||||
model.PlatIPhoneI: 1079,
|
||||
model.PlatAndroidG: 1417,
|
||||
model.PlatAndroidI: 1859,
|
||||
model.PlatIPadI: 1249,
|
||||
},
|
||||
165: map[int8]int{
|
||||
model.PlatIPhone: 1473,
|
||||
model.PlatIPad: 1485,
|
||||
model.PlatAndroid: 1479,
|
||||
model.PlatIPhoneI: 1491,
|
||||
model.PlatAndroidG: 1497,
|
||||
model.PlatAndroidI: 1873,
|
||||
model.PlatIPadI: 1503,
|
||||
},
|
||||
167: map[int8]int{
|
||||
model.PlatIPhone: 1934,
|
||||
model.PlatIPad: 1932,
|
||||
model.PlatAndroid: 1933,
|
||||
},
|
||||
181: map[int8]int{
|
||||
model.PlatIPhone: 2225,
|
||||
model.PlatIPad: 2239,
|
||||
model.PlatAndroid: 2232,
|
||||
},
|
||||
177: map[int8]int{
|
||||
model.PlatIPhone: 2275,
|
||||
model.PlatIPad: 2289,
|
||||
model.PlatAndroid: 2282,
|
||||
},
|
||||
188: map[int8]int{
|
||||
model.PlatIPhone: 2996,
|
||||
model.PlatIPad: 3008,
|
||||
model.PlatAndroid: 3002,
|
||||
model.PlatIPhoneI: 3014,
|
||||
model.PlatAndroidG: 3020,
|
||||
model.PlatAndroidI: 3032,
|
||||
model.PlatIPadI: 3026,
|
||||
},
|
||||
}
|
||||
_bannersPlat = map[int8]string{
|
||||
model.PlatIPhone: "454,453,455,456,457,458,459,460,462,463,464,465,466,1473,1934,2225,2275",
|
||||
model.PlatIPad: "788,787,789,790,791,792,793,794,795,796,797,798,799,1485,1932,2239,2289",
|
||||
model.PlatAndroid: "617,616,618,619,620,621,622,623,624,625,626,627,628,1479,1933,2232,2282",
|
||||
model.PlatIPhoneI: "1022,1017,1028,1033,1038,1043,1048,1053,1058,1063,1068,1073,1079,1491",
|
||||
model.PlatAndroidG: "1360,1355,1366,1371,1376,1381,1386,1391,1396,1401,1406,1411,1417,1497",
|
||||
model.PlatAndroidI: "1791,1785,1798,1804,1810,1816,1822,1828,1834,1840,1846,1852,1859,1873",
|
||||
model.PlatIPadI: "1192,1187,1198,1203,1208,1213,1218,1223,1228,1233,1238,1243,1249,1503",
|
||||
}
|
||||
_bannersPGC = map[int8]map[int]int{
|
||||
model.PlatAndroid: map[int]int{
|
||||
13: 83,
|
||||
167: 85,
|
||||
177: 232,
|
||||
11: 220,
|
||||
23: 49,
|
||||
},
|
||||
model.PlatIPhone: map[int]int{
|
||||
13: 97,
|
||||
167: 98,
|
||||
177: 233,
|
||||
11: 221,
|
||||
23: 50,
|
||||
},
|
||||
model.PlatIPad: map[int]int{
|
||||
13: 332,
|
||||
167: 333,
|
||||
177: 334,
|
||||
11: 336,
|
||||
23: 335,
|
||||
},
|
||||
}
|
||||
)
|
||||
|
||||
// getBanners get banners by plat, build channel, ip.
|
||||
func (s *Service) getBanners(c context.Context, plat int8, build, rid int, mid int64, channel, ip, buvid, network, mobiApp, device, adExtra string) (res map[string][]*banner.Banner) {
|
||||
var (
|
||||
resID = _banners[rid][plat]
|
||||
bs []*banner.Banner
|
||||
)
|
||||
res = map[string][]*banner.Banner{}
|
||||
if bs = s.bgmBanners(c, plat, rid); len(bs) == 0 {
|
||||
bs = s.resBanners(c, plat, build, mid, resID, channel, ip, buvid, network, mobiApp, device, adExtra)
|
||||
}
|
||||
if len(bs) > 0 {
|
||||
res["top"] = bs
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// resBannersplat
|
||||
func (s *Service) resBanners(c context.Context, plat int8, build int, mid int64, resID int, channel, ip, buvid, network, mobiApp, device, adExtra string) (res []*banner.Banner) {
|
||||
var (
|
||||
plm = s.bannerCache[plat] // operater banner
|
||||
err error
|
||||
resbs map[int][]*resource.Banner
|
||||
tmp []*resource.Banner
|
||||
)
|
||||
resIDStr := strconv.Itoa(resID)
|
||||
if resbs, err = s.res.ResBanner(c, plat, build, mid, resIDStr, channel, ip, buvid, network, mobiApp, device, adExtra, true); err != nil || len(resbs) == 0 {
|
||||
log.Error("s.res.ResBanner is null or err(%v)", err)
|
||||
resbs = plm
|
||||
}
|
||||
tmp = resbs[resID]
|
||||
for _, rb := range tmp {
|
||||
b := &banner.Banner{}
|
||||
b.ResChangeBanner(rb)
|
||||
res = append(res, b)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// bgmBanners bangumi banner
|
||||
func (s *Service) bgmBanners(c context.Context, plat int8, rid int) (bgmBanner []*banner.Banner) {
|
||||
var (
|
||||
bgmb = s.bannerBmgCache[plat][rid]
|
||||
resID = _banners[rid][plat]
|
||||
)
|
||||
for i, bb := range bgmb {
|
||||
b := &banner.Banner{}
|
||||
b.BgmChangeBanner(bb)
|
||||
b.RequestId = strconv.FormatInt(time.Now().UnixNano()/1000000, 10)
|
||||
b.Index = i + 1
|
||||
b.ResourceID = resID
|
||||
bgmBanner = append(bgmBanner, b)
|
||||
}
|
||||
return
|
||||
}
|
610
app/interface/main/app-show/service/region/cache.go
Normal file
610
app/interface/main/app-show/service/region/cache.go
Normal file
@ -0,0 +1,610 @@
|
||||
package region
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"go-common/app/interface/main/app-show/model"
|
||||
"go-common/app/interface/main/app-show/model/bangumi"
|
||||
"go-common/app/interface/main/app-show/model/card"
|
||||
"go-common/app/interface/main/app-show/model/region"
|
||||
"go-common/app/interface/main/app-show/model/tag"
|
||||
"go-common/app/service/main/archive/api"
|
||||
resource "go-common/app/service/main/resource/model"
|
||||
"go-common/library/log"
|
||||
)
|
||||
|
||||
var (
|
||||
// 番剧 动画,音乐,舞蹈,游戏,科技,娱乐,鬼畜,电影,时尚, 生活,国漫
|
||||
_tids = []int{13, 1, 3, 129, 4, 36, 5, 119, 23, 155, 160, 11, 167}
|
||||
)
|
||||
|
||||
// loadBanner1 load banner cache.
|
||||
func (s *Service) loadBanner() {
|
||||
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")
|
||||
}
|
||||
|
||||
func (s *Service) loadbgmBanner() {
|
||||
bgmBanners := map[int8]map[int][]*bangumi.Banner{}
|
||||
for plat, b := range _bannersPGC {
|
||||
ridBanners := map[int][]*bangumi.Banner{}
|
||||
for rid, pgcID := range b {
|
||||
bBanner, err := s.bgm.Banners(context.TODO(), pgcID)
|
||||
if err != nil {
|
||||
log.Error("s.bgmdao.Banners is null or err(%v)", err)
|
||||
return
|
||||
}
|
||||
ridBanners[rid] = bBanner
|
||||
}
|
||||
bgmBanners[plat] = ridBanners
|
||||
}
|
||||
s.bannerBmgCache = bgmBanners
|
||||
}
|
||||
|
||||
// loadRegionShow
|
||||
func (s *Service) loadShow() {
|
||||
// default use android regions TODO
|
||||
regionkey := fmt.Sprintf(_initRegionKey, model.PlatAndroid, _initlanguage)
|
||||
res := s.cachelist[regionkey]
|
||||
var (
|
||||
// region tmp
|
||||
showTmp = map[int][]*region.ShowItem{} // tmp hotCache
|
||||
showNTmp = map[int][]*region.ShowItem{} // tmp newCache
|
||||
showD = map[int][]*region.ShowItem{} // tmp dynamicCache
|
||||
sTmp = map[int]*region.Show{}
|
||||
// region tmp overseas
|
||||
showTmpOsea = map[int][]*region.ShowItem{} // tmp overseas hotCache
|
||||
showNTmpOsea = map[int][]*region.ShowItem{} // tmp overseas newCache
|
||||
showDOsea = map[int][]*region.ShowItem{} // tmp overseas dynamicCache
|
||||
sTmpOsea = map[int]*region.Show{}
|
||||
// aids
|
||||
showDynamicAids = map[int][]int64{}
|
||||
// new region feed
|
||||
regionFeedTmp = map[int]*region.Show{}
|
||||
regionFeedTmpOsea = map[int]*region.Show{}
|
||||
)
|
||||
for _, v := range res {
|
||||
if v.Reid == 0 {
|
||||
if v.Rid == 65537 || v.Rid == 65539 || v.Rid == 65541 || v.Rid == 65543 {
|
||||
continue
|
||||
}
|
||||
var (
|
||||
tmp, tmpOsea []*region.ShowItem
|
||||
aidsTmp []int64
|
||||
)
|
||||
tmp, tmpOsea = s.loadShowHot(v.Rid)
|
||||
showTmp[v.Rid], showTmpOsea[v.Rid] = s.upCache(tmp, tmpOsea, s.hotCache[v.Rid], s.hotOseaCache[v.Rid])
|
||||
tmp, tmpOsea = s.loadShowNewRpc(v.Rid)
|
||||
showNTmp[v.Rid], showNTmpOsea[v.Rid] = s.upCache(tmp, tmpOsea, s.newCache[v.Rid], s.newOseaCache[v.Rid])
|
||||
tmp, tmpOsea, aidsTmp = s.loadShowDynamic(v.Rid)
|
||||
showDynamicAids[v.Rid] = s.upAidsCache(aidsTmp, s.showDynamicAidsCache[v.Rid])
|
||||
showD[v.Rid], showDOsea[v.Rid] = s.upCache(tmp, tmpOsea, s.dynamicCache[v.Rid], s.dynamicOseaCache[v.Rid])
|
||||
sTmp[v.Rid] = s.mergeShow(showTmp[v.Rid], showNTmp[v.Rid], showD[v.Rid])
|
||||
// overseas
|
||||
sTmpOsea[v.Rid] = s.mergeShow(showTmpOsea[v.Rid], showNTmpOsea[v.Rid], showDOsea[v.Rid])
|
||||
// new region feed
|
||||
regionFeedTmp[v.Rid], _ = s.mergeChildShow(showTmp[v.Rid], showNTmp[v.Rid])
|
||||
regionFeedTmpOsea[v.Rid], _ = s.mergeChildShow(showTmpOsea[v.Rid], showNTmpOsea[v.Rid])
|
||||
}
|
||||
}
|
||||
s.showCache = sTmp
|
||||
s.hotCache = showTmp
|
||||
s.newCache = showNTmp
|
||||
s.dynamicCache = showD
|
||||
// overseas
|
||||
s.showOseaCache = sTmpOsea
|
||||
s.hotOseaCache = showTmpOsea
|
||||
s.newOseaCache = showNTmpOsea
|
||||
s.dynamicOseaCache = showDOsea
|
||||
// new region feed
|
||||
s.regionFeedCache = regionFeedTmp
|
||||
s.regionFeedOseaCache = regionFeedTmpOsea
|
||||
// aids
|
||||
s.showDynamicAidsCache = showDynamicAids
|
||||
}
|
||||
|
||||
// loadShowChild
|
||||
func (s *Service) loadShowChild() {
|
||||
// default use android regions TODO
|
||||
regionkey := fmt.Sprintf(_initRegionKey, model.PlatAndroid, _initlanguage)
|
||||
res := s.cachelist[regionkey]
|
||||
var (
|
||||
scTmp = map[int]*region.Show{}
|
||||
showC = map[int][]*region.ShowItem{} // tmp childHotCache
|
||||
showCN = map[int][]*region.ShowItem{} // tmp childNewCache
|
||||
// region tmp overseas
|
||||
scTmpOsea = map[int]*region.Show{}
|
||||
showCOsea = map[int][]*region.ShowItem{} // tmp overseas childHotCache
|
||||
showCNOsea = map[int][]*region.ShowItem{} // tmp overseas childNewCache
|
||||
// aids
|
||||
showChildAids = map[int][]int64{}
|
||||
showNewAids = map[int][]int64{}
|
||||
)
|
||||
for _, v := range res {
|
||||
if v.Reid != 0 {
|
||||
var (
|
||||
tmp, tmpOsea []*region.ShowItem
|
||||
aidsTmp []int64
|
||||
)
|
||||
tmp, tmpOsea, aidsTmp = s.loadShowChileHot(v.Rid)
|
||||
showChildAids[v.Rid] = s.upAidsCache(aidsTmp, s.childHotAidsCache[v.Rid])
|
||||
showC[v.Rid], showCOsea[v.Rid] = s.upCache(tmp, tmpOsea, s.childHotCache[v.Rid], s.childHotOseaCache[v.Rid])
|
||||
tmp, tmpOsea, aidsTmp = s.loadShowChildNew(v.Rid)
|
||||
showNewAids[v.Rid] = s.upAidsCache(aidsTmp, s.childNewAidsCache[v.Rid])
|
||||
showCN[v.Rid], showCNOsea[v.Rid] = s.upCache(tmp, tmpOsea, s.childNewCache[v.Rid], s.childNewOseaCache[v.Rid])
|
||||
scTmp[v.Rid], showCN[v.Rid] = s.mergeChildShow(showC[v.Rid], showCN[v.Rid])
|
||||
// overseas
|
||||
scTmpOsea[v.Rid], showCNOsea[v.Rid] = s.mergeChildShow(showCOsea[v.Rid], showCNOsea[v.Rid])
|
||||
}
|
||||
}
|
||||
s.childShowCache = scTmp
|
||||
s.childHotCache = showC
|
||||
s.childNewCache = showCN
|
||||
// overseas
|
||||
s.childShowOseaCache = scTmpOsea
|
||||
s.childHotOseaCache = showCOsea
|
||||
s.childNewOseaCache = showCNOsea
|
||||
// region child aids
|
||||
s.childHotAidsCache = showChildAids
|
||||
s.childNewAidsCache = showNewAids
|
||||
}
|
||||
|
||||
func (s *Service) loadShowChildTagsInfo() {
|
||||
// default use android regions TODO
|
||||
regionkey := fmt.Sprintf(_initRegionKey, model.PlatAndroid, _initlanguage)
|
||||
res := s.cachelist[regionkey]
|
||||
reslist := s.regionListCache[regionkey]
|
||||
var (
|
||||
// tag tmp
|
||||
tagsRegionTmp = map[int][]*region.SimilarTag{} // region tags
|
||||
tagsTmp = map[string]string{} // tagid cache
|
||||
)
|
||||
for _, v := range res {
|
||||
if v.Reid != 0 {
|
||||
//tag
|
||||
var rTmp *region.Region
|
||||
if r, ok := reslist[v.Reid]; ok {
|
||||
rTmp = r
|
||||
}
|
||||
if tids := s.loadShowChildTagIDs(v.Rid); len(tids) > 0 {
|
||||
for _, tag := range tids {
|
||||
tagInfo := ®ion.SimilarTag{
|
||||
TagId: int(tag.Tid),
|
||||
TagName: tag.Name,
|
||||
Rid: v.Rid,
|
||||
Rname: v.Name,
|
||||
}
|
||||
if rTmp != nil {
|
||||
tagInfo.Reid = rTmp.Rid
|
||||
tagInfo.Rename = rTmp.Name
|
||||
}
|
||||
//tags info
|
||||
tagsRegionTmp[v.Rid] = append(tagsRegionTmp[v.Rid], tagInfo)
|
||||
key := fmt.Sprintf(_initRegionTagKey, v.Rid, tag.Tid)
|
||||
tagsTmp[key] = tag.Name
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// region child aids
|
||||
s.regionTagCache = tagsRegionTmp
|
||||
s.tagsCache = tagsTmp
|
||||
}
|
||||
|
||||
// loadShowHot
|
||||
func (s *Service) loadShowHot(rid int) (resData, resOseaData []*region.ShowItem) {
|
||||
res, err := s.rcmmnd.RegionHots(context.TODO(), rid)
|
||||
if err != nil {
|
||||
log.Error("s.rcmmnd.RegionHot(%d) error(%v)", rid, err)
|
||||
return
|
||||
}
|
||||
if len(res) > 8 {
|
||||
res = res[:8]
|
||||
}
|
||||
resData, resOseaData = s.fromAids(context.TODO(), res, false, 0)
|
||||
log.Info("loadShowHot(%d) success", rid)
|
||||
return
|
||||
}
|
||||
|
||||
// loadShowNewRpc
|
||||
func (s *Service) loadShowNewRpc(rid int) (resData, resOseaData []*region.ShowItem) {
|
||||
arcs, err := s.arc.RankTopArcs(context.TODO(), rid, 1, 20)
|
||||
if err != nil {
|
||||
log.Error("s.arc.RankTopArcs(%d) error(%v)", rid, err)
|
||||
return
|
||||
}
|
||||
if len(arcs) > 20 {
|
||||
arcs = arcs[:20]
|
||||
}
|
||||
resData, resOseaData = s.fromArchivesPB(arcs)
|
||||
log.Info("loadShowNewRpc(%d) success", rid)
|
||||
return
|
||||
}
|
||||
|
||||
// loadShowDynamic
|
||||
func (s *Service) loadShowDynamic(rid int) (resData, resOseaData []*region.ShowItem, arcAids []int64) {
|
||||
var (
|
||||
err error
|
||||
arcs []*api.Arc
|
||||
)
|
||||
arcs, arcAids, err = s.dyn.RegionDynamic(context.TODO(), rid, 1, 100)
|
||||
if err != nil || len(arcs) < 20 {
|
||||
log.Error("s.rcmmnd.RegionDynamic(%d) error(%v)", rid, err)
|
||||
return
|
||||
}
|
||||
resData, resOseaData = s.fromArchivesPB(arcs)
|
||||
log.Info("loadShowRPCDynamic(%d) success", rid)
|
||||
return
|
||||
}
|
||||
|
||||
// loadShowChileHot
|
||||
func (s *Service) loadShowChileHot(rid int) (resData, resOseaData []*region.ShowItem, arcAids []int64) {
|
||||
var err error
|
||||
arcAids, err = s.rcmmnd.RegionChildHots(context.TODO(), rid)
|
||||
if err != nil || len(arcAids) < 4 {
|
||||
log.Error("s.rcmmnd.RegionChildHots(%d) error(%v)", rid, err)
|
||||
return
|
||||
}
|
||||
resData, resOseaData = s.fromAids(context.TODO(), arcAids, false, 0)
|
||||
log.Info("loadShowChileHot(%d) success", rid)
|
||||
return
|
||||
}
|
||||
|
||||
// loadShowChildNew
|
||||
func (s *Service) loadShowChildNew(rid int) (resData, resOseaData []*region.ShowItem, arcAids []int64) {
|
||||
var (
|
||||
err error
|
||||
arcs []*api.Arc
|
||||
)
|
||||
arcs, arcAids, err = s.arc.RanksArcs(context.TODO(), rid, 1, 300)
|
||||
if err != nil || len(arcAids) < 20 {
|
||||
log.Error("s.arc.RanksArc(%d) error(%v)", rid, err)
|
||||
return
|
||||
}
|
||||
resData, resOseaData = s.fromArchivesPB(arcs)
|
||||
log.Info("loadShowChildNew(%d) success", rid)
|
||||
return
|
||||
}
|
||||
|
||||
// loadShowChildTagIDs
|
||||
func (s *Service) loadShowChildTagIDs(rid int) (tags []*tag.Tag) {
|
||||
tags, err := s.tag.TagHotsId(context.TODO(), rid, time.Now())
|
||||
if err != nil || len(tags) == 0 {
|
||||
log.Error("s.tag.loadShowChildTagIDs(%d) error(%v)", rid, err)
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// loadRankRegionCache
|
||||
func (s *Service) loadRankRegionCache() {
|
||||
var (
|
||||
tmp = map[int][]*region.ShowItem{}
|
||||
tmpOsea = map[int][]*region.ShowItem{}
|
||||
)
|
||||
for _, rid := range _tids {
|
||||
aids, others, scores, err := s.rcmmnd.RankAppRegion(context.TODO(), rid)
|
||||
if err != nil {
|
||||
log.Error("s.rcmmnd.RankAppRegion rid (%v) error(%v)", rid, err)
|
||||
return
|
||||
}
|
||||
tRank, tOseaRank := s.fromRankAids(context.TODO(), aids, others, scores)
|
||||
tmp[rid] = tRank
|
||||
tmpOsea[rid] = tOseaRank
|
||||
}
|
||||
if len(tmp) > 0 {
|
||||
s.rankCache = tmp
|
||||
}
|
||||
if len(tmpOsea) > 0 {
|
||||
s.rankOseaCache = tmpOsea
|
||||
}
|
||||
}
|
||||
|
||||
// loadRegionListCache
|
||||
func (s *Service) loadRegionListCache() {
|
||||
res, err := s.dao.RegionPlat(context.TODO())
|
||||
if err != nil {
|
||||
log.Error("s.dao.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
|
||||
}
|
||||
|
||||
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]*region.ShowItem{}
|
||||
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]*region.ShowItem, now time.Time) (res map[string][]*region.Head) {
|
||||
// default use android regions TODO
|
||||
var (
|
||||
_topic = 1
|
||||
_activity = 0
|
||||
regionkey = fmt.Sprintf(_initRegionKey, model.PlatAndroid, _initlanguage)
|
||||
regionList = s.cachelist[regionkey]
|
||||
)
|
||||
res = map[string][]*region.Head{}
|
||||
for _, v := range regionList {
|
||||
if v.Reid != 0 {
|
||||
continue
|
||||
}
|
||||
for plat, phds := range hdm {
|
||||
hds, ok := phds[v.Rid]
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
for _, hd := range hds {
|
||||
key := fmt.Sprintf(_initCardKey, plat, v.Rid)
|
||||
var (
|
||||
sis []*region.ShowItem
|
||||
)
|
||||
its, ok := itm[hd.ID]
|
||||
if !ok {
|
||||
its = []*card.Content{}
|
||||
}
|
||||
tmpItem, ok := tmpItems[hd.ID]
|
||||
if !ok {
|
||||
tmpItem = map[int64]*region.ShowItem{}
|
||||
}
|
||||
// 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 {
|
||||
log.Error("s.act.Activitys topicID error (%v)", topicID, err)
|
||||
} else {
|
||||
if act, ok := actm[topicID]; ok && act.H5Cover != "" && act.H5URL != "" {
|
||||
si := ®ion.ShowItem{}
|
||||
si.FromTopic(act)
|
||||
sis = []*region.ShowItem{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 {
|
||||
log.Error("s.act.Activitys topicID error (%v)", topicID, err)
|
||||
} else {
|
||||
if act, ok := actm[topicID]; ok && act.H5Cover != "" && act.H5URL != "" {
|
||||
si := ®ion.ShowItem{}
|
||||
si.FromActivity(act, now)
|
||||
sis = []*region.ShowItem{si}
|
||||
}
|
||||
}
|
||||
}
|
||||
case 4:
|
||||
if tmpRank, ok := s.rankCache[v.Rid]; ok {
|
||||
if len(tmpRank) > 3 {
|
||||
sis = tmpRank[:3]
|
||||
} else {
|
||||
sis = tmpRank
|
||||
}
|
||||
}
|
||||
case 5, 6, 8:
|
||||
for _, ci := range its {
|
||||
si := s.fillCardItem(ci, tmpItem)
|
||||
if si.Title != "" {
|
||||
sis = append(sis, si)
|
||||
}
|
||||
}
|
||||
case 7:
|
||||
si := ®ion.ShowItem{
|
||||
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 := ®ion.Head{
|
||||
CardID: hd.ID,
|
||||
Title: hd.Title,
|
||||
Type: hd.TypeStr,
|
||||
Build: hd.Build,
|
||||
Condition: hd.Condition,
|
||||
Plat: hd.Plat,
|
||||
}
|
||||
if hd.Cover != "" {
|
||||
sw.Cover = hd.Cover
|
||||
}
|
||||
switch sw.Type {
|
||||
case model.GotoDaily:
|
||||
sw.Date = now.Unix()
|
||||
sw.Param = hd.Rvalue
|
||||
sw.URI = hd.URi
|
||||
sw.Goto = hd.Goto
|
||||
case model.GotoCard:
|
||||
sw.URI = hd.URi
|
||||
sw.Goto = hd.Goto
|
||||
sw.Param = hd.Param
|
||||
case model.GotoRank:
|
||||
sw.Param = strconv.Itoa(v.Rid)
|
||||
case model.GotoTopic, model.GotoActivity:
|
||||
if sw.Title == "" {
|
||||
if len(sis) > 0 {
|
||||
sw.Title = sis[0].Title
|
||||
}
|
||||
}
|
||||
case model.GotoVeidoCard:
|
||||
sw.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.URI = model.FillURICategory(hd.Goto, cidStr, hd.Param)
|
||||
}
|
||||
sw.Goto = model.GotoColumn
|
||||
} else {
|
||||
sw.Goto = hd.Goto
|
||||
sw.URI = hd.URi
|
||||
}
|
||||
if sisLen := len(sis); sisLen > 1 {
|
||||
if sisLen%2 != 0 {
|
||||
sis = sis[:sisLen-1]
|
||||
}
|
||||
} else {
|
||||
continue
|
||||
}
|
||||
case model.GotoSpecialCard:
|
||||
sw.Cover = ""
|
||||
case model.GotoTagCard:
|
||||
if hd.TagID > 0 {
|
||||
var tagIDInt int64
|
||||
sw.Title, tagIDInt = s.fromTagIDByName(c, hd.TagID, now)
|
||||
sw.Param = strconv.FormatInt(tagIDInt, 10)
|
||||
sw.Goto = model.GotoTagID
|
||||
}
|
||||
}
|
||||
sw.Body = sis
|
||||
res[key] = append(res[key], sw)
|
||||
}
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// fillCardItem
|
||||
func (s *Service) fillCardItem(csi *card.Content, tsi map[int64]*region.ShowItem) (si *region.ShowItem) {
|
||||
si = ®ion.ShowItem{}
|
||||
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 = ®ion.ShowItem{}
|
||||
}
|
||||
}
|
||||
}
|
||||
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
|
||||
}
|
||||
|
||||
// upCahce update cache
|
||||
func (s *Service) upCache(new, newOsea, old, oldOsea []*region.ShowItem) (res, resOsea []*region.ShowItem) {
|
||||
if len(new) > 0 {
|
||||
res = new
|
||||
} else {
|
||||
res = old
|
||||
}
|
||||
if len(newOsea) > 0 {
|
||||
resOsea = newOsea
|
||||
} else {
|
||||
resOsea = oldOsea
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// upAidsCache update aids cache
|
||||
func (s *Service) upAidsCache(new, old []int64) (aids []int64) {
|
||||
if len(new) > 0 {
|
||||
aids = new
|
||||
} else {
|
||||
aids = old
|
||||
}
|
||||
return
|
||||
}
|
101
app/interface/main/app-show/service/region/infoc.go
Normal file
101
app/interface/main/app-show/service/region/infoc.go
Normal file
@ -0,0 +1,101 @@
|
||||
package region
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"go-common/app/interface/main/app-show/conf"
|
||||
"go-common/library/log"
|
||||
binfoc "go-common/library/log/infoc"
|
||||
)
|
||||
|
||||
type infoc struct {
|
||||
mid string
|
||||
rid string
|
||||
tid string
|
||||
pn string
|
||||
hotavid []int64
|
||||
newavid []int64
|
||||
now string
|
||||
}
|
||||
|
||||
// Infoc write data for Hadoop do analytics
|
||||
func (s *Service) infoc(mid int64, hotavid, newavid []int64, rid, tid int, pull bool, now time.Time) {
|
||||
var pn string
|
||||
if pull {
|
||||
pn = "1"
|
||||
} else {
|
||||
pn = "2"
|
||||
}
|
||||
select {
|
||||
case s.logCh <- infoc{strconv.FormatInt(mid, 10), strconv.Itoa(rid), strconv.Itoa(tid), pn, hotavid, newavid, strconv.FormatInt(now.Unix(), 10)}:
|
||||
default:
|
||||
log.Warn("infoc log buffer is full")
|
||||
}
|
||||
}
|
||||
|
||||
// writeInfoc
|
||||
func (s *Service) infocproc() {
|
||||
const (
|
||||
noItem1 = `{"section":{"rid":`
|
||||
noItem2 = `,"tagid":`
|
||||
noItem3 = `,"mid":`
|
||||
noItem4 = `,"pn":`
|
||||
noItem5 = `,"hot_avids":[],"item_avids":[]}}`
|
||||
)
|
||||
var (
|
||||
msg1 = []byte(`{"section":{"rid":`)
|
||||
msg2 = []byte(`,"tagid":`)
|
||||
msg3 = []byte(`,"mid":`)
|
||||
msg4 = []byte(`,"pn":`)
|
||||
msg5 = []byte(`,"hot_avids":[`)
|
||||
msg6 = []byte(`,`)
|
||||
msg7 = []byte(`],"item_avids":[`)
|
||||
msg8 = []byte(`,`)
|
||||
msg9 = []byte(`]}}`)
|
||||
inf2 = binfoc.New(conf.Conf.FeedInfoc2)
|
||||
buf bytes.Buffer
|
||||
list string
|
||||
)
|
||||
for {
|
||||
i, ok := <-s.logCh
|
||||
if !ok {
|
||||
log.Warn("infoc proc exit")
|
||||
return
|
||||
}
|
||||
switch v := i.(type) {
|
||||
case infoc:
|
||||
if len(v.newavid) > 0 {
|
||||
buf.Write(msg1)
|
||||
buf.WriteString(v.rid)
|
||||
buf.Write(msg2)
|
||||
buf.WriteString(v.tid)
|
||||
buf.Write(msg3)
|
||||
buf.WriteString(v.mid)
|
||||
buf.Write(msg4)
|
||||
buf.WriteString(v.pn)
|
||||
buf.Write(msg5)
|
||||
for _, v := range v.hotavid {
|
||||
buf.WriteString(strconv.FormatInt(v, 10))
|
||||
buf.Write(msg6)
|
||||
}
|
||||
if len(v.hotavid) > 0 {
|
||||
buf.Truncate(buf.Len() - 1)
|
||||
}
|
||||
buf.Write(msg7)
|
||||
for _, v := range v.newavid {
|
||||
buf.WriteString(strconv.FormatInt(v, 10))
|
||||
buf.Write(msg8)
|
||||
}
|
||||
buf.Truncate(buf.Len() - 1)
|
||||
buf.Write(msg9)
|
||||
list = buf.String()
|
||||
buf.Reset()
|
||||
} else {
|
||||
list = noItem1 + v.rid + noItem2 + v.tid + noItem3 + v.mid + noItem4 + v.pn + noItem5
|
||||
}
|
||||
inf2.Info(v.now, list)
|
||||
}
|
||||
}
|
||||
}
|
362
app/interface/main/app-show/service/region/region.go
Normal file
362
app/interface/main/app-show/service/region/region.go
Normal file
@ -0,0 +1,362 @@
|
||||
package region
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"go-common/app/interface/main/app-show/model"
|
||||
"go-common/app/interface/main/app-show/model/region"
|
||||
locmdl "go-common/app/service/main/location/model"
|
||||
"go-common/library/ecode"
|
||||
"go-common/library/log"
|
||||
"go-common/library/net/metadata"
|
||||
|
||||
farm "github.com/dgryski/go-farm"
|
||||
)
|
||||
|
||||
const (
|
||||
_initRegionKey = "region_key_%d_%v"
|
||||
_initlanguage = "hans"
|
||||
_initVersion = "region_version"
|
||||
_regionAll = int8(0)
|
||||
_isRegion = int8(1)
|
||||
_isRank = int8(2)
|
||||
_initRegionlimit = "%d_%v"
|
||||
_regionRepeat = "r_%d_%d"
|
||||
)
|
||||
|
||||
var (
|
||||
_emptyRegions = []*region.Region{}
|
||||
_isBangumi = map[int]struct{}{
|
||||
13: struct{}{},
|
||||
177: struct{}{},
|
||||
23: struct{}{},
|
||||
11: struct{}{},
|
||||
}
|
||||
_isBangumiIndex = map[int]struct{}{
|
||||
13: struct{}{},
|
||||
23: struct{}{},
|
||||
11: struct{}{},
|
||||
167: struct{}{},
|
||||
}
|
||||
_regionlimit = map[int8]map[string]map[int]string{
|
||||
model.PlatIPhone: map[string]map[int]string{
|
||||
"65542_bilibili://cliparea": map[int]string{
|
||||
5960: "gt",
|
||||
6570: "lt",
|
||||
},
|
||||
"65541_bilibili://category/65541": map[int]string{
|
||||
5960: "gt",
|
||||
6570: "lt",
|
||||
},
|
||||
"65544_bilibili://albumarea": map[int]string{
|
||||
6090: "gt",
|
||||
6570: "lt",
|
||||
},
|
||||
},
|
||||
}
|
||||
)
|
||||
|
||||
// Regions get regions.
|
||||
func (s *Service) Regions(c context.Context, plat int8, build int, ver, mobiApp, device, language string) (rs []*region.Region, version string, err error) {
|
||||
ip := metadata.String(c, metadata.RemoteIP)
|
||||
rs, version, err = s.getCache(c, plat, build, ver, ip, mobiApp, device, language, "", false)
|
||||
return
|
||||
}
|
||||
|
||||
// Regions get regions.
|
||||
func (s *Service) RegionsList(c context.Context, plat int8, build int, ver, mobiApp, device, language, entrance string) (rs []*region.Region, version string, err error) {
|
||||
ip := metadata.String(c, metadata.RemoteIP)
|
||||
rs, version, err = s.getCache(c, plat, build, ver, ip, mobiApp, device, language, entrance, true)
|
||||
return
|
||||
}
|
||||
|
||||
// getCache get region from cache.
|
||||
func (s *Service) getCache(c context.Context, plat int8, build int, ver, ip, mobiApp, device, language, entrance string, isNew bool) (res []*region.Region, version string, err error) {
|
||||
if language == "" {
|
||||
language = _initlanguage
|
||||
}
|
||||
var (
|
||||
rs = s.cache[fmt.Sprintf(_initRegionKey, plat, language)]
|
||||
child = map[int][]*region.Region{}
|
||||
entranceShow = _isRegion
|
||||
ridlimit = _regionlimit[plat]
|
||||
ridtmp = map[string]struct{}{}
|
||||
pids []string
|
||||
auths map[string]*locmdl.Auth
|
||||
)
|
||||
switch entrance {
|
||||
case "region":
|
||||
entranceShow = _isRegion
|
||||
case "rank":
|
||||
entranceShow = _isRank
|
||||
}
|
||||
for _, rtmp := range rs {
|
||||
if rtmp.Area != "" {
|
||||
pids = append(pids, rtmp.Area)
|
||||
}
|
||||
}
|
||||
if len(pids) > 0 {
|
||||
auths, _ = s.loc.AuthPIDs(c, strings.Join(pids, ","), ip)
|
||||
}
|
||||
Retry:
|
||||
for _, rtmp := range rs {
|
||||
r := ®ion.Region{}
|
||||
*r = *rtmp
|
||||
if _, isgbm := _isBangumi[r.Rid]; isgbm {
|
||||
r.IsBangumi = 1
|
||||
}
|
||||
if isNew {
|
||||
if r.Entrance != _regionAll && entranceShow != r.Entrance {
|
||||
continue
|
||||
}
|
||||
} else {
|
||||
switch r.Rid {
|
||||
case 65545, 65542, 65541, 65543, 65544, 65546:
|
||||
if mobiApp == "android" {
|
||||
continue
|
||||
}
|
||||
}
|
||||
}
|
||||
if r.Rid != 165 || ((mobiApp != "iphone" || device != "pad") || build <= 3590) {
|
||||
if model.InvalidBuild(build, r.Build, r.Condition) {
|
||||
continue
|
||||
}
|
||||
}
|
||||
key := fmt.Sprintf(_initRegionlimit, r.Rid, r.URI)
|
||||
if rlimit, ok := ridlimit[key]; ok {
|
||||
for blimit, climit := range rlimit {
|
||||
if model.InvalidBuild(build, blimit, climit) {
|
||||
continue Retry
|
||||
}
|
||||
}
|
||||
}
|
||||
if r.Rid == 65541 && (plat == model.PlatIPhone && build == 7040) {
|
||||
continue
|
||||
}
|
||||
if r.Rid == 65543 && ((plat == model.PlatIPhone && (build == 7070 || build == 7040 || build == 7030)) ||
|
||||
(plat == model.PlatAndroid && (build == 591182 || build == 591181 || build == 591178 || build == 591177))) {
|
||||
continue
|
||||
}
|
||||
if auth, ok := auths[r.Area]; ok && auth.Play == locmdl.Forbidden {
|
||||
log.Warn("s.invalid area(%v) ip(%v) error(%v)", r.Area, ip, err)
|
||||
continue
|
||||
}
|
||||
if isAudit := s.auditRegion(mobiApp, plat, build, r.Rid); isAudit {
|
||||
continue
|
||||
}
|
||||
rkey := fmt.Sprintf(_regionRepeat, r.Rid, r.Reid)
|
||||
if _, ok := ridtmp[rkey]; !ok {
|
||||
ridtmp[rkey] = struct{}{}
|
||||
} else {
|
||||
continue
|
||||
}
|
||||
if r.Reid != 0 {
|
||||
cl, ok := child[r.Reid]
|
||||
if !ok {
|
||||
cl = []*region.Region{}
|
||||
}
|
||||
cl = append(cl, r)
|
||||
child[r.Reid] = cl
|
||||
} else {
|
||||
res = append(res, r)
|
||||
}
|
||||
}
|
||||
if len(res) == 0 {
|
||||
res = _emptyRegions
|
||||
} else {
|
||||
for _, r := range res {
|
||||
r.Children = child[r.Rid]
|
||||
}
|
||||
}
|
||||
if version = s.hash(res); version == ver {
|
||||
err = ecode.NotModified
|
||||
res = nil
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// NewRegionList get region from cache.
|
||||
func (s *Service) NewRegionList(c context.Context, plat int8, build int, ver, mobiApp, device, language string) (res []*region.Region, version string, err error) {
|
||||
ip := metadata.String(c, metadata.RemoteIP)
|
||||
var (
|
||||
hantlanguage = "hant"
|
||||
)
|
||||
if ok := model.IsOverseas(plat); ok && language != _initlanguage && language != hantlanguage {
|
||||
language = hantlanguage
|
||||
} else if language == "" {
|
||||
language = _initlanguage
|
||||
}
|
||||
var (
|
||||
rs = s.cachelist[fmt.Sprintf(_initRegionKey, plat, language)]
|
||||
child = map[int][]*region.Region{}
|
||||
ridtmp = map[string]struct{}{}
|
||||
pids []string
|
||||
auths map[string]*locmdl.Auth
|
||||
)
|
||||
for _, rtmp := range rs {
|
||||
if rtmp.Area != "" {
|
||||
pids = append(pids, rtmp.Area)
|
||||
}
|
||||
}
|
||||
if len(pids) > 0 {
|
||||
auths, _ = s.loc.AuthPIDs(c, strings.Join(pids, ","), ip)
|
||||
}
|
||||
LOOP:
|
||||
for _, rtmp := range rs {
|
||||
r := ®ion.Region{}
|
||||
*r = *rtmp
|
||||
if _, isgbm := _isBangumiIndex[r.Rid]; isgbm {
|
||||
r.IsBangumi = 1
|
||||
}
|
||||
var tmpl, limitshow bool
|
||||
if limit, ok := s.limitCache[r.ID]; ok {
|
||||
for i, l := range limit {
|
||||
if i+1 <= len(limit)-1 {
|
||||
if ((l.Condition == "gt" && limit[i+1].Condition == "lt") && (l.Build < limit[i+1].Build)) ||
|
||||
((l.Condition == "lt" && limit[i+1].Condition == "gt") && (l.Build > limit[i+1].Build)) {
|
||||
if (l.Condition == "gt" && limit[i+1].Condition == "lt") &&
|
||||
(build > l.Build && build < limit[i+1].Build) {
|
||||
break
|
||||
} else if (l.Condition == "lt" && limit[i+1].Condition == "gt") &&
|
||||
(build < l.Build && build > limit[i+1].Build) {
|
||||
break
|
||||
} else {
|
||||
tmpl = true
|
||||
continue
|
||||
}
|
||||
}
|
||||
}
|
||||
if tmpl {
|
||||
if i == len(limit)-1 {
|
||||
limitshow = true
|
||||
// continue LOOP
|
||||
break
|
||||
}
|
||||
tmpl = false
|
||||
continue
|
||||
}
|
||||
if model.InvalidBuild(build, l.Build, l.Condition) {
|
||||
limitshow = true
|
||||
continue
|
||||
// continue LOOP
|
||||
} else {
|
||||
limitshow = false
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
if limitshow {
|
||||
continue LOOP
|
||||
}
|
||||
if auth, ok := auths[r.Area]; ok && auth.Play == locmdl.Forbidden {
|
||||
log.Warn("s.invalid area(%v) ip(%v) error(%v)", r.Area, ip, err)
|
||||
continue
|
||||
}
|
||||
if isAudit := s.auditRegion(mobiApp, plat, build, r.Rid); isAudit {
|
||||
continue
|
||||
}
|
||||
if config, ok := s.configCache[r.ID]; ok {
|
||||
r.Config = config
|
||||
}
|
||||
key := fmt.Sprintf(_regionRepeat, r.Rid, r.Reid)
|
||||
if _, ok := ridtmp[key]; !ok {
|
||||
ridtmp[key] = struct{}{}
|
||||
} else {
|
||||
continue
|
||||
}
|
||||
if r.Reid != 0 {
|
||||
cl, ok := child[r.Reid]
|
||||
if !ok {
|
||||
cl = []*region.Region{}
|
||||
}
|
||||
cl = append(cl, r)
|
||||
child[r.Reid] = cl
|
||||
} else {
|
||||
res = append(res, r)
|
||||
}
|
||||
}
|
||||
if len(res) == 0 {
|
||||
res = _emptyRegions
|
||||
} else {
|
||||
for _, r := range res {
|
||||
r.Children = child[r.Rid]
|
||||
}
|
||||
}
|
||||
if version = s.hash(res); version == ver {
|
||||
err = ecode.NotModified
|
||||
res = nil
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (s *Service) hash(v []*region.Region) string {
|
||||
bs, err := json.Marshal(v)
|
||||
if err != nil {
|
||||
log.Error("json.Marshal error(%v)", err)
|
||||
return _initVersion
|
||||
}
|
||||
return strconv.FormatUint(farm.Hash64(bs), 10)
|
||||
}
|
||||
|
||||
// loadRegion regions cache.
|
||||
func (s *Service) loadRegion() {
|
||||
res, err := s.dao.All(context.TODO())
|
||||
if err != nil {
|
||||
log.Error("s.dao.All error(%v)", err)
|
||||
return
|
||||
}
|
||||
tmp := map[string][]*region.Region{}
|
||||
for _, v := range res {
|
||||
key := fmt.Sprintf(_initRegionKey, v.Plat, v.Language)
|
||||
tmp[key] = append(tmp[key], v)
|
||||
}
|
||||
if len(tmp) > 0 {
|
||||
s.cache = tmp
|
||||
}
|
||||
log.Info("region cacheproc success")
|
||||
}
|
||||
|
||||
func (s *Service) loadRegionlist() {
|
||||
res, err := s.dao.AllList(context.TODO())
|
||||
if err != nil {
|
||||
log.Error("s.dao.All error(%v)", err)
|
||||
return
|
||||
}
|
||||
tmp := map[string][]*region.Region{}
|
||||
tmpRegion := map[string]map[int]*region.Region{}
|
||||
for _, v := range res {
|
||||
key := fmt.Sprintf(_initRegionKey, v.Plat, v.Language)
|
||||
tmp[key] = append(tmp[key], v)
|
||||
// region list map
|
||||
if r, ok := tmpRegion[key]; ok {
|
||||
r[v.Rid] = v
|
||||
} else {
|
||||
tmpRegion[key] = map[int]*region.Region{
|
||||
v.Rid: v,
|
||||
}
|
||||
}
|
||||
}
|
||||
if len(tmp) > 0 && len(tmpRegion) > 0 {
|
||||
s.cachelist = tmp
|
||||
s.regionListCache = tmpRegion
|
||||
}
|
||||
log.Info("region list cacheproc success")
|
||||
limit, err := s.dao.Limit(context.TODO())
|
||||
if err != nil {
|
||||
log.Error("s.dao.limit error(%v)", err)
|
||||
return
|
||||
}
|
||||
s.limitCache = limit
|
||||
log.Info("region limit cacheproc success")
|
||||
config, err := s.dao.Config(context.TODO())
|
||||
if err != nil {
|
||||
log.Error("s.dao.Config error(%v)", err)
|
||||
return
|
||||
}
|
||||
s.configCache = config
|
||||
log.Info("region config cacheproc success")
|
||||
}
|
38
app/interface/main/app-show/service/region/region_test.go
Normal file
38
app/interface/main/app-show/service/region/region_test.go
Normal file
@ -0,0 +1,38 @@
|
||||
package region
|
||||
|
||||
import (
|
||||
"context"
|
||||
"flag"
|
||||
"go-common/app/interface/main/app-show/conf"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
. "github.com/smartystreets/goconvey/convey"
|
||||
)
|
||||
|
||||
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 TestRegions(t *testing.T) {
|
||||
Convey("get Regions data", t, WithService(func(s *Service) {
|
||||
res, ver, err := s.Regions(context.TODO(), 0, 11111, "", "android", "", _initlanguage)
|
||||
So(res, ShouldNotBeEmpty)
|
||||
So(ver, ShouldNotBeEmpty)
|
||||
So(err, ShouldBeNil)
|
||||
}))
|
||||
}
|
||||
|
||||
func TestRegionsList(t *testing.T) {
|
||||
Convey("get RegionsList data", t, WithService(func(s *Service) {
|
||||
res, ver, err := s.RegionsList(context.TODO(), 0, 11111, "", "android", "", _initlanguage, "region")
|
||||
So(res, ShouldNotBeEmpty)
|
||||
So(ver, ShouldNotBeEmpty)
|
||||
So(err, ShouldBeNil)
|
||||
}))
|
||||
}
|
338
app/interface/main/app-show/service/region/service.go
Normal file
338
app/interface/main/app-show/service/region/service.go
Normal file
@ -0,0 +1,338 @@
|
||||
package region
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"go-common/app/interface/main/app-show/conf"
|
||||
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"
|
||||
dyndao "go-common/app/interface/main/app-show/dao/dynamic"
|
||||
locdao "go-common/app/interface/main/app-show/dao/location"
|
||||
rcmmndao "go-common/app/interface/main/app-show/dao/recommend"
|
||||
rgdao "go-common/app/interface/main/app-show/dao/region"
|
||||
resdao "go-common/app/interface/main/app-show/dao/resource"
|
||||
searchdao "go-common/app/interface/main/app-show/dao/search"
|
||||
tagdao "go-common/app/interface/main/app-show/dao/tag"
|
||||
"go-common/app/interface/main/app-show/model/bangumi"
|
||||
"go-common/app/interface/main/app-show/model/card"
|
||||
"go-common/app/interface/main/app-show/model/region"
|
||||
resource "go-common/app/service/main/resource/model"
|
||||
"go-common/library/stat/prom"
|
||||
)
|
||||
|
||||
const (
|
||||
_initRegionTagKey = "region_tag_%d_%d"
|
||||
)
|
||||
|
||||
// Service is region service.
|
||||
type Service struct {
|
||||
c *conf.Config
|
||||
// prom
|
||||
pHit *prom.Prom
|
||||
pMiss *prom.Prom
|
||||
prmobi *prom.Prom
|
||||
// dao
|
||||
dao *rgdao.Dao
|
||||
// bnnr *bnnrdao.Dao
|
||||
rcmmnd *rcmmndao.Dao
|
||||
ad *addao.Dao // cptbanner
|
||||
tag *tagdao.Dao
|
||||
adt *adtdao.Dao
|
||||
arc *arcdao.Dao
|
||||
dyn *dyndao.Dao
|
||||
search *searchdao.Dao
|
||||
cdao *carddao.Dao
|
||||
act *actdao.Dao
|
||||
bgm *bgmdao.Dao
|
||||
res *resdao.Dao
|
||||
loc *locdao.Dao
|
||||
// tick
|
||||
tick time.Duration
|
||||
// regions cache
|
||||
cache map[string][]*region.Region
|
||||
// new region list cache
|
||||
cachelist map[string][]*region.Region
|
||||
limitCache map[int64][]*region.Limit
|
||||
configCache map[int64][]*region.Config
|
||||
regionListCache map[string]map[int]*region.Region
|
||||
verCache map[string]string
|
||||
// audit cache
|
||||
auditCache map[string]map[int]struct{} // audit mobi_app builds
|
||||
// region show item cache
|
||||
bannerCache map[int8]map[int][]*resource.Banner
|
||||
bannerBmgCache map[int8]map[int][]*bangumi.Banner
|
||||
hotCache map[int][]*region.ShowItem
|
||||
newCache map[int][]*region.ShowItem
|
||||
dynamicCache map[int][]*region.ShowItem
|
||||
// overseas
|
||||
hotOseaCache map[int][]*region.ShowItem
|
||||
newOseaCache map[int][]*region.ShowItem
|
||||
dynamicOseaCache map[int][]*region.ShowItem
|
||||
// region child show item cache
|
||||
childHotCache map[int][]*region.ShowItem
|
||||
childNewCache map[int][]*region.ShowItem
|
||||
childHotAidsCache map[int][]int64
|
||||
childNewAidsCache map[int][]int64
|
||||
showDynamicAidsCache map[int][]int64
|
||||
// overseas region child show item cache
|
||||
childHotOseaCache map[int][]*region.ShowItem
|
||||
childNewOseaCache map[int][]*region.ShowItem
|
||||
// region tag show item cache
|
||||
tagHotCache map[string][]*region.ShowItem
|
||||
tagNewCache map[string][]*region.ShowItem
|
||||
tagHotAidsCache map[string][]int64
|
||||
tagNewAidsCache map[string][]int64
|
||||
// overseas region tag show item cache
|
||||
tagHotOseaCache map[string][]*region.ShowItem
|
||||
tagNewOseaCache map[string][]*region.ShowItem
|
||||
// new region feed
|
||||
regionFeedCache map[int]*region.Show
|
||||
regionFeedOseaCache map[int]*region.Show
|
||||
// tags cache
|
||||
tagsCache map[string]string
|
||||
// region show
|
||||
showCache map[int]*region.Show
|
||||
childShowCache map[int]*region.Show
|
||||
// overseas region show
|
||||
showOseaCache map[int]*region.Show
|
||||
childShowOseaCache map[int]*region.Show
|
||||
// region dynamic show
|
||||
showDynamicCache map[int]*region.Show
|
||||
childShowDynamicCache map[int]*region.Show
|
||||
// overseas region dynamic show
|
||||
showDynamicOseaCache map[int]*region.Show
|
||||
childShowDynamicOseaCache map[int]*region.Show
|
||||
// similar tag
|
||||
similarTagCache map[string][]*region.SimilarTag
|
||||
// similar tag
|
||||
regionTagCache map[int][]*region.SimilarTag
|
||||
// ranking
|
||||
rankCache map[int][]*region.ShowItem
|
||||
rankOseaCache map[int][]*region.ShowItem
|
||||
// card
|
||||
cardCache map[string][]*region.Head
|
||||
columnListCache map[int]*card.ColumnList
|
||||
// region
|
||||
reRegionCache map[int]*region.Region
|
||||
// json tick
|
||||
jsonOn bool
|
||||
jsonCh chan int64
|
||||
jsonIdsCache map[int64]struct{} // rid<<32 | tid
|
||||
// cpm percentage 0~100
|
||||
cpmNum int
|
||||
cpmMid map[int64]struct{}
|
||||
cpmAll bool
|
||||
adIsPost bool
|
||||
// infoc
|
||||
logCh chan interface{}
|
||||
}
|
||||
|
||||
// New new a region service.
|
||||
func New(c *conf.Config) (s *Service) {
|
||||
s = &Service{
|
||||
c: c,
|
||||
pHit: prom.CacheHit,
|
||||
pMiss: prom.CacheMiss,
|
||||
prmobi: prom.BusinessInfoCount,
|
||||
// dao
|
||||
dao: rgdao.New(c),
|
||||
// bnnr: bnnrdao.New(c),
|
||||
rcmmnd: rcmmndao.New(c),
|
||||
ad: addao.New(c),
|
||||
adt: adtdao.New(c),
|
||||
arc: arcdao.New(c),
|
||||
tag: tagdao.New(c),
|
||||
dyn: dyndao.New(c),
|
||||
search: searchdao.New(c),
|
||||
cdao: carddao.New(c),
|
||||
act: actdao.New(c),
|
||||
bgm: bgmdao.New(c),
|
||||
res: resdao.New(c),
|
||||
loc: locdao.New(c),
|
||||
// tick
|
||||
tick: time.Duration(c.Tick),
|
||||
// audit cache
|
||||
auditCache: map[string]map[int]struct{}{},
|
||||
// regions cache
|
||||
cache: map[string][]*region.Region{},
|
||||
// new region list cache
|
||||
cachelist: map[string][]*region.Region{},
|
||||
limitCache: map[int64][]*region.Limit{},
|
||||
configCache: map[int64][]*region.Config{},
|
||||
regionListCache: map[string]map[int]*region.Region{},
|
||||
verCache: map[string]string{},
|
||||
// region show item cache
|
||||
bannerCache: map[int8]map[int][]*resource.Banner{},
|
||||
bannerBmgCache: map[int8]map[int][]*bangumi.Banner{},
|
||||
hotCache: map[int][]*region.ShowItem{},
|
||||
newCache: map[int][]*region.ShowItem{},
|
||||
dynamicCache: map[int][]*region.ShowItem{},
|
||||
// overseas
|
||||
hotOseaCache: map[int][]*region.ShowItem{},
|
||||
newOseaCache: map[int][]*region.ShowItem{},
|
||||
dynamicOseaCache: map[int][]*region.ShowItem{},
|
||||
// region child show item cache
|
||||
childHotCache: map[int][]*region.ShowItem{},
|
||||
childNewCache: map[int][]*region.ShowItem{},
|
||||
childHotAidsCache: map[int][]int64{},
|
||||
childNewAidsCache: map[int][]int64{},
|
||||
showDynamicAidsCache: map[int][]int64{},
|
||||
// overseas region child show item cache
|
||||
childHotOseaCache: map[int][]*region.ShowItem{},
|
||||
childNewOseaCache: map[int][]*region.ShowItem{},
|
||||
// region tag show item cache
|
||||
tagHotCache: map[string][]*region.ShowItem{},
|
||||
tagNewCache: map[string][]*region.ShowItem{},
|
||||
tagHotAidsCache: map[string][]int64{},
|
||||
tagNewAidsCache: map[string][]int64{},
|
||||
// overseas region tag show item cache
|
||||
tagHotOseaCache: map[string][]*region.ShowItem{},
|
||||
tagNewOseaCache: map[string][]*region.ShowItem{},
|
||||
// new region feed
|
||||
regionFeedCache: map[int]*region.Show{},
|
||||
regionFeedOseaCache: map[int]*region.Show{},
|
||||
// tags cache
|
||||
tagsCache: map[string]string{},
|
||||
// region show
|
||||
showCache: map[int]*region.Show{},
|
||||
childShowCache: map[int]*region.Show{},
|
||||
// overseas region show
|
||||
showOseaCache: map[int]*region.Show{},
|
||||
childShowOseaCache: map[int]*region.Show{},
|
||||
// region dynamic show
|
||||
showDynamicCache: map[int]*region.Show{},
|
||||
childShowDynamicCache: map[int]*region.Show{},
|
||||
// overseas region dynamic show
|
||||
showDynamicOseaCache: map[int]*region.Show{},
|
||||
childShowDynamicOseaCache: map[int]*region.Show{},
|
||||
// similar tag
|
||||
similarTagCache: map[string][]*region.SimilarTag{},
|
||||
// similar tag
|
||||
regionTagCache: map[int][]*region.SimilarTag{},
|
||||
// ranking
|
||||
rankCache: map[int][]*region.ShowItem{},
|
||||
rankOseaCache: map[int][]*region.ShowItem{},
|
||||
// card
|
||||
cardCache: map[string][]*region.Head{},
|
||||
columnListCache: map[int]*card.ColumnList{},
|
||||
// region
|
||||
reRegionCache: map[int]*region.Region{},
|
||||
// json tick
|
||||
jsonOn: false,
|
||||
jsonCh: make(chan int64, 128),
|
||||
jsonIdsCache: map[int64]struct{}{},
|
||||
// cpm percentage 0~100
|
||||
cpmNum: 0,
|
||||
cpmMid: map[int64]struct{}{},
|
||||
cpmAll: true,
|
||||
adIsPost: false,
|
||||
// infoc
|
||||
logCh: make(chan interface{}, 1024),
|
||||
}
|
||||
now := time.Now()
|
||||
s.loadRegionlist()
|
||||
s.loadRegion()
|
||||
s.loadShow()
|
||||
s.loadShowChild()
|
||||
s.loadShowChildTagsInfo()
|
||||
s.loadBanner()
|
||||
s.loadbgmBanner()
|
||||
s.loadAuditCache()
|
||||
s.loadRegionListCache()
|
||||
s.loadRankRegionCache()
|
||||
s.loadColumnListCache(now)
|
||||
s.loadCardCache(now)
|
||||
go s.loadproc()
|
||||
go s.infocproc()
|
||||
return
|
||||
}
|
||||
|
||||
func (s *Service) loadproc() {
|
||||
for {
|
||||
time.Sleep(s.tick)
|
||||
now := time.Now()
|
||||
s.loadRegionlist()
|
||||
s.loadRegion()
|
||||
s.loadShow()
|
||||
s.loadShowChild()
|
||||
s.loadShowChildTagsInfo()
|
||||
s.loadBanner()
|
||||
s.loadbgmBanner()
|
||||
s.loadAuditCache()
|
||||
s.loadRegionListCache()
|
||||
s.loadRankRegionCache()
|
||||
s.loadColumnListCache(now)
|
||||
s.loadCardCache(now)
|
||||
}
|
||||
}
|
||||
|
||||
// Close dao
|
||||
func (s *Service) Close() {
|
||||
s.dao.Close()
|
||||
}
|
||||
|
||||
// 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
|
||||
}
|
||||
|
||||
// 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
|
||||
}
|
926
app/interface/main/app-show/service/region/show.go
Normal file
926
app/interface/main/app-show/service/region/show.go
Normal file
@ -0,0 +1,926 @@
|
||||
package region
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"go-common/app/interface/main/app-show/model"
|
||||
seasongrpc "go-common/app/service/openplatform/pgc-season/api/grpc/season/v1"
|
||||
|
||||
"go-common/app/interface/main/app-show/model/region"
|
||||
"go-common/app/service/main/archive/api"
|
||||
"go-common/app/service/main/archive/model/archive"
|
||||
"go-common/library/log"
|
||||
"go-common/library/net/metadata"
|
||||
xtime "go-common/library/time"
|
||||
)
|
||||
|
||||
const (
|
||||
_initCardKey = "card_key_%d_%d"
|
||||
_bangumiSeasonID = 1
|
||||
_bangumiEpisodeID = 2
|
||||
)
|
||||
|
||||
var (
|
||||
_emptyShow = ®ion.Show{}
|
||||
_emptyShowItems = []*region.ShowItem{}
|
||||
_bangumiRids = map[int]struct{}{
|
||||
33: struct{}{},
|
||||
32: struct{}{},
|
||||
153: struct{}{},
|
||||
51: struct{}{},
|
||||
152: struct{}{},
|
||||
168: struct{}{},
|
||||
169: struct{}{},
|
||||
170: struct{}{},
|
||||
}
|
||||
_bangumiReids = map[int]struct{}{
|
||||
13: struct{}{},
|
||||
167: struct{}{},
|
||||
}
|
||||
)
|
||||
|
||||
// Show region show
|
||||
func (s *Service) Show(c context.Context, plat int8, rid, build int, mid int64, channel, buvid, network, mobiApp, device, adExtra string) (res *region.Show) {
|
||||
ip := metadata.String(c, metadata.RemoteIP)
|
||||
if model.IsOverseas(plat) {
|
||||
res = s.showOseaCache[rid]
|
||||
} else {
|
||||
res = s.showCache[rid]
|
||||
}
|
||||
if res == nil {
|
||||
res = _emptyShow
|
||||
return
|
||||
}
|
||||
if !model.IsIPad(plat) && len(res.Recommend) >= 4 {
|
||||
res = ®ion.Show{
|
||||
Recommend: res.Recommend[:4],
|
||||
New: res.New,
|
||||
Dynamic: res.Dynamic,
|
||||
}
|
||||
} else if model.IsIPad(plat) && len(res.Recommend) < 8 {
|
||||
var (
|
||||
max = 8
|
||||
hotlen = len(res.Recommend)
|
||||
)
|
||||
if last := max - hotlen; last < len(res.New) {
|
||||
res.Recommend = append(res.Recommend, res.New[:last]...)
|
||||
} else if len(res.New) > 0 {
|
||||
res.Recommend = append(res.Recommend, res.New...)
|
||||
} else {
|
||||
if last < len(res.Dynamic) {
|
||||
res.Recommend = append(res.Recommend, res.Dynamic[:last]...)
|
||||
} else if len(res.Dynamic) > 0 {
|
||||
res.Recommend = append(res.Recommend, res.Dynamic...)
|
||||
}
|
||||
}
|
||||
}
|
||||
res.Banner = s.getBanners(c, plat, build, rid, mid, channel, ip, buvid, network, mobiApp, device, adExtra)
|
||||
return
|
||||
}
|
||||
|
||||
// ShowDynamic show dynamic page
|
||||
func (s *Service) ShowDynamic(c context.Context, plat int8, build, rid, pn, ps int) (res []*region.ShowItem) {
|
||||
var (
|
||||
isOsea = model.IsOverseas(plat) //is overseas
|
||||
bangumiType = 0
|
||||
)
|
||||
if _, isBangumi := _bangumiReids[rid]; isBangumi {
|
||||
if (plat == model.PlatIPhone && build > 6090) || (plat == model.PlatAndroid && build > 514000) {
|
||||
bangumiType = _bangumiEpisodeID
|
||||
}
|
||||
}
|
||||
start := (pn - 1) * ps
|
||||
end := start + ps
|
||||
if bangumiType != 0 {
|
||||
if end < len(s.showDynamicAidsCache[rid]) {
|
||||
aids := s.showDynamicAidsCache[rid][start:end]
|
||||
res = s.fromAidsOsea(c, aids, false, isOsea, bangumiType)
|
||||
if len(res) > 0 {
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
if !isOsea {
|
||||
if end < len(s.dynamicCache[rid]) {
|
||||
res = s.dynamicCache[rid][start:end]
|
||||
return
|
||||
}
|
||||
} else {
|
||||
if end < len(s.dynamicOseaCache[rid]) {
|
||||
res = s.dynamicOseaCache[rid][start:end]
|
||||
return
|
||||
}
|
||||
}
|
||||
as, aids, err := s.dyn.RegionDynamic(c, rid, pn, ps)
|
||||
if err != nil {
|
||||
log.Error("s.rcmmnd.RegionDynamic(%d, %d, %d) error(%v)", rid, pn, ps, err)
|
||||
return
|
||||
}
|
||||
if bangumiType != 0 {
|
||||
res = s.fromArchivesPBBangumiOsea(c, as, aids, isOsea, bangumiType)
|
||||
} else {
|
||||
res = s.fromArchivesPBOsea(as, isOsea)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// ChildShow region child show
|
||||
func (s *Service) ChildShow(c context.Context, plat int8, mid int64, rid, tid, build int, channel, mobiApp string, now time.Time) (res *region.Show) {
|
||||
var (
|
||||
isOsea = model.IsOverseas(plat) //is overseas
|
||||
bangumiType = 0
|
||||
max = 20
|
||||
)
|
||||
if _, isBangumi := _bangumiRids[rid]; isBangumi {
|
||||
if (plat == model.PlatIPhone && build > 6050) || (plat == model.PlatAndroid && build > 512007) {
|
||||
bangumiType = _bangumiEpisodeID
|
||||
} else {
|
||||
bangumiType = _bangumiSeasonID
|
||||
}
|
||||
}
|
||||
if (mobiApp == "iphone" && build <= 4280) || (mobiApp == "ipad" && build <= 10400) || (mobiApp == "white" && build <= 101320) ||
|
||||
(mobiApp == "android" && build <= 501020) || (mobiApp == "android_tv" && build <= 1310) || mobiApp == "android_G" || mobiApp == "win" {
|
||||
bangumiType = 0
|
||||
}
|
||||
if tid == 0 {
|
||||
if bangumiType != 0 {
|
||||
var (
|
||||
hotTmp, newTmp []*region.ShowItem
|
||||
aids []int64
|
||||
hotOk, newOk bool
|
||||
)
|
||||
if aids, hotOk = s.childHotAidsCache[rid]; hotOk {
|
||||
if len(aids) > max {
|
||||
aids = aids[:max]
|
||||
}
|
||||
hotTmp = s.fromAidsOsea(c, aids, false, isOsea, bangumiType)
|
||||
}
|
||||
if aids, newOk = s.childNewAidsCache[rid]; newOk {
|
||||
if len(aids) > max {
|
||||
aids = aids[:max]
|
||||
}
|
||||
newTmp = s.fromAidsOsea(c, aids, false, isOsea, bangumiType)
|
||||
}
|
||||
if hotOk && newOk && len(hotTmp) > 0 && len(newTmp) > 0 {
|
||||
res, _ = s.mergeChildShow(hotTmp, newTmp)
|
||||
return
|
||||
}
|
||||
}
|
||||
if !isOsea {
|
||||
if res = s.childShowCache[rid]; res == nil {
|
||||
res = _emptyShow
|
||||
return
|
||||
}
|
||||
} else {
|
||||
if res = s.childShowOseaCache[rid]; res == nil {
|
||||
res = _emptyShow
|
||||
return
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
res = s.mergeTagShow(c, rid, tid, bangumiType, isOsea, now)
|
||||
if mid > 0 {
|
||||
var err error
|
||||
if res.Tag, err = s.tag.TagInfo(c, mid, tid, now); err != nil {
|
||||
log.Error("s.tag.TagInfo(%d, %d) error(%v)", mid, tid, err)
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// ChildListShow region childList show
|
||||
func (s *Service) ChildListShow(c context.Context, plat int8, rid, tid, pn, ps, build int, mid int64, order, platform, mobiApp, device string) (res []*region.ShowItem) {
|
||||
ip := metadata.String(c, metadata.RemoteIP)
|
||||
var (
|
||||
isOsea = model.IsOverseas(plat) //is overseas
|
||||
bangumiType = 0
|
||||
)
|
||||
start := (pn - 1) * ps
|
||||
end := start + ps
|
||||
key := fmt.Sprintf(_initRegionTagKey, rid, tid)
|
||||
if _, isBangumi := _bangumiRids[rid]; isBangumi {
|
||||
if (plat == model.PlatIPhone && build > 6050) || (plat == model.PlatAndroid && build > 512007) {
|
||||
bangumiType = _bangumiEpisodeID
|
||||
} else {
|
||||
bangumiType = _bangumiSeasonID
|
||||
}
|
||||
}
|
||||
if (mobiApp == "iphone" && build <= 4280) || (mobiApp == "ipad" && build <= 10400) || (mobiApp == "white" && build <= 101320) ||
|
||||
(mobiApp == "android" && build <= 501020) || (mobiApp == "android_tv" && build <= 1310) || mobiApp == "android_G" || mobiApp == "win" {
|
||||
bangumiType = 0
|
||||
}
|
||||
if bangumiType != 0 {
|
||||
if tid == 0 && (order == "" || order == "new") && end < len(s.childNewAidsCache[rid]) {
|
||||
aids := s.childNewAidsCache[rid][start:end]
|
||||
res = s.fromAidsOsea(c, aids, false, isOsea, bangumiType)
|
||||
if len(res) > 0 {
|
||||
return
|
||||
}
|
||||
}
|
||||
if tid > 0 && (order == "" || order == "new") && end < len(s.tagNewAidsCache[key]) {
|
||||
aids := s.tagNewAidsCache[key][start:end]
|
||||
res = s.fromAidsOsea(c, aids, false, isOsea, bangumiType)
|
||||
if len(res) > 0 {
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
if !isOsea {
|
||||
if tid == 0 && (order == "" || order == "new") && end < len(s.childNewCache[rid]) {
|
||||
res = s.childNewCache[rid][start:end]
|
||||
return
|
||||
}
|
||||
if tid > 0 && (order == "" || order == "new") && end < len(s.tagNewCache[key]) {
|
||||
res = s.tagNewCache[key][start:end]
|
||||
return
|
||||
}
|
||||
} else {
|
||||
if tid == 0 && (order == "" || order == "new") && end < len(s.childNewOseaCache[rid]) {
|
||||
res = s.childNewOseaCache[rid][start:end]
|
||||
return
|
||||
}
|
||||
if tid > 0 && (order == "" || order == "new") && end < len(s.tagNewOseaCache[key]) {
|
||||
res = s.tagNewOseaCache[key][start:end]
|
||||
return
|
||||
}
|
||||
}
|
||||
if (order == "" || order == "new") && tid == 0 {
|
||||
arcs, aids, err := s.arc.RanksArcs(c, rid, pn, ps)
|
||||
if err != nil {
|
||||
log.Error("s.rcmmnd.RegionArcList(%d, %d, %d, %d) error(%v)", rid, pn, ps, err)
|
||||
}
|
||||
if bangumiType != 0 {
|
||||
res = s.fromArchivesPBBangumiOsea(c, arcs, aids, isOsea, bangumiType)
|
||||
} else {
|
||||
res = s.fromArchivesPBOsea(arcs, isOsea)
|
||||
}
|
||||
return
|
||||
} else if (order == "" || order == "new") && tid > 0 {
|
||||
as, err := s.tag.NewArcs(c, rid, tid, pn, ps, time.Now())
|
||||
if err != nil {
|
||||
log.Error("s.tag.NewArcs(%d, %d) error(%v)", rid, tid, err)
|
||||
return
|
||||
}
|
||||
res = s.fromAidsOsea(c, as, false, isOsea, bangumiType)
|
||||
return
|
||||
}
|
||||
var (
|
||||
tname string
|
||||
ok bool
|
||||
)
|
||||
if tid > 0 {
|
||||
if tname, ok = s.tagsCache[key]; !ok {
|
||||
return
|
||||
}
|
||||
}
|
||||
as, err := s.search.SearchList(c, rid, build, pn, ps, mid, time.Now(), ip, order, tname, platform, mobiApp, device)
|
||||
if err != nil {
|
||||
log.Error("s.search.SearchList(%d, %d, %v, %d, %d) error(%v)", rid, tid, tname, pn, ps, err)
|
||||
}
|
||||
res = s.fromAidsOsea(c, as, false, isOsea, bangumiType)
|
||||
return
|
||||
}
|
||||
|
||||
// Dynamic region dynamic
|
||||
func (s *Service) Dynamic(c context.Context, plat int8, rid, build int, mid int64, channel, buvid, network, mobiApp, device, adExtra string, now time.Time) (res *region.Show) {
|
||||
ip := metadata.String(c, metadata.RemoteIP)
|
||||
var (
|
||||
isOsea = model.IsOverseas(plat) //is overseas
|
||||
resCache *region.Show
|
||||
)
|
||||
s.prmobi.Incr("region_dynamic_plat_" + mobiApp)
|
||||
if isOsea {
|
||||
if resCache = s.regionFeedOseaCache[rid]; resCache == nil {
|
||||
resCache = _emptyShow
|
||||
}
|
||||
} else {
|
||||
if resCache = s.regionFeedCache[rid]; resCache == nil {
|
||||
resCache = _emptyShow
|
||||
}
|
||||
}
|
||||
if dyn, err := s.feedRegionDynamic(c, plat, rid, 0, 0, false, true, 0, mid, resCache.Recommend, now); err == nil && dyn != nil {
|
||||
res = dyn
|
||||
} else {
|
||||
res = resCache
|
||||
}
|
||||
if res != nil {
|
||||
res.Banner = s.getBanners(c, plat, build, rid, mid, channel, ip, buvid, network, mobiApp, device, adExtra)
|
||||
res.Card = s.regionCardDisplay(plat, build, rid)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// regionCardDisplay
|
||||
func (s *Service) regionCardDisplay(plat int8, build, rid int) (res []*region.Head) {
|
||||
var ss []*region.Head
|
||||
key := fmt.Sprintf(_initCardKey, plat, rid)
|
||||
ss = s.cardCache[key]
|
||||
if len(ss) == 0 {
|
||||
res = []*region.Head{}
|
||||
return
|
||||
}
|
||||
res = []*region.Head{}
|
||||
for _, sw := range ss {
|
||||
if model.InvalidBuild(build, sw.Build, sw.Condition) {
|
||||
continue
|
||||
}
|
||||
tmp := ®ion.Head{}
|
||||
*tmp = *sw
|
||||
tmp.FillBuildURI(plat, build)
|
||||
res = append(res, tmp)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DynamicList show dynamic list
|
||||
func (s *Service) DynamicList(c context.Context, plat int8, rid int, pull bool, ctime, mid int64, now time.Time) (res *region.Show) {
|
||||
var (
|
||||
err error
|
||||
)
|
||||
if res, err = s.feedRegionDynamic(c, plat, rid, 0, 0, pull, false, ctime, mid, nil, now); err != nil || res == nil {
|
||||
res = _emptyShow
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DynamicChild region show dynamic
|
||||
func (s *Service) DynamicChild(c context.Context, plat int8, rid, tid, build int, mid int64, mobiApp string, now time.Time) (res *region.Show) {
|
||||
var (
|
||||
isOsea = model.IsOverseas(plat) //is overseas
|
||||
bangumiType = 0
|
||||
resCache *region.Show
|
||||
max = 20
|
||||
)
|
||||
s.prmobi.Incr("region_dynamic_child_plat_" + mobiApp)
|
||||
if _, isBangumi := _bangumiRids[rid]; isBangumi {
|
||||
if (plat == model.PlatIPhone && build > 6050) || (plat == model.PlatAndroid && build > 512007) {
|
||||
bangumiType = _bangumiEpisodeID
|
||||
} else {
|
||||
bangumiType = _bangumiSeasonID
|
||||
}
|
||||
}
|
||||
if tid == 0 {
|
||||
if bangumiType != 0 {
|
||||
var (
|
||||
hotTmp, newTmp []*region.ShowItem
|
||||
aids []int64
|
||||
hotOk, newOk bool
|
||||
)
|
||||
if aids, hotOk = s.childHotAidsCache[rid]; hotOk {
|
||||
if len(aids) > max {
|
||||
aids = aids[:max]
|
||||
}
|
||||
hotTmp = s.fromAidsOsea(c, aids, false, isOsea, bangumiType)
|
||||
}
|
||||
if aids, newOk = s.childNewAidsCache[rid]; newOk {
|
||||
if len(aids) > max {
|
||||
aids = aids[:max]
|
||||
}
|
||||
newTmp = s.fromAidsOsea(c, aids, false, isOsea, bangumiType)
|
||||
}
|
||||
if len(hotTmp) > 0 && len(newTmp) > 0 {
|
||||
resCache, _ = s.mergeChildShow(hotTmp, newTmp)
|
||||
}
|
||||
}
|
||||
if resCache == nil {
|
||||
if !isOsea {
|
||||
if resCache = s.childShowCache[rid]; resCache == nil {
|
||||
resCache = _emptyShow
|
||||
}
|
||||
} else {
|
||||
if resCache = s.childShowOseaCache[rid]; resCache == nil {
|
||||
resCache = _emptyShow
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
resCache = s.mergeTagShow(c, rid, tid, bangumiType, isOsea, now)
|
||||
}
|
||||
if resCache == nil {
|
||||
resCache = _emptyShow
|
||||
}
|
||||
if dyn, err := s.feedRegionDynamic(c, plat, rid, tid, bangumiType, false, true, 0, mid, nil, now); err == nil && dyn != nil {
|
||||
res = dyn
|
||||
s.pHit.Incr("feed_region_dynamic")
|
||||
} else {
|
||||
res = resCache
|
||||
s.pMiss.Incr("feed_region_dynamic")
|
||||
}
|
||||
if res != nil {
|
||||
if tid == 0 {
|
||||
if tags, ok := s.regionTagCache[rid]; ok {
|
||||
res.TopTag = tags
|
||||
}
|
||||
} else if mid > 0 {
|
||||
var err error
|
||||
if res.Tag, err = s.tag.TagInfo(c, mid, tid, now); err != nil {
|
||||
log.Error("s.tag.TagInfo(%d, %d) error(%v)", mid, tid, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DynamicListChild dynamic childList show
|
||||
func (s *Service) DynamicListChild(c context.Context, plat int8, rid, tid, build int, pull bool, ctime, mid int64, now time.Time) (res *region.Show) {
|
||||
var (
|
||||
err error
|
||||
bangumiType = 0
|
||||
)
|
||||
if _, isBangumi := _bangumiRids[rid]; isBangumi {
|
||||
if (plat == model.PlatIPhone && build > 6050) || (plat == model.PlatAndroid && build > 512007) {
|
||||
bangumiType = _bangumiEpisodeID
|
||||
} else {
|
||||
bangumiType = _bangumiSeasonID
|
||||
}
|
||||
}
|
||||
if res, err = s.feedRegionDynamic(c, plat, rid, tid, bangumiType, pull, false, ctime, mid, nil, now); err != nil || res == nil {
|
||||
res = _emptyShow
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// feedRegionDynamic
|
||||
func (s *Service) feedRegionDynamic(c context.Context, plat int8, rid, tid, bangumiType int, pull, isRecommend bool, ctime, mid int64, items []*region.ShowItem, now time.Time) (res *region.Show, err error) {
|
||||
var (
|
||||
smTagNum = 10
|
||||
smTagPos = 4
|
||||
)
|
||||
if res, err = s.feedDynamic(c, plat, rid, tid, bangumiType, pull, isRecommend, ctime, mid, items, now); err != nil || res == nil {
|
||||
log.Error("s.feedDynamic is null rid:%v tid:%v", rid, tid)
|
||||
} else {
|
||||
if isRecommend && tid > 0 {
|
||||
if st := s.similarTags(c, rid, tid, now); st != nil {
|
||||
if len(st) > smTagNum {
|
||||
res.TopTag = st[:smTagNum]
|
||||
res.NewTag = ®ion.NewTag{
|
||||
Position: smTagPos,
|
||||
Tag: st[smTagNum:],
|
||||
}
|
||||
} else {
|
||||
res.TopTag = st
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// feedRegionDynamic
|
||||
func (s *Service) feedDynamic(c context.Context, plat int8, rid, tid, bangumiType int, pull, isRecommend bool, ctime, mid int64, items []*region.ShowItem, now time.Time) (res *region.Show, err error) {
|
||||
var (
|
||||
isOsea = model.IsOverseas(plat) //is overseas
|
||||
newAids = []int64{}
|
||||
hotAids = []int64{}
|
||||
ctop, cbottom xtime.Time
|
||||
)
|
||||
if hotAids, newAids, ctop, cbottom, err = s.rcmmnd.FeedDynamic(c, pull, rid, tid, ctime, mid, now); err != nil || len(newAids) == 0 {
|
||||
log.Error("s.rcmmnd.FeedDynamic(%v) error(%v)", rid, err)
|
||||
return
|
||||
}
|
||||
newItems := s.fromAidsOsea(c, newAids, false, isOsea, bangumiType)
|
||||
hotItems := s.fromAidsOsea(c, hotAids, false, isOsea, bangumiType)
|
||||
if isRecommend && (len(newItems) > 0 || len(hotItems) > 4) && len(newItems) > 0 {
|
||||
if len(hotItems) >= 4 {
|
||||
res = s.mergeDynamicShow(hotItems, newItems, ctop, cbottom)
|
||||
} else {
|
||||
log.Error("feedDynamic_hot is null rid:%v tid:%v", rid, tid)
|
||||
res = s.mergeDynamicShow(items, newItems, ctop, cbottom)
|
||||
}
|
||||
} else if !isRecommend && len(newItems) > 0 {
|
||||
res = s.mergeDynamicShow(_emptyShowItems, newItems, ctop, cbottom)
|
||||
} else {
|
||||
log.Error("feedDynamic_newItems is null rid:%v tid:%v", rid, tid)
|
||||
}
|
||||
s.infoc(mid, hotAids, newAids, rid, tid, pull, now)
|
||||
return
|
||||
}
|
||||
|
||||
// fromArchives return region show items from archive archives.
|
||||
func (s *Service) fromArchivesPB(as []*api.Arc) (is, isOsea []*region.ShowItem) {
|
||||
var asLen = len(as)
|
||||
if asLen == 0 {
|
||||
is = _emptyShowItems
|
||||
return
|
||||
}
|
||||
is = make([]*region.ShowItem, 0, asLen)
|
||||
for _, a := range as {
|
||||
i := ®ion.ShowItem{}
|
||||
i.FromArchivePB(a)
|
||||
if a.AttrVal(archive.AttrBitOverseaLock) == 0 {
|
||||
isOsea = append(isOsea, i)
|
||||
}
|
||||
is = append(is, i)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// fromArchivesPBBangumi aid to sid
|
||||
func (s *Service) fromArchivesPBBangumi(c context.Context, as []*api.Arc, aids []int64, bangumiType int) (is, isOsea []*region.ShowItem) {
|
||||
var (
|
||||
asLen = len(as)
|
||||
err error
|
||||
// bangumi
|
||||
// sids map[int64]int64
|
||||
sids map[int32]*seasongrpc.CardInfoProto
|
||||
)
|
||||
if asLen == 0 {
|
||||
is = _emptyShowItems
|
||||
return
|
||||
}
|
||||
if sids, err = s.fromSeasonID(c, aids); err != nil {
|
||||
log.Error("s.fromSeasonID error(%v)", err)
|
||||
return
|
||||
}
|
||||
is = make([]*region.ShowItem, 0, asLen)
|
||||
for _, a := range as {
|
||||
if sid, ok := sids[int32(a.Aid)]; ok && sid.SeasonId != 0 {
|
||||
i := ®ion.ShowItem{}
|
||||
i.FromBangumiArchivePB(a, sid, bangumiType)
|
||||
if a.AttrVal(archive.AttrBitOverseaLock) == 0 {
|
||||
isOsea = append(isOsea, i)
|
||||
}
|
||||
is = append(is, i)
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// mergeShow merge show
|
||||
func (s *Service) mergeShow(hotTmp, newTmp, dynTmp []*region.ShowItem) (rs *region.Show) {
|
||||
rs = ®ion.Show{}
|
||||
if len(hotTmp) >= 4 {
|
||||
rs.Recommend = hotTmp
|
||||
} else {
|
||||
rs.Recommend = _emptyShowItems
|
||||
}
|
||||
if len(newTmp) >= 4 {
|
||||
rs.New = newTmp[:4]
|
||||
} else {
|
||||
rs.New = _emptyShowItems
|
||||
}
|
||||
if len(dynTmp) > 20 {
|
||||
rs.Dynamic = dynTmp[:20]
|
||||
} else if len(dynTmp) > 0 {
|
||||
rs.Dynamic = dynTmp
|
||||
} else {
|
||||
rs.Dynamic = _emptyShowItems
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// mergeChildShow merge child show
|
||||
func (s *Service) mergeChildShow(recTmp, newTmp []*region.ShowItem) (rs *region.Show, new []*region.ShowItem) {
|
||||
var (
|
||||
last int
|
||||
)
|
||||
rs = ®ion.Show{}
|
||||
if len(recTmp) >= 4 {
|
||||
rs.Recommend = recTmp[:4]
|
||||
} else if len(newTmp) >= 4 {
|
||||
var (
|
||||
max = 4
|
||||
hotlen = len(recTmp)
|
||||
)
|
||||
rs.Recommend = recTmp
|
||||
if last = max - hotlen; last < len(newTmp) {
|
||||
rs.Recommend = append(rs.Recommend, newTmp[:last]...)
|
||||
} else {
|
||||
rs.Recommend = append(rs.Recommend, newTmp...)
|
||||
}
|
||||
} else {
|
||||
rs.Recommend = _emptyShowItems
|
||||
}
|
||||
new = newTmp
|
||||
if last > 0 {
|
||||
if len(new) > last {
|
||||
new = new[last:]
|
||||
}
|
||||
}
|
||||
if len(new) >= 20 {
|
||||
rs.New = new[:20]
|
||||
} else if len(new) > 0 {
|
||||
rs.New = new
|
||||
} else {
|
||||
rs.New = _emptyShowItems
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// mergeDynamicShow
|
||||
func (s *Service) mergeDynamicShow(recTmp, dynTmp []*region.ShowItem, ctop, cbottom xtime.Time) (rs *region.Show) {
|
||||
if ctop == 0 || cbottom == 0 {
|
||||
rs = ®ion.Show{}
|
||||
} else {
|
||||
rs = ®ion.Show{
|
||||
Ctop: ctop,
|
||||
Cbottom: cbottom,
|
||||
}
|
||||
}
|
||||
if len(recTmp) >= 4 {
|
||||
rs.Recommend = recTmp[:4]
|
||||
} else {
|
||||
rs.Recommend = _emptyShowItems
|
||||
}
|
||||
if len(dynTmp) > 0 {
|
||||
rs.New = dynTmp
|
||||
} else {
|
||||
rs.New = _emptyShowItems
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// mergeTagShow merge tag show
|
||||
func (s *Service) mergeTagShow(c context.Context, rid, tid, bangumiType int, isOsea bool, now time.Time) (rs *region.Show) {
|
||||
const (
|
||||
strtNum = 1
|
||||
hotNum = 4
|
||||
newNum = 20
|
||||
maxNum = 50
|
||||
smTagNum = 10
|
||||
smTagPos = 4
|
||||
)
|
||||
rs = ®ion.Show{}
|
||||
// hots
|
||||
key := fmt.Sprintf(_initRegionTagKey, rid, tid)
|
||||
var (
|
||||
is []*region.ShowItem
|
||||
ok = false
|
||||
)
|
||||
if bangumiType != 0 {
|
||||
var aids []int64
|
||||
if aids, ok = s.tagHotAidsCache[key]; ok {
|
||||
is = s.fromAidsOsea(c, aids, false, isOsea, bangumiType)
|
||||
}
|
||||
} else if bangumiType == 0 || !ok {
|
||||
is, ok = s.tagHotCache[key]
|
||||
if isOsea {
|
||||
is, ok = s.tagHotOseaCache[key]
|
||||
}
|
||||
}
|
||||
if !ok {
|
||||
arcAids, err := s.tag.Hots(c, rid, tid, strtNum, hotNum, now)
|
||||
if err != nil {
|
||||
log.Error("s.tag.Hots(%d, %d) error(%v)", rid, tid, err)
|
||||
} else if is = s.fromAidsOsea(c, arcAids, true, isOsea, bangumiType); len(is) > 0 {
|
||||
if len(is) > hotNum {
|
||||
is = is[:hotNum]
|
||||
}
|
||||
}
|
||||
}
|
||||
rs.Recommend = is
|
||||
// news
|
||||
if bangumiType != 0 {
|
||||
var aids []int64
|
||||
if aids, ok = s.tagNewAidsCache[key]; ok {
|
||||
is = s.fromAidsOsea(c, aids, false, isOsea, bangumiType)
|
||||
}
|
||||
} else if bangumiType == 0 || !ok {
|
||||
is, ok = s.tagNewCache[key]
|
||||
if isOsea {
|
||||
is, ok = s.tagNewOseaCache[key]
|
||||
}
|
||||
}
|
||||
if !ok {
|
||||
as, err := s.tag.NewArcs(c, rid, tid, strtNum, maxNum, now)
|
||||
if err != nil {
|
||||
log.Error("s.tag.NewArcs(%d, %d) error(%v)", rid, tid, err)
|
||||
return
|
||||
}
|
||||
is = s.fromAidsOsea(c, as, false, isOsea, bangumiType)
|
||||
}
|
||||
var (
|
||||
hotlen = len(rs.Recommend)
|
||||
last int
|
||||
)
|
||||
if hotlen < hotNum {
|
||||
if last = hotNum - hotlen; last < len(is) {
|
||||
rs.Recommend = append(rs.Recommend, is[:last]...)
|
||||
} else {
|
||||
rs.Recommend = append(rs.Recommend, is...)
|
||||
}
|
||||
}
|
||||
if last > 0 {
|
||||
if len(is) > last {
|
||||
is = is[last:]
|
||||
}
|
||||
}
|
||||
if len(is) >= newNum {
|
||||
is = is[:newNum]
|
||||
}
|
||||
rs.New = is
|
||||
// similar tags
|
||||
if st := s.similarTags(c, rid, tid, now); st != nil {
|
||||
if len(st) > smTagNum {
|
||||
rs.TopTag = st[:smTagNum]
|
||||
rs.NewTag = ®ion.NewTag{
|
||||
Position: smTagPos,
|
||||
Tag: st[smTagNum+1:],
|
||||
}
|
||||
} else {
|
||||
rs.TopTag = st
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// fromAids get Aids. bangumiType 1 seasonid 2 epid
|
||||
func (s *Service) fromAids(c context.Context, arcAids []int64, isCheck bool, bangumiType int) (data, dataOsea []*region.ShowItem) {
|
||||
if len(arcAids) == 0 {
|
||||
return
|
||||
}
|
||||
var (
|
||||
ok bool
|
||||
aid int64
|
||||
arc *api.Arc
|
||||
as map[int64]*api.Arc
|
||||
err error
|
||||
// bangumi
|
||||
sids map[int32]*seasongrpc.CardInfoProto
|
||||
)
|
||||
if as, err = s.arc.ArchivesPB(c, arcAids); err != nil {
|
||||
log.Error("s.arc.ArchivesPB aids(%v) error(%v)", arcAids, err)
|
||||
return
|
||||
}
|
||||
data = make([]*region.ShowItem, 0, len(arcAids))
|
||||
if bangumiType != 0 {
|
||||
if sids, err = s.fromSeasonID(c, arcAids); err != nil {
|
||||
log.Error("s.fromSeasonID error(%v)", err)
|
||||
return
|
||||
}
|
||||
}
|
||||
for _, aid = range arcAids {
|
||||
if arc, ok = as[aid]; ok {
|
||||
if isCheck && !arc.IsNormal() {
|
||||
continue
|
||||
}
|
||||
i := ®ion.ShowItem{}
|
||||
if sid, ok := sids[int32(aid)]; ok && bangumiType != 0 && sid.SeasonId != 0 {
|
||||
i.FromBangumiArchivePB(arc, sid, bangumiType)
|
||||
} else {
|
||||
i.FromArchivePB(arc)
|
||||
}
|
||||
data = append(data, i)
|
||||
if arc.AttrVal(archive.AttrBitOverseaLock) == 0 {
|
||||
dataOsea = append(dataOsea, i)
|
||||
}
|
||||
}
|
||||
}
|
||||
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.bmg.CardsByAids error %v", err)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// similarTags similar tags
|
||||
func (s *Service) similarTags(c context.Context, rid, tid int, now time.Time) (res []*region.SimilarTag) {
|
||||
key := fmt.Sprintf(_initRegionTagKey, rid, tid)
|
||||
res, ok := s.similarTagCache[key]
|
||||
if !ok {
|
||||
sts, err := s.tag.SimilarTag(c, rid, tid, now)
|
||||
if err != nil {
|
||||
log.Error("s.tag.SimilarTag error(%v)", err)
|
||||
return
|
||||
}
|
||||
res = sts
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// isOverseas
|
||||
func (s *Service) fromAidsOsea(ctx context.Context, aids []int64, isCheck, isOsea bool, bangumiType int) (data []*region.ShowItem) {
|
||||
tmp, tmpOsea := s.fromAids(ctx, aids, isCheck, bangumiType)
|
||||
if isOsea {
|
||||
data = tmpOsea
|
||||
} else {
|
||||
data = tmp
|
||||
}
|
||||
if data == nil {
|
||||
data = _emptyShowItems
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// fromArchivesOsea isOverseas
|
||||
func (s *Service) fromArchivesPBOsea(as []*api.Arc, isOsea bool) (data []*region.ShowItem) {
|
||||
tmp, tmpOsea := s.fromArchivesPB(as)
|
||||
if isOsea {
|
||||
data = tmpOsea
|
||||
} else {
|
||||
data = tmp
|
||||
}
|
||||
if data == nil {
|
||||
data = _emptyShowItems
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// fromArchivesOsea isOverseas
|
||||
func (s *Service) fromArchivesPBBangumiOsea(c context.Context, as []*api.Arc, aids []int64, isOsea bool, bangumiType int) (data []*region.ShowItem) {
|
||||
tmp, tmpOsea := s.fromArchivesPBBangumi(c, as, aids, bangumiType)
|
||||
if isOsea {
|
||||
data = tmpOsea
|
||||
} else {
|
||||
data = tmp
|
||||
}
|
||||
if data == nil {
|
||||
data = _emptyShowItems
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// fromRankAids
|
||||
func (s *Service) fromRankAids(ctx context.Context, aids []int64, others, scores map[int64]int64) (sis, sisOsea []*region.ShowItem) {
|
||||
var (
|
||||
aid int64
|
||||
as map[int64]*api.Arc
|
||||
arc *api.Arc
|
||||
ok bool
|
||||
err error
|
||||
paid int64
|
||||
)
|
||||
if as, err = s.arc.ArchivesPB(ctx, aids); err != nil {
|
||||
log.Error("s.arc.ArchivesPB aids(%v) error(%v)", aids, err)
|
||||
return
|
||||
}
|
||||
if len(as) == 0 {
|
||||
log.Warn("s.arc.ArchivesPB aids(%v) length is 0", aids)
|
||||
return
|
||||
}
|
||||
child := map[int64][]*region.ShowItem{}
|
||||
childOsea := map[int64][]*region.ShowItem{}
|
||||
for _, aid = range aids {
|
||||
if arc, ok = as[aid]; ok {
|
||||
if paid, ok = others[arc.Aid]; ok {
|
||||
i := ®ion.ShowItem{}
|
||||
i.FromArchivePBRank(arc, scores)
|
||||
child[paid] = append(child[paid], i)
|
||||
if arc.AttrVal(archive.AttrBitOverseaLock) == 0 {
|
||||
childOsea[paid] = append(childOsea[paid], i)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for _, aid = range aids {
|
||||
if arc, ok = as[aid]; ok {
|
||||
if _, ok = others[arc.Aid]; !ok {
|
||||
i := ®ion.ShowItem{}
|
||||
i.FromArchivePBRank(arc, scores)
|
||||
if arc.AttrVal(archive.AttrBitOverseaLock) == 0 {
|
||||
if tmpchild, ok := childOsea[arc.Aid]; ok {
|
||||
i.Children = tmpchild
|
||||
}
|
||||
sisOsea = append(sisOsea, i)
|
||||
}
|
||||
if tmpchild, ok := child[arc.Aid]; ok {
|
||||
i.Children = tmpchild
|
||||
}
|
||||
sis = append(sis, i)
|
||||
}
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// fromCardAids get Aids.
|
||||
func (s *Service) fromCardAids(ctx context.Context, aids []int64) (data map[int64]*region.ShowItem) {
|
||||
var (
|
||||
arc *api.Arc
|
||||
ok bool
|
||||
)
|
||||
as, err := s.arc.ArchivesPB(ctx, aids)
|
||||
if err != nil {
|
||||
log.Error("s.arc.ArchivesPB error(%v)", err)
|
||||
return
|
||||
}
|
||||
if len(as) == 0 {
|
||||
log.Warn("s.arc.ArchivesPB(%v) length is 0", aids)
|
||||
return
|
||||
}
|
||||
data = map[int64]*region.ShowItem{}
|
||||
for _, aid := range aids {
|
||||
if arc, ok = as[aid]; ok {
|
||||
if !arc.IsNormal() {
|
||||
continue
|
||||
}
|
||||
i := ®ion.ShowItem{}
|
||||
i.FromArchivePB(arc)
|
||||
if region, ok := s.reRegionCache[int(arc.TypeID)]; ok {
|
||||
i.Reid = region.Rid
|
||||
}
|
||||
i.Desc = i.Rname
|
||||
data[aid] = i
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
108
app/interface/main/app-show/service/region/show_test.go
Normal file
108
app/interface/main/app-show/service/region/show_test.go
Normal file
@ -0,0 +1,108 @@
|
||||
package region
|
||||
|
||||
import (
|
||||
"context"
|
||||
"flag"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"go-common/app/interface/main/app-show/conf"
|
||||
"go-common/app/interface/main/app-show/model"
|
||||
|
||||
. "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 TestChildShow(t *testing.T) {
|
||||
Convey("get ChildShow data", t, WithService(func(s *Service) {
|
||||
res := s.ChildShow(context.TODO(), model.PlatIPhone, 0, 1, 0, 111, "", "iphone", time.Now())
|
||||
So(res, ShouldNotBeEmpty)
|
||||
}))
|
||||
}
|
||||
|
||||
func TestShow(t *testing.T) {
|
||||
Convey("get Show data", t, WithService(func(s *Service) {
|
||||
res := s.Show(context.TODO(), model.PlatIPhone, 1, 0, 0, "channel", "", "", "iphone", "phone", "")
|
||||
So(res, ShouldNotBeEmpty)
|
||||
}))
|
||||
}
|
||||
|
||||
func TestShowDynamic(t *testing.T) {
|
||||
Convey("get ShowDynamic data", t, WithService(func(s *Service) {
|
||||
res := s.ShowDynamic(context.TODO(), model.PlatIPhone, 0, 1, 1, 20)
|
||||
So(res, ShouldNotBeEmpty)
|
||||
}))
|
||||
}
|
||||
|
||||
func TestChildListShow(t *testing.T) {
|
||||
Convey("get ChildListShow data", t, WithService(func(s *Service) {
|
||||
res := s.ChildListShow(context.TODO(), model.PlatIPhone, 1, 0, 1, 20, 0, 0, "new", "ios", "iphone", "phone")
|
||||
So(res, ShouldNotBeEmpty)
|
||||
}))
|
||||
}
|
||||
|
||||
func TestDynamic(t *testing.T) {
|
||||
Convey("get Dynamic data", t, WithService(func(s *Service) {
|
||||
res := s.Dynamic(context.TODO(), model.PlatIPhone, 1, 0, 0, "channel", "", "", "iphone", "phone", "", time.Now())
|
||||
So(res, ShouldNotBeEmpty)
|
||||
}))
|
||||
}
|
||||
|
||||
func TestDynamicList(t *testing.T) {
|
||||
Convey("get DynamicList data", t, WithService(func(s *Service) {
|
||||
res := s.DynamicList(context.TODO(), model.PlatIPhone, 1, true, 0, 0, time.Now())
|
||||
So(res, ShouldNotBeEmpty)
|
||||
}))
|
||||
}
|
||||
|
||||
func TestDynamicChild(t *testing.T) {
|
||||
Convey("get DynamicChild data", t, WithService(func(s *Service) {
|
||||
res := s.DynamicChild(context.TODO(), model.PlatIPhone, 1, 0, 0, 0, "iphone", time.Now())
|
||||
So(res, ShouldNotBeEmpty)
|
||||
}))
|
||||
}
|
||||
func TestDynamicListChild(t *testing.T) {
|
||||
Convey("get DynamicListChild data", t, WithService(func(s *Service) {
|
||||
res := s.DynamicListChild(context.TODO(), model.PlatIPhone, 1, 0, 0, true, 0, 0, time.Now())
|
||||
So(res, ShouldNotBeEmpty)
|
||||
}))
|
||||
}
|
||||
|
||||
func TestAudit(t *testing.T) {
|
||||
Convey("get Audit data", t, WithService(func(s *Service) {
|
||||
res, _ := s.Audit(context.TODO(), "iphone", model.PlatIPhone, 1, 1, false)
|
||||
So(res, ShouldNotBeEmpty)
|
||||
}))
|
||||
}
|
||||
|
||||
func TestAuditChild(t *testing.T) {
|
||||
Convey("get AuditChild data", t, WithService(func(s *Service) {
|
||||
res, _ := s.AuditChild(context.TODO(), "iphone", "", model.PlatIPhone, 1, 1, 0)
|
||||
So(res, ShouldNotBeEmpty)
|
||||
}))
|
||||
}
|
||||
|
||||
func TestAuditChildList(t *testing.T) {
|
||||
Convey("get AuditChildList data", t, WithService(func(s *Service) {
|
||||
res, _ := s.AuditChildList(context.TODO(), "iphone", "", model.PlatIPhone, 1, 1, 0, 1, 1)
|
||||
So(res, ShouldNotBeEmpty)
|
||||
}))
|
||||
}
|
Reference in New Issue
Block a user