Create & Init Project...

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

View File

@@ -0,0 +1,61 @@
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_test",
"go_library",
)
go_test(
name = "go_default_test",
srcs = ["mine_test.go"],
embed = [":go_default_library"],
rundir = ".",
tags = ["automanaged"],
deps = [
"//app/interface/main/app-interface/conf:go_default_library",
"//vendor/github.com/smartystreets/goconvey/convey:go_default_library",
],
)
go_library(
name = "go_default_library",
srcs = [
"mine.go",
"service.go",
],
importpath = "go-common/app/interface/main/app-interface/service/account",
tags = ["automanaged"],
visibility = ["//visibility:public"],
deps = [
"//app/interface/main/app-interface/conf:go_default_library",
"//app/interface/main/app-interface/dao/account:go_default_library",
"//app/interface/main/app-interface/dao/audio:go_default_library",
"//app/interface/main/app-interface/dao/bplus:go_default_library",
"//app/interface/main/app-interface/dao/member:go_default_library",
"//app/interface/main/app-interface/dao/pay:go_default_library",
"//app/interface/main/app-interface/dao/relation:go_default_library",
"//app/interface/main/app-interface/dao/sidebar:go_default_library",
"//app/interface/main/app-interface/model:go_default_library",
"//app/interface/main/app-interface/model/space:go_default_library",
"//app/service/main/account/model:go_default_library",
"//app/service/main/relation/model:go_default_library",
"//app/service/main/resource/model:go_default_library",
"//library/log:go_default_library",
"//library/sync/errgroup.v2:go_default_library",
],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

View File

@@ -0,0 +1,362 @@
package space
import (
"context"
"encoding/json"
"fmt"
"sync"
"go-common/app/interface/main/app-interface/model/space"
accmdl "go-common/app/service/main/account/model"
relmdl "go-common/app/service/main/relation/model"
"go-common/library/log"
"go-common/library/sync/errgroup.v2"
)
const (
_initSidebarKey = "sidebar_%d_%d"
_selfCenter = 6
_mySerive = 7
_creative = 11
_ipadSelfCenter = 12
_ipadCreative = 13
)
var (
iphoneMenu = map[int]string{
_creative: "创作中心",
_selfCenter: "个人中心",
_mySerive: "我的服务",
}
iphoneNormalMenu = []int{_creative, _selfCenter, _mySerive}
iphoneFilterMenu = []int{_selfCenter, _mySerive}
ipadNormalMenu = []int{_ipadCreative, _ipadSelfCenter}
ipadFilterMenu = []int{_ipadSelfCenter}
)
// Mine mine center for iphone/android
func (s *Service) Mine(c context.Context, mid int64, platform, filtered string, build int, plat int8) (mine *space.Mine, err error) {
var whiteMap, rdMap map[int64]bool
mine = new(space.Mine)
mine.Official.Type = -1
if mid > 0 {
if mine, whiteMap, rdMap, err = s.userInfo(c, mid, platform, plat); err != nil {
return
}
}
if platform == "ios" {
mine.Sections = s.sections(c, whiteMap, rdMap, mid, build, filtered == "1", plat)
}
return
}
// MineIpad mine center for ipad
func (s *Service) MineIpad(c context.Context, mid int64, platform, filtered string, build int, plat int8) (mine *space.Mine, err error) {
var whiteMap, rdMap map[int64]bool
mine = new(space.Mine)
mine.Official.Type = -1
if mid > 0 {
if mine, whiteMap, rdMap, err = s.userInfo(c, mid, platform, plat); err != nil {
return
}
}
mine.IpadSections, mine.IpadUpperSections = s.ipadSections(c, whiteMap, rdMap, mid, build, filtered == "1", plat)
return
}
func (s *Service) userInfo(c context.Context, mid int64, platform string, plat int8) (mine *space.Mine, whiteMap, rdMap map[int64]bool, err error) {
mine = new(space.Mine)
whiteMap = make(map[int64]bool)
rdMap = make(map[int64]bool)
eg := errgroup.WithContext(c)
// account userinfo
eg.Go(func(ctx context.Context) (err error) {
var ps *accmdl.ProfileStat
if ps, err = s.accDao.Profile3(ctx, mid); err != nil {
log.Error("s.accDao.UserInfo(%d) error(%v)", mid, err)
return
}
if ps.Silence == 1 {
if mine.EndTime, err = s.accDao.BlockTime(ctx, mid); err != nil {
log.Error("%+v", err)
err = nil
}
}
mine.Silence = ps.Silence
mine.Mid = ps.Mid
mine.Name = ps.Name
mine.Face = ps.Face
mine.Coin = ps.Coins
if ps.Pendant.Image != "" {
mine.Pendant = &space.Pendant{Image: ps.Pendant.Image}
}
switch ps.Sex {
case "男":
mine.Sex = 1
case "女":
mine.Sex = 2
default:
mine.Sex = 0
}
mine.Rank = ps.Rank
mine.Level = ps.Level
if ps.Vip.Status == 1 {
mine.VipType = ps.Vip.Type
}
if ps.Official.Role == 0 {
mine.Official.Type = -1
} else {
if ps.Official.Role <= 2 {
mine.Official.Type = 0
} else {
mine.Official.Type = 1
}
mine.Official.Desc = ps.Official.Title
}
return
})
// music card
eg.Go(func(ctx context.Context) (err error) {
cardm, err := s.audioDao.Card(ctx, mid)
if err != nil {
log.Error("%+v", err)
err = nil
return
}
if card, ok := cardm[mid]; ok && card.Type == 1 && card.Status == 1 {
mine.AudioType = card.Type
}
return
})
// following and follower
eg.Go(func(ctx context.Context) (err error) {
var stat *relmdl.Stat
if stat, err = s.relDao.Stat(ctx, mid); err != nil {
log.Error("%+v", err)
err = nil
return
}
mine.Following = stat.Following
mine.Follower = stat.Follower
return
})
// new followers
eg.Go(func(ctx context.Context) (err error) {
if mine.NewFollowers, err = s.relDao.FollowersUnreadCount(ctx, mid); err != nil {
log.Error("%+v", err)
err = nil
return
}
return
})
// dynamic count
eg.Go(func(ctx context.Context) (err error) {
var count int64
if count, err = s.bplusDao.DynamicCount(ctx, mid); err != nil {
log.Error("%+v", err)
err = nil
return
}
mine.Dynamic = count
return
})
// bcoin
eg.Go(func(ctx context.Context) (err error) {
var bp float64
if bp, err = s.payDao.UserWalletInfo(ctx, mid, platform); err != nil {
log.Error("%+v", err)
err = nil
return
}
mine.BCoin = bp
return
})
// creative
eg.Go(func(ctx context.Context) (err error) {
var (
isUp int
show int
)
if isUp, show, err = s.memberDao.Creative(ctx, mid); err != nil {
log.Error("%+v", err)
err = nil
return
}
mine.ShowVideoup = show
mine.ShowCreative = isUp
return
})
if platform == "ios" {
var mutex sync.Mutex
//white
for _, v := range s.white[plat] {
tmpID := v.ID
tmpURL := v.URL
eg.Go(func(ctx context.Context) (err error) {
ok, err := s.accDao.UserCheck(ctx, mid, tmpURL)
if err != nil {
log.Error("s.accDao.UserCheck error(%+v)", err)
err = nil
return
}
if ok {
mutex.Lock()
whiteMap[tmpID] = true
mutex.Unlock()
}
return
})
}
//redDot
for _, v := range s.redDot[plat] {
tmpID := v.ID
tmpURL := v.URL
eg.Go(func(ctx context.Context) (err error) {
ok, err := s.accDao.RedDot(ctx, mid, tmpURL)
if err != nil {
log.Error("s.accDao.RedDot error(%+v)", err)
err = nil
return
}
if ok {
mutex.Lock()
rdMap[tmpID] = true
mutex.Unlock()
}
return
})
}
}
// when account info error,return,ingore else error
err = eg.Wait()
return
}
func (s *Service) sections(c context.Context, whiteMap, rdMap map[int64]bool, mid int64, build int, filtered bool, plat int8) (sections []*space.Section) {
menus := iphoneNormalMenu
if filtered {
menus = iphoneFilterMenu
}
for _, module := range menus {
key := fmt.Sprintf(_initSidebarKey, plat, module)
ss, ok := s.sectionCache[key]
if !ok {
continue
}
var items []*space.SectionItem
for _, si := range ss {
if !si.CheckLimit(build) {
continue
}
if si.Item.Name == "离线缓存" && filtered {
continue
}
if si.Item.WhiteURL != "" && !whiteMap[si.Item.ID] {
continue
}
tmpItem := &space.SectionItem{
Title: si.Item.Name,
Icon: si.Item.Logo,
NeedLogin: si.Item.NeedLogin,
URI: si.Item.Param,
}
if si.Item.Red != "" && rdMap[si.Item.ID] {
tmpItem.RedDot = 1
}
items = append(items, tmpItem)
}
if len(items) == 0 {
continue
}
sections = append(sections, &space.Section{
Title: iphoneMenu[module],
Items: items,
})
}
return
}
func (s *Service) ipadSections(c context.Context, whiteMap, rdMap map[int64]bool, mid int64, build int, filtered bool, plat int8) (ipadSections, ipadUpperSections []*space.SectionItem) {
menus := ipadNormalMenu
if filtered {
menus = ipadFilterMenu
}
for _, module := range menus {
key := fmt.Sprintf(_initSidebarKey, plat, module)
ss, ok := s.sectionCache[key]
if !ok {
continue
}
for _, si := range ss {
if !si.CheckLimit(build) {
continue
}
if si.Item.Name == "离线缓存" && filtered {
continue
}
if si.Item.WhiteURL != "" && !whiteMap[si.Item.ID] {
continue
}
tmpItem := &space.SectionItem{
Title: si.Item.Name,
Icon: si.Item.Logo,
NeedLogin: si.Item.NeedLogin,
URI: si.Item.Param,
}
if si.Item.Red != "" && rdMap[si.Item.ID] {
tmpItem.RedDot = 1
}
if module == _ipadCreative {
ipadUpperSections = append(ipadUpperSections, tmpItem)
} else {
ipadSections = append(ipadSections, tmpItem)
}
}
}
return
}
// Myinfo simple myinfo
func (s *Service) Myinfo(c context.Context, mid int64) (myinfo *space.Myinfo, err error) {
var pf *accmdl.ProfileStat
if pf, err = s.accDao.Profile3(c, mid); err != nil {
log.Error("%+v", err)
return
}
p, _ := json.Marshal(pf)
log.Warn("myinfo mid(%d) pf(%s)", mid, p)
myinfo = new(space.Myinfo)
if pf.Silence == 1 {
if myinfo.EndTime, err = s.accDao.BlockTime(c, mid); err != nil {
log.Error("%+v", err)
err = nil
}
}
myinfo.Coins = pf.Coins
myinfo.Sign = pf.Sign
switch pf.Sex {
case "男":
myinfo.Sex = 1
case "女":
myinfo.Sex = 2
default:
myinfo.Sex = 0
}
myinfo.Mid = mid
myinfo.Birthday = pf.Birthday.Time().Format("2006-01-02")
myinfo.Name = pf.Name
myinfo.Face = pf.Face
myinfo.Rank = pf.Rank
myinfo.Level = pf.Level
myinfo.Vip = pf.Vip
myinfo.Silence = pf.Silence
myinfo.EmailStatus = pf.EmailStatus
myinfo.TelStatus = pf.TelStatus
myinfo.Official = pf.Official
myinfo.Identification = pf.Identification
if pf.Pendant.Image != "" {
myinfo.Pendant = &space.Pendant{Image: pf.Pendant.Image}
}
return
}

View File

@@ -0,0 +1,67 @@
package space
import (
"context"
"flag"
"path/filepath"
"testing"
"time"
"go-common/app/interface/main/app-interface/conf"
. "github.com/smartystreets/goconvey/convey"
)
var s *Service
func init() {
dir, _ := filepath.Abs("../../cmd/app-interface-test.toml")
flag.Set("conf", dir)
conf.Init()
s = New(conf.Conf)
time.Sleep(3 * time.Second)
}
func Test_Mine(t *testing.T) {
Convey("Test_Mine", t, func() {
mine, err := s.Mine(context.Background(), 16840123, "ios", "", 0, 0)
So(err, ShouldBeNil)
for _, s := range mine.Sections {
Printf("%+v\n", s.Title)
for _, item := range s.Items {
Printf("%+v\n", item.Title)
}
}
})
}
func Test_MineIpad(t *testing.T) {
Convey("Test_Mine", t, func() {
mine, err := s.MineIpad(context.Background(), 16840123, "ios", "", 0, 2)
So(err, ShouldBeNil)
for _, item := range mine.IpadSections {
Printf("%+v\n", item.Title)
}
})
}
func Test_MyInfo(t *testing.T) {
Convey("Test_MyInfo", t, func() {
myinfo, err := s.Myinfo(context.Background(), 1684013)
So(err, ShouldBeNil)
Printf("%+v", myinfo)
})
}
func Test_LoadSidebar(t *testing.T) {
Convey("Test_LoadSidebar", t, func() {
Println("starting...")
sections := s.sections(context.Background(), nil, nil, 1, 1, true, 1)
for _, section := range sections {
Println("section标题:" + section.Title)
for _, item := range section.Items {
Println(item.Title)
}
}
})
}

View File

@@ -0,0 +1,125 @@
package space
import (
"context"
"fmt"
"time"
"go-common/app/interface/main/app-interface/conf"
accdao "go-common/app/interface/main/app-interface/dao/account"
audiodao "go-common/app/interface/main/app-interface/dao/audio"
bplusdao "go-common/app/interface/main/app-interface/dao/bplus"
memberdao "go-common/app/interface/main/app-interface/dao/member"
paydao "go-common/app/interface/main/app-interface/dao/pay"
reldao "go-common/app/interface/main/app-interface/dao/relation"
sidedao "go-common/app/interface/main/app-interface/dao/sidebar"
"go-common/app/interface/main/app-interface/model"
resmodel "go-common/app/service/main/resource/model"
"go-common/library/log"
)
// Service is space service
type Service struct {
c *conf.Config
accDao *accdao.Dao
audioDao *audiodao.Dao
relDao *reldao.Dao
bplusDao *bplusdao.Dao
payDao *paydao.Dao
memberDao *memberdao.Dao
sideDao *sidedao.Dao
sectionCache map[string][]*SectionItem
white map[int8][]*SectionURL
redDot map[int8][]*SectionURL
}
// SectionItem is
type SectionItem struct {
Item *resmodel.SideBar
Limit []*resmodel.SideBarLimit
}
// SectionURL is
type SectionURL struct {
ID int64
URL string
}
// CheckLimit is
func (item *SectionItem) CheckLimit(build int) bool {
for _, l := range item.Limit {
if model.InvalidBuild(build, l.Build, l.Condition) {
return false
}
}
return true
}
// New new space
func New(c *conf.Config) (s *Service) {
s = &Service{
c: c,
accDao: accdao.New(c),
audioDao: audiodao.New(c),
relDao: reldao.New(c),
bplusDao: bplusdao.New(c),
payDao: paydao.New(c),
memberDao: memberdao.New(c),
sideDao: sidedao.New(c),
sectionCache: map[string][]*SectionItem{},
white: map[int8][]*SectionURL{},
redDot: map[int8][]*SectionURL{},
}
if err := s.loadSidebar(); err != nil {
panic(fmt.Sprintf("load sidebar error(%+v)", err))
}
go s.tickproc()
return s
}
// tickproc tick load cache.
func (s *Service) tickproc() {
for {
time.Sleep(time.Duration(s.c.Tick))
s.loadSidebar()
}
}
func (s *Service) loadSidebar() (err error) {
var sidebar *resmodel.SideBars
if sidebar, err = s.sideDao.Sidebars(context.TODO()); err != nil {
log.Error("s.sideDao.SideBars error(%v)", err)
return
}
ss := make(map[string][]*SectionItem)
white := make(map[int8][]*SectionURL)
redDot := make(map[int8][]*SectionURL)
for _, item := range sidebar.SideBar {
item.Plat = s.convertPlat(item.Plat)
key := fmt.Sprintf(_initSidebarKey, item.Plat, item.Module)
ss[key] = append(ss[key], &SectionItem{
Item: item,
Limit: sidebar.Limit[item.ID],
})
if item.WhiteURL != "" {
white[item.Plat] = append(white[item.Plat], &SectionURL{ID: item.ID, URL: item.WhiteURL})
}
if item.Red != "" {
redDot[item.Plat] = append(redDot[item.Plat], &SectionURL{ID: item.ID, URL: item.Red})
}
}
s.sectionCache = ss
s.white = white
s.redDot = redDot
return
}
func (s *Service) convertPlat(oldPlat int8) (newPlat int8) {
newPlat = oldPlat
if oldPlat == 9 {
newPlat = model.PlatAndroidB
} else if oldPlat == 10 {
newPlat = model.PlatIPhoneB
}
return newPlat
}

View File

@@ -0,0 +1,45 @@
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_library",
"go_test",
)
go_library(
name = "go_default_library",
srcs = ["service.go"],
importpath = "go-common/app/interface/main/app-interface/service/dataflow",
tags = ["automanaged"],
visibility = ["//visibility:public"],
deps = [
"//app/interface/main/app-interface/conf:go_default_library",
"//library/log:go_default_library",
"//library/log/infoc: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"],
)
go_test(
name = "go_default_test",
srcs = ["service_test.go"],
embed = [":go_default_library"],
tags = ["automanaged"],
deps = [
"//app/interface/main/app-interface/conf:go_default_library",
"//vendor/github.com/smartystreets/goconvey/convey:go_default_library",
],
)

