livehomepage.go 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578
  1. package v2
  2. import (
  3. "context"
  4. "math"
  5. "strconv"
  6. "go-common/app/service/live/third_api/bvc"
  7. "go-common/library/sync/errgroup"
  8. "github.com/pkg/errors"
  9. v2pb "go-common/app/interface/live/app-interface/api/http/v2"
  10. "go-common/app/interface/live/app-interface/conf"
  11. "go-common/app/interface/live/app-interface/dao"
  12. relationV1 "go-common/app/interface/live/app-interface/service/v1"
  13. relationT "go-common/app/interface/live/app-interface/service/v1/relation"
  14. avV1 "go-common/app/service/live/av/api/liverpc/v1"
  15. relationRpcV1 "go-common/app/service/live/relation/api/liverpc/v1"
  16. roomV1 "go-common/app/service/live/room/api/liverpc/v1"
  17. accountM "go-common/app/service/main/account/model"
  18. actmdl "go-common/app/service/main/account/model"
  19. account "go-common/app/service/main/account/rpc/client"
  20. "go-common/library/ecode"
  21. "go-common/library/log"
  22. )
  23. // RelationService struct
  24. type RelationService struct {
  25. conf *conf.Config
  26. accountRPC *account.Service3
  27. }
  28. const (
  29. relationPageSize = 4
  30. app536relationPageSize = 2
  31. )
  32. // CheckLiveAnchorParams ... implementation
  33. // [app端关注首页]入参校验
  34. func CheckLiveAnchorParams(ctx context.Context, page int64) (uid int64, relationPage int64, err error) {
  35. mid := relationT.GetUIDFromHeader(ctx)
  36. relationPage = page
  37. err = nil
  38. if mid == 0 {
  39. err = errors.WithMessage(ecode.NeedLogIn, "GET SEA PATROL FAIL")
  40. return
  41. }
  42. if page <= 0 {
  43. err = errors.WithMessage(ecode.ResourceParamErr, "GET SEA PATROL FAIL")
  44. return
  45. }
  46. return mid, relationPage, err
  47. }
  48. // LiveAnchorHomePage ... implementation
  49. // [app端关注首页]正在直播接口
  50. func (s *IndexService) LiveAnchorHomePage(ctx context.Context, relationPage int64, build int64, platform string, quality int64) (Resp []*v2pb.MMyIdol) {
  51. List := make([]*v2pb.MyIdolItem, 0)
  52. ExtraInfo := &v2pb.MyIdolExtra{CardType: relationT.App533CardType}
  53. Resp = make([]*v2pb.MMyIdol, 0)
  54. s.MakeLiveAnchorDefaultResult(Resp, ExtraInfo)
  55. uid, relationPage, err := CheckLiveAnchorParams(ctx, relationPage)
  56. if err != nil && uid != 0 {
  57. log.Error("[LiveAnchorHomePage]CheckParamsError,uid:%d,relationPage:%d", uid, relationPage)
  58. return
  59. }
  60. wg, _ := errgroup.WithContext(ctx)
  61. relationInfo, groupList, mapUfos2Rolaids, mapRoomID2UID, AllRoomID, err := relationV1.GetAttentionListAndGroup(ctx)
  62. if err != nil {
  63. log.Error("[LiveAnchorHomePage]get_attentionList_rpc_error")
  64. return
  65. }
  66. // 获取全量room信息,不过滤
  67. roomParams := &roomV1.RoomGetStatusInfoByUidsReq{Uids: groupList["all"], FilterOffline: 0, NeedBroadcastType: 1}
  68. // room
  69. roomResp := make(map[int64]*roomV1.RoomGetStatusInfoByUidsResp_RoomInfo)
  70. userResp := make(map[int64]*accountM.Card)
  71. roomCornerResp := make(map[int64]*roomV1.RoomPendantGetPendantByIdsResp_Result)
  72. pkResp := make(map[string]int64)
  73. wg.Go(func() error {
  74. roomResp, err = s.GetRoomInfo(ctx, roomParams)
  75. return err
  76. })
  77. if err = wg.Wait(); nil != err {
  78. log.Error("[LiveAnchorHomePage][first_step]get_room_rpc_error")
  79. return
  80. }
  81. livingUfos := make([]int64, 0)
  82. livingRolaids := make([]int64, 0)
  83. livingRoomInfo := GetLivingRooms(roomResp)
  84. // 没有人直播
  85. if len(livingRoomInfo) == 0 {
  86. GetLastLiveAnchorInfo(ctx, roomResp, AllRoomID, mapRoomID2UID, ExtraInfo)
  87. moduleInfoMap := s.GetAllModuleInfoMapFromCache(ctx)
  88. for _, m := range moduleInfoMap[_feedType] {
  89. Resp = append(Resp, &v2pb.MMyIdol{ModuleInfo: m, List: List, ExtraInfo: ExtraInfo})
  90. }
  91. return
  92. }
  93. wgHasLive := &errgroup.Group{}
  94. wgHasLive, _ = errgroup.WithContext(ctx)
  95. for k, v := range livingRoomInfo {
  96. livingUfos = append(livingUfos, k)
  97. livingRolaids = append(livingRolaids, v.RoomId)
  98. }
  99. // user信息
  100. wgHasLive.Go(func() error {
  101. userResp, err = s.GetUserInfo(ctx, livingUfos)
  102. return err
  103. })
  104. // room
  105. roomPendentParams := &roomV1.RoomPendantGetPendantByIdsReq{Ids: livingRolaids, Type: relationT.PendentMobileBadge, Position: relationT.PendentPosition}
  106. wgHasLive.Go(func() error {
  107. roomCornerResp, err = s.GetRoomPendantInfo(ctx, roomPendentParams)
  108. return err
  109. })
  110. // pk_id
  111. pkParams := &avV1.PkGetPkIdsByRoomIdsReq{RoomIds: livingRolaids, Platform: platform}
  112. wgHasLive.Go(func() error {
  113. pkResp, err = s.GetPkID(ctx, pkParams)
  114. return err
  115. })
  116. if err = wgHasLive.Wait(); nil != err {
  117. log.Error("[LiveAnchorHomePage][second_step]room/main.account/pkID/rpc_error")
  118. return
  119. }
  120. attentionRoomListPlayURLMap := dao.BvcApi.GetPlayUrlMulti(ctx, livingRolaids, 0, quality, build, platform)
  121. // 下游数据收集完成
  122. mapSp := make([]int64, 0)
  123. normalSp := make([]int64, 0)
  124. mapSp = append(mapSp, groupList["special"]...)
  125. normalSp = append(normalSp, groupList["normal"]...)
  126. List = AdaptLivingField(livingRoomInfo, roomCornerResp, userResp, relationInfo, pkResp, attentionRoomListPlayURLMap, mapSp, normalSp, mapUfos2Rolaids)
  127. ExtraInfo.TotalCount = int64(len(List))
  128. // 注释原因:app536灰度策略,需要恢复2卡样式(之前在535已全量4卡,但是需求变了)产品:古月
  129. // https://www.tapd.cn/20082211/prong/stories/view/1120082211001104459
  130. // userExtParams := &userExV1.GrayRuleGetByMarkReq{Mark: relationT.App536GrayRule}
  131. // grayRule, err := relationT.GetGrayRule(ctx, userExtParams)
  132. // var UserExApp536Rule string
  133. // if err != nil {
  134. // log.Error("[LiveAnchorHomePage]get_GrayRule_rpc_error")
  135. // UserExApp536Rule = ""
  136. // } else if grayRule != nil {
  137. // UserExApp536Rule = grayRule.Content
  138. // }
  139. SliceList, page := s.SliceForHomePage(List, relationPage, uid, platform)
  140. ExtraInfo.RelationPage = page
  141. var result v2pb.MMyIdol
  142. result.ExtraInfo = ExtraInfo
  143. result.List = SliceList
  144. moduleInfoMap := s.GetAllModuleInfoMapFromCache(ctx)
  145. for _, m := range moduleInfoMap[_feedType] {
  146. Resp = append(Resp, &v2pb.MMyIdol{ModuleInfo: m, List: result.List, ExtraInfo: result.ExtraInfo})
  147. }
  148. return
  149. }
  150. // AdaptLivingField ... implementation
  151. // [app端关注首页]填充数据
  152. func AdaptLivingField(roomInfo map[int64]*roomV1.RoomGetStatusInfoByUidsResp_RoomInfo,
  153. roomPendentInfo map[int64]*roomV1.RoomPendantGetPendantByIdsResp_Result,
  154. userResult map[int64]*accountM.Card,
  155. relationInfo map[int64]*relationRpcV1.BaseInfoGetFollowTypeResp_UidInfo,
  156. pkIDInfo map[string]int64, playURLInfo map[int64]*bvc.PlayUrlItem, specialUID []int64, normalUID []int64,
  157. mapUfos2Rolaids map[int64]int64) (resp []*v2pb.MyIdolItem) {
  158. resp = make([]*v2pb.MyIdolItem, 0)
  159. normalResp := make([]*v2pb.MyIdolItem, 0)
  160. resp = make([]*v2pb.MyIdolItem, 0)
  161. if len(specialUID) > 0 {
  162. item := LiveFireField(roomInfo, roomPendentInfo, userResult, pkIDInfo, playURLInfo, relationInfo, specialUID, mapUfos2Rolaids)
  163. resp = AppSortRuleOnline(item)
  164. }
  165. if len(normalUID) > 0 {
  166. tempResp := LiveFireField(roomInfo, roomPendentInfo, userResult, pkIDInfo, playURLInfo, relationInfo, normalUID, mapUfos2Rolaids)
  167. normalResp = AppSortRuleOnline(tempResp)
  168. }
  169. if len(normalResp) > 0 {
  170. resp = append(resp, normalResp...)
  171. }
  172. return
  173. }
  174. // SliceForHomePage ... implementation
  175. // app534规则 [app端关注首页]首页slice逻辑,客户端只显示偶数个数,为兼容推荐去重,当个数为3时返回2
  176. // https://www.tapd.cn/20082211/prong/stories/view/1120082211001067961
  177. // https://www.tapd.cn/20082211/prong/stories/view/1120082211001085685
  178. //
  179. // app536规则 https://www.tapd.cn/20082211/prong/stories/view/1120082211001104459
  180. func (s *IndexService) SliceForHomePage(input []*v2pb.MyIdolItem, page int64, uid int64, platform string) (resp []*v2pb.MyIdolItem, relationPage int64) {
  181. resp = make([]*v2pb.MyIdolItem, 0)
  182. grayRule := s.App536ABTest(uid, platform)
  183. relationPage = page
  184. if len(input) <= 0 {
  185. return
  186. }
  187. count := int64(len(input))
  188. // 536规则
  189. if grayRule == 1 {
  190. switch count {
  191. case 1:
  192. {
  193. resp = input[:]
  194. relationPage = 1
  195. return
  196. }
  197. case 2:
  198. {
  199. resp = input[:]
  200. relationPage = 1
  201. return
  202. }
  203. }
  204. var pageSize int64
  205. pageSize = page
  206. if page < 1 {
  207. pageSize = 1
  208. }
  209. start := (pageSize - 1) * app536relationPageSize
  210. end := int64(start + app536relationPageSize)
  211. // 正常slice
  212. if end <= count {
  213. resp = input[start:end]
  214. } else {
  215. // 回环逻辑,最后一页不足pagesize时返回第一页
  216. relationPage = 1
  217. startIndex := 0
  218. var startCount int64
  219. if count > app536relationPageSize {
  220. startCount = app536relationPageSize
  221. } else {
  222. startCount = count
  223. }
  224. resp = input[startIndex:startCount]
  225. }
  226. return
  227. }
  228. // 536之前4卡逻辑
  229. switch count {
  230. case 1:
  231. {
  232. resp = input[:]
  233. relationPage = 1
  234. return
  235. }
  236. case 2:
  237. {
  238. resp = input[:]
  239. relationPage = 1
  240. return
  241. }
  242. case 3:
  243. {
  244. resp = input[0:2]
  245. relationPage = 1
  246. return
  247. }
  248. }
  249. var pageSize int64
  250. pageSize = page
  251. if page < 1 {
  252. pageSize = 1
  253. }
  254. start := (pageSize - 1) * relationPageSize
  255. end := int64(start + relationPageSize)
  256. if end <= count {
  257. resp = input[start:end]
  258. } else {
  259. relationPage = 1
  260. startIndex := 0
  261. var startCount int64
  262. if count > relationPageSize {
  263. startCount = relationPageSize
  264. } else {
  265. startCount = count
  266. }
  267. resp = input[startIndex:startCount]
  268. }
  269. return
  270. }
  271. // LiveFireField ... implementation
  272. // [app端关注首页]填充数据
  273. func LiveFireField(roomInfo map[int64]*roomV1.RoomGetStatusInfoByUidsResp_RoomInfo,
  274. roomPendentInfo map[int64]*roomV1.RoomPendantGetPendantByIdsResp_Result,
  275. userResult map[int64]*accountM.Card,
  276. pkIDInfo map[string]int64, playURLInfo map[int64]*bvc.PlayUrlItem,
  277. relationInfo map[int64]*relationRpcV1.BaseInfoGetFollowTypeResp_UidInfo,
  278. ufos []int64, mapUfos2Rolaids map[int64]int64) (resp []*v2pb.MyIdolItem) {
  279. for _, v := range ufos {
  280. item := v2pb.MyIdolItem{}
  281. roomID, roomIDExist := mapUfos2Rolaids[v]
  282. if !roomIDExist {
  283. continue
  284. }
  285. roomItem := roomInfo[v]
  286. roomPendentItem := roomPendentInfo[roomID]
  287. userItem := userResult[v]
  288. relationItem := relationInfo[v]
  289. pkItem := pkIDInfo[strconv.Itoa(int(roomID))]
  290. playURLItem := playURLInfo[roomID]
  291. if roomItem == nil || userItem == nil || relationItem == nil {
  292. continue
  293. }
  294. PlayURL := ""
  295. PlayURL265 := ""
  296. PlayURLAcc := make([]int64, 0)
  297. PlayURLCur := 0
  298. PendentRu := ""
  299. PendentRuColor := ""
  300. PendentRuPic := ""
  301. if playURLItem != nil {
  302. PlayURL = playURLItem.Url["h264"]
  303. PlayURL265 = playURLItem.Url["h265"]
  304. PlayURLAcc = playURLItem.AcceptQuality
  305. PlayURLCur = int(playURLItem.CurrentQuality)
  306. }
  307. if roomPendentItem != nil {
  308. PendentRu = roomPendentItem.Value
  309. PendentRuColor = roomPendentItem.BgColor
  310. PendentRuPic = roomPendentItem.BgPic
  311. }
  312. item.Roomid = roomItem.RoomId
  313. item.Uid = roomItem.Uid
  314. item.Uname = userItem.Name
  315. item.Face = userItem.Face
  316. item.Title = roomItem.Title
  317. item.LiveTagName = roomItem.AreaV2Name
  318. item.LiveTime = roomItem.LiveTime
  319. item.Online = roomItem.Online
  320. item.PlayUrl = PlayURL
  321. item.PlayUrlH265 = PlayURL265
  322. item.AcceptQuality = PlayURLAcc
  323. item.CurrentQuality = int64(PlayURLCur)
  324. item.PkId = pkItem
  325. item.Area = roomItem.Area
  326. item.AreaName = roomItem.AreaName
  327. item.AreaV2Id = roomItem.AreaV2Id
  328. item.AreaV2Name = roomItem.AreaV2Name
  329. item.AreaV2ParentId = roomItem.AreaV2ParentId
  330. item.AreaV2ParentName = roomItem.AreaV2ParentName
  331. item.BroadcastType = roomItem.BroadcastType
  332. item.Link = relationT.LiveDomain + strconv.Itoa(int(roomID)) + relationT.BoastURL + strconv.Itoa(int(item.BroadcastType))
  333. item.OfficialVerify = int64(RoleMap(userItem.Official.Role))
  334. item.SpecialAttention = relationItem.Special
  335. item.PendentRu = PendentRu
  336. item.PendentRuColor = PendentRuColor
  337. item.PendentRuPic = PendentRuPic
  338. if len(roomItem.CoverFromUser) == 0 {
  339. item.Cover = roomItem.Keyframe
  340. } else {
  341. item.Cover = roomItem.CoverFromUser
  342. }
  343. resp = append(resp, &item)
  344. }
  345. return
  346. }
  347. // MakeLiveAnchorDefaultResult ...
  348. // 正在直播默认返回
  349. func (s *IndexService) MakeLiveAnchorDefaultResult(Resp []*v2pb.MMyIdol, ExtraInfo *v2pb.MyIdolExtra) {
  350. if ExtraInfo != nil {
  351. ExtraInfo.TotalCount = 0
  352. ExtraInfo.TagsDesc = ""
  353. ExtraInfo.UnameDesc = ""
  354. ExtraInfo.TimeDesc = ""
  355. // [历史原因]cardType只能为1,否则客户端报错,见 https://www.tapd.cn/20082211/prong/stories/view/1120082211001086997
  356. ExtraInfo.CardType = 1
  357. ExtraInfo.RelationPage = 1
  358. }
  359. moduleInfoMap := s.GetAllModuleInfoMapFromCache(context.TODO())
  360. for _, m := range moduleInfoMap[_feedType] {
  361. Resp = append(Resp, &v2pb.MMyIdol{ModuleInfo: m, List: []*v2pb.MyIdolItem{}, ExtraInfo: ExtraInfo})
  362. }
  363. }
  364. // GetLivingRooms ... implementation
  365. // [app端关注首页]获取正在直播房间
  366. func GetLivingRooms(roomResult map[int64]*roomV1.RoomGetStatusInfoByUidsResp_RoomInfo) (liveRoom map[int64]*roomV1.RoomGetStatusInfoByUidsResp_RoomInfo) {
  367. liveRoom = make(map[int64]*roomV1.RoomGetStatusInfoByUidsResp_RoomInfo)
  368. if len(roomResult) == 0 {
  369. return
  370. }
  371. for k, v := range roomResult {
  372. if v.LiveStatus == relationV1.RoomStatusLive {
  373. liveRoom[k] = v
  374. }
  375. }
  376. return
  377. }
  378. // CheckLiveAnchorParams implementation
  379. // 入参校验
  380. func (s *IndexService) CheckLiveAnchorParams(ctx context.Context, req *v2pb.GetAllListReq) (uid int64, relationPage int64, err error) {
  381. if req == nil {
  382. err = ecode.LiveAnchorReqV2ParamsNil
  383. return
  384. }
  385. uid = relationT.GetUIDFromHeader(ctx)
  386. if uid == 0 {
  387. err = errors.WithMessage(ecode.NeedLogIn, "GET SEA PATROL FAIL")
  388. return
  389. }
  390. if req.RelationPage <= 0 {
  391. log.Error("CallRelationLiveAnchorV2ParamsCheckError|relationPage:%d", req.RelationPage)
  392. err = errors.WithMessage(ecode.LiveAnchorReqV2ParamsError, "GET SEA PATROL FAIL")
  393. return
  394. }
  395. return
  396. }
  397. // GetLastLiveAnchorInfo ... implementation
  398. // [app端关注首页]获取最新一次直播信息
  399. func GetLastLiveAnchorInfo(ctx context.Context, roomResult map[int64]*roomV1.RoomGetStatusInfoByUidsResp_RoomInfo,
  400. RoomIDs []int64, RoomID2UID map[int64]int64, ExtraInfo *v2pb.MyIdolExtra) (uid int64, relationPage int64, err error) {
  401. if len(roomResult) == 0 || len(RoomIDs) == 0 || len(RoomID2UID) == 0 {
  402. return
  403. }
  404. lastLiveTime, _ := relationT.GetLastLiveTime(ctx, RoomIDs)
  405. _, _, sorted := relationV1.GetLastAnchorLiveTime(lastLiveTime)
  406. var firstRoom int64
  407. var firstValue int64
  408. if sorted.Len() > 0 {
  409. for _, v := range sorted {
  410. firstRoom = int64(v.Key)
  411. firstValue = int64(v.Value)
  412. break
  413. }
  414. firstUID := int64(RoomID2UID[firstRoom])
  415. tempTime := make(map[int64]int64)
  416. if firstValue > 0 {
  417. tempTime[firstUID] = firstValue
  418. if roomItem, exist := roomResult[firstUID]; exist {
  419. ExtraInfo.UnameDesc = roomItem.Uname
  420. ExtraInfo.TagsDesc = roomItem.AreaV2Name
  421. liveDesc, _ := relationV1.TimeLineRule(tempTime, nil)
  422. ExtraInfo.TimeDesc = liveDesc[firstUID]
  423. }
  424. }
  425. }
  426. return
  427. }
  428. // GetUserInfoData ...
  429. // 调用account grpc接口cards获取用户信息
  430. func (s *RelationService) GetUserInfoData(ctx context.Context, UIDs []int64) (userResult map[int64]*accountM.Card, err error) {
  431. rpcChunkSize, RPCTimeout, err := relationT.GetChunkInfo(relationT.AccountGRPC)
  432. params := relationT.ChunkCallInfo{ParamsName: "ufos", URLName: relationT.AccountGRPC, ChunkSize: rpcChunkSize, RPCTimeout: RPCTimeout}
  433. userResult = make(map[int64]*accountM.Card)
  434. lens := len(UIDs)
  435. if lens <= 0 {
  436. return
  437. }
  438. // 批次
  439. params.ChunkNum = int64(math.Ceil(float64(lens) / float64(params.ChunkSize)))
  440. chunkResult := make([]map[int64]*accountM.Card, params.ChunkNum)
  441. wg, _ := errgroup.WithContext(ctx)
  442. for i := int64(1); i <= params.ChunkNum; i++ {
  443. x := i
  444. wg.Go(func() error {
  445. chunkUfosIds := make([]int64, 20)
  446. if x == params.ChunkNum {
  447. chunkUfosIds = UIDs[(x-1)*params.ChunkSize:]
  448. } else {
  449. chunkUfosIds = UIDs[(x-1)*params.ChunkSize : x*params.ChunkSize]
  450. }
  451. ret, err := s.accountRPC.Cards3(ctx, &actmdl.ArgMids{Mids: chunkUfosIds})
  452. if err != nil {
  453. err = errors.WithMessage(ecode.AccountGRPCError, "GET SEA PATROL FAIL")
  454. log.Error("Call main.Account.Cards Error.Infos(%+v) error(%+v)", chunkUfosIds, err)
  455. }
  456. chunkResult[x-1] = ret
  457. return nil
  458. })
  459. }
  460. if err := wg.Wait(); err != nil {
  461. erelongInfo := relationT.ErrLogStrut{}
  462. erelongInfo.ErrType = "GoRoutingWaitError"
  463. erelongInfo.URLName = relationT.AccountGRPC
  464. erelongInfo.ErrDesc = relationT.GoRoutingErr
  465. erelongInfo.Code = 1003001
  466. erelongInfo.RPCTimeout = params.RPCTimeout
  467. erelongInfo.ErrorPtr = &err
  468. log.Error(erelongInfo.ErrType+"|"+erelongInfo.URLName+"|error:%+v"+"|Code:%d"+"|Msg:%s"+"|RPCTimeout:%d"+"|ChunkSize:%d"+"|ChunkNum:%d"+"|ParamsName:%s",
  469. *erelongInfo.ErrorPtr, erelongInfo.Code, erelongInfo.Msg, erelongInfo.RPCTimeout, erelongInfo.ChunkSize, erelongInfo.ChunkNum, params.ParamsName)
  470. err = errors.WithMessage(ecode.AccountGRPCFrameError, "GET SEA PATROL FAIL")
  471. return nil, err
  472. }
  473. // 整理数据
  474. for _, chunkItemList := range chunkResult {
  475. for _, item := range chunkItemList {
  476. if item != nil {
  477. userResult[item.Mid] = item
  478. }
  479. }
  480. }
  481. return
  482. }
  483. // App536ABTest ... hard code配置
  484. // ABTest
  485. func (s *IndexService) App536ABTest(mid int64, platform string) (grayType int64) {
  486. // 因为ipad屏幕尺寸较大,展示2卡会影响体验,故如果是ipad客户端则使用4卡样式,产品:tianyumo
  487. if platform == "ipad" {
  488. return 0
  489. }
  490. mUID := mid % 100
  491. if mUID >= 0 && mUID <= 89 {
  492. // 4卡
  493. return 0
  494. }
  495. return 1
  496. }
  497. // 后台配置
  498. // // App536ABTest ...
  499. // // ABTest
  500. // func (s *IndexService) App536ABTest(content string, mid int64) (grayType int64) {
  501. // if len(content) == 0 {
  502. // grayType = 0
  503. // return
  504. // }
  505. // resultMap := make(map[string]int64)
  506. // resultMap["app536_4card_type"] = 0
  507. // resultMap["app536_2card_type"] = 1
  508. // typeMap := make([]string, 0)
  509. // mr := &[]GrayRule{}
  510. // if err := json.Unmarshal([]byte(content), mr); err != nil {
  511. // grayType = 0
  512. // return
  513. // }
  514. // ruleArr := *mr
  515. // scoreMap := make(map[string]int)
  516. //
  517. // for _, v := range ruleArr {
  518. // scoreMap[v.Mark] = int(RParseInt(v.Value, 100))
  519. // }
  520. // sortedScore := SortMapByValue(scoreMap)
  521. // scoreEnd := make([]int, 0)
  522. // for _, v := range sortedScore {
  523. // scoreEnd = append(scoreEnd, v.Value)
  524. // typeMap = append(typeMap, v.Key)
  525. // }
  526. // score1 := scoreEnd[0]
  527. // score2 := 100
  528. // section1 := make(map[int]bool)
  529. // section2 := make(map[int]bool)
  530. // for section1Loop := 0; section1Loop < score1; section1Loop++ {
  531. // section1[section1Loop] = true
  532. // }
  533. // for sectionLoop2 := score1; sectionLoop2 < score2; sectionLoop2++ {
  534. // section2[sectionLoop2] = true
  535. // }
  536. // result := int(mid % 100)
  537. // if scoreEnd[0] != 0 {
  538. // if _, exist := section1[result]; exist {
  539. // grayType = resultMap[typeMap[0]]
  540. // return
  541. // }
  542. // }
  543. // if scoreEnd[1] != 0 {
  544. // if _, exist := section2[result]; exist {
  545. // grayType = resultMap[typeMap[1]]
  546. // return
  547. // }
  548. // }
  549. // grayType = 0
  550. // return
  551. // }