1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279 |
- package v1
- import (
- "context"
- "encoding/json"
- "fmt"
- "net/url"
- "reflect"
- "strconv"
- "sync/atomic"
- "time"
- v1indexpb "go-common/app/interface/live/app-interface/api/http/v1"
- "go-common/app/interface/live/app-interface/conf"
- "go-common/app/interface/live/app-interface/dao"
- liveuserV1 "go-common/app/service/live/live_user/api/liverpc/v1"
- relationV2 "go-common/app/service/live/relation/api/liverpc/v2"
- roomV1 "go-common/app/service/live/room/api/liverpc/v1"
- roomV2 "go-common/app/service/live/room/api/liverpc/v2"
- bannerV1 "go-common/app/service/live/room_ex/api/liverpc/v1"
- "go-common/app/service/live/third_api/bvc"
- userextV1 "go-common/app/service/live/userext/api/liverpc/v1"
- "go-common/library/ecode"
- "go-common/library/log"
- "go-common/library/net/metadata"
- "go-common/library/net/rpc/liverpc"
- rpcCtx "go-common/library/net/rpc/liverpc/context"
- "go-common/library/sync/errgroup"
- "go-common/library/xstr"
- "math/rand"
- "github.com/bitly/go-simplejson"
- "github.com/pkg/errors"
- "go-common/library/net/http/blademaster"
- )
- const (
- _bannerType = 1
- _navigatorType = 2
- _yunyingRecFormType = 3
- _yunyingRecSquareType = 4
- _recFormType = 6
- _recSquareType = 7
- _feedType = 8
- _parentAreaFormType = 9
- _parentAreaSquareType = 10
- _myAreaTagType = 12
- _seaPatrolType = 14
- _myAreaTagListType = 13
- _activityType = 11
- // _recTypeOnline = 1
- // _recTypeIncome = 2
- _recTypeForce = 3
- _recTypeSkyHorse = 4
- _defaultRecNum = 24
- _skyHorseRecTimeOut = 100
- _areaModuleLink = "https://live.bilibili.com/app/area?parent_area_id=%d&parent_area_name=%s&area_id=%d&area_name=%s"
- _activityGo = 0
- _activityBook = 1
- _activityUnbook = 2
- _mobileIndexBadgeColorDefault = "#FB9E60"
- )
- // Service struct
- type Service struct {
- conf *conf.Config
- // optionally add other properties here, such as dao
- dao *dao.Dao
- allListInfo atomic.Value
- }
- type roomItem struct {
- RoomId int64 `json:"roomid"`
- Title string `json:"title"`
- Uname string `json:"uname"`
- Online int64 `json:"online"`
- Cover string `json:"cover"`
- Link string `json:"link"`
- Face string `json:"face"`
- AreaV2ParentId int64 `json:"area_v2_parent_id"`
- AreaV2ParentName string `json:"area_v2_parent_name"`
- AreaV2Id int64 `json:"area_v2_id"`
- AreaV2Name string `json:"area_v2_name"`
- PlayUrl string `json:"play_url"`
- PlayUrlH265 string `json:"play_url_h265"`
- CurrentQuality int64 `json:"current_quality"`
- BroadcastType int64 `json:"broadcast_type"`
- PendentRu string `json:"pendent_ru"`
- PendentRuPic string `json:"pendent_ru_pic"`
- PendentRuColor string `json:"pendent_ru_color"`
- RecType int64 `json:"rec_type"`
- PkId int64 `json:"pk_id"`
- AcceptQuality []int64 `json:"accept_quality"`
- }
- type offlineItem struct {
- Id int `json:"id"`
- Name string `json:"name"`
- }
- type userTagItem struct {
- AreaV2Id int `json:"area_v2_id"`
- AreaV2Name string `json:"area_v2_name"`
- AreaV2ParentId int `json:"area_v2_parent_id"`
- AreaV2ParentName string `json:"area_v2_parent_name"`
- Pic string `json:"pic"`
- Link string `json:"link"`
- IsAdvice int `json:"is_advice"`
- }
- type commonResp struct {
- ModuleInfo map[string]interface{}
- ExtraInfo map[string]interface{}
- List interface{}
- }
- type ModuleResp struct {
- Interval int `json:"interval"`
- ModuleList []map[string]interface{} `json:"module_list"`
- }
- // New init
- func New(c *conf.Config) (s *Service) {
- s = &Service{
- conf: c,
- dao: dao.New(c),
- }
- go s.tickCacheAllList(context.TODO())
- return s
- }
- // GetAllList implementation
- // 首页大接口
- func (s *Service) GetAllList(ctx context.Context, req *v1indexpb.GetAllListReq) (ret interface{}, err error) {
- resp := &ModuleResp{
- Interval: 10,
- }
- build := req.Build
- relationTimeout := conf.GetTimeout("relation", 200)
- // dao.LiveUserApi.V1UserSetting.GetTag(ctx, &liveuserV1.UserSettingGetTagReq{})
- midInterface, isUIDSet := metadata.Value(ctx, metadata.Mid).(int64) // 大多使用header里的mid解析, 框架已封装请求的header
- isSkyHorseGray := false
- mid := int64(0)
- if isUIDSet {
- mid = midInterface
- // 天马灰度
- isSkyHorseGray = s.isSkyHorseRec(mid)
- }
- buvid := ""
- // 主站封好的,可从device里获取到sid、buvid、buvid3、build、channel、device、mobi_app、platform
- device, ok := metadata.Value(ctx, metadata.Device).(*blademaster.Device)
- if ok {
- buvid = device.Buvid
- }
- // deviceInterface := req.Device
- // device := deviceInterface.(*bm.Device)
- if req.Platform == "" || req.Device == "" || req.Scale == "" || req.RelationPage == 0 {
- err = errors.WithMessage(ecode.InvalidParam, "INVALID PARAM")
- return
- }
- allListTimeout := time.Duration(conf.GetTimeout("allList", 50)) * time.Millisecond
- rawModuleList := s.getAllListFromCache(rpcCtx.WithTimeout(ctx, allListTimeout))
- if rawModuleList == nil {
- err = errors.WithMessage(ecode.GetAllListReturnError, "")
- return
- }
- // 大分区常量定义
- parentName := map[int64]string{
- 1: "娱乐",
- 2: "游戏",
- 3: "手游",
- 4: "绘画",
- 5: "电台",
- }
- // 天马灰度/保底
- defaultRecSlice := make([]map[string]interface{}, 0)
- loginRecRoomIDSlice := make([]int64, 0)
- // [{module_info:{},list:{}}...]
- resp.ModuleList = make([]map[string]interface{}, len(rawModuleList))
- for _, m := range rawModuleList {
- module := m.(map[string]interface{})
- if module["module_info"] == nil {
- log.Error("empty_module_info:%+v \n", m)
- fmt.Printf("empty_module_info:raw_all:%+v \n", rawModuleList)
- }
- moduleInfo := module["module_info"].(map[string]interface{})
- moduleType := jsonMustInt(moduleInfo["type"], 0)
- if moduleType == 0 {
- continue
- }
- list := module["list"].([]interface{})
- if moduleType == _recFormType || moduleType == _recSquareType {
- for _, r := range list {
- recItem := r.(map[string]interface{})
- defaultRecSlice = append(defaultRecSlice, recItem)
- roomID := jsonMustInt(recItem["roomid"], 0)
- if roomID == 0 {
- continue
- }
- // 登录了也有可能请求不到数据,登录的保底用
- loginRecRoomIDSlice = append(loginRecRoomIDSlice, roomID)
- }
- }
- }
- // 常用标签 roomListMap
- myTagRoomListMap := make(map[int64][]*roomV2.AppIndexGetMultiRoomListResp_RoomList)
- myTagAreaIds := make([]int64, 0, 4)
- myTagAreaInfoMap := make(map[int64]*liveuserV1.UserSettingGetTagResp_Tags)
- myTagResp := commonResp{
- List: make([]interface{}, 0),
- }
- attentionResp := commonResp{
- List: make([]interface{}, 0),
- }
- loginRecResp := commonResp{}
- seaResp := commonResp{}
- bannerResp := commonResp{
- List: make([]interface{}, 0),
- }
- // playurl定义
- attentionRoomListPlayURLMap := make(map[int64]*bvc.PlayUrlItem)
- loginRecRoomListPlayURLMap := make(map[int64]*bvc.PlayUrlItem)
- myTagRoomListPlayURLMap := make(map[int64]*bvc.PlayUrlItem)
- otherRoomListPlayURLMap := make(map[int64]*bvc.PlayUrlItem)
- otherRoomIDSlice := make([]int64, 0)
- isSkyHorseGrayOk := 0
- // 此group包含首页的一些任务
- // 但是任务之间不能同时cancel
- // 不然一个接口出错所有任务都cancel首页就空了
- // 所以return固定为nil(一个wg的任务使用的是从bm context继承来的ctx,cancel后一起推出)
- // 只有上层ctx(http的ctx)出问题(超时等)才会退出后续任务1
- wg, _ := errgroup.WithContext(ctx)
- for _, m := range rawModuleList {
- // {module_info:xx}
- module := m.(map[string]interface{})
- // {id:xx,type:xx,pic:xx,title:xx,link:xx,...}
- moduleInfo := module["module_info"].(map[string]interface{})
- moduleList := module["list"].([]interface{})
- moduleType := jsonMustInt(moduleInfo["type"], 0)
- if moduleType == 0 {
- continue
- }
- // banner分支 分端分版本
- if moduleType == _bannerType {
- bannerTimeout := time.Duration(conf.GetTimeout("banner", 100)) * time.Millisecond
- wg.Go(func() error {
- bannerList, bannerErr := dao.RoomExtApi.V1Banner.GetNewBanner(rpcCtx.WithTimeout(ctx, time.Duration(bannerTimeout)*time.Millisecond), &bannerV1.BannerGetNewBannerReq{UserPlatform: req.Platform, Build: build, UserDevice: req.Device})
- if bannerErr != nil {
- log.Error("[GetAllList]get banner rpc error, roomex.v1.Banner.GetNewBanner, error:%+v,rpctimeout:%d", bannerErr, bannerTimeout)
- return nil
- }
- if bannerList.Code != 0 || bannerList.Data == nil {
- log.Error("[GetAllList]get banner response error, code, %d, msg: %s, error:%+v", bannerList.Code, bannerList.Msg, bannerErr)
- return nil
- }
- if len(bannerList.Data) > 0 {
- for _, bannerInfo := range bannerList.Data {
- bannerResp.List = append(bannerResp.List.([]interface{}), map[string]interface{}{
- "id": bannerInfo.Id,
- "pic": bannerInfo.Pic,
- "link": bannerInfo.Link,
- "title": bannerInfo.Title,
- })
- }
- }
- return nil
- })
- }
- // 关注分支
- if moduleType == _feedType {
- if !isUIDSet {
- continue
- }
- wg.Go(func() error {
- currentAttentionRoomMap := make(map[int64]bool)
- currentAttentionRoomSlice := make([]int64, 0)
- attentionResp.ModuleInfo = moduleInfo
- currentAttention, attentionErr := dao.RelationApi.V2App.LiveHomePage(rpcCtx.WithTimeout(ctx, time.Duration(relationTimeout)*time.Millisecond), &relationV2.AppLiveHomePageReq{RelationPage: req.RelationPage})
- if attentionErr != nil {
- log.Error("[GetAllList]get user attention rpc error, relation.v2.App.liveHomePage, error:%+v,rpctimeout:%d", attentionErr, relationTimeout)
- } else if currentAttention.Code != 0 || currentAttention.Data == nil {
- log.Error("[GetAllList]get user attention response error, code, %d, msg: %s, error:%+v", currentAttention.Code, currentAttention.Msg, attentionErr)
- } else {
- attentionResp.ExtraInfo = map[string]interface{}{
- "total_count": currentAttention.Data.TotalCount,
- "time_desc": currentAttention.Data.TimeDesc,
- "uname_desc": currentAttention.Data.UnameDesc,
- "tags_desc": currentAttention.Data.TagsDesc,
- "relation_page": currentAttention.Data.RelationPage,
- }
- // 存关注map
- for _, attentionCard := range currentAttention.Data.Rooms {
- currentAttentionRoomMap[attentionCard.Roomid] = true
- currentAttentionRoomSlice = append(currentAttentionRoomSlice, attentionCard.Roomid)
- attentionResp.List = append(attentionResp.List.([]interface{}), attentionCard)
- }
- // playurl
- attentionRoomListPlayURLMap = dao.BvcApi.GetPlayUrlMulti(ctx, currentAttentionRoomSlice, 0, 4, build, req.Platform)
- }
- useDefaultRec := false
- isOpen := conf.Conf.SkyHorseStatus
- if isOpen && isSkyHorseGray {
- // 取天马数据,传入关注当前刷列表roomid+强推,天马会对传入的roomid去重
- // duplicates := append(currentAttentionRoomSlice, forceRecSlice...)
- // getSkyHorseRoomList已经对强推去重
- duplicates := currentAttentionRoomSlice
- skyRecResult, skyHorseErr := getSkyHorseRoomList(ctx, mid, buvid, req.Build, req.Platform, duplicates, 1)
- if skyHorseErr != nil {
- log.Warn("[GetAllList]get data from skyHorse err: %v", skyHorseErr)
- useDefaultRec = true
- }
- if skyRecResult == nil {
- log.Warn("[GetAllList]get data from skyHorse empty: %v", skyHorseErr)
- useDefaultRec = true
- }
- if len(skyRecResult) < 6 {
- log.Warn("[GetAllList]get data from skyHorse not enough: %v", skyRecResult)
- useDefaultRec = true
- }
- skyRecResultInterface := make([]map[string]interface{}, 0)
- for _, item := range skyRecResult {
- loginRecRoomIDSlice = append(loginRecRoomIDSlice, item.RoomId)
- skyRecResultInterface = append(skyRecResultInterface, map[string]interface{}{
- "roomid": item.RoomId,
- "title": item.Title,
- "uname": item.Uname,
- "online": item.Online,
- "cover": item.Cover,
- "link": item.Link,
- "face": item.Face,
- "area_v2_parent_id": item.AreaV2ParentId,
- "area_v2_parent_name": item.AreaV2ParentName,
- "area_v2_id": item.AreaV2Id,
- "area_v2_name": item.AreaV2Name,
- "play_url": item.PlayUrl,
- "current_quality": item.CurrentQuality,
- "broadcast_type": item.BroadcastType,
- "pendent_ru": item.PendentRu,
- "pendent_ru_pic": item.PendentRuPic,
- "pendent_ru_color": item.PendentRuColor,
- "rec_type": item.RecType,
- "pk_id": item.PkId,
- "accept_quality": item.AcceptQuality,
- })
- }
- loginRecResp.List = skyRecResultInterface
- isSkyHorseGrayOk = 1
- }
- // 保底逻辑
- if !isOpen || !isSkyHorseGray || useDefaultRec {
- newDefaultRecSlice := make([]map[string]interface{}, 0)
- for _, defaultRecRoom := range defaultRecSlice {
- roomID := jsonMustInt(defaultRecRoom["roomid"], 0)
- if roomID == 0 {
- continue
- }
- if _, exist := currentAttentionRoomMap[roomID]; !exist {
- // 天马没取到保底:默认推荐要对关注当前刷去重
- newDefaultRecSlice = append(newDefaultRecSlice, defaultRecRoom)
- }
- }
- // 只返24个
- if len(newDefaultRecSlice) > _defaultRecNum {
- loginRecResp.List = newDefaultRecSlice[:_defaultRecNum]
- } else {
- loginRecResp.List = newDefaultRecSlice
- }
- isSkyHorseGrayOk = 0
- }
- loginRecRoomListPlayURLMap = dao.BvcApi.GetPlayUrlMulti(ctx, loginRecRoomIDSlice, 0, 4, build, req.Platform)
- return nil
- })
- }
- // 常用标签分支
- if moduleType == _myAreaTagType {
- wg.Go(func() error {
- myTagResp.ModuleInfo = moduleInfo
- getMyTagTimeout := time.Duration(conf.GetTimeout("getMyTag", 100)) * time.Millisecond
- myTagListResp, userTagError := dao.LiveUserApi.V1UserSetting.GetTag(rpcCtx.WithTimeout(ctx, getMyTagTimeout), &liveuserV1.UserSettingGetTagReq{})
- if userTagError != nil {
- log.Error("[GetAllList]get user tag rpc error, live_user.v1.usersetting.get_tag, error:%+v", userTagError)
- return nil // 如果return err 则所有当前group的任务都会cancel
- }
- if myTagListResp.Code != 0 || myTagListResp.Data == nil {
- log.Error("[GetAllList]get user tag return error, code, %d, msg: %s, error:%+v", myTagListResp.Code, myTagListResp.Msg, userTagError)
- return nil
- }
- if myTagListResp.Data != nil {
- myTagResp.ExtraInfo = make(map[string]interface{})
- myTagResp.ExtraInfo["is_gray"] = myTagListResp.Data.IsGray
- myTagResp.ExtraInfo["offline"] = make([]interface{}, 0)
- for _, offlineInfo := range myTagListResp.Data.Offline {
- myTagResp.ExtraInfo["offline"] = append(myTagResp.ExtraInfo["offline"].([]interface{}), &offlineItem{Id: int(offlineInfo.Id), Name: offlineInfo.Name})
- }
- }
- for _, tagInfo := range myTagListResp.Data.Tags {
- myTagAreaIds = append(myTagAreaIds, tagInfo.Id)
- myTagAreaInfoMap[tagInfo.Id] = tagInfo
- link := fmt.Sprintf("http://live.bilibili.com/app/area?parent_area_id=%d&parent_area_name=%s&area_id=%d&area_name=%s", tagInfo.ParentId, parentName[tagInfo.ParentId], tagInfo.Id, tagInfo.Name)
- myTagResp.List = append(myTagResp.List.([]interface{}), &userTagItem{AreaV2Id: int(tagInfo.Id), AreaV2Name: tagInfo.Name, AreaV2ParentId: int(tagInfo.ParentId), AreaV2ParentName: parentName[tagInfo.ParentId], Link: link, Pic: tagInfo.Pic, IsAdvice: int(tagInfo.IsAdvice)})
- }
- if (req.Platform == "ios" && build > 8220) || (req.Platform == "android" && build > 5333002) {
- myTagResp.List = append(myTagResp.List.([]interface{}), &userTagItem{AreaV2Id: int(0), AreaV2Name: "全部标签", AreaV2ParentId: int(0), AreaV2ParentName: "", Pic: "http://i0.hdslb.com/bfs/vc/ff03528785fc8c91491d79e440398484811d6d87.png", Link: "http://live.bilibili.com/app/mytag/", IsAdvice: 1})
- }
- if len(myTagAreaIds) <= 0 {
- log.Error("[GetAllList]get user tag return empty!uid:%d", mid)
- return nil
- }
- // 常用标签房间列表 先生成最后wait替换就好了
- getMultiRoomListTimeout := time.Duration(conf.GetTimeout("getMultiRoomList", 100)) * time.Millisecond
- myTagRoomListResp, multiRoomListErr := dao.RoomApi.V2AppIndex.GetMultiRoomList(rpcCtx.WithTimeout(ctx, getMultiRoomListTimeout), &roomV2.AppIndexGetMultiRoomListReq{AreaIds: xstr.JoinInts(myTagAreaIds), Platform: req.Platform})
- if multiRoomListErr != nil {
- log.Error("[GetAllList]get multi list rpc error, room.v2.AppIndex.GetMultiRoomList, error:%+v", multiRoomListErr)
- return nil
- }
- if myTagRoomListResp.Code != 0 || myTagRoomListResp.Data == nil {
- log.Error("[GetAllList]get multi list response error, code, %d, msg: %s, error:%+v", myTagRoomListResp.Code, myTagRoomListResp.Msg, multiRoomListErr)
- return nil
- }
- // 保存roomListMap,wait 聚合数据
- myTagRoomIDSlice := make([]int64, 0)
- for _, myTagRoomItem := range myTagRoomListResp.Data {
- myTagRoomListMap[myTagRoomItem.Id] = myTagRoomItem.List
- for _, item := range myTagRoomItem.List {
- myTagRoomIDSlice = append(myTagRoomIDSlice, item.Roomid)
- }
- }
- myTagRoomListPlayURLMap = dao.BvcApi.GetPlayUrlMulti(ctx, myTagRoomIDSlice, 0, 4, build, req.Platform)
- return nil
- })
- }
- if moduleType == _seaPatrolType {
- seaPatrolList := make([]interface{}, 0)
- if !isUIDSet {
- continue
- }
- // 大航海分支
- wg.Go(func() error {
- seaPatrolTimeout := time.Duration(conf.GetTimeout("seaPatrol", 100)) * time.Millisecond
- seaPatrol, seaPatrolError := dao.LiveUserApi.V1Note.Get(rpcCtx.WithTimeout(ctx, seaPatrolTimeout), &liveuserV1.NoteGetReq{})
- if seaPatrolError != nil {
- log.Error("[GetAllList]get sea patrol rpc error, liveuser.v1.Note.Get, error:%+v", seaPatrolError)
- return nil
- }
- if seaPatrol.Code != 0 || seaPatrol.Data == nil {
- log.Error("[GetAllList]get sea patrol note from liveuser response error, code, %d, msg: %s, error:%+v", seaPatrol.Code, seaPatrol.Msg, seaPatrolError)
- return nil
- }
- if seaPatrol.Data.Title != "" {
- seaPatrolList = append(seaPatrolList, map[string]interface{}{
- "pic": seaPatrol.Data.Logo,
- "title": seaPatrol.Data.Title,
- "link": seaPatrol.Data.Link,
- "content": seaPatrol.Data.Content,
- })
- }
- seaResp.List = seaPatrolList
- seaResp.ModuleInfo = moduleInfo
- seaResp.ExtraInfo = make(map[string]interface{})
- return nil
- })
- }
- if moduleType == _activityType {
- cardList := module["list"].([]interface{})
- actyInfo := cardList[0].(map[string]interface{})
- bookStatus := jsonMustInt(actyInfo["status"], 0)
- // status=0(非预约类型的活动)
- if bookStatus == _activityGo {
- actyInfo["button_text"] = "去围观"
- actyInfo["status"] = _activityGo
- continue
- }
- // 未登入 显示预约
- if !isUIDSet {
- actyInfo["button_text"] = "预约"
- actyInfo["status"] = _activityBook
- continue
- }
- // 登入状态 设置保底数据
- actyInfo["button_text"] = "去围观"
- actyInfo["status"] = _activityGo
- // 获取活动id
- materialID := jsonMustInt(moduleInfo["material_id"], 0)
- if materialID == 0 {
- continue
- }
- log.Info("[GetAllList]materialID is %v", materialID)
- wg.Go(func() error {
- activityQueryTimeout := time.Duration(conf.GetTimeout("activityQuery", 100)) * time.Millisecond
- bookInfo, userExtError := dao.UserExtApi.V1Remind.Query(rpcCtx.WithTimeout(ctx, activityQueryTimeout), &userextV1.RemindQueryReq{Aid: materialID})
- if userExtError != nil {
- log.Error("[GetAllList]get activity book info rpc error, userext.v1.Remind.Query, error:%+v", userExtError)
- return nil
- }
- if bookInfo.Code != 0 {
- log.Error("[GetAllList]get activity book info response error, code, %d, msg: %s, error:%+v", bookInfo.Code, bookInfo.Msg, userExtError)
- return nil
- }
- log.Info("[GetAllList]materialID is %v and bookInfo.Data.Status is %v", materialID, bookInfo.Data.Status)
- switch bookInfo.Data.Status {
- case _activityBook:
- actyInfo["button_text"] = "已预约"
- actyInfo["status"] = _activityUnbook
- case _activityUnbook:
- actyInfo["button_text"] = "预约"
- actyInfo["status"] = _activityBook
- default:
- actyInfo["button_text"] = "去围观"
- actyInfo["status"] = _activityGo
- }
- return nil
- })
- }
- // 其他playurl,注意这里取的推荐是未登录下的推荐play_url
- if moduleType == _yunyingRecFormType || moduleType == _yunyingRecSquareType ||
- moduleType == _parentAreaFormType || moduleType == _parentAreaSquareType ||
- moduleType == _recFormType || moduleType == _recSquareType {
- // append Roomid
- for _, item := range moduleList {
- itemV := item.(map[string]interface{})
- roomID := jsonMustInt(itemV["roomid"], 0)
- if roomID == 0 {
- continue
- }
- otherRoomIDSlice = append(otherRoomIDSlice, roomID)
- }
- }
- }
- // +其他模块playurl
- wg.Go(func() error {
- otherRoomListPlayURLMap = dao.BvcApi.GetPlayUrlMulti(ctx, otherRoomIDSlice, 0, 4, build, req.Platform)
- return nil
- })
- waitErr := wg.Wait()
- if waitErr != nil {
- log.Error("[GetAllList]wait error: %s", waitErr)
- return
- }
- // 封装
- tagIndex := 0
- for index, m := range rawModuleList {
- module := m.(map[string]interface{})
- moduleInfo := module["module_info"].(map[string]interface{})
- moduleList := module["list"].([]interface{})
- moduleType := jsonMustInt(moduleInfo["type"], 0)
- if moduleType == 0 {
- continue
- }
- // 初始化
- resp.ModuleList[index] = make(map[string]interface{})
- resp.ModuleList[index]["list"] = moduleList
- resp.ModuleList[index]["module_info"] = moduleInfo
- if moduleType == _bannerType {
- resp.ModuleList[index]["list"] = bannerResp.List
- }
- if moduleType == _navigatorType && req.Platform == "android" && build <= 5333002 {
- // 分区入口5.33版本还返回4个(前3个+全部),5.34透传后台的5个
- if len(moduleList) > 3 {
- resp.ModuleList[index]["list"] = append(moduleList[:3], map[string]interface{}{
- "id": 12,
- "pic": "https://i0.hdslb.com/bfs/vc/ff03528785fc8c91491d79e440398484811d6d87.png",
- "link": "https://live.bilibili.com/app/mytag/",
- "title": "全部标签",
- })
- }
- }
- if moduleType == _seaPatrolType {
- if seaResp.List != nil {
- resp.ModuleList[index]["list"] = seaResp.List
- }
- if seaResp.ModuleInfo != nil {
- resp.ModuleList[index]["module_info"] = seaResp.ModuleInfo
- }
- if seaResp.ExtraInfo != nil {
- resp.ModuleList[index]["extra_info"] = seaResp.ExtraInfo
- }
- }
- if moduleType == _myAreaTagType {
- if myTagResp.List != nil {
- resp.ModuleList[index]["list"] = myTagResp.List
- }
- if myTagResp.ModuleInfo != nil {
- resp.ModuleList[index]["module_info"] = myTagResp.ModuleInfo
- }
- if myTagResp.ExtraInfo != nil {
- resp.ModuleList[index]["extra_info"] = myTagResp.ExtraInfo
- }
- }
- var isTagGray int
- iTmp, _ := myTagResp.ExtraInfo["is_gray"].(int64)
- isTagGray = int(iTmp)
- // 常用分区房间列表填充
- if moduleType == _myAreaTagListType {
- if isTagGray == 0 {
- continue
- }
- if len(myTagAreaIds) == 0 || tagIndex >= len(myTagAreaIds) {
- continue
- }
- mTagAreaID := myTagAreaIds[tagIndex]
- if _, ok := myTagRoomListMap[mTagAreaID]; ok {
- for _, v := range myTagRoomListMap[mTagAreaID] {
- if myTagRoomListPlayURLMap[v.Roomid] != nil {
- v.AcceptQuality = myTagRoomListPlayURLMap[v.Roomid].AcceptQuality
- v.CurrentQuality = myTagRoomListPlayURLMap[v.Roomid].CurrentQuality
- v.PlayUrl = myTagRoomListPlayURLMap[v.Roomid].Url["h264"]
- v.PlayUrlH265 = myTagRoomListPlayURLMap[v.Roomid].Url["h265"]
- }
- }
- resp.ModuleList[index]["list"] = myTagRoomListMap[mTagAreaID]
- if _, ok := myTagAreaInfoMap[mTagAreaID]; ok {
- areaInfo := myTagAreaInfoMap[mTagAreaID]
- moduleInfo["title"] = areaInfo.Name
- moduleInfo["link"] = fmt.Sprintf(_areaModuleLink, areaInfo.ParentId, parentName[areaInfo.ParentId], areaInfo.Id, areaInfo.Name)
- resp.ModuleList[index]["module_info"] = moduleInfo
- }
- }
- tagIndex++
- }
- // 运营推荐分区对常用分区去重
- if moduleType == _yunyingRecFormType || moduleType == _yunyingRecSquareType {
- link := moduleInfo["link"]
- u, err := url.Parse(link.(string))
- if err != nil {
- log.Warn("[GetAllList]url.Parse (%s) error: %v", link, err)
- continue
- }
- m, err := url.ParseQuery(u.RawQuery)
- if err != nil {
- log.Warn("[GetAllList]url.ParseQuery (%s) error: %v", link, err)
- continue
- }
- area, ok := m["area_id"]
- if !ok {
- log.Warn("[GetAllList]url ((%s) area_id lost: %v", link, ok)
- continue
- }
- trueArea, err := strconv.Atoi(area[0])
- if err != nil {
- log.Warn("[GetAllList]get trueAreaId error: %v", link, ok)
- continue
- }
- if _, ok := myTagRoomListMap[int64(trueArea)]; ok && isTagGray == 1 {
- resp.ModuleList[index]["list"] = nil
- } else {
- for _, v := range moduleList {
- if v == nil {
- continue
- }
- vv := v.(map[string]interface{})
- roomID := jsonMustInt(vv["roomid"], 0)
- if roomID == 0 {
- continue
- }
- if otherRoomListPlayURLMap[roomID] != nil {
- vv["accept_quality"] = otherRoomListPlayURLMap[roomID].AcceptQuality
- vv["current_quality"] = otherRoomListPlayURLMap[roomID].CurrentQuality
- vv["play_url"] = otherRoomListPlayURLMap[roomID].Url["h264"]
- vv["play_url_h265"] = otherRoomListPlayURLMap[roomID].Url["h265"]
- }
- }
- resp.ModuleList[index]["list"] = moduleList
- resp.ModuleList[index]["module_info"] = moduleInfo
- }
- }
- if moduleType == _feedType {
- if attentionResp.ModuleInfo != nil {
- resp.ModuleList[index]["module_info"] = attentionResp.ModuleInfo
- }
- if attentionResp.ExtraInfo != nil {
- resp.ModuleList[index]["extra_info"] = attentionResp.ExtraInfo
- }
- if attentionResp.List != nil {
- for _, v := range attentionResp.List.([]interface{}) {
- vv := v.(*relationV2.AppLiveHomePageResp_Rooms)
- if attentionRoomListPlayURLMap[vv.Roomid] != nil {
- vv.AcceptQuality = attentionRoomListPlayURLMap[vv.Roomid].AcceptQuality
- vv.CurrentQuality = attentionRoomListPlayURLMap[vv.Roomid].CurrentQuality
- vv.PlayUrl = attentionRoomListPlayURLMap[vv.Roomid].Url["h264"]
- vv.PlayUrlH265 = attentionRoomListPlayURLMap[vv.Roomid].Url["h265"]
- }
- }
- resp.ModuleList[index]["list"] = attentionResp.List
- }
- }
- if moduleType == _recFormType || moduleType == _recSquareType {
- moduleInfo["is_sky_horse_gray"] = isSkyHorseGrayOk
- resp.ModuleList[index]["module_info"] = moduleInfo
- if loginRecResp.List != nil {
- // is uid set
- for _, v := range loginRecResp.List.([]map[string]interface{}) {
- roomID := int64(0)
- r, ok := v["roomid"].(json.Number)
- if ok {
- rr, intErr := r.Int64()
- if intErr != nil {
- continue
- }
- roomID = rr
- } else {
- roomID = v["roomid"].(int64)
- }
- if roomID == 0 {
- continue
- }
- if loginRecRoomListPlayURLMap[roomID] != nil {
- v["accept_quality"] = loginRecRoomListPlayURLMap[roomID].AcceptQuality
- v["current_quality"] = loginRecRoomListPlayURLMap[roomID].CurrentQuality
- v["play_url"] = loginRecRoomListPlayURLMap[roomID].Url["h264"]
- v["play_url_h265"] = loginRecRoomListPlayURLMap[roomID].Url["h265"]
- }
- }
- resp.ModuleList[index]["list"] = loginRecResp.List
- } else {
- for _, v := range moduleList {
- if v == nil {
- continue
- }
- vv := v.(map[string]interface{})
- roomID := jsonMustInt(vv["roomid"], 0)
- if roomID == 0 {
- continue
- }
- if otherRoomListPlayURLMap[roomID] != nil {
- vv["accept_quality"] = otherRoomListPlayURLMap[roomID].AcceptQuality
- vv["current_quality"] = otherRoomListPlayURLMap[roomID].CurrentQuality
- vv["play_url"] = otherRoomListPlayURLMap[roomID].Url["h264"]
- vv["play_url_h265"] = otherRoomListPlayURLMap[roomID].Url["h265"]
- }
- }
- // 只返24个,新推荐已在上面做处理
- if len(moduleList) > _defaultRecNum {
- resp.ModuleList[index]["list"] = moduleList[:_defaultRecNum]
- } else {
- resp.ModuleList[index]["list"] = moduleList
- }
- }
- }
- if moduleType == _parentAreaFormType || moduleType == _parentAreaSquareType {
- for _, v := range moduleList {
- if v == nil {
- continue
- }
- vv := v.(map[string]interface{})
- roomID := jsonMustInt(vv["roomid"], 0)
- if roomID == 0 {
- continue
- }
- if otherRoomListPlayURLMap[roomID] != nil {
- vv["accept_quality"] = otherRoomListPlayURLMap[roomID].AcceptQuality
- vv["current_quality"] = otherRoomListPlayURLMap[roomID].CurrentQuality
- vv["play_url"] = otherRoomListPlayURLMap[roomID].Url["h264"]
- vv["play_url_h265"] = otherRoomListPlayURLMap[roomID].Url["h265"]
- }
- }
- resp.ModuleList[index]["list"] = moduleList
- }
- }
- ret = resp
- return
- }
- func jsonMustInt(arg interface{}, def int64) int64 {
- if arg == nil {
- log.Warn("jsonMustInt arg(%v) nil!", arg)
- return def
- }
- r, ok := arg.(json.Number)
- if !ok {
- log.Warn("jsonMustInt arg(%v) is not json.Number but %v", arg, reflect.TypeOf(arg))
- return def
- }
- rr, err := r.Int64()
- if err != nil {
- log.Warn("jsonMustInt arg(%v) transfer error: %v", arg, err)
- return def
- }
- return rr
- }
- // Change implementation
- // 首页换一换接口 for 天马
- func (s *Service) Change(ctx context.Context, req *v1indexpb.ChangeReq) (resp *v1indexpb.ChangeResp, err error) {
- resp = &v1indexpb.ChangeResp{
- ModuleList: make([]*v1indexpb.ChangeResp_ModuleList, 0),
- }
- mid, isUIDSet := metadata.Value(ctx, metadata.Mid).(int64)
- var uid int64
- if isUIDSet {
- uid = mid
- }
- // deviceInterface, _ := ctx.Get("device")
- // device := req.Device
- duplicates, _ := xstr.SplitInts(req.AttentionRoomId)
- duplicatesMap := make(map[int64]bool)
- for _, roomID := range duplicates {
- duplicatesMap[roomID] = true
- }
- build := req.Build
- buvid := ""
- // 主站封好的,可从device里获取到sid、buvid、buvid3、build、channel、device、mobi_app、platform
- device, ok := metadata.Value(ctx, metadata.Device).(*blademaster.Device)
- if ok {
- buvid = device.Buvid
- }
- var recModuleInfo *v1indexpb.ChangeResp_ModuleInfo
- allListOut, callErr := dao.RoomApi.V2AppIndex.GetAllList(rpcCtx.WithTimeout(ctx, 100*time.Millisecond), &roomV2.AppIndexGetAllListReq{
- Platform: req.Platform,
- Device: req.Device,
- Scale: req.Scale,
- Build: int64(build),
- ModuleId: req.ModuleId,
- })
- if callErr != nil {
- log.Error("[Change]get all list rpc error, room.v2.AppIndex.setAllList, error:%+v", callErr)
- err = errors.WithMessage(ecode.ChangeGetAllListRPCError, "CHANGE GET ALL LIST FAIL#1")
- return
- }
- if allListOut.Code != 0 || allListOut.Data == nil {
- log.Error("[Change]get all list return data error, code, %d, msg: %s, error:%+v", allListOut.Code, allListOut.Msg, err)
- err = errors.WithMessage(ecode.ChangeGetAllListReturnError, "CHANGE GET ALL LIST FAIL#2")
- return
- }
- if len(allListOut.Data.ModuleList) == 0 {
- log.Error("[Change]get all list return empty, code, %d, msg: %s, error:%+v", allListOut.Code, allListOut.Msg, err)
- err = errors.WithMessage(ecode.ChangeGetAllListEmptyError, "CHANGE GET ALL LIST FAIL#3")
- return
- }
- m := allListOut.Data.ModuleList[0]
- duplicateList := make([]*roomV2.AppIndexGetAllListResp_RoomList, 0)
- for _, itemInfo := range m.List {
- if _, ok := duplicatesMap[itemInfo.Roomid]; !ok {
- duplicateList = append(duplicateList, itemInfo)
- }
- }
- m.List = duplicateList
- recModuleInfo = &v1indexpb.ChangeResp_ModuleInfo{
- Id: m.ModuleInfo.Id,
- Title: m.ModuleInfo.Title,
- Pic: m.ModuleInfo.Pic,
- Type: m.ModuleInfo.Type,
- Link: m.ModuleInfo.Link,
- Count: m.ModuleInfo.Count,
- IsSkyHorseGray: 0,
- }
- // 目前只有推荐-天马有换一换,都必须有登陆态
- roomIds := make([]int64, 0)
- list := make([]*v1indexpb.ChangeResp_List, 0)
- for i, itemInfo := range m.List {
- if i >= 24 {
- break
- }
- roomIds = append(roomIds, itemInfo.Roomid)
- list = append(list, &v1indexpb.ChangeResp_List{
- Roomid: itemInfo.Roomid,
- Title: itemInfo.Title,
- Uname: itemInfo.Uname,
- Online: itemInfo.Online,
- Cover: itemInfo.Cover,
- Link: "/" + strconv.Itoa(int(itemInfo.Roomid)),
- Face: itemInfo.Face,
- AreaV2ParentId: itemInfo.AreaV2ParentId,
- AreaV2ParentName: itemInfo.AreaV2ParentName,
- AreaV2Id: itemInfo.AreaV2Id,
- AreaV2Name: itemInfo.AreaV2Name,
- BroadcastType: itemInfo.BroadcastType,
- PendentRu: itemInfo.PendentRu,
- PendentRuPic: itemInfo.PendentRuPic,
- PendentRuColor: itemInfo.PendentRuColor,
- RecType: itemInfo.RecType,
- CurrentQuality: itemInfo.CurrentQuality,
- AcceptQuality: itemInfo.AcceptQuality,
- PlayUrl: itemInfo.PlayUrl,
- })
- }
- resp.ModuleList = append(resp.ModuleList, &v1indexpb.ChangeResp_ModuleList{
- List: list,
- ModuleInfo: recModuleInfo,
- })
- isOpen := conf.Conf.SkyHorseStatus
- if isOpen && isUIDSet && s.isSkyHorseRec(uid) {
- recPage := rand.Intn(4)
- if recPage == 1 || recPage == 0 {
- recPage = 2
- }
- recList, skyHorseErr := getSkyHorseRoomList(ctx, uid, buvid, req.Build, req.Platform, duplicates, int64(recPage))
- if skyHorseErr != nil {
- log.Error("[Change]getSkyHorseRoomList error:%+v", skyHorseErr)
- // err = errors.WithMessage(ecode.SkyHorseError, "")
- } else if len(recList) <= 0 {
- log.Error("[Change]getSkyHorseRoomList empty:%+v", recList)
- // err = errors.WithMessage(ecode.ChangeSkyHorseEmptyError, "")
- } else {
- list := make([]*v1indexpb.ChangeResp_List, 0)
- for i, recInfo := range recList {
- if i >= 6 {
- continue
- }
- roomIds = append(roomIds, recInfo.RoomId)
- list = append(list, &v1indexpb.ChangeResp_List{
- Roomid: recInfo.RoomId,
- Title: recInfo.Title,
- Uname: recInfo.Uname,
- Online: recInfo.Online,
- Cover: recInfo.Cover,
- Link: "/" + strconv.Itoa(int(recInfo.RoomId)),
- Face: recInfo.Face,
- AreaV2ParentId: recInfo.AreaV2ParentId,
- AreaV2ParentName: recInfo.AreaV2ParentName,
- AreaV2Id: recInfo.AreaV2Id,
- AreaV2Name: recInfo.AreaV2Name,
- BroadcastType: recInfo.BroadcastType,
- PendentRu: recInfo.PendentRu,
- PendentRuPic: recInfo.PendentRuPic,
- PendentRuColor: recInfo.PendentRuColor,
- RecType: _recTypeSkyHorse,
- })
- }
- skyHorseList := make([]*v1indexpb.ChangeResp_ModuleList, 0)
- recModuleInfo.IsSkyHorseGray = 1
- skyHorseList = append(skyHorseList, &v1indexpb.ChangeResp_ModuleList{
- List: list,
- ModuleInfo: recModuleInfo,
- })
- resp.ModuleList = skyHorseList
- }
- }
- changeRoomListPlayURLMap := dao.BvcApi.GetPlayUrlMulti(ctx, roomIds, 0, 4, build, req.Platform)
- for _, v := range resp.ModuleList[0].List {
- if changeRoomListPlayURLMap[v.Roomid] != nil {
- v.AcceptQuality = changeRoomListPlayURLMap[v.Roomid].AcceptQuality
- v.CurrentQuality = changeRoomListPlayURLMap[v.Roomid].CurrentQuality
- v.PlayUrl = changeRoomListPlayURLMap[v.Roomid].Url["h264"]
- v.PlayUrlH265 = changeRoomListPlayURLMap[v.Roomid].Url["h265"]
- }
- }
- // 赋值
- return
- }
- // 获取天马房间信息列表
- // 已将强推roomids传给天马,其他的可通过传duplicates来merge进去
- func getSkyHorseRoomList(ctx context.Context, uid int64, buvid string, build int64, platform string, duplicates []int64, recPage int64) (resp []*roomItem, err error) {
- clientRecStrongTimeout := time.Duration(conf.GetTimeout("clientRecStrong", 100)) * time.Millisecond
- strongRecList, strongRecErr := dao.RoomApi.V1RoomRecommend.ClientRecStrong(rpcCtx.WithTimeout(ctx, clientRecStrongTimeout), &roomV1.RoomRecommendClientRecStrongReq{RecPage: recPage})
- // liverpc.NewClient().CallRaw()
- recDuplicate := make([]int64, 0)
- if strongRecErr != nil {
- log.Error("[getSkyHorseRoomList]room.v1.ClientRecStrong rpc error:%+v", strongRecErr)
- } else if strongRecList.Code != 0 {
- log.Error("[getSkyHorseRoomList]room.v1.ClientRecStrong response error:%+v,code:%d,msg:%s", strongRecErr, strongRecList.Code, strongRecList.Msg)
- } else {
- for _, strongInfo := range strongRecList.Data.Result {
- if strongInfo.Roomid == 0 {
- continue
- }
- recDuplicate = append(recDuplicate, strongInfo.Roomid)
- }
- }
- strongLen := len(recDuplicate)
- duplicates = append(duplicates, recDuplicate...)
- skyHorseRec, skyHorseErr := dao.SkyHorseApi.GetSkyHorseRec(ctx, uid, buvid, build, platform, duplicates, strongLen, _skyHorseRecTimeOut)
- if skyHorseErr != nil {
- err = errors.WithMessage(ecode.SkyHorseError, "")
- return
- }
- roomIds := make([]int64, 0)
- for _, skyHorseInfo := range skyHorseRec.Data {
- roomIds = append(roomIds, int64(skyHorseInfo.Id))
- }
- indexRoomListFields := []string{
- "roomid",
- "title",
- "uname",
- "online",
- "cover",
- "user_cover",
- "link",
- "face",
- "area_v2_parent_id",
- "area_v2_parent_name",
- "area_v2_id",
- "area_v2_name",
- "broadcast_type",
- "uid",
- }
- wg, _ := errgroup.WithContext(ctx)
- // 房间基础信息(是map,但是天马返回是无序的)
- var multiRoomListResp *roomV2.RoomGetByIdsResp
- wg.Go(func() error {
- getByIdsTimeout := time.Duration(conf.GetTimeout("getByIds", 50)) * time.Millisecond
- multiRoomList, getByIdsError := dao.RoomApi.V2Room.GetByIds(rpcCtx.WithTimeout(ctx, getByIdsTimeout), &roomV2.RoomGetByIdsReq{
- Ids: roomIds,
- NeedBroadcastType: 1,
- NeedUinfo: 1,
- Fields: indexRoomListFields,
- From: "app-interface.gateway",
- })
- if getByIdsError != nil {
- log.Error("[getSkyHorseRoomList]room.v2.getByIds rpc error:%+v", getByIdsError)
- // 这个是推荐房间列表的基础信息,如果失败需要cancel,不然返回值会很奇怪
- return errors.WithMessage(ecode.GetRoomError, "room.v2.getByIds rpc error")
- }
- if multiRoomList.Code != 0 {
- log.Error("[getSkyHorseRoomList]room.v2.getByIds response error:%+v,code:%d,msg:%s", getByIdsError, multiRoomList.Code, multiRoomList.Msg)
- // 这个是推荐房间列表的基础信息,如果失败需要cancel,不然返回值会很奇怪
- return errors.WithMessage(ecode.GetRoomError, "room.v2.getByIds response error")
- }
- multiRoomListResp = multiRoomList
- return nil
- })
- // 房间角标信息
- pendantRoomListResp := &roomV1.RoomPendantGetPendantByIdsResp{}
- wg.Go(func() error {
- getPendantByIdsTimeout := time.Duration(conf.GetTimeout("getPendantByIds", 50)) * time.Millisecond
- pendantRoomList, getPendantError := dao.RoomApi.V1RoomPendant.GetPendantByIds(rpcCtx.WithTimeout(ctx, getPendantByIdsTimeout), &roomV1.RoomPendantGetPendantByIdsReq{
- Ids: roomIds,
- Type: "mobile_index_badge",
- Position: 2, // 历史原因,取右上,但客户端展示在左上
- })
- if getPendantError != nil {
- log.Error("[getSkyHorseRoomList]room.v1.getPendantByIds rpc error:%+v", getPendantError)
- return nil
- }
- if pendantRoomList.Code != 0 {
- log.Error("[getSkyHorseRoomList]room.v1.getPendantByIds response error:%+v,code:%d,msg:%s", getPendantError, pendantRoomList.Code, pendantRoomList.Msg)
- return nil
- }
- pendantRoomListResp = pendantRoomList
- return nil
- })
- waitErr := wg.Wait()
- if waitErr != nil {
- log.Error("[getSkyHorseRoomList]wait error(%+v)", waitErr)
- return
- }
- pendantResult := make(map[int64]*roomV1.RoomPendantGetPendantByIdsResp_Result)
- // 天马返回是无序的
- if multiRoomListResp == nil {
- err = errors.WithMessage(ecode.GetRoomEmptyError, "")
- return
- }
- respSlice := make([]*roomV2.RoomGetByIdsResp_RoomInfo, 0)
- for _, roomBaseInfo := range multiRoomListResp.Data {
- respSlice = append(respSlice, roomBaseInfo)
- }
- for i := 0; i < 6; i++ {
- if strongRecList != nil && strongRecList.Data != nil && strongRecList.Data.Result != nil {
- if recInfo, ok := strongRecList.Data.Result[int64(i)]; ok {
- resp = append(resp, &roomItem{
- RoomId: recInfo.Roomid,
- Title: recInfo.Title,
- Uname: recInfo.Uname,
- Online: recInfo.Online,
- Cover: recInfo.Cover,
- Link: "/" + strconv.Itoa(int(recInfo.Roomid)),
- Face: recInfo.Face,
- AreaV2ParentId: recInfo.AreaV2ParentId,
- AreaV2ParentName: recInfo.AreaV2ParentName,
- AreaV2Id: recInfo.AreaV2Id,
- AreaV2Name: recInfo.AreaV2Name,
- BroadcastType: recInfo.BroadcastType,
- PendentRu: recInfo.PendentRu,
- PendentRuPic: recInfo.PendentRuPic,
- PendentRuColor: recInfo.PendentRuColor,
- RecType: _recTypeForce,
- CurrentQuality: recInfo.CurrentQuality,
- AcceptQuality: recInfo.AcceptQuality,
- })
- continue
- }
- }
- if len(respSlice) <= 0 {
- continue
- }
- tmpItem := respSlice[0:1][0]
- respSlice = respSlice[1:]
- pendantValue := ""
- pendantBgPic := ""
- pendantBgColor := ""
- if pendantRoomListResp != nil && pendantRoomListResp.Data != nil {
- pendantResult = pendantRoomListResp.Data.Result
- if pendantResult[tmpItem.Roomid] != nil {
- // 移动端取value, web取name
- pendantValue = pendantResult[tmpItem.Roomid].Value
- pendantBgPic = pendantResult[tmpItem.Roomid].BgPic
- if pendantResult[tmpItem.Roomid].BgColor != "" {
- pendantBgColor = pendantResult[tmpItem.Roomid].BgColor
- } else {
- pendantBgColor = _mobileIndexBadgeColorDefault
- }
- }
- }
- cover := ""
- if tmpItem.UserCover != "" {
- cover = tmpItem.UserCover
- } else {
- cover = tmpItem.Cover
- }
- resp = append(resp, &roomItem{
- RoomId: tmpItem.Roomid,
- Title: tmpItem.Title,
- Uname: tmpItem.Uname,
- Online: tmpItem.Online,
- Cover: cover,
- Link: "/" + strconv.Itoa(int(tmpItem.Roomid)),
- Face: tmpItem.Face,
- AreaV2ParentId: tmpItem.AreaV2ParentId,
- AreaV2ParentName: tmpItem.AreaV2ParentName,
- AreaV2Id: tmpItem.AreaV2Id,
- AreaV2Name: tmpItem.AreaV2Name,
- BroadcastType: tmpItem.BroadcastType,
- PendentRu: pendantValue,
- PendentRuPic: pendantBgPic,
- PendentRuColor: pendantBgColor,
- RecType: _recTypeSkyHorse,
- })
- }
- return
- }
- func (s *Service) isSkyHorseRec(mid int64) bool {
- lastMid := strconv.Itoa(int(mid % 100))
- if len(lastMid) < 2 {
- lastMid = "0" + lastMid
- }
- _, isSkyHorseGray := s.conf.SkyHorseGray[lastMid]
- return isSkyHorseGray
- }
- func (s *Service) getAllList(ctx context.Context) (json.RawMessage, error) {
- allListOut, err := dao.RoomRawApi.CallRaw(ctx, 2,
- "AppIndex.getAllRawList", &liverpc.Args{})
- if err != nil {
- log.Error("[getAllList]get all list rpc error, room.v2.AppIndex.getAllRawList, error:%+v", err)
- err = errors.WithMessage(ecode.GetAllListRPCError, "GET ALL LIST FAIL#1")
- return json.RawMessage{}, err
- }
- if allListOut == nil {
- log.Error("[getAllList]get all list raw data nil, room.v2.AppIndex.getAllRawList")
- err = errors.WithMessage(ecode.GetAllListRPCError, "GET ALL LIST FAIL#2")
- return json.RawMessage{}, err
- }
- if allListOut.Code != 0 || allListOut.Data == nil {
- log.Error("[getAllList]get all list return data error, code, %d, msg: %s, error:%+v", allListOut.Code, allListOut.Message, err)
- err = errors.WithMessage(ecode.GetAllListReturnError, "GET ALL LIST FAIL#3")
- return json.RawMessage{}, err
- }
- allListJSONObj, jsonErr := simplejson.NewJson(allListOut.Data)
- if jsonErr != nil {
- log.Error("[getAllList]get all list simplejson error, error:%+v", err)
- err = errors.WithMessage(ecode.GetAllListReturnError, "GET ALL LIST FAIL#4")
- return json.RawMessage{}, err
- }
- allListCache := allListJSONObj.Get("module_list").MustArray()
- if len(allListCache) > 1 && allListCache[1] == nil {
- log.Error("[getAllList]abnormal module, allListCache:%+v", allListCache)
- err = errors.WithMessage(ecode.GetAllListReturnError, "GET ALL LIST FAIL#5")
- return json.RawMessage{}, err
- }
- return allListOut.Data, nil
- }
- func (s *Service) tickCacheAllList(ctx context.Context) {
- ticker := time.NewTicker(5 * time.Second)
- for {
- select {
- case <-ticker.C:
- allListData, err := s.getAllList(ctx)
- if err != nil {
- log.Error("[tickCacheAllList] setAllList error(%+v)", err)
- continue
- }
- if len(allListData) <= 0 {
- log.Error("[tickCacheAllList] setAllList empty data(%+v)", allListData)
- continue
- }
- log.Info("[tickCacheAllList] setAllList success!")
- s.allListInfo.Store(allListData)
- }
- }
- }
- func (s *Service) getAllListFromCache(ctx context.Context) (allListCache []interface{}) {
- allListRawCache := s.allListInfo.Load()
- if allListRawCache == nil {
- log.Warn("[getAllListFromCache] cache miss!")
- allList, err := s.getAllList(ctx)
- if err != nil {
- log.Error("[getAllListFromCache] pass through error(%+v)", err)
- }
- allListRawCache = allList
- }
- allListJSONObj, err := simplejson.NewJson(allListRawCache.(json.RawMessage))
- if err != nil {
- log.Error("[getAllListFromCache]get all list simplejson error, error:%+v", err)
- return
- }
- allListCache = allListJSONObj.Get("module_list").MustArray()
- if allListCache[1] == nil {
- fmt.Printf("abnormal module, allListRawCache: %+v, module_list: %+v", allListRawCache, allListJSONObj.Get("module_list"))
- }
- log.Info("[getAllListFromCache] cache hit! len: %d", len(allListCache))
- return
- }
|