View File

@@ -0,0 +1,33 @@
package dataflow
import (
"context"
"strconv"
"time"
"go-common/app/interface/main/app-interface/conf"
"go-common/library/log"
"go-common/library/log/infoc"
)
// Service is search service
type Service struct {
c *conf.Config
infoc *infoc.Infoc
}
// New is search service initial func
func New(c *conf.Config) (s *Service) {
s = &Service{
c: c,
infoc: infoc.New(c.Infoc),
}
return
}
func (s *Service) Report(c context.Context, eventID, eventType, buvid, fts, messageInfo string, now time.Time) (err error) {
if err = s.infoc.Info(strconv.FormatInt(now.Unix(), 10), eventID, eventType, buvid, fts, messageInfo); err != nil {
log.Error("s.infoc2.Info(%v,%v,%v,%v,%v,%v) error(%v)", strconv.FormatInt(now.Unix(), 10), eventID, eventType, buvid, fts, messageInfo, err)
}
return
}

View File

@@ -0,0 +1,38 @@
package dataflow
import (
"context"
"flag"
"path/filepath"
"testing"
"time"
"go-common/app/interface/main/app-interface/conf"
. "github.com/smartystreets/goconvey/convey"
)
var (
s *Service
)
func init() {
dir, _ := filepath.Abs("../cmd/app-interface-test.toml")
flag.Set("conf", dir)
conf.Init()
s = New(conf.Conf)
time.Sleep(time.Second)
}
func WithService(f func(s *Service)) func() {
return func() {
f(s)
}
}
func TestReport(t *testing.T) {
Convey("get app banner", t, WithService(func(s *Service) {
err := s.Report(context.Background(), "1", "2", "3", "4", "5", time.Now())
So(err, ShouldBeNil)
}))
}

View File

