256 lines
6.8 KiB
Go
256 lines
6.8 KiB
Go
|
package service
|
||
|
|
||
|
import (
|
||
|
"context"
|
||
|
"encoding/json"
|
||
|
"go-common/app/interface/bbq/app-bbq/api/http/v1"
|
||
|
topic "go-common/app/service/bbq/topic/api"
|
||
|
"go-common/library/ecode"
|
||
|
"go-common/library/log"
|
||
|
"net/http"
|
||
|
"net/url"
|
||
|
)
|
||
|
|
||
|
func (s *Service) getExtension(ctx context.Context, svids []int64) (res map[int64]*topic.VideoExtension, err error) {
|
||
|
res = make(map[int64]*topic.VideoExtension, len(svids))
|
||
|
// 0. check
|
||
|
|
||
|
// 1. get extension
|
||
|
req := &topic.ListExtensionReq{Svids: svids}
|
||
|
reply, err := s.topicClient.ListExtension(ctx, req)
|
||
|
if err != nil {
|
||
|
log.Warnw(ctx, "log", "get extension fail")
|
||
|
return
|
||
|
}
|
||
|
|
||
|
// 2. form extension
|
||
|
for _, extension := range reply.List {
|
||
|
res[extension.Svid] = extension
|
||
|
}
|
||
|
return
|
||
|
}
|
||
|
|
||
|
// TopicDetail 获取话题详情
|
||
|
func (s *Service) TopicDetail(ctx context.Context, mid int64, req *topic.TopicVideosReq) (res *v1.TopicDetail, err error) {
|
||
|
res = new(v1.TopicDetail)
|
||
|
// 0. check
|
||
|
if req.TopicId == 0 {
|
||
|
err = ecode.TopicReqParamErr
|
||
|
log.Warnw(ctx, "log", "topic id is 0")
|
||
|
return
|
||
|
}
|
||
|
|
||
|
// 1. 获取话题信息及话题内视频
|
||
|
topicDetails, err := s.topicClient.ListTopicVideos(ctx, req)
|
||
|
if err != nil {
|
||
|
log.Errorw(ctx, "log", "get list topic videos fail")
|
||
|
return
|
||
|
}
|
||
|
|
||
|
// 2. 获取视频详情
|
||
|
// 2.0 获取视频id
|
||
|
var svids []int64
|
||
|
topicVideoMap := make(map[int64]*topic.VideoItem)
|
||
|
for _, item := range topicDetails.List {
|
||
|
if _, exists := topicVideoMap[item.Svid]; !exists {
|
||
|
topicVideoMap[item.Svid] = item
|
||
|
svids = append(svids, item.Svid)
|
||
|
}
|
||
|
}
|
||
|
// 2.1 获取详情
|
||
|
svInfos, err := s.svInfos(ctx, svids, mid, false)
|
||
|
if err != nil {
|
||
|
log.Warnw(ctx, "log", "get sv infos fail", "svid", svids)
|
||
|
return
|
||
|
}
|
||
|
|
||
|
// 3. 组装回包
|
||
|
res.TopicInfo = topicDetails.TopicInfo
|
||
|
res.HasMore = topicDetails.HasMore
|
||
|
for _, item := range topicDetails.List {
|
||
|
var topicVideo *v1.TopicVideo
|
||
|
if svInfo, exists := svInfos[item.Svid]; !exists {
|
||
|
log.Errorw(ctx, "log", "cannot find topicVideo response in topic detail", "svid", item.Svid)
|
||
|
continue
|
||
|
} else {
|
||
|
topicVideo = new(v1.TopicVideo)
|
||
|
topicVideo.VideoResponse = svInfo
|
||
|
}
|
||
|
topicVideo.CursorValue = item.CursorValue
|
||
|
topicVideo.HotType = item.HotType
|
||
|
res.List = append(res.List, topicVideo)
|
||
|
}
|
||
|
|
||
|
return
|
||
|
}
|
||
|
|
||
|
func (s *Service) getDiscoveryData(ctx context.Context, uri string) (data []byte, err error) {
|
||
|
var ret struct {
|
||
|
Code int `json:"code"`
|
||
|
Msg string `json:"message"`
|
||
|
Data json.RawMessage `json:"data"`
|
||
|
}
|
||
|
|
||
|
req, err := s.httpClient.NewRequest(http.MethodGet, uri, "", url.Values{})
|
||
|
if err != nil {
|
||
|
log.Errorw(ctx, "log", "http.NewRequest error", "err", err)
|
||
|
return
|
||
|
}
|
||
|
if err = s.httpClient.Do(ctx, req, &ret); err != nil {
|
||
|
log.Errorw(ctx, "log", "client Do error", "err", err)
|
||
|
return
|
||
|
}
|
||
|
if ret.Code != 0 {
|
||
|
log.Errorw(ctx, "log", "return code error", "code", ret.Code)
|
||
|
return
|
||
|
}
|
||
|
data = ret.Data
|
||
|
return
|
||
|
}
|
||
|
|
||
|
func (s *Service) getHotWords(ctx context.Context) (list []string, err error) {
|
||
|
list = make([]string, 0, 1)
|
||
|
|
||
|
data, err := s.getDiscoveryData(ctx, "http://bbq-mng.bilibili.co/bbq/cms/hotword/api")
|
||
|
if err != nil {
|
||
|
log.Warnw(ctx, "log", "get discovery data fail")
|
||
|
return
|
||
|
}
|
||
|
|
||
|
var hotWordResponse struct {
|
||
|
OnshelfList []string `json:"onshelf_list"`
|
||
|
}
|
||
|
err = json.Unmarshal(data, &hotWordResponse)
|
||
|
if err != nil {
|
||
|
log.Errorw(ctx, "log", "unmarshal hot word response fail", "data", string(data))
|
||
|
return
|
||
|
}
|
||
|
list = hotWordResponse.OnshelfList
|
||
|
if list == nil {
|
||
|
list = make([]string, 0, 1)
|
||
|
}
|
||
|
return
|
||
|
}
|
||
|
|
||
|
func (s *Service) getBanner(ctx context.Context) (list []*v1.Banner, err error) {
|
||
|
list = make([]*v1.Banner, 0, 1)
|
||
|
|
||
|
data, err := s.getDiscoveryData(ctx, "http://bbq-mng.bilibili.co/bbq/cms/banner/api")
|
||
|
if err != nil {
|
||
|
log.Warnw(ctx, "log", "get discovery data fail")
|
||
|
return
|
||
|
}
|
||
|
|
||
|
type httpBanner struct {
|
||
|
Title string `json:"title"`
|
||
|
ImgUrl string `json:"img_url"`
|
||
|
JumpUrl string `json:"jump_url"`
|
||
|
}
|
||
|
var bannerResponse struct {
|
||
|
BannerList []*httpBanner `json:"banner_list"`
|
||
|
}
|
||
|
bannerResponse.BannerList = make([]*httpBanner, 0)
|
||
|
err = json.Unmarshal(data, &bannerResponse)
|
||
|
if err != nil {
|
||
|
log.Errorw(ctx, "log", "unmarshal hot word response fail", "data", string(data))
|
||
|
return
|
||
|
}
|
||
|
|
||
|
for _, item := range bannerResponse.BannerList {
|
||
|
banner := new(v1.Banner)
|
||
|
banner.Name = item.Title
|
||
|
banner.PIC = item.ImgUrl
|
||
|
banner.Scheme = item.JumpUrl
|
||
|
list = append(list, banner)
|
||
|
}
|
||
|
|
||
|
if list == nil {
|
||
|
list = make([]*v1.Banner, 0, 1)
|
||
|
}
|
||
|
return
|
||
|
}
|
||
|
|
||
|
// Discovery 发现页
|
||
|
func (s *Service) Discovery(ctx context.Context, mid int64, req *v1.DiscoveryReq) (res *v1.DiscoveryRes, err error) {
|
||
|
res = new(v1.DiscoveryRes)
|
||
|
res.BannerList = make([]*v1.Banner, 0, 10)
|
||
|
res.HotWords = make([]string, 0, 10)
|
||
|
res.TopicList = make([]*v1.TopicDetail, 0, 10)
|
||
|
res.HasMore = false
|
||
|
// check
|
||
|
|
||
|
// 1. 条件判断
|
||
|
if req.Page == 1 {
|
||
|
// 请求热词
|
||
|
if res.HotWords, err = s.getHotWords(ctx); err != nil {
|
||
|
log.Warnw(ctx, "log", "get hot words fail", "err", err)
|
||
|
}
|
||
|
// 请求banner
|
||
|
if res.BannerList, err = s.getBanner(ctx); err != nil {
|
||
|
log.Warnw(ctx, "log", "get banner fail", "err", err)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// 2. 请求话题详情
|
||
|
reply, err := s.topicClient.ListDiscoveryTopics(ctx, &topic.ListDiscoveryTopicReq{Page: req.Page})
|
||
|
if err != nil {
|
||
|
log.Errorw(ctx, "log", "get discovery topics list fail")
|
||
|
return
|
||
|
}
|
||
|
// 2.1 收集svid
|
||
|
var svids []int64
|
||
|
for _, topicDetail := range reply.List {
|
||
|
for _, videoItem := range topicDetail.List {
|
||
|
svids = append(svids, videoItem.Svid)
|
||
|
}
|
||
|
}
|
||
|
// 2.2 获取视频详情
|
||
|
svInfos, err := s.svInfos(ctx, svids, mid, false)
|
||
|
if err != nil {
|
||
|
log.Warnw(ctx, "log", "get sv infos fail", "svids", svids)
|
||
|
return
|
||
|
}
|
||
|
|
||
|
// 3. 组装回包
|
||
|
res.HasMore = reply.HasMore
|
||
|
for _, topicDetail := range reply.List {
|
||
|
newTopicDetail := new(v1.TopicDetail)
|
||
|
newTopicDetail.TopicInfo = topicDetail.TopicInfo
|
||
|
newTopicDetail.HasMore = topicDetail.HasMore
|
||
|
for _, videoItem := range topicDetail.List {
|
||
|
if val, exists := svInfos[videoItem.Svid]; exists {
|
||
|
topicVideo := &v1.TopicVideo{CursorValue: videoItem.CursorValue, VideoResponse: val}
|
||
|
newTopicDetail.List = append(newTopicDetail.List, topicVideo)
|
||
|
} else {
|
||
|
log.Warnw(ctx, "log", "get sv info fail", "svid", videoItem.Svid)
|
||
|
}
|
||
|
}
|
||
|
if len(newTopicDetail.List) == 0 {
|
||
|
log.Warnw(ctx, "log", "topic has nothing", "topic", topicDetail)
|
||
|
continue
|
||
|
}
|
||
|
res.TopicList = append(res.TopicList, newTopicDetail)
|
||
|
}
|
||
|
|
||
|
return
|
||
|
}
|
||
|
|
||
|
// TopicSearch 话题搜索
|
||
|
func (s *Service) TopicSearch(ctx context.Context, req *v1.TopicSearchReq) (res *v1.TopicSearchResponse, err error) {
|
||
|
res = new(v1.TopicSearchResponse)
|
||
|
|
||
|
if len(req.Keyword) == 0 {
|
||
|
var reply *topic.ListTopicsReply
|
||
|
reply, err = s.topicClient.ListTopics(ctx, &topic.ListTopicsReq{Page: 1})
|
||
|
if err != nil {
|
||
|
log.Warnw(ctx, "log", "get topic list fail", "err", err)
|
||
|
return
|
||
|
}
|
||
|
res.List = reply.List
|
||
|
res.HasMore = reply.HasMore
|
||
|
}
|
||
|
res.HasMore = false
|
||
|
|
||
|
return
|
||
|
}
|