like.go 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780
  1. package like
  2. import (
  3. "bytes"
  4. "context"
  5. "strconv"
  6. "sync"
  7. dao "go-common/app/interface/main/activity/dao/like"
  8. likemdl "go-common/app/interface/main/activity/model/like"
  9. tagmdl "go-common/app/interface/main/tag/model"
  10. "go-common/app/service/main/archive/api"
  11. "go-common/app/service/main/archive/model/archive"
  12. thpmdl "go-common/app/service/main/thumbup/model"
  13. "go-common/library/ecode"
  14. "go-common/library/log"
  15. "go-common/library/sync/errgroup"
  16. "go-common/library/xstr"
  17. )
  18. const (
  19. _aidBulkSize = 100
  20. _tagBlkSize = 50
  21. _tagArcType = 3
  22. _tagLikePoint = 100
  23. _orderTypeCtime = "ctime"
  24. _orderTypeRandom = "random"
  25. _specialLikeRate = 1000
  26. _businessLike = "archive"
  27. )
  28. var (
  29. _emptyLikeList = make([]*likemdl.Like, 0)
  30. _emptyArcs = make([]*api.Arc, 0)
  31. )
  32. // UpdateActSourceList update act arc list.
  33. func (s *Service) updateActSourceList(c context.Context, sid int64, typ string) (err error) {
  34. var (
  35. likes []*likemdl.Item
  36. )
  37. if likes, err = s.dao.LikeList(c, sid); err != nil {
  38. log.Error("UpdateActSourceList s.dao.LikeList(%d) error(%v)", sid, err)
  39. return
  40. }
  41. s.cache.Do(c, func(c context.Context) {
  42. if typ == _typeAll {
  43. s.updateActCacheList(c, sid, likes)
  44. }
  45. if typ == _typeRegion {
  46. s.updateActRegionList(c, sid, likes)
  47. }
  48. })
  49. return
  50. }
  51. func (s *Service) updateActCacheList(c context.Context, sid int64, likes []*likemdl.Item) (err error) {
  52. var (
  53. aids []int64
  54. tags map[int64][]*tagmdl.Tag
  55. arcs map[int64]*api.Arc
  56. )
  57. likeMap := make(map[int64]*likemdl.Item, len(likes))
  58. for _, v := range likes {
  59. if v.Wid > 0 {
  60. aids = append(aids, v.Wid)
  61. likeMap[v.Wid] = v
  62. }
  63. }
  64. if len(aids) == 0 {
  65. return
  66. }
  67. if tags, err = s.arcTags(c, aids); err != nil {
  68. return
  69. }
  70. if arcs, err = s.archives(c, aids); err != nil {
  71. return
  72. }
  73. arcTagMap := make(map[int64][]*likemdl.Item, len(s.dialectTags))
  74. tagLikePtTmp := make(map[int64]int32, len(s.dialectTags))
  75. for aid, arcTag := range tags {
  76. for _, tag := range arcTag {
  77. if _, ok := s.dialectTags[tag.ID]; ok {
  78. arcTagMap[tag.ID] = append(arcTagMap[tag.ID], likeMap[aid])
  79. if arc, ok := arcs[aid]; ok && arc.IsNormal() {
  80. tagLikePtTmp[tag.ID] += arc.Stat.Like
  81. }
  82. }
  83. }
  84. }
  85. tagPtMap := make(map[int64]int32, len(s.dialectTags))
  86. for tagID, v := range arcTagMap {
  87. s.dao.SetLikeTagCache(c, sid, tagID, v)
  88. if like, ok := tagLikePtTmp[tagID]; ok {
  89. tagPt := int32(len(v)*_tagLikePoint) + like
  90. tagPtMap[tagID] = tagPt
  91. }
  92. }
  93. s.dao.SetTagLikeCountsCache(c, sid, tagPtMap)
  94. regionMap := make(map[int16][]*likemdl.Item, len(s.dialectRegions))
  95. for _, arc := range arcs {
  96. if region, ok := s.arcType[int16(arc.TypeID)]; ok {
  97. if _, ok := s.dialectRegions[region.Pid]; ok {
  98. regionMap[region.Pid] = append(regionMap[region.Pid], likeMap[arc.Aid])
  99. }
  100. }
  101. }
  102. for rid, v := range regionMap {
  103. s.dao.SetLikeRegionCache(c, sid, rid, v)
  104. }
  105. return
  106. }
  107. func (s *Service) updateActRegionList(c context.Context, sid int64, likes []*likemdl.Item) (err error) {
  108. var (
  109. aids []int64
  110. arcs map[int64]*api.Arc
  111. )
  112. likeMap := make(map[int64]*likemdl.Item, len(likes))
  113. for _, v := range likes {
  114. if v.Wid > 0 {
  115. aids = append(aids, v.Wid)
  116. likeMap[v.Wid] = v
  117. }
  118. }
  119. if len(aids) == 0 {
  120. return
  121. }
  122. if arcs, err = s.archives(c, aids); err != nil {
  123. return
  124. }
  125. regionMap := make(map[int16][]*likemdl.Item)
  126. for _, arc := range arcs {
  127. if region, ok := s.arcType[int16(arc.TypeID)]; ok {
  128. regionMap[region.Pid] = append(regionMap[region.Pid], likeMap[arc.Aid])
  129. }
  130. }
  131. for rid, v := range regionMap {
  132. s.dao.SetLikeRegionCache(c, sid, rid, v)
  133. }
  134. return
  135. }
  136. func (s *Service) archives(c context.Context, aids []int64) (archives map[int64]*api.Arc, err error) {
  137. var (
  138. mutex = sync.Mutex{}
  139. aidsLen = len(aids)
  140. group, errCtx = errgroup.WithContext(c)
  141. )
  142. archives = make(map[int64]*api.Arc, aidsLen)
  143. for i := 0; i < aidsLen; i += _aidBulkSize {
  144. var partAids []int64
  145. if i+_aidBulkSize > aidsLen {
  146. partAids = aids[i:]
  147. } else {
  148. partAids = aids[i : i+_aidBulkSize]
  149. }
  150. group.Go(func() (err error) {
  151. var arcs map[int64]*api.Arc
  152. arg := &archive.ArgAids2{Aids: partAids}
  153. if arcs, err = s.arcRPC.Archives3(errCtx, arg); err != nil {
  154. log.Error("s.arcRPC.Archives(%v) error(%v)", partAids, err)
  155. return
  156. }
  157. mutex.Lock()
  158. for _, v := range arcs {
  159. archives[v.Aid] = v
  160. }
  161. mutex.Unlock()
  162. return
  163. })
  164. }
  165. err = group.Wait()
  166. return
  167. }
  168. func (s *Service) arcTags(c context.Context, aids []int64) (tags map[int64][]*tagmdl.Tag, err error) {
  169. var (
  170. tagErr error
  171. mutex = sync.Mutex{}
  172. )
  173. group, errCtx := errgroup.WithContext(c)
  174. aidsLen := len(aids)
  175. tags = make(map[int64][]*tagmdl.Tag, aidsLen)
  176. for i := 0; i < aidsLen; i += _tagBlkSize {
  177. var partAids []int64
  178. if i+_tagBlkSize > aidsLen {
  179. partAids = aids[i:]
  180. } else {
  181. partAids = aids[i : i+_tagBlkSize]
  182. }
  183. group.Go(func() (err error) {
  184. var tmpRes map[int64][]*tagmdl.Tag
  185. arg := &tagmdl.ArgResTags{Oids: partAids, Type: _tagArcType}
  186. if tmpRes, tagErr = s.tagRPC.ResTags(errCtx, arg); tagErr != nil {
  187. dao.PromError("ResTags接口错误", "s.tag.ResTag(%+v) error(%v)", arg, tagErr)
  188. return
  189. }
  190. mutex.Lock()
  191. for aid, tmpTags := range tmpRes {
  192. tags[aid] = tmpTags
  193. }
  194. mutex.Unlock()
  195. return nil
  196. })
  197. }
  198. group.Wait()
  199. return
  200. }
  201. // TagArcList tag arc list.
  202. func (s *Service) TagArcList(c context.Context, sid, tagID int64, pn, ps int, typ, ip string) (list []*likemdl.Like, cnt int, err error) {
  203. var (
  204. likes []*likemdl.Item
  205. start, end int
  206. aids []int64
  207. archives map[int64]*api.Arc
  208. )
  209. if sid != s.c.Rule.DialectSid {
  210. err = ecode.RequestErr
  211. return
  212. }
  213. if _, ok := s.dialectTags[tagID]; !ok {
  214. err = ecode.RequestErr
  215. return
  216. }
  217. if cnt, err = s.dao.LikeTagCnt(c, sid, tagID); err != nil {
  218. log.Error("TagArcList s.dao.LikeTagCnt sid(%d) tagID(%d) error(%v)", sid, tagID, err)
  219. return
  220. }
  221. if start, end, err = s.fmtStartEnd(pn, ps, cnt, typ); err != nil {
  222. err = nil
  223. list = _emptyLikeList
  224. return
  225. }
  226. if likes, err = s.dao.LikeTagCache(c, sid, tagID, start, end); err != nil {
  227. log.Error("TagArcList s.dao.LikeTagCache sid(%d) tagID(%d) start(%d) end(%d) error(%+v)", sid, tagID, start, end, err)
  228. return
  229. }
  230. for _, v := range likes {
  231. if v.Wid > 0 {
  232. aids = append(aids, v.Wid)
  233. }
  234. }
  235. if len(aids) == 0 {
  236. list = _emptyLikeList
  237. return
  238. }
  239. if archives, err = s.arcRPC.Archives3(c, &archive.ArgAids2{Aids: aids, RealIP: ip}); err != nil {
  240. log.Error("TagArcList s.arcRPC.Archives3 aids(%v) error(%+v)", aids, err)
  241. return
  242. }
  243. for _, v := range likes {
  244. if arc, ok := archives[v.Wid]; ok && arc.IsNormal() {
  245. list = append(list, &likemdl.Like{Item: v, Archive: arc})
  246. }
  247. }
  248. l := len(list)
  249. if l == 0 {
  250. list = _emptyLikeList
  251. return
  252. }
  253. if typ == _orderTypeRandom {
  254. s.shuffle(l, func(i, j int) {
  255. list[i], list[j] = list[j], list[i]
  256. })
  257. }
  258. return
  259. }
  260. // RegionArcList region arc list.
  261. func (s *Service) RegionArcList(c context.Context, sid int64, rid int16, pn, ps int, typ, ip string) (list []*likemdl.Like, cnt int, err error) {
  262. var (
  263. likes []*likemdl.Item
  264. start, end int
  265. aids []int64
  266. archives map[int64]*api.Arc
  267. )
  268. if sid != s.c.Rule.DialectSid {
  269. err = ecode.RequestErr
  270. return
  271. }
  272. if _, ok := s.dialectRegions[rid]; !ok {
  273. err = ecode.RequestErr
  274. return
  275. }
  276. if cnt, err = s.dao.LikeRegionCnt(c, sid, rid); err != nil {
  277. log.Error("RegionArcList s.dao.LikeRegionCnt sid(%d) rid(%d) error(%v)", sid, rid, err)
  278. return
  279. }
  280. if start, end, err = s.fmtStartEnd(pn, ps, cnt, typ); err != nil {
  281. err = nil
  282. list = _emptyLikeList
  283. return
  284. }
  285. if likes, err = s.dao.LikeRegionCache(c, sid, rid, start, end); err != nil {
  286. log.Error("RegionArcList s.dao.LikeRegionCache sid(%d) rid(%d) start(%d) end(%d) error(%+v)", sid, rid, start, end, err)
  287. return
  288. }
  289. for _, v := range likes {
  290. if v.Wid > 0 {
  291. aids = append(aids, v.Wid)
  292. }
  293. }
  294. if len(aids) == 0 {
  295. list = _emptyLikeList
  296. return
  297. }
  298. if archives, err = s.arcRPC.Archives3(c, &archive.ArgAids2{Aids: aids, RealIP: ip}); err != nil {
  299. log.Error("RegionArcList s.arcRPC.Archives3 aids(%v) error(%+v)", aids, err)
  300. return
  301. }
  302. for _, v := range likes {
  303. if arc, ok := archives[v.Wid]; ok && arc.IsNormal() {
  304. list = append(list, &likemdl.Like{Item: v, Archive: arc})
  305. }
  306. }
  307. l := len(list)
  308. if l == 0 {
  309. list = _emptyLikeList
  310. return
  311. }
  312. if typ == _orderTypeRandom {
  313. s.shuffle(l, func(i, j int) {
  314. list[i], list[j] = list[j], list[i]
  315. })
  316. }
  317. return
  318. }
  319. // TagLikeCounts .
  320. func (s *Service) TagLikeCounts(c context.Context, sid int64) (data map[int64]int32, err error) {
  321. if sid != s.c.Rule.DialectSid {
  322. err = ecode.RequestErr
  323. return
  324. }
  325. return s.dao.TagLikeCountsCache(c, sid, s.c.Rule.DialectTags)
  326. }
  327. func (s *Service) fmtStartEnd(pn, ps, cnt int, typ string) (start, end int, err error) {
  328. if typ == _orderTypeCtime {
  329. start = (pn - 1) * ps
  330. end = start + ps - 1
  331. if start > cnt {
  332. err = ecode.NothingFound
  333. return
  334. }
  335. if end > cnt {
  336. end = cnt
  337. }
  338. } else {
  339. if ps >= cnt-1 {
  340. start = 0
  341. } else {
  342. start = s.r.Intn(cnt - ps - 1)
  343. }
  344. end = start + ps - 1
  345. }
  346. return
  347. }
  348. func (s *Service) shuffle(l int, swap func(i, j int)) {
  349. for i := l - 1; i > 0; i-- {
  350. j := s.r.Intn(i + 1)
  351. swap(i, j)
  352. }
  353. }
  354. // LikeInitialize initialize like cache data .
  355. func (s *Service) LikeInitialize(c context.Context, lid int64) (err error) {
  356. if lid < 0 {
  357. lid = 0
  358. }
  359. var likesItem []*likemdl.Item
  360. for {
  361. if likesItem, err = s.dao.LikeListMoreLid(c, lid); err != nil {
  362. log.Error("dao.LikeInitialize(%d) error(%+v)", lid, err)
  363. break
  364. }
  365. if len(likesItem) == 0 {
  366. log.Info("LikeInitialize end success")
  367. break
  368. }
  369. for _, val := range likesItem {
  370. item := val
  371. if lid < item.ID {
  372. lid = item.ID
  373. }
  374. id := item.ID
  375. //the likes offline is stored with empty data
  376. if item.State != 1 {
  377. item = &likemdl.Item{}
  378. }
  379. s.cache.Do(c, func(c context.Context) {
  380. s.dao.AddCacheLike(c, id, item)
  381. })
  382. }
  383. }
  384. s.cache.Do(c, func(c context.Context) {
  385. s.LikeMaxIDInitialize(c)
  386. })
  387. return
  388. }
  389. // LikeMaxIDInitialize likes max id initialize
  390. func (s *Service) LikeMaxIDInitialize(c context.Context) (err error) {
  391. var likeItem *likemdl.Item
  392. if likeItem, err = s.dao.LikeMaxID(c); err != nil {
  393. log.Error("s.dao.LikeMaxID() error(%+v)", err)
  394. return
  395. }
  396. if likeItem.ID >= 0 {
  397. if err = s.dao.AddCacheLikeMaxID(c, likeItem.ID); err != nil {
  398. log.Error("s.dao.AddCacheLikeMaxID(%d),error(%v)", likeItem.ID, err)
  399. }
  400. }
  401. return
  402. }
  403. // LikeUp update likes cache and like maxID cache
  404. func (s *Service) LikeUp(c context.Context, lid int64) (err error) {
  405. var (
  406. likeItem *likemdl.Item
  407. likeMaxID int64
  408. )
  409. group, ctx := errgroup.WithContext(c)
  410. group.Go(func() (e error) {
  411. if likeItem, e = s.dao.RawLike(ctx, lid); e != nil {
  412. log.Error("LikeUp:s.dao.RawLike(%d) error(%+v)", lid, e)
  413. }
  414. return
  415. })
  416. group.Go(func() (e error) {
  417. if likeMaxID, e = s.dao.CacheLikeMaxID(ctx); e != nil {
  418. log.Error("LikeUp:s.dao.CacheLikeMaxID() error(%v)", e)
  419. }
  420. return
  421. })
  422. if err = group.Wait(); err != nil {
  423. log.Error("LikeUp: group.Wait() error(%v)", err)
  424. return
  425. }
  426. if likeMaxID < lid {
  427. s.cache.Do(c, func(c context.Context) {
  428. s.dao.AddCacheLikeMaxID(c, lid)
  429. })
  430. }
  431. if likeItem.ID == 0 {
  432. likeItem = &likemdl.Item{}
  433. }
  434. s.cache.Do(c, func(c context.Context) {
  435. s.dao.AddCacheLike(c, lid, likeItem)
  436. })
  437. return
  438. }
  439. // AddLikeCtimeCache add cache .
  440. func (s *Service) AddLikeCtimeCache(c context.Context, lid int64) (err error) {
  441. var (
  442. likeItem *likemdl.Item
  443. cItems = make([]*likemdl.Item, 0, 1)
  444. )
  445. if likeItem, err = s.dao.RawLike(c, lid); err != nil {
  446. log.Error("LikeUp:s.dao.RawLike(%d) error(%+v)", lid, err)
  447. return
  448. }
  449. if likeItem.ID > 0 {
  450. eg, errCtx := errgroup.WithContext(c)
  451. cItems = append(cItems, likeItem)
  452. eg.Go(func() (e error) {
  453. e = s.dao.LikeListCtime(errCtx, likeItem.Sid, cItems)
  454. return
  455. })
  456. eg.Go(func() (e error) {
  457. // 初始化排行榜数据
  458. e = s.dao.SetRedisCache(c, likeItem.Sid, lid, 0, likeItem.Type)
  459. return
  460. })
  461. if err = eg.Wait(); err != nil {
  462. log.Error("AddLikeCtimeCache eg.Wait() error(%+v)", err)
  463. }
  464. }
  465. return
  466. }
  467. // DelLikeCtimeCache delete ctime cache.
  468. func (s *Service) DelLikeCtimeCache(c context.Context, lid, sid int64, likeType int) (err error) {
  469. var (
  470. cItems = make([]*likemdl.Item, 0, 1)
  471. )
  472. likeItem := &likemdl.Item{
  473. ID: lid,
  474. Sid: sid,
  475. Type: likeType,
  476. }
  477. cItems = append(cItems, likeItem)
  478. if err = s.dao.DelLikeListCtime(c, likeItem.Sid, cItems); err != nil {
  479. log.Error("s.dao.DelLikeListCtime(%v) error (%v)", likeItem, err)
  480. }
  481. return
  482. }
  483. // SubjectStat get subject stat .
  484. func (s *Service) SubjectStat(c context.Context, sid int64) (score *likemdl.SubjectScore, err error) {
  485. if sid == s.c.Rule.S8Sid {
  486. var arcScore, artScore int64
  487. group, errCtx := errgroup.WithContext(c)
  488. group.Go(func() error {
  489. var (
  490. stat *likemdl.SubjectStat
  491. arcErr error
  492. )
  493. if stat, arcErr = s.dao.CacheSubjectStat(errCtx, s.c.Rule.S8ArcSid); arcErr != nil {
  494. log.Error("s.dao.CacheSubjectStat sid(%d) error(%v)", sid, arcErr)
  495. }
  496. if stat == nil {
  497. stat = new(likemdl.SubjectStat)
  498. }
  499. arcScore = stat.Count*_specialLikeRate + stat.Like
  500. return nil
  501. })
  502. group.Go(func() error {
  503. var (
  504. stat *likemdl.SubjectStat
  505. artErr error
  506. )
  507. if stat, artErr = s.dao.CacheSubjectStat(errCtx, s.c.Rule.S8ArtSid); artErr != nil {
  508. log.Error("s.dao.CacheSubjectStat sid(%d) error(%v)", sid, artErr)
  509. }
  510. if stat == nil {
  511. stat = new(likemdl.SubjectStat)
  512. }
  513. artScore = stat.Count*_specialLikeRate + stat.Like
  514. return nil
  515. })
  516. group.Wait()
  517. score = &likemdl.SubjectScore{Score: arcScore + artScore}
  518. } else {
  519. var stat *likemdl.SubjectStat
  520. if stat, err = s.dao.CacheSubjectStat(c, sid); err != nil {
  521. log.Error("s.dao.CacheSubjectStat sid(%d) error(%v)", sid, err)
  522. err = nil
  523. }
  524. if stat == nil {
  525. stat = new(likemdl.SubjectStat)
  526. }
  527. if sid == s.c.Rule.KingStorySid {
  528. score = &likemdl.SubjectScore{Score: stat.View + stat.Fav + stat.Coin + stat.Like}
  529. } else {
  530. score = &likemdl.SubjectScore{Score: stat.Count*_specialLikeRate + stat.Like}
  531. }
  532. }
  533. return
  534. }
  535. // SetSubjectStat set subject stat .
  536. func (s *Service) SetSubjectStat(c context.Context, stat *likemdl.SubjectStat) (err error) {
  537. return s.dao.AddCacheSubjectStat(c, stat.Sid, stat)
  538. }
  539. // ViewRank get view rank arcs.
  540. func (s *Service) ViewRank(c context.Context, sid int64, pn, ps int) (list []*api.Arc, count int, err error) {
  541. var (
  542. aidsCache string
  543. aids, pieceAids []int64
  544. arcs map[int64]*api.Arc
  545. )
  546. if aidsCache, err = s.dao.CacheViewRank(c, sid); err != nil {
  547. log.Error("ViewRank s.dao.CacheViewRank(%d) error(%v)", sid, err)
  548. return
  549. }
  550. if aids, err = xstr.SplitInts(aidsCache); err != nil {
  551. log.Error("ViewRank xstr.SplitInts(%d,%s) error(%v)", sid, aidsCache, err)
  552. return
  553. }
  554. count = len(aids)
  555. start := (pn - 1) * ps
  556. end := start + ps - 1
  557. if count < start {
  558. list = _emptyArcs
  559. return
  560. }
  561. if count > end {
  562. pieceAids = aids[start : end+1]
  563. } else {
  564. pieceAids = aids[start:]
  565. }
  566. if arcs, err = s.arcRPC.Archives3(c, &archive.ArgAids2{Aids: pieceAids}); err != nil {
  567. log.Error("ViewRank s.arcRPC.Archives3(%v) error(%v)", aids, err)
  568. return
  569. }
  570. for _, aid := range pieceAids {
  571. if arc, ok := arcs[aid]; ok && arc.IsNormal() {
  572. list = append(list, arc)
  573. }
  574. }
  575. if len(list) == 0 {
  576. list = _emptyArcs
  577. }
  578. return
  579. }
  580. // SetViewRank set view rank arcs.
  581. func (s *Service) SetViewRank(c context.Context, sid int64, aids []int64) (err error) {
  582. aidsStr := xstr.JoinInts(aids)
  583. if err = s.dao.AddCacheViewRank(c, sid, aidsStr); err != nil {
  584. log.Error("SetViewRank s.dao.AddCacheViewRank(%d,%s) error(%v)", sid, aidsStr, err)
  585. }
  586. return
  587. }
  588. // ObjectGroup group like data.
  589. func (s *Service) ObjectGroup(c context.Context, sid int64, ck string) (data map[int64][]*likemdl.GroupItem, err error) {
  590. var sids []int64
  591. if sids, err = s.dao.SourceItemData(c, sid); err != nil {
  592. log.Error("ObjectGroup SourceItemData(%d) error(%+v)", sid, err)
  593. return
  594. }
  595. if len(sids) == 0 {
  596. log.Warn("ObjectGroup sid(%d) len(sids) == 0", sid)
  597. err = ecode.NothingFound
  598. return
  599. }
  600. data = make(map[int64][]*likemdl.GroupItem, len(sids))
  601. group, errCtx := errgroup.WithContext(c)
  602. mutex := sync.Mutex{}
  603. for _, v := range sids {
  604. groupSid := v
  605. group.Go(func() error {
  606. item, e := s.dao.GroupItemData(errCtx, groupSid, ck)
  607. if e != nil {
  608. log.Error("ObjectGroup s.dao.GroupItemData(%d) error(%+v)", groupSid, e)
  609. } else {
  610. mutex.Lock()
  611. data[groupSid] = item
  612. mutex.Unlock()
  613. }
  614. return nil
  615. })
  616. }
  617. group.Wait()
  618. return
  619. }
  620. // SetLikeContent .
  621. func (s *Service) SetLikeContent(c context.Context, lid int64) (err error) {
  622. var (
  623. conts map[int64]*likemdl.LikeContent
  624. )
  625. if conts, err = s.dao.RawLikeContent(c, []int64{lid}); err != nil {
  626. log.Error("s.dao.RawLikeContent(%d) error(%+v)", lid, err)
  627. return
  628. }
  629. if _, ok := conts[lid]; !ok {
  630. conts = make(map[int64]*likemdl.LikeContent, 1)
  631. conts[lid] = &likemdl.LikeContent{}
  632. }
  633. if err = s.dao.AddCacheLikeContent(c, conts); err != nil {
  634. log.Error("s.dao.AddCacheLikeContent(%d) error(%+v)", lid, err)
  635. }
  636. return
  637. }
  638. // AddLikeActCache .
  639. func (s *Service) AddLikeActCache(c context.Context, sid, lid, score int64) (err error) {
  640. var (
  641. likeItem *likemdl.Item
  642. )
  643. if likeItem, err = s.dao.Like(c, lid); err != nil {
  644. log.Error("AddLikeActCache:s.dao.Like(%d) error(%+v)", lid, err)
  645. return
  646. }
  647. if likeItem.ID == 0 {
  648. return
  649. }
  650. if err = s.dao.SetRedisCache(c, sid, lid, score, likeItem.Type); err != nil {
  651. log.Error("AddLikeActCache:s.dao.SetRedisCache(%d,%d,%d) error(%+v)", sid, lid, score, err)
  652. }
  653. return
  654. }
  655. // LikeActCache .
  656. func (s *Service) LikeActCache(c context.Context, sid, lid int64) (res int64, err error) {
  657. return s.dao.LikeActZscore(c, sid, lid)
  658. }
  659. // BatchInsertLikeExtend batch insert like_extend table.
  660. func (s *Service) BatchInsertLikeExtend(c context.Context, extends []*likemdl.Extend) (res int64, err error) {
  661. var (
  662. buf bytes.Buffer
  663. cnt int
  664. rows int64
  665. )
  666. for _, v := range extends {
  667. buf.WriteString("(")
  668. buf.WriteString(strconv.FormatInt(v.Lid, 10))
  669. buf.WriteString(",")
  670. buf.WriteString(strconv.FormatInt(v.Like, 10))
  671. buf.WriteString("),")
  672. cnt++
  673. if cnt%500 == 0 {
  674. buf.Truncate(buf.Len() - 1)
  675. if rows, err = s.dao.AddExtend(c, buf.String()); err != nil {
  676. log.Error("dao.dealAddExtend() error(%+v)", err)
  677. return
  678. }
  679. res += rows
  680. buf.Reset()
  681. }
  682. }
  683. if buf.Len() > 0 {
  684. buf.Truncate(buf.Len() - 1)
  685. if rows, err = s.dao.AddExtend(c, buf.String()); err != nil {
  686. log.Error("dao.dealAddExtend() error(%+v)", err)
  687. return
  688. }
  689. res += rows
  690. }
  691. return
  692. }
  693. // arcTag get archive and tags.
  694. func (s *Service) arcTag(c context.Context, list []*likemdl.List, order string, mid int64) (err error) {
  695. var (
  696. arcsReply *api.ArcsReply
  697. lt = len(list)
  698. wids = make([]int64, 0, lt)
  699. tagRes map[int64][]string
  700. hasLikeList map[int64]int8
  701. )
  702. for _, v := range list {
  703. if v.Wid > 0 {
  704. wids = append(wids, v.Wid)
  705. }
  706. }
  707. eg, errCtx := errgroup.WithContext(c)
  708. eg.Go(func() (e error) {
  709. arcsReply, e = s.arcClient.Arcs(errCtx, &api.ArcsRequest{Aids: wids})
  710. return
  711. })
  712. eg.Go(func() (e error) {
  713. tagRes, e = s.dao.MultiTags(errCtx, wids)
  714. return
  715. })
  716. if mid != 0 && (order == dao.EsOrderLikes || order == dao.ActOrderCtime) {
  717. eg.Go(func() (e error) {
  718. hasLikeList, e = s.thumbup.HasLike(errCtx, &thpmdl.ArgHasLike{Business: _businessLike, MessageIDs: wids, Mid: mid})
  719. return
  720. })
  721. }
  722. if err = eg.Wait(); err != nil {
  723. log.Error("arcTag:eg.Wait() error(%+v)", err)
  724. return
  725. }
  726. for _, v := range list {
  727. if v.Wid == 0 {
  728. continue
  729. }
  730. obj := new(likemdl.ArgTag)
  731. if _, ok := arcsReply.Arcs[v.Wid]; ok {
  732. obj.Archive = arcsReply.Arcs[v.Wid]
  733. }
  734. if _, ok := tagRes[v.Wid]; ok {
  735. obj.Tags = tagRes[v.Wid]
  736. }
  737. v.Object = obj
  738. if _, ok := hasLikeList[v.Wid]; ok {
  739. v.HasLikes = hasLikeList[v.Wid]
  740. }
  741. }
  742. return
  743. }
  744. // LikeOidsInfo .
  745. func (s *Service) LikeOidsInfo(c context.Context, sType int, oids []int64) (res map[int64]*likemdl.Item, err error) {
  746. if res, err = s.dao.OidInfoFromES(c, oids, sType); err != nil {
  747. log.Error("s.dao.OidInfoFromES(%v,%d) error(%v)", oids, sType, err)
  748. }
  749. return
  750. }