@@ -0,0 +1,52 @@
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_test",
"go_library",
)
go_test(
name = "go_default_test",
srcs = ["service_test.go"],
embed = [":go_default_library"],
rundir = ".",
tags = ["automanaged"],
deps = [
"//app/interface/main/app-interface/conf:go_default_library",
"//vendor/github.com/smartystreets/goconvey/convey:go_default_library",
],
)
go_library(
name = "go_default_library",
srcs = [
"display.go",
"service.go",
],
importpath = "go-common/app/interface/main/app-interface/service/display",
tags = ["automanaged"],
visibility = ["//visibility:public"],
deps = [
"//app/interface/main/app-interface/conf:go_default_library",
"//app/interface/main/app-interface/dao/location:go_default_library",
"//app/service/main/location/model:go_default_library",
"//library/log:go_default_library",
"//library/net/ip:go_default_library",
"//library/net/metadata:go_default_library",
],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

View File

@@ -0,0 +1,45 @@
package display
import (
"context"
"go-common/library/net/metadata"
"strconv"
"time"
locmdl "go-common/app/service/main/location/model"
"go-common/library/log"
xip "go-common/library/net/ip"
)
// DisplayID is display id .
func (s *Service) DisplayID(c context.Context, mid int64, buvid string, now time.Time) (id string) {
if mid == 0 {
id = buvid + "-" + strconv.FormatInt(now.Unix(), 10)
} else {
id = strconv.FormatInt(mid, 10) + "-" + strconv.FormatInt(now.Unix(), 10)
}
return
}
// Zone is zone id and district info .
func (s *Service) Zone(c context.Context, now time.Time) (zone *xip.Zone) {
var (
info *locmdl.Info
err error
)
zone = &xip.Zone{}
if info, err = s.loc.Info(c, metadata.String(c, metadata.RemoteIP)); err != nil || info == nil {
log.Error("error %v or info is nil", err)
return
}
zone.ID = info.ZoneID
zone.Addr = info.Addr
zone.ISP = info.ISP
zone.Country = info.Country
zone.Province = info.Province
zone.City = info.City
zone.Latitude = info.Latitude
zone.Longitude = info.Longitude
zone.CountryCode = info.CountryCode
return
}

View File

@@ -0,0 +1,20 @@
package display
import (
"go-common/app/interface/main/app-interface/conf"
locdao "go-common/app/interface/main/app-interface/dao/location"
)
// Service is zone service.
type Service struct {
// ip
loc *locdao.Dao
}
// New initial display service.
func New(c *conf.Config) (s *Service) {
s = &Service{
loc: locdao.New(c),
}
return
}

View File

@@ -0,0 +1,38 @@
package display
import (
"context"
"flag"
"path/filepath"
"testing"
"time"
"go-common/app/interface/main/app-interface/conf"
. "github.com/smartystreets/goconvey/convey"
)
var (
s *Service
)
func init() {
dir, _ := filepath.Abs("../cmd/app-interface-test.toml")
flag.Set("conf", dir)
conf.Init()
s = New(conf.Conf)
time.Sleep(time.Second)
}
func WithService(f func(s *Service)) func() {
return func() {
f(s)
}
}
func Test_Zone(t *testing.T) {
Convey("get Zone", t, WithService(func(s *Service) {
zone := s.Zone(context.Background(), time.Now())
So(zone, ShouldNotBeNil)
}))
}

View File

@@ -0,0 +1,65 @@
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_test",
"go_library",
)
go_test(
name = "go_default_test",
srcs = [
"favorite_test.go",
"service_test.go",
],
embed = [":go_default_library"],
rundir = ".",
tags = ["automanaged"],
deps = [
"//app/interface/main/app-interface/conf:go_default_library",
"//app/interface/main/app-interface/model/favorite:go_default_library",
"//vendor/github.com/smartystreets/goconvey/convey:go_default_library",
],
)
go_library(
name = "go_default_library",
srcs = [
"favorite.go",
"service.go",
],
importpath = "go-common/app/interface/main/app-interface/service/favorite",
tags = ["automanaged"],
visibility = ["//visibility:public"],
deps = [
"//app/interface/main/app-interface/conf:go_default_library",
"//app/interface/main/app-interface/dao/article:go_default_library",
"//app/interface/main/app-interface/dao/audio:go_default_library",
"//app/interface/main/app-interface/dao/bangumi:go_default_library",
"//app/interface/main/app-interface/dao/bplus:go_default_library",
"//app/interface/main/app-interface/dao/favorite:go_default_library",
"//app/interface/main/app-interface/dao/mall:go_default_library",
"//app/interface/main/app-interface/dao/sp:go_default_library",
"//app/interface/main/app-interface/dao/ticket:go_default_library",
"//app/interface/main/app-interface/dao/topic:go_default_library",
"//app/interface/main/app-interface/model:go_default_library",
"//app/interface/main/app-interface/model/favorite:go_default_library",
"//app/service/main/favorite/api:go_default_library",
"//library/log:go_default_library",
"//library/sync/errgroup:go_default_library",
],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

View File

@@ -0,0 +1,435 @@
package favorite
import (
"context"
"go-common/app/interface/main/app-interface/model"
"go-common/app/interface/main/app-interface/model/favorite"
fav "go-common/app/service/main/favorite/api"
"go-common/library/log"
"go-common/library/sync/errgroup"
)
const (
_av = "av" //视频ipad没有播单还是视频
_playlist = "playlist" // 播单
_bangumi = "bangumi" // 追番
_cinema = "cinema" // 追剧
_topic = "topic" // 话题
_article = "article" // 专栏
_menu = "menu" // 歌单
_pgcMenu = "pgc_menu" // 专辑
_clips = "clips" // 小视频
_albums = "albums" // 相簿
_product = "product" // 商品
_ticket = "ticket" // 展演
_favorite = "favorite"
)
var tabMap = map[string]*favorite.TabItem{
_av: {Name: "视频", Uri: "bilibili://main/favorite/video", Tab: _favorite},
_playlist: {Name: "播单", Uri: "bilibili://main/favorite/playlist", Tab: _favorite},
_bangumi: {Name: "追番", Uri: "bilibili://pgc/favorite/bangumi", Tab: _bangumi},
_cinema: {Name: "追剧", Uri: "bilibili://pgc/favorite/cinema", Tab: _cinema},
_topic: {Name: "话题", Uri: "bilibili://main/favorite/topic", Tab: _topic},
_article: {Name: "专栏", Uri: "bilibili://column/favorite/article", Tab: _article},
_menu: {Name: "歌单", Uri: "bilibili://music/favorite/menu", Tab: _menu},
_pgcMenu: {Name: "专辑", Uri: "bilibili://music/favorite/album", Tab: _pgcMenu},
_clips: {Name: "小视频", Uri: "bilibili://clip/favorite", Tab: _clips},
_albums: {Name: "相簿", Uri: "bilibili://pictureshow/favorite", Tab: _albums},
_product: {Name: "商品", Uri: "bilibili://mall/favorite/goods", Tab: _product},
_ticket: {Name: "展演", Uri: "bilibili://mall/favorite/ticket", Tab: _ticket},
}
var tabArr = []string{_av, _playlist, _bangumi, _cinema, _topic, _article, _menu, _pgcMenu, _clips, _albums, _product, _ticket}
// Folder get my favorite.
func (s *Service) Folder(c context.Context, accessKey, actionKey, device, mobiApp, platform string, build int, aid, vmid, mid int64) (rs *favorite.MyFavorite, err error) {
var pn, ps int = 1, 5
rs = &favorite.MyFavorite{
Tab: &favorite.Tab{
Fav: true,
},
}
g, ctx := errgroup.WithContext(c)
g.Go(func() (err error) {
var (
mediaList bool
folders []*favorite.Folder
)
plat := model.Plat(mobiApp, device)
// 双端版本号限制,符合此条件显示为“默认收藏夹”:
// iPhone <5.36.1(8300) 或iPhone>5.36.1(8300)
// Android <5360001或Android>5361000
// 双端版本号限制,符合此条件显示为“默认播单”:
// iPhone=5.36.1(8300)
// 5360001 <=Android <=5361000
if (plat == model.PlatIPhone && build == 8300) || (plat == model.PlatAndroid && build >= 5360001 && build <= 5361000) {
mediaList = true
}
if folders, err = s.favDao.Folders(ctx, mid, vmid, mobiApp, build, mediaList); err != nil {
log.Error("%+v", err)
return
}
if len(folders) != 0 {
rs.Favorite = &favorite.FavList{
Count: len(folders),
Items: make([]*favorite.FavItem, 0, len(folders)),
}
for _, v := range folders {
fi := &favorite.FavItem{}
fi.FromFav(v)
rs.Favorite.Items = append(rs.Favorite.Items, fi)
}
}
return
})
g.Go(func() (err error) {
var topic *fav.UserFolderReply
if topic, err = s.topicDao.UserFolder(ctx, mid, 4); err != nil {
log.Error("%+v", err)
err = nil
return
}
if topic != nil && topic.Res != nil && topic.Res.Count > 0 {
rs.Tab.Topic = true
}
return
})
g.Go(func() error {
article := s.Article(ctx, mid, pn, ps)
if article != nil && article.Count > 0 {
rs.Tab.Article = true
}
return nil
})
g.Go(func() error {
clips := s.Clips(ctx, mid, accessKey, actionKey, device, mobiApp, platform, build, pn, ps)
if clips != nil && clips.PageInfo != nil && clips.Count > 0 {
rs.Tab.Clips = true
}
return nil
})
g.Go(func() error {
albums := s.Albums(ctx, mid, accessKey, actionKey, device, mobiApp, platform, build, pn, ps)
if albums != nil && albums.PageInfo != nil && albums.Count > 0 {
rs.Tab.Albums = true
}
return nil
})
g.Go(func() error {
specil := s.Specil(ctx, accessKey, actionKey, device, mobiApp, platform, build, pn, ps)
if specil != nil && specil.Count > 0 {
rs.Tab.Specil = true
}
return nil
})
g.Go(func() (err error) {
var has bool
if has, err = s.bangumiDao.HasFollows(ctx, mid); err != nil {
log.Error("%+v", err)
err = nil
return
}
rs.Tab.Cinema = has
return
})
g.Go(func() (err error) {
fav, err := s.audioDao.Fav(ctx, mid)
if err != nil {
log.Error("%+v", err)
err = nil
return
}
if fav != nil {
rs.Tab.Menu = fav.Menu
rs.Tab.PGCMenu = fav.PGCMenu
rs.Tab.Audios = fav.Song
}
return
})
g.Go(func() (err error) {
var ticket int32
if ticket, err = s.ticketDao.FavCount(ctx, mid); err != nil {
log.Error("%+v", err)
err = nil
return
}
if ticket > 0 {
rs.Tab.Ticket = true
}
return
})
g.Go(func() (err error) {
var product int32
if product, err = s.mallDao.FavCount(ctx, mid); err != nil {
log.Error("%+v", err)
err = nil
return
}
if product > 0 {
rs.Tab.Product = true
}
return
})
if err = g.Wait(); err != nil {
log.Error("%+v", err)
}
return
}
func (s *Service) FolderVideo(c context.Context, accessKey, actionKey, device, mobiApp, platform, keyword, order string, build, tid, pn, ps int, mid, fid, vmid int64) (folder *favorite.FavideoList) {
video, err := s.favDao.FolderVideo(c, accessKey, actionKey, device, mobiApp, platform, keyword, order, build, tid, pn, ps, mid, fid, vmid)
if err != nil {
folder = &favorite.FavideoList{Items: []*favorite.FavideoItem{}}
log.Error("%+v", err)
return
}
folder = &favorite.FavideoList{
Count: video.Total,
Items: make([]*favorite.FavideoItem, 0, len(video.Archives)),
}
if video != nil {
for _, v := range video.Archives {
fi := &favorite.FavideoItem{}
fi.FromFavideo(v)
folder.Items = append(folder.Items, fi)
}
}
return
}
func (s *Service) Topic(c context.Context, accessKey, actionKey, device, mobiApp, platform string, build, ps, pn int, mid int64) (topic *favorite.TopicList) {
topics, err := s.topicDao.Topic(c, accessKey, actionKey, device, mobiApp, platform, build, ps, pn, mid)
if err != nil {
topic = &favorite.TopicList{Items: []*favorite.TopicItem{}}
log.Error("%+v", err)
return
}
topic = &favorite.TopicList{
Count: topics.Total,
Items: make([]*favorite.TopicItem, 0, len(topics.Lists)),
}
if topics != nil {
for _, v := range topics.Lists {
fi := &favorite.TopicItem{}
fi.FromTopic(v)
topic.Items = append(topic.Items, fi)
}
}
return
}
func (s *Service) Article(c context.Context, mid int64, pn, ps int) (article *favorite.ArticleList) {
articleTmp, err := s.artDao.Favorites(c, mid, pn, ps)
if err != nil {
article = &favorite.ArticleList{Items: []*favorite.ArticleItem{}}
log.Error("%+v", err)
return
}
article = &favorite.ArticleList{
Count: len(articleTmp),
Items: make([]*favorite.ArticleItem, 0, len(articleTmp)),
}
if len(articleTmp) != 0 {
for _, v := range articleTmp {
fi := &favorite.ArticleItem{}
fi.FromArticle(v)
article.Items = append(article.Items, fi)
}
}
return
}
// Clips
func (s *Service) Clips(c context.Context, mid int64, accessKey, actionKey, device, mobiApp, platform string, build, pn, ps int) (clips *favorite.ClipsList) {
clipsTmp, err := s.bplusDao.FavClips(c, mid, accessKey, actionKey, device, mobiApp, platform, build, pn, ps)
if err != nil {
clips = &favorite.ClipsList{Items: []*favorite.ClipsItem{}}
log.Error("%+v", err)
return
}
clips = &favorite.ClipsList{
PageInfo: clipsTmp.PageInfo,
Items: make([]*favorite.ClipsItem, 0, len(clipsTmp.List)),
}
if clipsTmp != nil {
for _, v := range clipsTmp.List {
fi := &favorite.ClipsItem{}
fi.FromClips(v)
clips.Items = append(clips.Items, fi)
}
}
return
}
func (s *Service) Albums(c context.Context, mid int64, accessKey, actionKey, device, mobiApp, platform string, build, pn, ps int) (albums *favorite.AlbumsList) {
albumsTmp, err := s.bplusDao.FavAlbums(c, mid, accessKey, actionKey, device, mobiApp, platform, build, pn, ps)
if err != nil {
albums = &favorite.AlbumsList{Items: []*favorite.AlbumItem{}}
log.Error("%+v", err)
return
}
albums = &favorite.AlbumsList{
PageInfo: albumsTmp.PageInfo,
Items: make([]*favorite.AlbumItem, 0, len(albumsTmp.List)),
}
if albumsTmp != nil {
for _, v := range albumsTmp.List {
fi := &favorite.AlbumItem{}
fi.FromAlbum(v)
albums.Items = append(albums.Items, fi)
}
}
return
}
func (s *Service) Specil(c context.Context, accessKey, actionKey, device, mobiApp, platform string, build, pn, ps int) (specil *favorite.SpList) {
specilTmp, err := s.spDao.Specil(c, accessKey, actionKey, device, mobiApp, platform, build, pn, ps)
if err != nil {
specil = &favorite.SpList{Items: []*favorite.SpItem{}}
log.Error("%+v", err)
return
}
specil = &favorite.SpList{
Count: len(specilTmp.Items),
Items: make([]*favorite.SpItem, 0, len(specilTmp.Items)),
}
if specilTmp != nil {
for _, v := range specilTmp.Items {
fi := &favorite.SpItem{}
fi.FromSp(v)
specil.Items = append(specil.Items, fi)
}
}
return
}
func (s *Service) Audio(c context.Context, accessKey string, mid int64, pn, ps int) (audio *favorite.AudioList) {
audioTmp, err := s.audioDao.FavAudio(c, accessKey, mid, pn, ps)
if err != nil {
audio = &favorite.AudioList{Items: []*favorite.AudioItem{}}
log.Error("%+v", err)
return
}
audio = &favorite.AudioList{
Count: len(audioTmp),
Items: make([]*favorite.AudioItem, 0, len(audioTmp)),
}
for _, v := range audioTmp {
fi := &favorite.AudioItem{}
fi.FromAudio(v)
audio.Items = append(audio.Items, fi)
}
return
}
// Tab fav tab.
func (s *Service) Tab(c context.Context, accessKey, actionKey, device, mobiApp, platform, filtered string, build int, mid int64) (tab []*favorite.TabItem, err error) {
var (
pn, ps = 1, 5
tabDisplay = []string{_playlist}
)
plat := model.Plat(mobiApp, device)
if model.IsIPad(plat) {
tabDisplay = []string{_av}
}
g, ctx := errgroup.WithContext(c)
g.Go(func() (err error) {
var bangumiFav, cinemaFav int
if bangumiFav, cinemaFav, err = s.bangumiDao.FavDisplay(ctx, mid); err != nil {
log.Error("%+v", err)
err = nil
return
}
if bangumiFav == 1 {
tabDisplay = append(tabDisplay, _bangumi)
}
if cinemaFav == 1 {
tabDisplay = append(tabDisplay, _cinema)
}
return
})
if !model.IsIPad(plat) {
if filtered != "1" {
g.Go(func() (err error) {
var topic *fav.UserFolderReply
if topic, err = s.topicDao.UserFolder(ctx, mid, 4); err != nil {
log.Error("%+v", err)
err = nil
return
}
if topic != nil && topic.Res != nil && topic.Res.Count > 0 {
tabDisplay = append(tabDisplay, _topic)
}
return
})
}
g.Go(func() error {
article := s.Article(ctx, mid, pn, ps)
if article != nil && article.Count > 0 {
tabDisplay = append(tabDisplay, _article)
}
return nil
})
g.Go(func() error {
clips := s.Clips(ctx, mid, accessKey, actionKey, device, mobiApp, platform, build, pn, ps)
if clips != nil && clips.PageInfo != nil && clips.Count > 0 {
tabDisplay = append(tabDisplay, _clips)
}
return nil
})
g.Go(func() error {
albums := s.Albums(ctx, mid, accessKey, actionKey, device, mobiApp, platform, build, pn, ps)
if albums != nil && albums.PageInfo != nil && albums.Count > 0 {
tabDisplay = append(tabDisplay, _albums)
}
return nil
})
g.Go(func() (err error) {
fav, err := s.audioDao.Fav(ctx, mid)
if err != nil {
log.Error("%+v", err)
err = nil
return
}
if fav != nil {
tabDisplay = append(tabDisplay, _menu)
tabDisplay = append(tabDisplay, _pgcMenu)
}
return
})
g.Go(func() (err error) {
var ticket int32
if ticket, err = s.ticketDao.FavCount(ctx, mid); err != nil {
log.Error("%+v", err)
err = nil
return
}
if ticket > 0 {
tabDisplay = append(tabDisplay, _ticket)
}
return
})
g.Go(func() (err error) {
var product int32
if product, err = s.mallDao.FavCount(ctx, mid); err != nil {
log.Error("%+v", err)
err = nil
return
}
if product > 0 {
tabDisplay = append(tabDisplay, _product)
}
return
})
}
g.Wait()
for _, t := range tabArr {
for _, dt := range tabDisplay {
if t == dt {
tab = append(tab, tabMap[t])
}
}
}
return
}

View File

@@ -0,0 +1,246 @@
package favorite
import (
"context"
"encoding/json"
"fmt"
"reflect"
"testing"
"go-common/app/interface/main/app-interface/model/favorite"
"github.com/smartystreets/goconvey/convey"
)
var s *Service
func TestFolder(t *testing.T) {
var (
c = context.TODO()
)
convey.Convey("Folder", t, func(ctx convey.C) {
folder, err := s.Folder(c, "", "", "", "", "", 0, 1, 27515397, 27515397)
b, _ := json.Marshal(folder)
fmt.Printf("%s", b)
ctx.Convey("Then err should be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
})
}
func TestService_FolderVideo(t *testing.T) {
type args struct {
c context.Context
accessKey string
actionKey string
device string
mobiApp string
platform string
keyword string
order string
build int
tid int
pn int
ps int
mid int64
fid int64
vmid int64
}
tests := []struct {
name string
s *Service
args args
wantFolder *favorite.FavideoList
}{
// TODO: Add test cases.
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if gotFolder := tt.s.FolderVideo(tt.args.c, tt.args.accessKey, tt.args.actionKey, tt.args.device, tt.args.mobiApp, tt.args.platform, tt.args.keyword, tt.args.order, tt.args.build, tt.args.tid, tt.args.pn, tt.args.ps, tt.args.mid, tt.args.fid, tt.args.vmid); !reflect.DeepEqual(gotFolder, tt.wantFolder) {
t.Errorf("Service.FolderVideo() = %v, want %v", gotFolder, tt.wantFolder)
}
})
}
}
func TestService_Topic(t *testing.T) {
type args struct {
c context.Context
accessKey string
actionKey string
device string
mobiApp string
platform string
build int
ps int
pn int
mid int64
}
tests := []struct {
name string
s *Service
args args
wantTopic *favorite.TopicList
}{
// TODO: Add test cases.
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if gotTopic := tt.s.Topic(tt.args.c, tt.args.accessKey, tt.args.actionKey, tt.args.device, tt.args.mobiApp, tt.args.platform, tt.args.build, tt.args.ps, tt.args.pn, tt.args.mid); !reflect.DeepEqual(gotTopic, tt.wantTopic) {
t.Errorf("Service.Topic() = %v, want %v", gotTopic, tt.wantTopic)
}
})
}
}
func TestService_Article(t *testing.T) {
type args struct {
c context.Context
mid int64
pn int
ps int
}
tests := []struct {
name string
s *Service
args args
wantArticle *favorite.ArticleList
}{
// TODO: Add test cases.
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if gotArticle := tt.s.Article(tt.args.c, tt.args.mid, tt.args.pn, tt.args.ps); !reflect.DeepEqual(gotArticle, tt.wantArticle) {
t.Errorf("Service.Article() = %v, want %v", gotArticle, tt.wantArticle)
}
})
}
}
func TestService_Clips(t *testing.T) {
type args struct {
c context.Context
mid int64
accessKey string
actionKey string
device string
mobiApp string
platform string
build int
pn int
ps int
}
tests := []struct {
name string
s *Service
args args
wantClips *favorite.ClipsList
}{
// TODO: Add test cases.
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if gotClips := tt.s.Clips(tt.args.c, tt.args.mid, tt.args.accessKey, tt.args.actionKey, tt.args.device, tt.args.mobiApp, tt.args.platform, tt.args.build, tt.args.pn, tt.args.ps); !reflect.DeepEqual(gotClips, tt.wantClips) {
t.Errorf("Service.Clips() = %v, want %v", gotClips, tt.wantClips)
}
})
}
}
func TestService_Albums(t *testing.T) {
type args struct {
c context.Context
mid int64
accessKey string
actionKey string
device string
mobiApp string
platform string
build int
pn int
ps int
}
tests := []struct {
name string
s *Service
args args
wantAlbums *favorite.AlbumsList
}{
// TODO: Add test cases.
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if gotAlbums := tt.s.Albums(tt.args.c, tt.args.mid, tt.args.accessKey, tt.args.actionKey, tt.args.device, tt.args.mobiApp, tt.args.platform, tt.args.build, tt.args.pn, tt.args.ps); !reflect.DeepEqual(gotAlbums, tt.wantAlbums) {
t.Errorf("Service.Albums() = %v, want %v", gotAlbums, tt.wantAlbums)
}
})
}
}
func TestService_Specil(t *testing.T) {
type args struct {
c context.Context
accessKey string
actionKey string
device string
mobiApp string
platform string
build int
pn int
ps int
}
tests := []struct {
name string
s *Service
args args
wantSpecil *favorite.SpList
}{
// TODO: Add test cases.
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if gotSpecil := tt.s.Specil(tt.args.c, tt.args.accessKey, tt.args.actionKey, tt.args.device, tt.args.mobiApp, tt.args.platform, tt.args.build, tt.args.pn, tt.args.ps); !reflect.DeepEqual(gotSpecil, tt.wantSpecil) {
t.Errorf("Service.Specil() = %v, want %v", gotSpecil, tt.wantSpecil)
}
})
}
}
func TestService_Audio(t *testing.T) {
type args struct {
c context.Context
accessKey string
mid int64
pn int
ps int
}
tests := []struct {
name string
s *Service
args args
wantAudio *favorite.AudioList
}{
// TODO: Add test cases.
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if gotAudio := tt.s.Audio(tt.args.c, tt.args.accessKey, tt.args.mid, tt.args.pn, tt.args.ps); !reflect.DeepEqual(gotAudio, tt.wantAudio) {
t.Errorf("Service.Audio() = %v, want %v", gotAudio, tt.wantAudio)
}
})
}
}
func TestTab(t *testing.T) {
var (
c = context.TODO()
)
convey.Convey("Tab", t, func(ctx convey.C) {
tab, err := s.Tab(c, "", "", "", "", "", "", 0, 27515397)
b, _ := json.Marshal(tab)
fmt.Printf("%s", b)
ctx.Convey("Then err should be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
})
}

View File

@@ -0,0 +1,47 @@
package favorite
import (
"go-common/app/interface/main/app-interface/conf"
artdao "go-common/app/interface/main/app-interface/dao/article"
audiodao "go-common/app/interface/main/app-interface/dao/audio"
bangumidao "go-common/app/interface/main/app-interface/dao/bangumi"
bplusdao "go-common/app/interface/main/app-interface/dao/bplus"
favdao "go-common/app/interface/main/app-interface/dao/favorite"
malldao "go-common/app/interface/main/app-interface/dao/mall"
spdao "go-common/app/interface/main/app-interface/dao/sp"
ticketdao "go-common/app/interface/main/app-interface/dao/ticket"
topicdao "go-common/app/interface/main/app-interface/dao/topic"
)
// Service is favorite.
type Service struct {
c *conf.Config
// dao
favDao *favdao.Dao
artDao *artdao.Dao
spDao *spdao.Dao
topicDao *topicdao.Dao
bplusDao *bplusdao.Dao
audioDao *audiodao.Dao
bangumiDao *bangumidao.Dao
ticketDao *ticketdao.Dao
mallDao *malldao.Dao
}
// New new favorite。
func New(c *conf.Config) (s *Service) {
s = &Service{
c: c,
// dao
favDao: favdao.New(c),
topicDao: topicdao.New(c),
artDao: artdao.New(c),
spDao: spdao.New(c),
bplusDao: bplusdao.New(c),
audioDao: audiodao.New(c),
bangumiDao: bangumidao.New(c),
ticketDao: ticketdao.New(c),
mallDao: malldao.New(c),
}
return s
}

View File

@@ -0,0 +1,30 @@
package favorite
import (
"flag"
"os"
"testing"
"go-common/app/interface/main/app-interface/conf"
)
func TestMain(m *testing.M) {
if os.Getenv("DEPLOY_ENV") != "" {
flag.Set("app_id", "main.app-svr.app-interface")
flag.Set("conf_token", "1mWvdEwZHmCYGoXJCVIdszBOPVdtpXb3")
flag.Set("tree_id", "2688")
flag.Set("conf_version", "docker-1")
flag.Set("deploy_env", "uat")
flag.Set("conf_host", "config.bilibili.co")
flag.Set("conf_path", "/tmp")
flag.Set("region", "sh")
flag.Set("zone", "sh001")
}
flag.Parse()
if err := conf.Init(); err != nil {
panic(err)
}
s = New(conf.Conf)
m.Run()
os.Exit(0)
}

View File

@@ -0,0 +1,61 @@
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_test",
"go_library",
)
go_test(
name = "go_default_test",
srcs = [
"history_test.go",
"service_test.go",
],
embed = [":go_default_library"],
rundir = ".",
tags = ["automanaged"],
deps = [
"//app/interface/main/app-interface/conf:go_default_library",
"//vendor/github.com/smartystreets/goconvey/convey:go_default_library",
],
)
go_library(
name = "go_default_library",
srcs = [
"history.go",
"service.go",
],
importpath = "go-common/app/interface/main/app-interface/service/history",
tags = ["automanaged"],
visibility = ["//visibility:public"],
deps = [
"//app/interface/main/app-interface/conf:go_default_library",
"//app/interface/main/app-interface/dao/history:go_default_library",
"//app/interface/main/app-interface/dao/live:go_default_library",
"//app/interface/main/app-interface/model:go_default_library",
"//app/interface/main/app-interface/model/history:go_default_library",
"//app/interface/main/app-interface/model/live:go_default_library",
"//app/interface/main/history/model:go_default_library",
"//app/interface/openplatform/article/model:go_default_library",
"//app/service/main/archive/model/archive:go_default_library",
"//library/log:go_default_library",
"//library/sync/errgroup:go_default_library",
"//library/xstr:go_default_library",
],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

View File

@@ -0,0 +1,370 @@
package history
import (
"context"
"strconv"
"go-common/app/interface/main/app-interface/model"
"go-common/app/interface/main/app-interface/model/history"
livemdl "go-common/app/interface/main/app-interface/model/live"
hismodle "go-common/app/interface/main/history/model"
artmodle "go-common/app/interface/openplatform/article/model"
arcmdl "go-common/app/service/main/archive/model/archive"
"go-common/library/log"
"go-common/library/sync/errgroup"
"go-common/library/xstr"
)
const (
_tpOld = -1
_tpOffline = 0
_tpArchive = 3
_tpPGC = 4
_tpArticle = 5
_tpLive = 6
_tpCorpus = 7
_androidBroadcast = 5305000
)
var (
gotoDesc = map[int8]string{
_tpOld: "av",
_tpOffline: "av",
_tpArchive: "av",
_tpPGC: "pgc",
_tpArticle: "article",
_tpLive: "live",
_tpCorpus: "article",
}
badge = map[int8]string{
1: "番剧",
2: "电影",
3: "纪录片",
4: "国创",
5: "电视剧",
7: "综艺",
}
busTab = []*history.BusTab{
{
Business: "all",
Name: "全部",
},
{
Business: "archive",
Name: "视频",
},
{
Business: "live",
Name: "直播",
},
{
Business: "article",
Name: "专栏",
},
}
)
// List history list
func (s *Service) List(c context.Context, mid, build int64, pn, ps int, platform string, plat int8) (data []*history.ListRes, err error) {
res, err := s.historyDao.History(c, mid, pn, ps)
if len(res) > 50 {
log.Warn("history lens(%d) mid(%d) pn(%d) ps(%d)", len(res), mid, pn, ps)
}
if err != nil {
log.Error("%+v ", err)
return
}
if len(res) == 0 {
data = []*history.ListRes{}
return
}
data = s.TogetherHistory(c, res, mid, build, platform, plat)
return
}
// Live get live for history
func (s *Service) Live(c context.Context, roomIDs []int64) (res []*livemdl.RoomInfo, err error) {
live, err := s.liveDao.LiveByRIDs(c, roomIDs)
if err != nil {
log.Error("%+v", err)
return
}
if len(live) == 0 {
res = []*livemdl.RoomInfo{}
return
}
for _, lv := range live {
item := &livemdl.RoomInfo{
RoomID: lv.RoomID,
URI: model.FillURI("live", strconv.FormatInt(lv.RoomID, 10), model.LiveHandler(lv)),
}
if lv.Status == 1 {
item.Status = lv.Status
}
res = append(res, item)
}
return
}
// LiveList get live list for history
func (s *Service) LiveList(c context.Context, mid, build int64, pn, ps int, platform string, plat int8) (data []*history.ListRes, err error) {
res, err := s.historyDao.HistoryByTP(c, mid, pn, ps, _tpLive)
if err != nil {
log.Error("%+v ", err)
return
}
if len(res) == 0 {
data = []*history.ListRes{}
return
}
data = s.TogetherHistory(c, res, mid, build, platform, plat)
return
}
// Cursor for history
func (s *Service) Cursor(c context.Context, mid, build, paramMax int64, ps int, platform string, paramMaxTP, plat int8, businesses []string) (data *history.ListCursor, err error) {
data = &history.ListCursor{
List: []*history.ListRes{},
Tab: busTab,
}
// 国际版不出直播
if plat == model.PlatAndroidI {
data.Tab = []*history.BusTab{
{
Business: "all",
Name: "全部",
},
{
Business: "archive",
Name: "视频",
},
{
Business: "article",
Name: "专栏",
},
}
}
curPs := 50
res, err := s.historyDao.Cursor(c, mid, paramMax, curPs, paramMaxTP, businesses)
if len(res) > curPs {
log.Warn("history lens(%d) mid(%d) paramMax(%d) paramMaxTP(%d) curPs(%d)", len(res), mid, paramMax, paramMaxTP, curPs)
}
if err != nil {
log.Error("%+v ", err)
return
}
if len(res) == 0 {
return
}
data.List = s.TogetherHistory(c, res, mid, build, platform, plat)
if len(data.List) >= ps {
data.List = data.List[:ps]
}
if len(data.List) > 0 {
data.Cursor = &history.Cursor{
Max: data.List[len(data.List)-1].ViewAt,
MaxTP: data.List[len(data.List)-1].History.Tp,
Ps: ps,
}
}
return
}
// TogetherHistory always return 0~50
func (s *Service) TogetherHistory(c context.Context, res []*hismodle.Resource, mid, build int64, platform string, plat int8) (data []*history.ListRes) {
var (
aids []int64
epids []int64
articleIDs []int64
roomIDs []int64
archive map[int64]*arcmdl.View3
pgcInfo map[int64]*history.PGCRes
article map[int64]*artmodle.Meta
live map[int64]*livemdl.RoomInfo
)
i := 0
for _, his := range res {
i++
//由于出现过history吐出数量无限制限制请求archive的数量逻辑保留
if i > 80 {
break
}
switch his.TP {
case _tpOld, _tpOffline, _tpArchive:
aids = append(aids, his.Oid)
case _tpPGC:
aids = append(aids, his.Oid) //用cid拿时长duration
epids = append(epids, his.Epid)
case _tpArticle:
articleIDs = append(articleIDs, his.Oid)
case _tpLive:
roomIDs = append(roomIDs, his.Oid)
case _tpCorpus:
articleIDs = append(articleIDs, his.Cid)
default:
log.Warn("unknow history type(%d) msg(%+v)", his.TP, his)
}
}
eg, ctx := errgroup.WithContext(c)
if len(aids) > 0 {
eg.Go(func() (err error) {
archive, err = s.historyDao.Archive(ctx, aids)
if err != nil {
log.Error("%+v", err)
err = nil
}
return
})
}
if len(epids) > 0 {
eg.Go(func() (err error) {
pgcInfo, err = s.historyDao.PGC(ctx, xstr.JoinInts(epids), platform, build, mid)
if err != nil {
log.Error("%+v", err)
err = nil
}
return
})
}
if len(articleIDs) > 0 {
eg.Go(func() (err error) {
article, err = s.historyDao.Article(ctx, articleIDs)
if err != nil {
log.Error("%+v", err)
err = nil
}
return
})
}
if len(roomIDs) > 0 {
eg.Go(func() (err error) {
live, err = s.liveDao.LiveByRIDs(ctx, roomIDs)
if err != nil {
log.Error("%+v", err)
err = nil
}
return
})
}
eg.Wait()
for _, his := range res {
// 国际版不出直播
if plat == model.PlatAndroidI && his.TP == _tpLive {
continue
}
tmpInfo := &history.ListRes{
Goto: gotoDesc[his.TP],
ViewAt: his.Unix,
}
tmpInfo.History.Oid = his.Oid
tmpInfo.History.Tp = his.TP
tmpInfo.History.Business = his.Business
switch his.TP {
case _tpOld, _tpOffline, _tpArchive:
arc, ok := archive[his.Oid]
if !ok {
continue
}
tmpInfo.Title = arc.Title
tmpInfo.Cover = arc.Pic
tmpInfo.Mid = arc.Author.Mid
tmpInfo.Name = arc.Author.Name
tmpInfo.Progress = his.Pro
tmpInfo.Videos = arc.Videos
for _, p := range arc.Pages {
if p.Cid == his.Cid {
tmpInfo.Duration = p.Duration
tmpInfo.History.Cid = p.Cid
tmpInfo.History.Page = p.Page
tmpInfo.History.Part = p.Part
break
}
}
tmpInfo.URI = model.FillURI(tmpInfo.Goto, strconv.FormatInt(his.Oid, 10), model.AvHandler(arc.Archive3))
case _tpPGC:
pgc, okPGC := pgcInfo[his.Epid]
arc, okArc := archive[his.Oid]
if !okPGC || !okArc {
continue
}
tmpInfo.Title = pgc.Title
tmpInfo.ShowTitle = pgc.ShowTitle
tmpInfo.Cover = pgc.Cover
tmpInfo.Badge = badge[his.STP]
tmpInfo.Progress = his.Pro
tmpInfo.URI = model.FillURI(tmpInfo.Goto, strconv.FormatInt(his.Sid, 10), nil)
for _, p := range arc.Pages {
if p.Cid == his.Cid {
tmpInfo.Duration = p.Duration
break
}
}
case _tpArticle:
art, ok := article[his.Oid]
if !ok {
continue
}
tmpInfo.Title = art.Title
tmpInfo.Covers = art.ImageURLs
tmpInfo.Mid = art.Author.Mid
tmpInfo.Name = art.Author.Name
tmpInfo.Badge = "专栏"
tmpInfo.URI = model.FillURI(tmpInfo.Goto, strconv.FormatInt(his.Oid, 10), nil)
case _tpLive:
lv, ok := live[his.Oid]
if !ok {
continue
}
tmpInfo.Title = lv.Title
tmpInfo.Cover = lv.UserCover
if lv.UserCover == "" {
tmpInfo.Cover = lv.Cover
}
tmpInfo.Mid = lv.Mid
tmpInfo.Name = lv.Name
tmpInfo.TagName = lv.TagName
if lv.Status == 1 { //1是直播中0、2是未开播
tmpInfo.LiveStatus = 1
}
if model.IsAndroid(plat) && build < _androidBroadcast {
lv = nil
}
tmpInfo.URI = model.FillURI(tmpInfo.Goto, strconv.FormatInt(his.Oid, 10), model.LiveHandler(lv))
case _tpCorpus:
art, ok := article[his.Cid]
if !ok {
continue
}
tmpInfo.Title = art.Title
tmpInfo.Covers = art.ImageURLs
tmpInfo.Mid = art.Author.Mid
tmpInfo.Name = art.Author.Name
tmpInfo.Badge = "专栏"
tmpInfo.URI = model.FillURI("article", strconv.FormatInt(his.Cid, 10), nil)
default:
continue
}
data = append(data, tmpInfo)
}
return
}
// Del for history
func (s *Service) Del(c context.Context, mid int64, hisRes []*hismodle.Resource) (err error) {
err = s.historyDao.Del(c, mid, hisRes)
if err != nil {
log.Error("%+v ", err)
return
}
return
}
// Clear for history
func (s *Service) Clear(c context.Context, mid int64, businesses []string) (err error) {
err = s.historyDao.Clear(c, mid, businesses)
if err != nil {
log.Error("%+v ", err)
return
}
return
}

View File

@@ -0,0 +1,29 @@
package history
import (
"context"
"testing"
. "github.com/smartystreets/goconvey/convey"
)
func TestService_List(t *testing.T) {
Convey("list", t, WithService(func(s *Service) {
_, err := s.List(context.TODO(), 27515256, 111, 1, 20, "0", 0)
So(err, ShouldBeNil)
}))
}
func TestService_Live(t *testing.T) {
Convey("live", t, WithService(func(s *Service) {
_, err := s.Live(context.TODO(), []int64{27515256})
So(err, ShouldBeNil)
}))
}
func TestService_LiveList(t *testing.T) {
Convey("live", t, WithService(func(s *Service) {
_, err := s.LiveList(context.TODO(), 27515256, 111, 1, 20, "0", 0)
So(err, ShouldBeNil)
}))
}

View File

@@ -0,0 +1,22 @@
package history
import (
"go-common/app/interface/main/app-interface/conf"
historydao "go-common/app/interface/main/app-interface/dao/history"
livedao "go-common/app/interface/main/app-interface/dao/live"
)
// Service service struct
type Service struct {
historyDao *historydao.Dao
liveDao *livedao.Dao
}
// New new service
func New(c *conf.Config) (s *Service) {
s = &Service{
historyDao: historydao.New(c),
liveDao: livedao.New(c),
}
return
}

View File

@@ -0,0 +1,28 @@
package history
import (
"flag"
"path/filepath"
"time"
"go-common/app/interface/main/app-interface/conf"
)
var (
s *Service
)
func init() {
dir, _ := filepath.Abs("../cmd/app-interface-test.toml")
flag.Set("conf", dir)
conf.Init()
s = New(conf.Conf)
time.Sleep(time.Second)
}
func WithService(f func(s *Service)) func() {
return func() {
f(s)
}
}

View File

@@ -0,0 +1,61 @@
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_test",
"go_library",
)
go_test(
name = "go_default_test",
srcs = [
"relation_test.go",
"service_test.go",
],
embed = [":go_default_library"],
rundir = ".",
tags = ["automanaged"],
deps = [
"//app/interface/main/app-interface/conf:go_default_library",
"//app/interface/main/app-interface/model/relation:go_default_library",
"//vendor/github.com/smartystreets/goconvey/convey:go_default_library",
],
)
go_library(
name = "go_default_library",
srcs = [
"relation.go",
"service.go",
],
importpath = "go-common/app/interface/main/app-interface/service/relation",
tags = ["automanaged"],
visibility = ["//visibility:public"],
deps = [
"//app/interface/main/app-interface/conf:go_default_library",
"//app/interface/main/app-interface/dao/account:go_default_library",
"//app/interface/main/app-interface/dao/live:go_default_library",
"//app/interface/main/app-interface/dao/relation:go_default_library",
"//app/interface/main/app-interface/model/live:go_default_library",
"//app/interface/main/app-interface/model/relation:go_default_library",
"//app/service/main/account/model:go_default_library",
"//app/service/main/relation/model:go_default_library",
"//library/ecode:go_default_library",
"//library/log:go_default_library",
"//library/sync/errgroup:go_default_library",
],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

View File

@@ -0,0 +1,166 @@
package relation
import (
"context"
"fmt"
"hash/crc32"
"sort"
"go-common/app/interface/main/app-interface/model/live"
model "go-common/app/interface/main/app-interface/model/relation"
account "go-common/app/service/main/account/model"
relation "go-common/app/service/main/relation/model"
"go-common/library/ecode"
"go-common/library/log"
"go-common/library/sync/errgroup"
)
var (
_emptyFollowings = []*model.Following{}
_emptyTagInfos = []*model.Tag{}
)
// Followings get user followings list.
func (s *Service) Followings(c context.Context, vmid, mid int64, pn, ps int, version uint64, order string) (f []*model.Following, crc32v uint32, total int, err error) {
res, err := s.relDao.Followings(c, vmid)
if err != nil {
return
}
total = len(res)
if order == "asc" {
sort.Sort(model.ByMTime(res))
}
start, end := (pn-1)*ps, pn*ps
switch {
case start >= len(res):
res = res[:0]
case end >= len(res):
res = res[start:]
default:
res = res[start:end]
}
if len(res) == 0 {
f = _emptyFollowings
return
}
data := []byte(fmt.Sprintf("%s", res))
crc32v = crc32.Checksum(data, crc32.IEEETable)
if uint64(crc32v) == version {
err = ecode.NotModified
return
}
var fids []int64
for _, r := range res {
fids = append(fids, r.Mid)
}
var (
flm map[int64]*relation.Following
cardm map[int64]*account.Card
sm map[int64]*live.Status
)
g, ctx := errgroup.WithContext(c)
g.Go(func() (err error) {
cardm, err = s.accDao.Cards3(ctx, fids)
return
})
// !self, compute !self user and up's followings' attr
if mid != vmid && mid != 0 {
g.Go(func() (err error) {
if flm, err = s.relDao.Relations(ctx, mid, fids); err != nil {
log.Error("%+v", err)
err = nil
}
return
})
}
g.Go(func() error {
sm, _ = s.liveDao.StatusInfo(ctx, fids)
return nil
})
if err = g.Wait(); err != nil {
log.Error("%+v", err)
return
}
f = make([]*model.Following, 0, len(res))
for _, r := range res {
fl := &model.Following{Following: r}
if _, ok := cardm[r.Mid]; ok {
fl.Face = cardm[r.Mid].Face
fl.Uname = cardm[r.Mid].Name
fl.Sign = cardm[r.Mid].Sign
if mid != vmid {
if f, ok := flm[r.Mid]; ok {
fl.Attribute = f.Attribute
} else {
fl.Attribute = relation.AttrNoRelation
}
}
fl.OfficialVerify = cardm[r.Mid].Official
fl.Vip.Type = int(cardm[r.Mid].Vip.Type)
fl.Vip.VipStatus = int(cardm[r.Mid].Vip.Status)
fl.Vip.DueDate = cardm[r.Mid].Vip.DueDate
if status, ok := sm[r.Mid]; ok {
fl.Live = status.LiveStatus
}
}
f = append(f, fl)
}
return
}
func (s *Service) Tag(c context.Context, mid, tid int64, pn, ps int) (t []*model.Tag, err error) {
mids, err := s.relDao.Tag(c, mid, tid)
if err != nil {
return
}
start, end := (pn-1)*ps, pn*ps
switch {
case start >= len(mids):
mids = mids[:0]
case end >= len(mids):
mids = mids[start:]
default:
mids = mids[start:end]
}
if len(mids) == 0 {
t = _emptyTagInfos
return
}
var (
cardm map[int64]*account.Card
sm map[int64]*live.Status
)
g, ctx := errgroup.WithContext(c)
g.Go(func() (err error) {
cardm, err = s.accDao.Cards3(ctx, mids)
return
})
g.Go(func() error {
sm, _ = s.liveDao.StatusInfo(ctx, mids)
return nil
})
if err = g.Wait(); err != nil {
log.Error("%+v", err)
return
}
t = make([]*model.Tag, 0, len(mids))
for _, mid = range mids {
tag := &model.Tag{Mid: mid}
if _, ok := cardm[mid]; ok {
tag.Mid = mid
tag.Face = cardm[mid].Face
tag.Uname = cardm[mid].Name
tag.Sign = cardm[mid].Sign
tag.OfficialVerify = cardm[mid].Official
tag.Vip.Type = int(cardm[mid].Vip.Type)
tag.Vip.VipStatus = int(cardm[mid].Vip.Status)
tag.Vip.DueDate = cardm[mid].Vip.DueDate
}
if status, ok := sm[mid]; ok {
tag.Live = status.LiveStatus
}
t = append(t, tag)
}
return
}

View File

@@ -0,0 +1,83 @@
package relation
import (
"context"
"flag"
"path/filepath"
"testing"
"time"
. "github.com/smartystreets/goconvey/convey"
"go-common/app/interface/main/app-interface/conf"
model "go-common/app/interface/main/app-interface/model/relation"
)
var (
s *Service
)
func init() {
dir, _ := filepath.Abs("../../cmd/app-interface-test.toml")
flag.Set("conf", dir)
conf.Init()
s = New(conf.Conf)
time.Sleep(3 * time.Second)
}
func TestService_Followings(t *testing.T) {
type args struct {
c context.Context
vmid int64
mid int64
pn int
ps int
version uint64
order string
}
tests := []struct {
name string
args args
wantF []*model.Following
wantCrc32v uint32
wantTotal int
wantErr error
}{
// TODO: Add test cases.
}
for _, tt := range tests {
Convey(tt.name, t, func() {
gotF, gotCrc32v, gotTotal, err := s.Followings(tt.args.c, tt.args.vmid, tt.args.mid, tt.args.pn, tt.args.ps, tt.args.version, tt.args.order)
So(gotF, ShouldResemble, tt.wantF)
So(gotCrc32v, ShouldResemble, tt.wantCrc32v)
So(gotTotal, ShouldResemble, tt.wantTotal)
So(err, ShouldEqual, tt.wantErr)
})
}
}
func TestService_Tag(t *testing.T) {
type args struct {
c context.Context
mid int64
tid int64
pn int
ps int
}
tests := []struct {
name string
s *Service
args args
wantT []*model.Tag
wantErr error
}{
// TODO: Add test cases.
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
gotT, err := tt.s.Tag(tt.args.c, tt.args.mid, tt.args.tid, tt.args.pn, tt.args.ps)
So(gotT, ShouldResemble, tt.wantT)
So(err, ShouldEqual, tt.wantErr)
})
}
}

View File

@@ -0,0 +1,29 @@
package relation
import (
"go-common/app/interface/main/app-interface/conf"
accdao "go-common/app/interface/main/app-interface/dao/account"
livedao "go-common/app/interface/main/app-interface/dao/live"
reldao "go-common/app/interface/main/app-interface/dao/relation"
)
// Service is favorite.
type Service struct {
c *conf.Config
// dao
accDao *accdao.Dao
relDao *reldao.Dao
liveDao *livedao.Dao
}
// New new favorite。
func New(c *conf.Config) (s *Service) {
s = &Service{
c: c,
// dao
accDao: accdao.New(c),
relDao: reldao.New(c),
liveDao: livedao.New(c),
}
return s
}

View File

@@ -0,0 +1,28 @@
package relation
import (
"reflect"
"testing"
"go-common/app/interface/main/app-interface/conf"
)
func TestNew(t *testing.T) {
type args struct {
c *conf.Config
}
tests := []struct {
name string
args args
wantS *Service
}{
// TODO: Add test cases.
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if gotS := New(tt.args.c); !reflect.DeepEqual(gotS, tt.wantS) {
t.Errorf("New() = %v, want %v", gotS, tt.wantS)
}
})
}
}

View File

@@ -0,0 +1,67 @@
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_test",
"go_library",
)
go_test(
name = "go_default_test",
srcs = ["search_test.go"],
embed = [":go_default_library"],
rundir = ".",
tags = ["automanaged"],
deps = [
"//app/interface/main/app-interface/conf:go_default_library",
"//vendor/github.com/smartystreets/goconvey/convey:go_default_library",
],
)
go_library(
name = "go_default_library",
srcs = ["search.go"],
importpath = "go-common/app/interface/main/app-interface/service/search",
tags = ["automanaged"],
visibility = ["//visibility:public"],
deps = [
"//app/interface/main/app-interface/conf:go_default_library",
"//app/interface/main/app-interface/dao/account:go_default_library",
"//app/interface/main/app-interface/dao/archive:go_default_library",
"//app/interface/main/app-interface/dao/article:go_default_library",
"//app/interface/main/app-interface/dao/bangumi:go_default_library",
"//app/interface/main/app-interface/dao/bplus:go_default_library",
"//app/interface/main/app-interface/dao/live:go_default_library",
"//app/interface/main/app-interface/dao/resource:go_default_library",
"//app/interface/main/app-interface/dao/search:go_default_library",
"//app/interface/main/app-interface/dao/tag:go_default_library",
"//app/interface/main/app-interface/model:go_default_library",
"//app/interface/main/app-interface/model/bangumi:go_default_library",
"//app/interface/main/app-interface/model/banner:go_default_library",
"//app/interface/main/app-interface/model/bplus:go_default_library",
"//app/interface/main/app-interface/model/live:go_default_library",
"//app/interface/main/app-interface/model/search:go_default_library",
"//app/interface/main/app-interface/model/tag:go_default_library",
"//app/interface/openplatform/article/model:go_default_library",
"//app/service/main/account/model:go_default_library",
"//app/service/main/archive/api:go_default_library",
"//app/service/main/resource/model:go_default_library",
"//app/service/openplatform/pgc-season/api/grpc/season/v1:go_default_library",
"//library/log:go_default_library",
"//library/sync/errgroup:go_default_library",
],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,59 @@
package search
import (
"context"
"flag"
"path/filepath"
"testing"
"time"
"go-common/app/interface/main/app-interface/conf"
. "github.com/smartystreets/goconvey/convey"
)
var (
s *Service
)
func init() {
dir, _ := filepath.Abs("../cmd/app-interface-test.toml")
flag.Set("conf", dir)
conf.Init()
s = New(conf.Conf)
time.Sleep(time.Second)
}
func WithService(f func(s *Service)) func() {
return func() {
f(s)
}
}
func Test_Search(t *testing.T) {
Convey("get app banner", t, WithService(func(s *Service) {
_, err := s.Search(context.Background(), 1, 2, "", "", "", "", "", "", "", "", "", "", "", "", 3, 4, 5, 6, 7, 8, 1, false, time.Now())
So(err, ShouldBeNil)
}))
}
func Test_SearchByType(t *testing.T) {
Convey("get app banner", t, WithService(func(s *Service) {
_, err := s.SearchByType(context.Background(), 1, 2, "", "", "", "", "", "", "", "", 3, 4, 5, 6, 7, 8, 8, 8, false, time.Now())
So(err, ShouldBeNil)
}))
}
func Test_SearchLive(t *testing.T) {
Convey("get app SearchLive", t, WithService(func(s *Service) {
_, err := s.SearchLive(context.Background(), 1, "", "", "", "", "", "", "", 3, 4, 5)
So(err, ShouldBeNil)
}))
}
func Test_upper(t *testing.T) {
Convey("get app upper", t, WithService(func(s *Service) {
_, err := s.upper(context.Background(), 1, "", "", "", "", "", "", "", 3, 4, 5, 3, 4, 5, 7, false, time.Now())
So(err, ShouldBeNil)
}))
}

View File

@@ -0,0 +1,91 @@
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_test",
"go_library",
)
go_test(
name = "go_default_test",
srcs = [
"contribute_test.go",
"service_test.go",
"space_test.go",
],
embed = [":go_default_library"],
rundir = ".",
tags = ["automanaged"],
deps = [
"//app/interface/main/app-interface/conf:go_default_library",
"//app/interface/main/app-interface/model:go_default_library",
"//app/interface/main/app-interface/model/space:go_default_library",
"//app/service/main/account/model:go_default_library",
"//vendor/github.com/smartystreets/goconvey/convey:go_default_library",
],
)
go_library(
name = "go_default_library",
srcs = [
"contribute.go",
"service.go",
"space.go",
],
importpath = "go-common/app/interface/main/app-interface/service/space",
tags = ["automanaged"],
visibility = ["//visibility:public"],
deps = [
"//app/interface/main/app-interface/conf:go_default_library",
"//app/interface/main/app-interface/dao/account:go_default_library",
"//app/interface/main/app-interface/dao/archive:go_default_library",
"//app/interface/main/app-interface/dao/article:go_default_library",
"//app/interface/main/app-interface/dao/audio:go_default_library",
"//app/interface/main/app-interface/dao/bangumi:go_default_library",
"//app/interface/main/app-interface/dao/bplus:go_default_library",
"//app/interface/main/app-interface/dao/coin:go_default_library",
"//app/interface/main/app-interface/dao/community:go_default_library",
"//app/interface/main/app-interface/dao/elec:go_default_library",
"//app/interface/main/app-interface/dao/favorite:go_default_library",
"//app/interface/main/app-interface/dao/live:go_default_library",
"//app/interface/main/app-interface/dao/member:go_default_library",
"//app/interface/main/app-interface/dao/pay:go_default_library",
"//app/interface/main/app-interface/dao/relation:go_default_library",
"//app/interface/main/app-interface/dao/search:go_default_library",
"//app/interface/main/app-interface/dao/shop:go_default_library",
"//app/interface/main/app-interface/dao/space:go_default_library",
"//app/interface/main/app-interface/dao/tag:go_default_library",
"//app/interface/main/app-interface/dao/thumbup:go_default_library",
"//app/interface/main/app-interface/model:go_default_library",
"//app/interface/main/app-interface/model/audio:go_default_library",
"//app/interface/main/app-interface/model/bangumi:go_default_library",
"//app/interface/main/app-interface/model/bplus:go_default_library",
"//app/interface/main/app-interface/model/community:go_default_library",
"//app/interface/main/app-interface/model/favorite:go_default_library",
"//app/interface/main/app-interface/model/shop:go_default_library",
"//app/interface/main/app-interface/model/space:go_default_library",
"//app/interface/openplatform/article/model:go_default_library",
"//app/service/main/account/model:go_default_library",
"//app/service/main/archive/api:go_default_library",
"//app/service/main/thumbup/model:go_default_library",
"//library/ecode:go_default_library",
"//library/log:go_default_library",
"//library/sync/errgroup:go_default_library",
"//library/time:go_default_library",
"//vendor/github.com/pkg/errors:go_default_library",
],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

View File

@@ -0,0 +1,482 @@
package space
import (
"context"
"sort"
"time"
"go-common/app/interface/main/app-interface/model"
"go-common/app/interface/main/app-interface/model/audio"
"go-common/app/interface/main/app-interface/model/bplus"
"go-common/app/interface/main/app-interface/model/space"
article "go-common/app/interface/openplatform/article/model"
"go-common/app/service/main/archive/api"
"go-common/library/log"
"go-common/library/sync/errgroup"
xtime "go-common/library/time"
)
const (
_androidAudio = 516009
_iosAudio = 6160
)
// Contribute func
func (s *Service) Contribute(c context.Context, plat int8, build int, vmid int64, pn, ps int, now time.Time) (res *space.Contributes, err error) {
var (
attrs *space.Attrs
items []*space.Item
)
if pn == 1 {
var (
ctime xtime.Time
cached bool
)
size := ps
if items, err = s.bplusDao.RangeContributeCache(c, vmid, pn, ps); err != nil {
log.Error("%+v", err)
} else if len(items) != 0 {
ctime = items[0].CTime
} else {
size = 100
cached = true
}
if res, err = s.firstContribute(c, vmid, size, now); err != nil {
log.Error("%+v", err)
err = nil
}
if res != nil && len(res.Items) != 0 {
if res.Items[0].CTime > ctime {
if err = s.bplusDao.NotifyContribute(c, vmid, nil, ctime); err != nil {
log.Error("%+v", err)
err = nil
}
}
if cached {
ris := res.Items
s.addCache(func() {
s.bplusDao.AddContributeCache(context.Background(), vmid, nil, ris)
})
}
if len(items) == 0 {
ris := make([]*space.Item, 0, ps)
for _, item := range res.Items {
item.FormatKey()
switch item.Goto {
case model.GotoAudio:
if (plat == model.PlatAndroid && build > _androidAudio) || (plat == model.PlatIPhone && build > _iosAudio) || plat == model.PlatAndroidB {
ris = append(ris, item)
}
default:
ris = append(ris, item)
}
if len(ris) == ps {
break
}
}
res.Items = ris
return
}
}
} else {
if items, err = s.bplusDao.RangeContributeCache(c, vmid, pn, ps); err != nil {
return
}
}
if len(items) != 0 {
if attrs, err = s.bplusDao.AttrCache(c, vmid); err != nil {
log.Error("%+v", err)
}
// merge res
if res, err = s.dealContribute(c, plat, build, vmid, attrs, items, now); err != nil {
log.Error("%+v", err)
}
}
if res == nil {
res = &space.Contributes{Tab: &space.Tab{}, Items: []*space.Item{}, Links: &space.Links{}}
}
return
}
// Contribution func
func (s *Service) Contribution(c context.Context, plat int8, build int, vmid int64, cursor *model.Cursor, now time.Time) (res *space.Contributes, err error) {
var (
attrs *space.Attrs
items []*space.Item
)
if cursor.Latest() {
var (
ctime xtime.Time
cached bool
)
size := cursor.Size
if items, err = s.bplusDao.RangeContributeCache(c, vmid, 1, 1); err != nil {
log.Error("%+v", err)
} else if len(items) != 0 {
ctime = items[0].CTime
} else {
size = 100
cached = true
}
if res, err = s.firstContribute(c, vmid, size, now); err != nil {
log.Error("%+v", err)
}
if res != nil && len(res.Items) != 0 {
if cached {
ris := res.Items
s.addCache(func() {
s.bplusDao.AddContributeCache(context.Background(), vmid, nil, ris)
})
}
if res.Items[0].CTime > ctime {
if len(items) != 0 {
if attrs, err = s.bplusDao.AttrCache(c, vmid); err != nil {
log.Error("%+v", err)
}
}
if err = s.bplusDao.NotifyContribute(c, vmid, attrs, ctime); err != nil {
log.Error("%+v", err)
err = nil
}
}
ris := make([]*space.Item, 0, cursor.Size)
for _, item := range res.Items {
item.FormatKey()
ris = append(ris, item)
if len(ris) == cursor.Size {
break
}
}
if len(ris) != 0 {
res.Items = ris
res.Links.Link(0, int64(ris[len(ris)-1].Member))
}
return
}
}
if items, err = s.bplusDao.RangeContributionCache(c, vmid, cursor); err != nil {
return
}
if len(items) != 0 {
if attrs, err = s.bplusDao.AttrCache(c, vmid); err != nil {
log.Error("%+v", err)
}
// merge res
if res, err = s.dealContribute(c, plat, build, vmid, attrs, items, now); err != nil {
log.Error("%+v", err)
}
}
if res == nil {
res = &space.Contributes{Tab: &space.Tab{}, Items: []*space.Item{}, Links: &space.Links{}}
}
return
}
func (s *Service) firstContribute(c context.Context, vmid int64, size int, now time.Time) (res *space.Contributes, err error) {
res = &space.Contributes{Tab: &space.Tab{}, Items: []*space.Item{}, Links: &space.Links{}}
g, ctx := errgroup.WithContext(c)
var arcItem, artItem, clipItem, albumItem, audioItem, items []*space.Item
g.Go(func() (err error) {
var arcs []*api.Arc
if arcs, err = s.arcDao.UpArcs3(ctx, vmid, 1, size); err != nil {
log.Error("s.arcDao.UpArcs3(%d,%d,%d) error(%v)", vmid, 1, size, err)
err = nil
return
}
if len(arcs) != 0 {
arcItem = make([]*space.Item, 0, len(arcs))
for _, v := range arcs {
if v.IsNormal() {
si := &space.Item{}
si.FromArc3(v)
arcItem = append(arcItem, si)
}
}
}
return
})
g.Go(func() (err error) {
var arts []*article.Meta
if arts, _, err = s.artDao.UpArticles(ctx, vmid, 1, size); err != nil {
log.Error("s.artDao.UpArticles(%d,%d,%d) error(%v)", vmid, 1, size, err)
err = nil
return
}
if len(arts) != 0 {
artItem = make([]*space.Item, 0, len(arts))
for _, v := range arts {
if v.AttrVal(article.AttrBitNoDistribute) {
continue
}
si := &space.Item{}
si.FromArticle(v)
artItem = append(artItem, si)
}
}
return
})
g.Go(func() (err error) {
var clips []*bplus.Clip
if clips, _, err = s.bplusDao.AllClip(c, vmid, size); err != nil {
log.Error("s.bplusDao.AllClip(%d,%d) error(%v)", vmid, size, err)
err = nil
return
}
if len(clips) != 0 {
clipItem = make([]*space.Item, 0, len(clips))
for _, v := range clips {
si := &space.Item{}
si.FromClip(v)
clipItem = append(clipItem, si)
}
}
return
})
g.Go(func() (err error) {
var album []*bplus.Album
if album, _, err = s.bplusDao.AllAlbum(c, vmid, size); err != nil {
log.Error("s.bplusDao.AllAlbum(%d,%d) error(%v)", vmid, size, err)
err = nil
return
}
if len(album) != 0 {
albumItem = make([]*space.Item, 0, len(album))
for _, v := range album {
si := &space.Item{}
si.FromAlbum(v)
albumItem = append(albumItem, si)
}
}
return
})
g.Go(func() (err error) {
var audio []*audio.Audio
if audio, err = s.audioDao.AllAudio(c, vmid); err != nil {
log.Error("s.audioDao.AllAudio(%d) error(%v)", vmid, err)
err = nil
return
}
if len(audio) != 0 {
audioItem = make([]*space.Item, 0, len(audio))
for _, v := range audio {
si := &space.Item{}
si.FromAudio(v)
audioItem = append(audioItem, si)
}
}
return
})
if err = g.Wait(); err != nil {
log.Error("Contribute errgroup.WithContext error(%v)", err)
}
items = make([]*space.Item, 0, len(arcItem)+len(artItem)+len(clipItem)+len(albumItem)+len(audioItem))
if len(arcItem) != 0 {
res.Tab.Archive = true
items = append(items, arcItem...)
}
if len(artItem) != 0 {
res.Tab.Article = true
items = append(items, artItem...)
}
if len(clipItem) != 0 {
res.Tab.Clip = true
items = append(items, clipItem...)
}
if len(albumItem) != 0 {
res.Tab.Album = true
items = append(items, albumItem...)
}
if len(audioItem) != 0 {
res.Tab.Audios = true
items = append(items, audioItem...)
}
sort.Sort(space.Items(items))
res.Items = items
return
}
func (s *Service) dealContribute(c context.Context, plat int8, build int, vmid int64, attrs *space.Attrs, items []*space.Item, now time.Time) (res *space.Contributes, err error) {
res = &space.Contributes{Tab: &space.Tab{}, Items: []*space.Item{}, Links: &space.Links{}}
var aids, cvids, clids, alids, auids []int64
if attrs == nil {
attrs = &space.Attrs{}
} else if !((plat == model.PlatAndroid && build > _androidAudio) || (plat == model.PlatIPhone && build > _iosAudio) || plat == model.PlatAndroidB) {
attrs.Audio = false
}
for _, item := range items {
if item.ID == 0 {
continue
}
switch item.Goto {
case model.GotoAv:
aids = append(aids, item.ID)
case model.GotoArticle:
cvids = append(cvids, item.ID)
case model.GotoClip:
clids = append(clids, item.ID)
case model.GotoAlbum:
alids = append(alids, item.ID)
case model.GotoAudio:
if (plat == model.PlatAndroid && build > _androidAudio) || (plat == model.PlatIPhone && build > _iosAudio) || plat == model.PlatAndroidB {
auids = append(auids, item.ID)
}
}
}
var (
am map[int64]*api.Arc
atm map[int64]*article.Meta
clm map[int64]*bplus.Clip
alm map[int64]*bplus.Album
aum map[int64]*audio.Audio
)
g, ctx := errgroup.WithContext(c)
if len(aids) != 0 {
g.Go(func() (err error) {
if am, err = s.arcDao.Archives2(ctx, aids); err != nil {
log.Error("s.arcDao.Archives(%v) error(%v)", aids, err)
err = nil
}
return
})
}
if len(cvids) != 0 {
g.Go(func() (err error) {
if atm, err = s.artDao.Articles(ctx, cvids); err != nil {
log.Error("s.artDao.Articles(%v) error(%v)", cvids, err)
err = nil
}
return
})
}
if len(clids) != 0 {
g.Go(func() (err error) {
if clm, err = s.bplusDao.ClipDetail(ctx, clids); err != nil {
log.Error("s.bplusDao.ClipDetail(%v) error(%v)", clids, err)
err = nil
}
return
})
}
if len(alids) != 0 {
g.Go(func() (err error) {
if alm, err = s.bplusDao.AlbumDetail(ctx, vmid, alids); err != nil {
log.Error("s.bplusDao.AlbumDetail(%v) error(%v)", alids, err)
err = nil
}
return
})
}
if len(auids) != 0 {
g.Go(func() (err error) {
if aum, err = s.audioDao.AudioDetail(c, auids); err != nil {
log.Error("s.audioDao.AudioDetail(%v) error(%v)", auids, err)
err = nil
}
return
})
}
if err = g.Wait(); err != nil {
log.Error("Contribute errgroup.WithContext error(%v)", err)
return
}
if len(am) != 0 || attrs.Archive {
res.Tab.Archive = true
}
if len(atm) != 0 || attrs.Article {
res.Tab.Article = true
}
if len(clm) != 0 || attrs.Clip {
res.Tab.Clip = true
}
if len(alm) != 0 || attrs.Album {
res.Tab.Album = true
}
if len(aum) != 0 || attrs.Audio {
res.Tab.Audios = true
}
ris := make([]*space.Item, 0, len(items))
for _, item := range items {
ri := &space.Item{}
switch item.Goto {
case model.GotoAv:
if a, ok := am[item.ID]; ok && a.IsNormal() {
ri.FromArc3(a)
}
case model.GotoArticle:
if at, ok := atm[item.ID]; ok {
ri.FromArticle(at)
}
case model.GotoClip:
if cl, ok := clm[item.ID]; ok {
ri.FromClip(cl)
}
case model.GotoAlbum:
if al, ok := alm[item.ID]; ok {
ri.FromAlbum(al)
}
case model.GotoAudio:
if au, ok := aum[item.ID]; ok {
ri.FromAudio(au)
}
}
if ri.Goto != "" {
ri.FormatKey()
ris = append(ris, ri)
}
}
res.Items = ris
res.Links.Link(int64(items[0].Member), int64(items[len(items)-1].Member))
return
}
// Clip func
func (s *Service) Clip(c context.Context, vmid int64, pos, size int) (res *space.ClipList) {
var (
clips []*bplus.Clip
err error
)
res = &space.ClipList{Item: []*space.Item{}}
if clips, res.More, res.Offset, err = s.bplusDao.Clips(c, vmid, pos, size); err != nil {
log.Error("%+v", err)
return
}
if len(clips) > 0 {
res.Item = make([]*space.Item, 0, len(clips))
for _, v := range clips {
si := &space.Item{}
si.FromClip(v)
res.Item = append(res.Item, si)
}
}
return
}
// Album func
func (s *Service) Album(c context.Context, vmid int64, pos, size int) (res *space.AlbumList) {
var (
albums []*bplus.Album
err error
)
res = &space.AlbumList{Item: []*space.Item{}}
if albums, res.More, res.Offset, err = s.bplusDao.Albums(c, vmid, pos, size); err != nil {
log.Error("%+v", err)
return
}
if len(albums) > 0 {
res.Item = make([]*space.Item, 0, len(albums))
for _, v := range albums {
si := &space.Item{}
si.FromAlbum(v)
res.Item = append(res.Item, si)
}
}
return
}
// AddContribute func
func (s *Service) AddContribute(c context.Context, vmid int64, attrs *space.Attrs, items []*space.Item) (err error) {
if err = s.bplusDao.AddContributeCache(c, vmid, attrs, items); err != nil {
log.Error("%+v", err)
}
return
}

View File

@@ -0,0 +1,211 @@
package space
import (
"context"
"reflect"
"testing"
"time"
"go-common/app/interface/main/app-interface/model"
"go-common/app/interface/main/app-interface/model/space"
)
func TestService_Contribute(t *testing.T) {
type args struct {
c context.Context
plat int8
build int
vmid int64
pn int
ps int
now time.Time
}
tests := []struct {
name string
s *Service
args args
wantRes *space.Contributes
wantErr bool
}{
// TODO: Add test cases.
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
gotRes, err := tt.s.Contribute(tt.args.c, tt.args.plat, tt.args.build, tt.args.vmid, tt.args.pn, tt.args.ps, tt.args.now)
if (err != nil) != tt.wantErr {
t.Errorf("Service.Contribute() error = %v, wantErr %v", err, tt.wantErr)
return
}
if !reflect.DeepEqual(gotRes, tt.wantRes) {
t.Errorf("Service.Contribute() = %v, want %v", gotRes, tt.wantRes)
}
})
}
}
func TestService_Contribution(t *testing.T) {
type args struct {
c context.Context
plat int8
build int
vmid int64
cursor *model.Cursor
now time.Time
}
tests := []struct {
name string
s *Service
args args
wantRes *space.Contributes
wantErr bool
}{
// TODO: Add test cases.
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
gotRes, err := tt.s.Contribution(tt.args.c, tt.args.plat, tt.args.build, tt.args.vmid, tt.args.cursor, tt.args.now)
if (err != nil) != tt.wantErr {
t.Errorf("Service.Contribution() error = %v, wantErr %v", err, tt.wantErr)
return
}
if !reflect.DeepEqual(gotRes, tt.wantRes) {
t.Errorf("Service.Contribution() = %v, want %v", gotRes, tt.wantRes)
}
})
}
}
func TestService_firstContribute(t *testing.T) {
type args struct {
c context.Context
vmid int64
size int
now time.Time
}
tests := []struct {
name string
s *Service
args args
wantRes *space.Contributes
wantErr bool
}{
// TODO: Add test cases.
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
gotRes, err := tt.s.firstContribute(tt.args.c, tt.args.vmid, tt.args.size, tt.args.now)
if (err != nil) != tt.wantErr {
t.Errorf("Service.firstContribute() error = %v, wantErr %v", err, tt.wantErr)
return
}
if !reflect.DeepEqual(gotRes, tt.wantRes) {
t.Errorf("Service.firstContribute() = %v, want %v", gotRes, tt.wantRes)
}
})
}
}
func TestService_dealContribute(t *testing.T) {
type args struct {
c context.Context
plat int8
build int
vmid int64
attrs *space.Attrs
items []*space.Item
now time.Time
}
tests := []struct {
name string
s *Service
args args
wantRes *space.Contributes
wantErr bool
}{
// TODO: Add test cases.
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
gotRes, err := tt.s.dealContribute(tt.args.c, tt.args.plat, tt.args.build, tt.args.vmid, tt.args.attrs, tt.args.items, tt.args.now)
if (err != nil) != tt.wantErr {
t.Errorf("Service.dealContribute() error = %v, wantErr %v", err, tt.wantErr)
return
}
if !reflect.DeepEqual(gotRes, tt.wantRes) {
t.Errorf("Service.dealContribute() = %v, want %v", gotRes, tt.wantRes)
}
})
}
}
func TestService_Clip(t *testing.T) {
type args struct {
c context.Context
vmid int64
pos int
size int
}
tests := []struct {
name string
s *Service
args args
wantRes *space.ClipList
}{
// TODO: Add test cases.
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if gotRes := tt.s.Clip(tt.args.c, tt.args.vmid, tt.args.pos, tt.args.size); !reflect.DeepEqual(gotRes, tt.wantRes) {
t.Errorf("Service.Clip() = %v, want %v", gotRes, tt.wantRes)
}
})
}
}
func TestService_Album(t *testing.T) {
type args struct {
c context.Context
vmid int64
pos int
size int
}
tests := []struct {
name string
s *Service
args args
wantRes *space.AlbumList
}{
// TODO: Add test cases.
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if gotRes := tt.s.Album(tt.args.c, tt.args.vmid, tt.args.pos, tt.args.size); !reflect.DeepEqual(gotRes, tt.wantRes) {
t.Errorf("Service.Album() = %v, want %v", gotRes, tt.wantRes)
}
})
}
}
func TestService_AddContribute(t *testing.T) {
type args struct {
c context.Context
vmid int64
attrs *space.Attrs
items []*space.Item
}
tests := []struct {
name string
s *Service
args args
wantErr bool
}{
// TODO: Add test cases.
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if err := tt.s.AddContribute(tt.args.c, tt.args.vmid, tt.args.attrs, tt.args.items); (err != nil) != tt.wantErr {
t.Errorf("Service.AddContribute() error = %v, wantErr %v", err, tt.wantErr)
}
})
}
}

View File

@@ -0,0 +1,138 @@
package space
import (
"context"
"runtime"
"time"
"go-common/app/interface/main/app-interface/conf"
accdao "go-common/app/interface/main/app-interface/dao/account"
arcdao "go-common/app/interface/main/app-interface/dao/archive"
artdao "go-common/app/interface/main/app-interface/dao/article"
audiodao "go-common/app/interface/main/app-interface/dao/audio"
bgmdao "go-common/app/interface/main/app-interface/dao/bangumi"
bplusdao "go-common/app/interface/main/app-interface/dao/bplus"
coindao "go-common/app/interface/main/app-interface/dao/coin"
commdao "go-common/app/interface/main/app-interface/dao/community"
elecdao "go-common/app/interface/main/app-interface/dao/elec"
favdao "go-common/app/interface/main/app-interface/dao/favorite"
livedao "go-common/app/interface/main/app-interface/dao/live"
memberdao "go-common/app/interface/main/app-interface/dao/member"
paydao "go-common/app/interface/main/app-interface/dao/pay"
reldao "go-common/app/interface/main/app-interface/dao/relation"
srchdao "go-common/app/interface/main/app-interface/dao/search"
shopdao "go-common/app/interface/main/app-interface/dao/shop"
spcdao "go-common/app/interface/main/app-interface/dao/space"
tagdao "go-common/app/interface/main/app-interface/dao/tag"
thumbupdao "go-common/app/interface/main/app-interface/dao/thumbup"
"go-common/library/log"
)
// Service is space service
type Service struct {
c *conf.Config
arcDao *arcdao.Dao
spcDao *spcdao.Dao
accDao *accdao.Dao
coinDao *coindao.Dao
commDao *commdao.Dao
srchDao *srchdao.Dao
favDao *favdao.Dao
bgmDao *bgmdao.Dao
tagDao *tagdao.Dao
liveDao *livedao.Dao
elecDao *elecdao.Dao
artDao *artdao.Dao
audioDao *audiodao.Dao
relDao *reldao.Dao
bplusDao *bplusdao.Dao
shopDao *shopdao.Dao
thumbupDao *thumbupdao.Dao
payDao *paydao.Dao
memberDao *memberdao.Dao
// chan
mCh chan func()
tick time.Duration
BlackList map[int64]struct{}
}
// New new space
func New(c *conf.Config) (s *Service) {
s = &Service{
c: c,
arcDao: arcdao.New(c),
spcDao: spcdao.New(c),
accDao: accdao.New(c),
coinDao: coindao.New(c),
commDao: commdao.New(c),
srchDao: srchdao.New(c),
favDao: favdao.New(c),
bgmDao: bgmdao.New(c),
tagDao: tagdao.New(c),
liveDao: livedao.New(c),
elecDao: elecdao.New(c),
artDao: artdao.New(c),
audioDao: audiodao.New(c),
relDao: reldao.New(c),
bplusDao: bplusdao.New(c),
shopDao: shopdao.New(c),
thumbupDao: thumbupdao.New(c),
payDao: paydao.New(c),
memberDao: memberdao.New(c),
// mc proc
mCh: make(chan func(), 1024),
tick: time.Duration(c.Tick),
BlackList: make(map[int64]struct{}),
}
// video db
for i := 0; i < runtime.NumCPU(); i++ {
go s.cacheproc()
}
if c != nil && c.Space != nil {
for _, mid := range c.Space.ForbidMid {
s.BlackList[mid] = struct{}{}
}
}
s.loadBlacklist()
go s.blacklistproc()
return
}
// addCache add archive to mc or redis
func (s *Service) addCache(f func()) {
select {
case s.mCh <- f:
default:
log.Warn("cacheproc chan full")
}
}
// cacheproc write memcache and stat redis use goroutine
func (s *Service) cacheproc() {
for {
f := <-s.mCh
f()
}
}
// Ping check server ok
func (s *Service) Ping(c context.Context) (err error) {
return
}
// loadBlacklist
func (s *Service) loadBlacklist() {
list, err := s.spcDao.Blacklist(context.Background())
if err != nil {
log.Error("%+v", err)
return
}
s.BlackList = list
}
func (s *Service) blacklistproc() {
for {
time.Sleep(s.tick)
s.loadBlacklist()
}
}

View File

@@ -0,0 +1,82 @@
package space
import (
"context"
"reflect"
"testing"
"go-common/app/interface/main/app-interface/conf"
)
func TestNew(t *testing.T) {
type args struct {
c *conf.Config
}
tests := []struct {
name string
args args
wantS *Service
}{
// TODO: Add test cases.
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if gotS := New(tt.args.c); !reflect.DeepEqual(gotS, tt.wantS) {
t.Errorf("New() = %v, want %v", gotS, tt.wantS)
}
})
}
}
func TestService_addCache(t *testing.T) {
type args struct {
f func()
}
tests := []struct {
name string
s *Service
args args
}{
// TODO: Add test cases.
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
tt.s.addCache(tt.args.f)
})
}
}
func TestService_cacheproc(t *testing.T) {
tests := []struct {
name string
s *Service
}{
// TODO: Add test cases.
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
tt.s.cacheproc()
})
}
}
func TestService_Ping(t *testing.T) {
type args struct {
c context.Context
}
tests := []struct {
name string
s *Service
args args
wantErr bool
}{
// TODO: Add test cases.
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if err := tt.s.Ping(tt.args.c); (err != nil) != tt.wantErr {
t.Errorf("Service.Ping() error = %v, wantErr %v", err, tt.wantErr)
}
})
}
}

View File

@@ -0,0 +1,679 @@
package space
import (
"context"
"strconv"
"time"
"go-common/app/interface/main/app-interface/model"
"go-common/app/interface/main/app-interface/model/audio"
"go-common/app/interface/main/app-interface/model/bangumi"
"go-common/app/interface/main/app-interface/model/bplus"
"go-common/app/interface/main/app-interface/model/community"
"go-common/app/interface/main/app-interface/model/favorite"
"go-common/app/interface/main/app-interface/model/shop"
"go-common/app/interface/main/app-interface/model/space"
article "go-common/app/interface/openplatform/article/model"
account "go-common/app/service/main/account/model"
"go-common/app/service/main/archive/api"
thumbup "go-common/app/service/main/thumbup/model"
"go-common/library/ecode"
"go-common/library/log"
"go-common/library/sync/errgroup"
"github.com/pkg/errors"
)
const (
_shopName = "的店铺"
_businessLike = "archive"
)
// Space aggregation space data.
func (s *Service) Space(c context.Context, mid, vmid int64, plat int8, build int, pn, ps int, platform, device, mobiApp, name string, now time.Time) (sp *space.Space, err error) {
if _, ok := s.BlackList[vmid]; ok {
err = ecode.NothingFound
return
}
sp = &space.Space{}
// get card
card, err := s.card(c, vmid, name)
if err != nil {
if ecode.String(errors.Cause(err).Error()) == ecode.UserNotExist || vmid < 1 {
err = ecode.NothingFound
return
}
sp.Card = &space.Card{Mid: strconv.FormatInt(vmid, 10)}
log.Error("%+v", err)
} else if card == nil {
log.Warn("space mid(%d) vmid(%d) name(%s) plat(%s) device(%s) card is nil", mid, vmid, name, platform, device)
err = ecode.NothingFound
return
} else {
if card.Mid == "" {
err = ecode.NothingFound
return
}
if vmid > 0 && card.Mid != strconv.FormatInt(vmid, 10) {
err = ecode.NothingFound
return
}
if vmid < 1 {
if vmid, _ = strconv.ParseInt(card.Mid, 10, 64); vmid < 1 {
err = ecode.NothingFound
return
}
}
sp.Card = card
// ignore some card field
sp.Card.Rank = ""
sp.Card.DisplayRank = ""
sp.Card.Regtime = 0
sp.Card.Spacesta = 0
sp.Card.Birthday = ""
sp.Card.Place = ""
sp.Card.Article = 0
sp.Card.Friend = 0
sp.Card.Attentions = nil
sp.Card.Pendant.Pid = 0
sp.Card.Pendant.Image = ""
sp.Card.Pendant.Expire = 0
sp.Card.Nameplate.Nid = 0
sp.Card.Nameplate.Name = ""
sp.Card.Nameplate.Image = ""
sp.Card.Nameplate.ImageSmall = ""
sp.Card.Nameplate.Level = ""
sp.Card.Nameplate.Condition = ""
}
// space
g, ctx := errgroup.WithContext(c)
g.Go(func() error {
sp.Space, _ = s.spcDao.SpaceMob(ctx, mid, vmid, platform, device)
return nil
})
g.Go(func() error {
sp.Card.FansGroup, _ = s.bplusDao.GroupsCount(ctx, mid, vmid)
return nil
})
g.Go(func() (err error) {
cardm, err := s.audioDao.Card(ctx, vmid)
if err != nil {
log.Error("%+v", err)
err = nil
return
}
if card, ok := cardm[vmid]; ok && card.Type == 1 && card.Status == 1 {
sp.Card.Audio = 1
}
return
})
if vmid == mid {
g.Go(func() (err error) {
if sp.Card.FansUnread, err = s.relDao.FollowersUnread(ctx, vmid); err != nil {
log.Error("%+v", err)
err = nil
}
return
})
}
g.Go(func() (err error) {
cert, err := s.audioDao.UpperCert(ctx, vmid)
if err != nil {
log.Error("%+v", err)
err = nil
return
}
if cert == nil || cert.Cert == nil || cert.Cert.Type == -1 || cert.Cert.Desc == "" {
return
}
if sp.Card.OfficialVerify.Type == -1 {
sp.Card.OfficialVerify.Type = int8(cert.Cert.Type)
}
if sp.Card.OfficialVerify.Desc != "" {
sp.Card.OfficialVerify.Desc = sp.Card.OfficialVerify.Desc + "、" + cert.Cert.Desc
} else {
sp.Card.OfficialVerify.Desc = cert.Cert.Desc
}
return
})
// iOS蓝版 强行去除充电模块
if model.IsIPhone(plat) && (build >= 7000 && build <= 8000) {
sp.Elec = nil
} else {
// elec rank
g.Go(func() (err error) {
info, err := s.elecDao.Info(ctx, vmid, mid)
if err != nil {
log.Error("%+v", err)
err = nil
return
}
if info != nil {
info.Show = true
sp.Elec = info
}
return
})
}
g.Go(func() error {
rel, _ := s.accDao.RichRelations3(ctx, mid, vmid)
// -999:无关系, -1:我已经拉黑该用户, 0:我悄悄关注了该用户, 1:我公开关注了该用户
// 1- 悄悄关注 2 关注 6-好友 128-拉黑
if rel == 1 {
sp.Relation = 0
} else if rel == 2 || rel == 6 {
sp.Relation = 1
} else if rel >= 128 {
sp.Relation = -1
} else {
sp.Relation = -999
}
return nil
})
g.Go(func() (err error) {
if sp.Medal, err = s.liveDao.MedalStatus(ctx, vmid); err != nil {
log.Error("%+v", err)
err = nil
}
return
})
// g.Go(func() (err error) {
// if sp.Attention, err = s.relDao.Attention(ctx, mid, vmid); err != nil {
// log.Error("%+v", err)
// err = nil
// }
// return
// })
g.Go(func() (err error) {
if sp.Live, err = s.liveDao.Live(ctx, vmid, platform); err != nil {
log.Error("%+v", err)
err = nil
}
return
})
sp.Tab = &space.Tab{}
// up archives
g.Go(func() error {
sp.Archive = s.UpArcs(ctx, vmid, pn, ps, now)
if sp.Archive != nil && len(sp.Archive.Item) > 0 {
sp.Tab.Archive = true
}
return nil
})
g.Go(func() (err error) {
if sp.Tab.Dynamic, err = s.bplusDao.Dynamic(ctx, vmid); err != nil {
log.Error("%+v", err)
err = nil
}
return
})
g.Go(func() error {
sp.Article = s.UpArticles(ctx, vmid, 0, 3)
if sp.Article != nil && len(sp.Article.Item) != 0 {
sp.Tab.Article = true
}
return nil
})
g.Go(func() error {
sp.Clip = s.upClips(ctx, vmid)
if sp.Clip != nil && len(sp.Clip.Item) != 0 {
sp.Tab.Clip = true
}
return nil
})
g.Go(func() error {
sp.Album = s.upAlbums(ctx, vmid)
if sp.Album != nil && len(sp.Album.Item) != 0 {
sp.Tab.Album = true
}
return nil
})
g.Go(func() error {
sp.Audios = s.audios(ctx, vmid, 1, 3)
if sp.Audios != nil && len(sp.Audios.Item) != 0 {
sp.Tab.Audios = true
}
return nil
})
g.Go(func() (err error) {
var info *shop.Info
if info, err = s.shopDao.Info(ctx, vmid, mobiApp, device, build); err != nil {
log.Error("%+v", err)
err = nil
return
}
if info != nil && info.Shop != nil && info.Shop.Status == 2 {
sp.Tab.Shop = true
sp.Shop = &space.Shop{ID: info.Shop.ID, Name: info.Shop.Name + _shopName}
}
return
})
if sp.Setting, err = s.spcDao.Setting(c, vmid); err != nil {
log.Error("%+v", err)
err = nil
}
if sp.Setting == nil {
err = g.Wait()
return
}
g.Go(func() error {
sp.Favourite = s.favFolders(ctx, mid, vmid, sp.Setting, plat, build, mobiApp)
if sp.Favourite != nil && len(sp.Favourite.Item) != 0 {
sp.Tab.Favorite = true
}
return nil
})
g.Go(func() error {
sp.Season = s.Bangumi(ctx, mid, vmid, sp.Setting, pn, ps)
if sp.Season != nil && len(sp.Season.Item) != 0 {
sp.Tab.Bangumi = true
}
return nil
})
g.Go(func() error {
sp.CoinArc = s.CoinArcs(ctx, mid, vmid, sp.Setting, pn, ps)
if sp.CoinArc != nil && len(sp.CoinArc.Item) != 0 {
sp.Tab.Coin = true
}
return nil
})
g.Go(func() error {
sp.LikeArc = s.LikeArcs(ctx, mid, vmid, sp.Setting, pn, ps)
if sp.LikeArc != nil && len(sp.LikeArc.Item) != 0 {
sp.Tab.Like = true
}
return nil
})
err = g.Wait()
return
}
// UpArcs get upload archive .
func (s *Service) UpArcs(c context.Context, uid int64, pn, ps int, now time.Time) (res *space.ArcList) {
var (
arcs []*api.Arc
err error
)
res = &space.ArcList{Item: []*space.ArcItem{}}
if res.Count, err = s.arcDao.UpCount2(c, uid); err != nil {
log.Error("%+v", err)
}
if arcs, err = s.arcDao.UpArcs3(c, uid, pn, ps); err != nil {
log.Error("%+v", err)
return
}
if len(arcs) != 0 {
res.Item = make([]*space.ArcItem, 0, len(arcs))
for _, v := range arcs {
si := &space.ArcItem{}
si.FromArc(v)
res.Item = append(res.Item, si)
}
}
return
}
// UpArticles get article.
func (s *Service) UpArticles(c context.Context, uid int64, pn, ps int) (res *space.ArticleList) {
res = &space.ArticleList{Item: []*space.ArticleItem{}, Lists: []*article.List{}}
g, ctx := errgroup.WithContext(c)
g.Go(func() (err error) {
var ams []*article.Meta
if ams, res.Count, err = s.artDao.UpArticles(ctx, uid, pn, ps); err != nil {
return err
}
if len(ams) != 0 {
res.Item = make([]*space.ArticleItem, 0, len(ams))
for _, v := range ams {
if v.AttrVal(article.AttrBitNoDistribute) {
continue
}
si := &space.ArticleItem{}
si.FromArticle(v)
res.Item = append(res.Item, si)
}
}
return err
})
g.Go(func() (err error) {
var lists []*article.List
lists, res.ListsCount, err = s.artDao.UpLists(c, uid)
if err != nil {
return err
}
if len(lists) > 0 {
res.Lists = lists
}
return err
})
if err := g.Wait(); err != nil {
log.Error("%+v", err)
}
return
}
// favFolders get favorite folders
func (s *Service) favFolders(c context.Context, mid, vmid int64, setting *space.Setting, plat int8, build int, mobiApp string) (res *space.FavList) {
const (
_oldAndroidBuild = 427100
_oldIOSBuild = 3910
)
var (
fs []*favorite.Folder
err error
)
res = &space.FavList{Item: []*favorite.Folder{}}
if mid != vmid {
if setting == nil {
setting, err = s.spcDao.Setting(c, vmid)
if err != nil {
log.Error("%+v", err)
return
}
}
if setting.FavVideo != 1 {
return
}
}
var mediaList bool
// 双端版本号限制,符合此条件显示为“默认收藏夹”:
// iPhone <5.36.1(8300) 或iPhone>5.36.1(8300)
// Android <5360001或Android>5361000
// 双端版本号限制,符合此条件显示为“默认播单”:
// iPhone=5.36.1(8300)
// 5360001 <=Android <=5361000
if (plat == model.PlatIPhone && build == 8300) || (plat == model.PlatAndroid && build >= 5360001 && build <= 5361000) {
mediaList = true
}
if fs, err = s.favDao.Folders(c, mid, vmid, mobiApp, build, mediaList); err != nil {
log.Error("%+v", err)
return
}
for _, v := range fs {
if ((plat == model.PlatAndroid || plat == model.PlatAndroidG) && build <= _oldAndroidBuild) || ((plat == model.PlatIPhone || plat == model.PlatIPhoneI) && build <= _oldIOSBuild) {
v.Videos = v.Cover
v.Cover = nil
}
}
res.Item = fs
res.Count = len(fs)
return
}
// Bangumi get concern season
func (s *Service) Bangumi(c context.Context, mid, vmid int64, setting *space.Setting, pn, ps int) (res *space.BangumiList) {
var (
seasons []*bangumi.Season
err error
)
res = &space.BangumiList{Item: []*space.BangumiItem{}}
if mid != vmid {
if setting == nil {
setting, err = s.spcDao.Setting(c, vmid)
if err != nil {
log.Error("%+v", err)
return
}
}
if setting.Bangumi != 1 {
return
}
}
if seasons, res.Count, err = s.bgmDao.Concern(c, mid, vmid, pn, ps); err != nil {
log.Error("%+v", err)
return
}
if len(seasons) != 0 {
res.Item = make([]*space.BangumiItem, 0, len(seasons))
for _, v := range seasons {
si := &space.BangumiItem{}
si.FromSeason(v)
res.Item = append(res.Item, si)
}
}
return
}
// Community get community
func (s *Service) Community(c context.Context, uid int64, pn, ps int, ak, platform string) (res *space.CommuList) {
var (
comm []*community.Community
err error
)
res = &space.CommuList{Item: []*space.CommItem{}}
if comm, res.Count, err = s.commDao.Community(c, uid, ak, platform, pn, ps); err != nil {
log.Error("%+v", err)
return
}
if len(comm) != 0 {
res.Item = make([]*space.CommItem, 0, len(comm))
for _, v := range comm {
si := &space.CommItem{}
si.FromCommunity(v)
res.Item = append(res.Item, si)
}
}
return
}
// CoinArcs get coin archives.
func (s *Service) CoinArcs(c context.Context, mid, vmid int64, setting *space.Setting, pn, ps int) (res *space.ArcList) {
var (
coins []*api.Arc
err error
)
res = &space.ArcList{Item: []*space.ArcItem{}}
if mid != vmid {
if setting == nil {
setting, err = s.spcDao.Setting(c, vmid)
if err != nil {
log.Error("%+v", err)
return
}
}
if setting.CoinsVideo != 1 {
return
}
}
if coins, res.Count, err = s.coinDao.CoinList(c, vmid, pn, ps); err != nil {
log.Error("%+v", err)
return
}
if len(coins) != 0 {
res.Item = make([]*space.ArcItem, 0, len(coins))
for _, v := range coins {
si := &space.ArcItem{}
si.FromCoinArc(v)
res.Item = append(res.Item, si)
}
}
return
}
// LikeArcs get like archives.
func (s *Service) LikeArcs(c context.Context, mid, vmid int64, setting *space.Setting, pn, ps int) (res *space.ArcList) {
var (
likes []*thumbup.ItemLikeRecord
err error
)
res = &space.ArcList{Item: []*space.ArcItem{}}
if mid != vmid {
if setting == nil {
setting, err = s.spcDao.Setting(c, vmid)
if err != nil {
log.Error("%+v", err)
return
}
}
if setting.LikesVideo != 1 {
return
}
}
if likes, res.Count, err = s.thumbupDao.UserTotalLike(c, vmid, _businessLike, pn, ps); err != nil {
log.Error("%+v", err)
return
}
if len(likes) != 0 {
aids := make([]int64, 0, len(likes))
for _, v := range likes {
aids = append(aids, v.MessageID)
}
var as map[int64]*api.Arc
if as, err = s.arcDao.Archives2(c, aids); err != nil {
log.Error("%+v", err)
return
}
if len(as) == 0 {
return
}
res.Item = make([]*space.ArcItem, 0, len(as))
for _, v := range likes {
if a, ok := as[v.MessageID]; ok {
si := &space.ArcItem{}
si.FromLikeArc(a)
res.Item = append(res.Item, si)
}
}
}
return
}
func (s *Service) upClips(c context.Context, uid int64) (res *space.ClipList) {
var (
clips []*bplus.Clip
err error
)
res = &space.ClipList{Item: []*space.Item{}}
if clips, res.Count, err = s.bplusDao.AllClip(c, uid, 200); err != nil {
log.Error("%+v", err)
return
}
if len(clips) != 0 {
res.Item = make([]*space.Item, 0, len(clips))
for k, v := range clips {
si := &space.Item{}
si.FromClip(v)
res.Item = append(res.Item, si)
if k == 1 {
break
}
}
}
return
}
func (s *Service) upAlbums(c context.Context, uid int64) (res *space.AlbumList) {
var (
album []*bplus.Album
err error
)
res = &space.AlbumList{Item: []*space.Item{}}
if album, res.Count, err = s.bplusDao.AllAlbum(c, uid, 6); err != nil {
log.Error("%+v", err)
return
}
if len(album) != 0 {
res.Item = make([]*space.Item, 0, len(album))
for k, v := range album {
si := &space.Item{}
si.FromAlbum(v)
res.Item = append(res.Item, si)
if k == 5 {
break
}
}
}
return
}
// card get card by mid, vmid or name.
func (s *Service) card(c context.Context, vmid int64, name string) (scard *space.Card, err error) {
scard = &space.Card{}
var profile *account.ProfileStat
if vmid > 0 {
profile, err = s.accDao.Profile3(c, vmid)
} else if name != "" {
profile, err = s.accDao.ProfileByName3(c, name)
}
if err != nil {
err = errors.Wrapf(err, "%v,%v", vmid, name)
return
}
scard.Mid = strconv.FormatInt(profile.Mid, 10)
scard.Name = profile.Name
// scard.Approve =
scard.Sex = profile.Sex
scard.Rank = strconv.FormatInt(int64(profile.Rank), 10)
scard.Face = profile.Face
scard.DisplayRank = strconv.FormatInt(int64(profile.Rank), 10)
// scard.Regtime =
if profile.Silence == 1 {
scard.Spacesta = -2
}
// scard.Birthday =
// scard.Place =
scard.Description = profile.Official.Desc
scard.Article = 0
scard.Attentions = []int64{}
scard.Fans = int(profile.Follower)
// scard.Friend = profile.Following
scard.Attention = int(profile.Following)
scard.Sign = profile.Sign
scard.LevelInfo.Cur = profile.Level
scard.LevelInfo.Min = profile.LevelExp.Min
scard.LevelInfo.NowExp = profile.LevelExp.NowExp
scard.LevelInfo.NextExp = profile.LevelExp.NextExp
if profile.LevelExp.NextExp == -1 {
scard.LevelInfo.NextExp = "--"
}
scard.Pendant.Pid = profile.Pendant.Pid
scard.Pendant.Name = profile.Pendant.Name
scard.Pendant.Image = profile.Pendant.Image
scard.Pendant.Expire = profile.Pendant.Expire
scard.OfficialVerify.Role = profile.Official.Role
scard.OfficialVerify.Title = profile.Official.Title
if profile.Official.Role == 0 {
scard.OfficialVerify.Type = -1
} else {
if profile.Official.Role <= 2 {
scard.OfficialVerify.Type = 0
} else {
scard.OfficialVerify.Type = 1
}
scard.OfficialVerify.Desc = profile.Official.Title
}
scard.Vip.Type = int(profile.Vip.Type)
scard.Vip.VipStatus = int(profile.Vip.Status)
scard.Vip.DueDate = profile.Vip.DueDate
// scard.FansGroup =
// scard.Audio =
// scard.FansUnread =
return
}
// audios
func (s *Service) audios(c context.Context, mid int64, pn, ps int) (res *space.AudioList) {
var (
audios []*audio.Audio
err error
)
res = &space.AudioList{Item: []*space.AudioItem{}}
if audios, res.Count, err = s.audioDao.Audios(c, mid, pn, ps); err != nil {
log.Error("%+v", err)
return
}
if len(audios) != 0 {
res.Item = make([]*space.AudioItem, 0, len(audios))
for _, v := range audios {
si := &space.AudioItem{}
si.FromAudio(v)
res.Item = append(res.Item, si)
}
}
return
}
// Report func
func (s *Service) Report(c context.Context, mid int64, reason, ak string) (err error) {
return s.spcDao.Report(c, mid, reason, ak)
}

View File

@@ -0,0 +1,341 @@
package space
import (
"context"
"reflect"
"testing"
"time"
"go-common/app/interface/main/app-interface/model/space"
account "go-common/app/service/main/account/model"
. "github.com/smartystreets/goconvey/convey"
)
func TestService_Space(t *testing.T) {
type args struct {
c context.Context
mid int64
vmid int64
plat int8
build int
pn int
ps int
platform string
device string
mobiApp string
name string
now time.Time
}
tests := []struct {
name string
s *Service
args args
wantSp *space.Space
wantErr error
}{
// TODO: Add test cases.
}
for _, tt := range tests {
Convey(tt.name, t, func(t *testing.T) {
gotSp, err := tt.s.Space(tt.args.c, tt.args.mid, tt.args.vmid, tt.args.plat, tt.args.build, tt.args.pn, tt.args.ps, tt.args.platform, tt.args.device, tt.args.mobiApp, tt.args.name, tt.args.now)
So(err, ShouldEqual, tt.wantErr)
So(gotSp, ShouldNotResemble, tt.wantSp)
})
}
}
func TestService_UpArcs(t *testing.T) {
type args struct {
c context.Context
uid int64
pn int
ps int
now time.Time
}
tests := []struct {
name string
s *Service
args args
wantRes *space.ArcList
}{
// TODO: Add test cases.
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if gotRes := tt.s.UpArcs(tt.args.c, tt.args.uid, tt.args.pn, tt.args.ps, tt.args.now); !reflect.DeepEqual(gotRes, tt.wantRes) {
t.Errorf("Service.UpArcs() = %v, want %v", gotRes, tt.wantRes)
}
})
}
}
func TestService_UpArticles(t *testing.T) {
type args struct {
c context.Context
uid int64
pn int
ps int
}
tests := []struct {
name string
s *Service
args args
wantRes *space.ArticleList
}{
// TODO: Add test cases.
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if gotRes := tt.s.UpArticles(tt.args.c, tt.args.uid, tt.args.pn, tt.args.ps); !reflect.DeepEqual(gotRes, tt.wantRes) {
t.Errorf("Service.UpArticles() = %v, want %v", gotRes, tt.wantRes)
}
})
}
}
func TestService_favFolders(t *testing.T) {
type args struct {
c context.Context
mid int64
uid int64
plat int8
build int
mobiApp string
}
tests := []struct {
name string
s *Service
args args
wantRes *space.FavList
}{
// TODO: Add test cases.
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if gotRes := tt.s.favFolders(tt.args.c, tt.args.mid, tt.args.uid, nil, tt.args.plat, tt.args.build, tt.args.mobiApp); !reflect.DeepEqual(gotRes, tt.wantRes) {
t.Errorf("Service.favFolders() = %v, want %v", gotRes, tt.wantRes)
}
})
}
}
func TestService_Bangumi(t *testing.T) {
type args struct {
c context.Context
mid int64
uid int64
pn int
ps int
}
tests := []struct {
name string
s *Service
args args
wantRes *space.BangumiList
}{
// TODO: Add test cases.
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if gotRes := tt.s.Bangumi(tt.args.c, tt.args.mid, tt.args.uid, nil, tt.args.pn, tt.args.ps); !reflect.DeepEqual(gotRes, tt.wantRes) {
t.Errorf("Service.Bangumi() = %v, want %v", gotRes, tt.wantRes)
}
})
}
}
func TestService_Community(t *testing.T) {
type args struct {
c context.Context
uid int64
pn int
ps int
ak string
platform string
}
tests := []struct {
name string
s *Service
args args
wantRes *space.CommuList
}{
// TODO: Add test cases.
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if gotRes := tt.s.Community(tt.args.c, tt.args.uid, tt.args.pn, tt.args.ps, tt.args.ak, tt.args.platform); !reflect.DeepEqual(gotRes, tt.wantRes) {
t.Errorf("Service.Community() = %v, want %v", gotRes, tt.wantRes)
}
})
}
}
func TestService_CoinArcs(t *testing.T) {
type args struct {
c context.Context
uid int64
pn int
ps int
}
tests := []struct {
name string
s *Service
args args
wantRes *space.ArcList
}{
// TODO: Add test cases.
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if gotRes := tt.s.CoinArcs(tt.args.c, 0, tt.args.uid, nil, tt.args.pn, tt.args.ps); !reflect.DeepEqual(gotRes, tt.wantRes) {
t.Errorf("Service.CoinArcs() = %v, want %v", gotRes, tt.wantRes)
}
})
}
}
func TestService_LikeArcs(t *testing.T) {
type args struct {
c context.Context
uid int64
pn int
ps int
}
tests := []struct {
name string
s *Service
args args
wantRes *space.ArcList
}{
// TODO: Add test cases.
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if gotRes := tt.s.LikeArcs(tt.args.c, 0, tt.args.uid, nil, tt.args.pn, tt.args.ps); !reflect.DeepEqual(gotRes, tt.wantRes) {
t.Errorf("Service.LikeArcs() = %v, want %v", gotRes, tt.wantRes)
}
})
}
}
func TestService_upClips(t *testing.T) {
type args struct {
c context.Context
uid int64
}
tests := []struct {
name string
s *Service
args args
wantRes *space.ClipList
}{
// TODO: Add test cases.
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if gotRes := tt.s.upClips(tt.args.c, tt.args.uid); !reflect.DeepEqual(gotRes, tt.wantRes) {
t.Errorf("Service.upClips() = %v, want %v", gotRes, tt.wantRes)
}
})
}
}
func TestService_upAlbums(t *testing.T) {
type args struct {
c context.Context
uid int64
}
tests := []struct {
name string
s *Service
args args
wantRes *space.AlbumList
}{
// TODO: Add test cases.
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if gotRes := tt.s.upAlbums(tt.args.c, tt.args.uid); !reflect.DeepEqual(gotRes, tt.wantRes) {
t.Errorf("Service.upAlbums() = %v, want %v", gotRes, tt.wantRes)
}
})
}
}
func TestService_card(t *testing.T) {
type args struct {
c context.Context
vmid int64
name string
}
tests := []struct {
name string
s *Service
args args
wantCard *account.Card
wantErr bool
}{
// TODO: Add test cases.
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
gotCard, err := tt.s.card(tt.args.c, tt.args.vmid, tt.args.name)
if (err != nil) != tt.wantErr {
t.Errorf("Service.card() error = %v, wantErr %v", err, tt.wantErr)
return
}
if !reflect.DeepEqual(gotCard, tt.wantCard) {
t.Errorf("Service.card() = %v, want %v", gotCard, tt.wantCard)
}
})
}
}
func TestService_audios(t *testing.T) {
type args struct {
c context.Context
mid int64
pn int
ps int
}
tests := []struct {
name string
s *Service
args args
wantRes *space.AudioList
}{
// TODO: Add test cases.
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if gotRes := tt.s.audios(tt.args.c, tt.args.mid, tt.args.pn, tt.args.ps); !reflect.DeepEqual(gotRes, tt.wantRes) {
t.Errorf("Service.audios() = %v, want %v", gotRes, tt.wantRes)
}
})
}
}
func TestService_Report(t *testing.T) {
type args struct {
c context.Context
mid int64
reason string
ak string
}
tests := []struct {
name string
s *Service
args args
wantErr bool
}{
// TODO: Add test cases.
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if err := tt.s.Report(tt.args.c, tt.args.mid, tt.args.reason, tt.args.ak); (err != nil) != tt.wantErr {
t.Errorf("Service.Report() error = %v, wantErr %v", err, tt.wantErr)
}
})
}
}