relation.go 32 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218
  1. package relation
  2. import (
  3. "context"
  4. "fmt"
  5. "hash/crc32"
  6. "sort"
  7. "strconv"
  8. "sync"
  9. "go-common/app/interface/main/account/conf"
  10. "go-common/app/interface/main/account/dao/relation"
  11. "go-common/app/interface/main/account/model"
  12. acml "go-common/app/service/main/account/model"
  13. account "go-common/app/service/main/account/rpc/client"
  14. archive "go-common/app/service/main/archive/api/gorpc"
  15. mrl "go-common/app/service/main/relation/model"
  16. rlrpc "go-common/app/service/main/relation/rpc/client"
  17. "go-common/library/ecode"
  18. "go-common/library/log"
  19. "go-common/library/net/metadata"
  20. )
  21. var (
  22. _emptyFollowings = []*model.Following{}
  23. _emptyTagInfos = []*model.Tag{}
  24. _emptyTags = make(map[int64]string)
  25. _allTagsStr = "all"
  26. _specialTagsStr = "special"
  27. _defaultTagsStr = "default"
  28. _listTagsStr = "list"
  29. _emptySpList = []int64{}
  30. )
  31. // Service struct of service.
  32. type Service struct {
  33. // conf
  34. c *conf.Config
  35. // rpc
  36. relationRPC *rlrpc.Service
  37. accountRPC *account.Service3
  38. archiveRPC *archive.Service2
  39. // dao
  40. dao *relation.Dao
  41. }
  42. // New create service instance and return.
  43. func New(c *conf.Config) (s *Service) {
  44. s = &Service{
  45. c: c,
  46. relationRPC: rlrpc.New(c.RPCClient2.Relation),
  47. accountRPC: account.New3(c.RPCClient2.Account),
  48. archiveRPC: archive.New2(c.RPCClient2.Archive),
  49. dao: relation.New(c),
  50. }
  51. return
  52. }
  53. // Modify modify user relation.
  54. func (s *Service) Modify(c context.Context, mid, fid int64, act int8, src uint8, ric map[string]string) (err error) {
  55. if act < mrl.ActAddFollowing || act > mrl.ActDelFollower {
  56. err = ecode.RequestErr
  57. return
  58. }
  59. arg := &mrl.ArgFollowing{Mid: mid, Fid: fid, Source: src, Action: act, Infoc: ric}
  60. if err = s.relationRPC.ModifyRelation(c, arg); err != nil {
  61. log.Error("s.relationRPC.ModifyRelation(mid:%d,fid:%d,src:%d,act:%d) err(%v)", mid, fid, act, src, err)
  62. }
  63. return
  64. }
  65. // BatchModify batch modify user relation.
  66. func (s *Service) BatchModify(c context.Context, mid int64, fids []int64, act int8, src uint8, ric map[string]string) (result *model.BatchModifyResult, err error) {
  67. if len(fids) > 50 {
  68. err = ecode.RequestErr
  69. return
  70. }
  71. for _, fid := range fids {
  72. if fid <= 0 || fid == mid {
  73. err = ecode.RequestErr
  74. return
  75. }
  76. }
  77. // luoweiling: 把非加关注的动作全部拒绝掉
  78. if act != mrl.ActAddFollowing {
  79. err = ecode.RequestErr
  80. return
  81. }
  82. if act < mrl.ActAddFollowing || act > mrl.ActDelFollower {
  83. err = ecode.RequestErr
  84. return
  85. }
  86. // zhangsusu: 批量关注里保持悄悄关注的状态
  87. whispers, err := s.relationRPC.Whispers(c, &mrl.ArgMid{
  88. Mid: mid,
  89. RealIP: "",
  90. })
  91. if err != nil {
  92. log.Error("Failed to get user whispers: mid: %d: %+v", mid, err)
  93. return
  94. }
  95. whispersmap := make(map[int64]struct{}, len(whispers))
  96. for _, w := range whispers {
  97. whispersmap[w.Mid] = struct{}{}
  98. }
  99. filteredFids := make([]int64, 0, len(fids))
  100. for _, fid := range fids {
  101. if _, ok := whispersmap[fid]; ok {
  102. continue
  103. }
  104. filteredFids = append(filteredFids, fid)
  105. }
  106. raiseErr := func(in error) error {
  107. shouldRaise := map[int]struct{}{
  108. ecode.RelFollowAlreadyBlack.Code(): {},
  109. ecode.RelFollowReachTelLimit.Code(): {},
  110. ecode.RelFollowReachMaxLimit.Code(): {},
  111. }
  112. ec := ecode.Cause(in)
  113. if _, ok := shouldRaise[ec.Code()]; ok {
  114. return ec
  115. }
  116. return nil
  117. }
  118. lock := sync.Mutex{}
  119. result = &model.BatchModifyResult{
  120. FailedFids: []int64{},
  121. }
  122. wg := sync.WaitGroup{}
  123. for _, fid := range filteredFids {
  124. fid := fid
  125. wg.Add(1)
  126. go func() {
  127. defer wg.Done()
  128. arg := &mrl.ArgFollowing{Mid: mid, Fid: fid, Source: src, Action: act, Infoc: ric}
  129. rerr := s.relationRPC.ModifyRelation(c, arg)
  130. if rerr == nil {
  131. return
  132. }
  133. lock.Lock()
  134. defer lock.Unlock()
  135. err = raiseErr(rerr)
  136. log.Error("s.relationRPC.ModifyRelation(mid:%d,fid:%d,src:%d,act:%d) err(%v)", mid, fid, act, src, rerr)
  137. result.FailedFids = append(result.FailedFids, fid)
  138. }()
  139. }
  140. wg.Wait()
  141. return
  142. }
  143. // Relation get user relation.
  144. func (s *Service) Relation(c context.Context, mid, fid int64) (f *mrl.Following, err error) {
  145. ip := metadata.String(c, metadata.RemoteIP)
  146. arg := &mrl.ArgRelation{Mid: mid, Fid: fid, RealIP: ip}
  147. if f, err = s.relationRPC.Relation(c, arg); err != nil {
  148. log.Error("s.Relation(mid %d,fid %d) err(%v)", mid, fid, err)
  149. }
  150. return
  151. }
  152. // Relations get relations between users.
  153. func (s *Service) Relations(c context.Context, mid int64, fids []int64) (f map[int64]*mrl.Following, err error) {
  154. ip := metadata.String(c, metadata.RemoteIP)
  155. arg := &mrl.ArgRelations{Mid: mid, Fids: fids, RealIP: ip}
  156. if f, err = s.relationRPC.Relations(c, arg); err != nil {
  157. log.Error("s.Relations(mid %d,fids %d) err(%v)", mid, fids, err)
  158. }
  159. return
  160. }
  161. // Blacks get user black list.
  162. func (s *Service) Blacks(c context.Context, mid int64, version uint64, pn, ps int64) (f []*model.Following, crc32v uint32, total int, err error) {
  163. ip := metadata.String(c, metadata.RemoteIP)
  164. arg := &mrl.ArgMid{Mid: mid, RealIP: ip}
  165. fr, err := s.relationRPC.Blacks(c, arg)
  166. if err != nil {
  167. log.Error("s.Blacks(mid %d) err(%v)", mid, err)
  168. return
  169. }
  170. total = len(fr)
  171. stat, err := s.relationRPC.Stat(c, arg)
  172. if err != nil {
  173. log.Error("s.Stat(mid %d) err(%v)", mid, err)
  174. return
  175. }
  176. total = int(stat.Black)
  177. start, end := (pn-1)*ps, pn*ps
  178. switch {
  179. case start >= int64(len(fr)):
  180. fr = fr[:0]
  181. case end >= int64(len(fr)):
  182. fr = fr[start:]
  183. default:
  184. fr = fr[start:end]
  185. }
  186. if len(fr) == 0 {
  187. f = _emptyFollowings
  188. return
  189. }
  190. temp := []byte(fmt.Sprintf("%s", fr))
  191. crc32v = crc32.Checksum(temp, crc32.IEEETable)
  192. if uint64(crc32v) == version {
  193. err = ecode.NotModified
  194. return
  195. }
  196. var (
  197. mids []int64
  198. infos map[int64]*acml.Info
  199. fi *mrl.Following
  200. )
  201. for _, fi = range fr {
  202. mids = append(mids, fi.Mid)
  203. }
  204. accArg := &acml.ArgMids{Mids: mids}
  205. if infos, err = s.accountRPC.Infos3(c, accArg); err != nil {
  206. log.Error("s.accountRPC.Infos3(mid:%v) err(%v)", accArg, err)
  207. return
  208. }
  209. for _, fi = range fr {
  210. tmp := &model.Following{Following: fi}
  211. info, ok := infos[fi.Mid]
  212. if !ok {
  213. log.Warn("Failed to fetch infos with mid: %d", fi.Mid)
  214. continue
  215. }
  216. tmp.Face = info.Face
  217. tmp.Uname = info.Name
  218. tmp.Sign = info.Sign
  219. f = append(f, tmp)
  220. }
  221. return
  222. }
  223. // Whispers get user Whispers.
  224. func (s *Service) Whispers(c context.Context, mid int64, pn, ps int64, version uint64) (f []*model.Following, crc32v uint32, err error) {
  225. ip := metadata.String(c, metadata.RemoteIP)
  226. arg := &mrl.ArgMid{Mid: mid, RealIP: ip}
  227. fr, err := s.relationRPC.Whispers(c, arg)
  228. if err != nil {
  229. log.Error("s.Whispers(mid %d) err(%v)", mid, err)
  230. return
  231. }
  232. start, end := (pn-1)*ps, pn*ps
  233. switch {
  234. case start >= int64(len(fr)):
  235. fr = fr[:0]
  236. case end >= int64(len(fr)):
  237. fr = fr[start:]
  238. default:
  239. fr = fr[start:end]
  240. }
  241. if len(fr) == 0 {
  242. f = _emptyFollowings
  243. return
  244. }
  245. temp := []byte(fmt.Sprintf("%s", fr))
  246. crc32v = crc32.Checksum(temp, crc32.IEEETable)
  247. if uint64(crc32v) == version {
  248. err = ecode.NotModified
  249. return
  250. }
  251. var (
  252. mids []int64
  253. cards map[int64]*acml.Card
  254. fi *mrl.Following
  255. )
  256. for _, fi = range fr {
  257. mids = append(mids, fi.Mid)
  258. }
  259. accArg := &acml.ArgMids{Mids: mids}
  260. if cards, err = s.accountRPC.Cards3(c, accArg); err != nil {
  261. log.Error("s.accountRPC(mid:%v) err(%v)", accArg, err)
  262. return
  263. }
  264. for _, fi = range fr {
  265. tmp := &model.Following{Following: fi}
  266. card, ok := cards[fi.Mid]
  267. if !ok {
  268. log.Warn("Failed to fetch card with mid: %d", mid)
  269. continue
  270. }
  271. tmp.Face = card.Face
  272. tmp.Uname = card.Name
  273. tmp.Sign = card.Sign
  274. of := card.Official
  275. if of.Role == 0 {
  276. tmp.OfficialVerify.Type = -1
  277. } else {
  278. if of.Role <= 2 {
  279. tmp.OfficialVerify.Type = 0
  280. } else {
  281. tmp.OfficialVerify.Type = 1
  282. }
  283. tmp.OfficialVerify.Desc = of.Title
  284. }
  285. // tmp.Vip = cards[fi.Mid].Vip
  286. tmp.Vip.Type = int(card.Vip.Type)
  287. tmp.Vip.VipStatus = int(card.Vip.Status)
  288. tmp.Vip.DueDate = card.Vip.DueDate
  289. f = append(f, tmp)
  290. }
  291. return
  292. }
  293. // Friends get user friends list: follow eachother.
  294. func (s *Service) Friends(c context.Context, mid int64, version uint64) (f []*model.Following, crc32v uint32, err error) {
  295. var (
  296. mids []int64
  297. cards map[int64]*acml.Card
  298. fi *mrl.Following
  299. fo, fs []*mrl.Following
  300. ip = metadata.String(c, metadata.RemoteIP)
  301. )
  302. arg := &mrl.ArgMid{Mid: mid, RealIP: ip}
  303. if fo, err = s.relationRPC.Followings(c, arg); err != nil {
  304. log.Error("s.Followings(mid %d) err(%v)", mid, err)
  305. return
  306. }
  307. for _, fi = range fo {
  308. if mrl.Attr(fi.Attribute) == mrl.AttrFriend {
  309. fs = append(fs, fi)
  310. }
  311. }
  312. if len(fs) == 0 {
  313. f = _emptyFollowings
  314. return
  315. }
  316. temp := []byte(fmt.Sprintf("%s", fo))
  317. crc32v = crc32.Checksum(temp, crc32.IEEETable)
  318. if uint64(crc32v) == version {
  319. err = ecode.NotModified
  320. return
  321. }
  322. for _, fi = range fs {
  323. mids = append(mids, fi.Mid)
  324. }
  325. accArg := &acml.ArgMids{Mids: mids}
  326. if cards, err = s.accountRPC.Cards3(c, accArg); err != nil {
  327. log.Error("s.accountRPC.Cards3(mid:%v) err(%v)", accArg, err)
  328. return
  329. }
  330. for _, fi = range fs {
  331. tmp := &model.Following{Following: fi}
  332. card, ok := cards[fi.Mid]
  333. if !ok {
  334. log.Warn("Failed to fetch card with mid: %d", fi.Mid)
  335. continue
  336. }
  337. tmp.Face = card.Face
  338. tmp.Uname = card.Name
  339. tmp.Sign = card.Sign
  340. // tmp.OfficialVerify = cards[fi.Mid].Official
  341. of := card.Official
  342. if of.Role == 0 {
  343. tmp.OfficialVerify.Type = -1
  344. } else {
  345. if of.Role <= 2 {
  346. tmp.OfficialVerify.Type = 0
  347. } else {
  348. tmp.OfficialVerify.Type = 1
  349. }
  350. tmp.OfficialVerify.Desc = of.Title
  351. }
  352. // tmp.Vip = infos[fi.Mid].Vip
  353. tmp.Vip.Type = int(card.Vip.Type)
  354. tmp.Vip.VipStatus = int(card.Vip.Status)
  355. tmp.Vip.DueDate = card.Vip.DueDate
  356. f = append(f, tmp)
  357. }
  358. return
  359. }
  360. // Followers get user followings.
  361. func (s *Service) Followers(c context.Context, vmid, mid, pn, ps int64, version uint64) (f []*model.Following, crc32v uint32, total int, err error) {
  362. var (
  363. mids []int64
  364. cards map[int64]*acml.Card
  365. fi *mrl.Following
  366. ip = metadata.String(c, metadata.RemoteIP)
  367. )
  368. arg := &mrl.ArgMid{Mid: vmid, RealIP: ip}
  369. fr, err := s.relationRPC.Followers(c, arg)
  370. if err != nil {
  371. log.Error("s.Followers(mid %d) err(%v)", vmid, err)
  372. return
  373. }
  374. stat, err := s.relationRPC.Stat(c, arg)
  375. if err != nil {
  376. log.Error("s.Stat(mid %d) err(%v)", vmid, err)
  377. return
  378. }
  379. total = int(stat.Follower)
  380. start, end := (pn-1)*ps, pn*ps
  381. switch {
  382. case start >= int64(len(fr)):
  383. fr = fr[:0]
  384. case end >= int64(len(fr)):
  385. fr = fr[start:]
  386. default:
  387. fr = fr[start:end]
  388. }
  389. if len(fr) == 0 {
  390. f = _emptyFollowings
  391. return
  392. }
  393. for _, fi = range fr {
  394. mids = append(mids, fi.Mid)
  395. }
  396. // !self, compute !self user and up's followings' attr
  397. var frs map[int64]*mrl.Following
  398. if mid != 0 {
  399. argfrs := &mrl.ArgRelations{Mid: mid, Fids: mids, RealIP: ip}
  400. frs, err = s.relationRPC.Relations(c, argfrs)
  401. if err != nil {
  402. log.Error("s.relationRPC.Relations(c, %v) error(%v)", argfrs, err)
  403. return
  404. }
  405. }
  406. temp := []byte(fmt.Sprintf("%s", fr))
  407. crc32v = crc32.Checksum(temp, crc32.IEEETable)
  408. if uint64(crc32v) == version {
  409. err = ecode.NotModified
  410. return
  411. }
  412. accArg := &acml.ArgMids{Mids: mids}
  413. if cards, err = s.accountRPC.Cards3(c, accArg); err != nil {
  414. log.Error("s.accountRPC.Cards3(mid:%v) err(%v)", accArg, err)
  415. return
  416. }
  417. for _, fi = range fr {
  418. tmp := &model.Following{Following: fi}
  419. card, ok := cards[fi.Mid]
  420. if !ok {
  421. log.Warn("Failed to fetch card with mid: %d", mid)
  422. continue
  423. }
  424. tmp.Face = card.Face
  425. tmp.Uname = card.Name
  426. tmp.Sign = card.Sign
  427. if frst, ok := frs[fi.Mid]; ok {
  428. tmp.Attribute = frst.Attribute
  429. } else {
  430. tmp.Attribute = mrl.AttrNoRelation
  431. }
  432. // tmp.OfficialVerify = cards[fi.Mid].Official
  433. of := card.Official
  434. if of.Role == 0 {
  435. tmp.OfficialVerify.Type = -1
  436. } else {
  437. if of.Role <= 2 {
  438. tmp.OfficialVerify.Type = 0
  439. } else {
  440. tmp.OfficialVerify.Type = 1
  441. }
  442. tmp.OfficialVerify.Desc = of.Title
  443. }
  444. // tmp.Vip = infos[fi.Mid].Vip
  445. tmp.Vip.Type = int(card.Vip.Type)
  446. tmp.Vip.VipStatus = int(card.Vip.Status)
  447. tmp.Vip.DueDate = card.Vip.DueDate
  448. f = append(f, tmp)
  449. }
  450. return
  451. }
  452. // Followings get user followings list.
  453. func (s *Service) Followings(c context.Context, vmid, mid, pn, ps int64, version uint64, order string) (f []*model.Following, crc32v uint32, total int, err error) {
  454. var (
  455. mids []int64
  456. cards map[int64]*acml.Card
  457. fi *mrl.Following
  458. ip = metadata.String(c, metadata.RemoteIP)
  459. )
  460. arg := &mrl.ArgMid{Mid: vmid, RealIP: ip}
  461. fr, err := s.relationRPC.Followings(c, arg)
  462. if err != nil {
  463. log.Error("s.Followings(mid %d) err(%v)", vmid, err)
  464. return
  465. }
  466. stat, err := s.relationRPC.Stat(c, arg)
  467. if err != nil {
  468. log.Error("s.Stat(mid %d) err(%v)", vmid, err)
  469. return
  470. }
  471. total = int(stat.Following)
  472. if order == "asc" {
  473. sort.Sort(ByMTime(fr))
  474. }
  475. start, end := (pn-1)*ps, pn*ps
  476. switch {
  477. case start >= int64(len(fr)):
  478. fr = fr[:0]
  479. case end >= int64(len(fr)):
  480. fr = fr[start:]
  481. default:
  482. fr = fr[start:end]
  483. }
  484. if len(fr) == 0 {
  485. f = _emptyFollowings
  486. return
  487. }
  488. for _, fi = range fr {
  489. mids = append(mids, fi.Mid)
  490. }
  491. // !self, compute !self user and up's followings' attr
  492. var frs map[int64]*mrl.Following
  493. if mid != vmid && mid != 0 {
  494. argfrs := &mrl.ArgRelations{Mid: mid, Fids: mids, RealIP: ip}
  495. frs, err = s.relationRPC.Relations(c, argfrs)
  496. if err != nil {
  497. log.Error("s.relationRPC.Relations(c, %v) error(%v)", argfrs, err)
  498. return
  499. }
  500. }
  501. temp := []byte(fmt.Sprintf("%s", fr))
  502. crc32v = crc32.Checksum(temp, crc32.IEEETable)
  503. if uint64(crc32v) == version {
  504. err = ecode.NotModified
  505. return
  506. }
  507. accArg := &acml.ArgMids{Mids: mids}
  508. if cards, err = s.accountRPC.Cards3(c, accArg); err != nil {
  509. log.Error("s.accountRPC.Cards3(mid:%v) err(%v)", accArg, err)
  510. return
  511. }
  512. for _, fi = range fr {
  513. tmp := &model.Following{Following: fi}
  514. card, ok := cards[fi.Mid]
  515. if !ok {
  516. log.Warn("Failed to fetch card with mid: %d", mid)
  517. continue
  518. }
  519. tmp.Face = card.Face
  520. tmp.Uname = card.Name
  521. tmp.Sign = card.Sign
  522. if mid != vmid {
  523. if frst, ok := frs[fi.Mid]; ok {
  524. tmp.Attribute = frst.Attribute
  525. } else {
  526. tmp.Attribute = mrl.AttrNoRelation
  527. }
  528. }
  529. // tmp.OfficialVerify = cards[fi.Mid].Official
  530. of := card.Official
  531. if of.Role == 0 {
  532. tmp.OfficialVerify.Type = -1
  533. } else {
  534. if of.Role <= 2 {
  535. tmp.OfficialVerify.Type = 0
  536. } else {
  537. tmp.OfficialVerify.Type = 1
  538. }
  539. tmp.OfficialVerify.Desc = of.Title
  540. }
  541. // tmp.Vip = infos[fi.Mid].Vip
  542. tmp.Vip.Type = int(card.Vip.Type)
  543. tmp.Vip.VipStatus = int(card.Vip.Status)
  544. tmp.Vip.DueDate = card.Vip.DueDate
  545. f = append(f, tmp)
  546. }
  547. return
  548. }
  549. // Stat get user relation stat.
  550. func (s *Service) Stat(c context.Context, mid int64, self bool) (st *mrl.Stat, err error) {
  551. ip := metadata.String(c, metadata.RemoteIP)
  552. arg := &mrl.ArgMid{Mid: mid, RealIP: ip}
  553. if st, err = s.relationRPC.Stat(c, arg); err != nil {
  554. log.Error("s.Stat(mid %d) err(%v)", mid, err)
  555. return
  556. }
  557. if !self {
  558. st.Whisper = 0
  559. st.Black = 0
  560. }
  561. return
  562. }
  563. // Stats get users relation stat.
  564. func (s *Service) Stats(c context.Context, mids []int64) (st map[int64]*mrl.Stat, err error) {
  565. ip := metadata.String(c, metadata.RemoteIP)
  566. arg := &mrl.ArgMids{Mids: mids, RealIP: ip}
  567. return s.relationRPC.Stats(c, arg)
  568. }
  569. // Ping check server ok.
  570. func (s *Service) Ping(c context.Context) (err error) {
  571. return
  572. }
  573. // ByMTime implements sort.Interface for []model.Following based on the MTime field.
  574. type ByMTime []*mrl.Following
  575. func (mt ByMTime) Len() int { return len(mt) }
  576. func (mt ByMTime) Swap(i, j int) { mt[i], mt[j] = mt[j], mt[i] }
  577. func (mt ByMTime) Less(i, j int) bool { return mt[i].MTime < mt[j].MTime }
  578. // Tag get tag info by tag.
  579. func (s *Service) Tag(c context.Context, mid int64, tagid int64, pn int64, ps int64) (tagInfo []*model.Tag, err error) {
  580. var (
  581. mids []int64
  582. cards map[int64]*acml.Card
  583. ip = metadata.String(c, metadata.RemoteIP)
  584. )
  585. arg := &mrl.ArgTagId{Mid: mid, TagId: tagid, RealIP: ip}
  586. if mids, err = s.relationRPC.Tag(c, arg); err != nil {
  587. log.Error("s.relationRPC(%d).Arg(%v) error(%v)", mid, arg, err)
  588. return
  589. }
  590. var tmpMids []int64
  591. start, end := (pn-1)*ps, pn*ps
  592. switch {
  593. case start >= int64(len(mids)):
  594. tmpMids = mids[:0]
  595. case end >= int64(len(mids)):
  596. tmpMids = mids[start:]
  597. default:
  598. tmpMids = mids[start:end]
  599. }
  600. if len(tmpMids) == 0 {
  601. tagInfo = _emptyTagInfos
  602. return
  603. }
  604. accArg := &acml.ArgMids{Mids: mids}
  605. if cards, err = s.accountRPC.Cards3(c, accArg); err != nil {
  606. log.Error("s.accountRPC.Cards3(mid:%v) err(%v)", accArg, err)
  607. return
  608. }
  609. for _, mid = range tmpMids {
  610. tmp := &model.Tag{Mid: mid}
  611. card, ok := cards[mid]
  612. if !ok {
  613. log.Warn("Failed to fetch card with mid: %d", mid)
  614. continue
  615. }
  616. tmp.Mid = mid
  617. tmp.Face = card.Face
  618. tmp.Uname = card.Name
  619. tmp.Sign = card.Sign
  620. // tmp.OfficialVerify = cards[mid].Official
  621. of := card.Official
  622. if of.Role == 0 {
  623. tmp.OfficialVerify.Type = -1
  624. } else {
  625. if of.Role <= 2 {
  626. tmp.OfficialVerify.Type = 0
  627. } else {
  628. tmp.OfficialVerify.Type = 1
  629. }
  630. tmp.OfficialVerify.Desc = of.Title
  631. }
  632. // tmp.Vip = infos[mid].Vip
  633. tmp.Vip.Type = int(card.Vip.Type)
  634. tmp.Vip.VipStatus = int(card.Vip.Status)
  635. tmp.Vip.DueDate = card.Vip.DueDate
  636. tagInfo = append(tagInfo, tmp)
  637. }
  638. return
  639. }
  640. // Tags is.
  641. func (s *Service) Tags(c context.Context, mid int64) (tagsCount []*mrl.TagCount, err error) {
  642. ip := metadata.String(c, metadata.RemoteIP)
  643. arg := &mrl.ArgMid{Mid: mid, RealIP: ip}
  644. if tagsCount, err = s.relationRPC.Tags(c, arg); err != nil {
  645. log.Error("s.relationRPC(%d).Arg(%v) error(%v)", mid, arg, err)
  646. return
  647. }
  648. return
  649. }
  650. // MobileTags is.
  651. func (s *Service) MobileTags(c context.Context, mid int64) (tagsCount map[string][]*mrl.TagCount, err error) {
  652. ip := metadata.String(c, metadata.RemoteIP)
  653. arg := &mrl.ArgMid{Mid: mid, RealIP: ip}
  654. tags, err := s.relationRPC.Tags(c, arg)
  655. if err != nil {
  656. log.Error("s.relationRPC(%d).Arg(%v) error(%v)", mid, arg, err)
  657. return
  658. }
  659. var st *mrl.Stat
  660. argStat := &mrl.ArgMid{Mid: mid, RealIP: ip}
  661. if st, err = s.relationRPC.Stat(c, argStat); err != nil {
  662. log.Error("s.Stat(mid %d) err(%v)", mid, err)
  663. return
  664. }
  665. tagsCount = map[string][]*mrl.TagCount{
  666. _allTagsStr: {{
  667. Tagid: -1,
  668. Name: "公开关注",
  669. Count: st.Following,
  670. }},
  671. _specialTagsStr: {{
  672. Tagid: -10,
  673. Name: "特别关注",
  674. Count: 0,
  675. }},
  676. _listTagsStr: make([]*mrl.TagCount, 0, len(tags)),
  677. _defaultTagsStr: make([]*mrl.TagCount, 0, 1),
  678. }
  679. for _, v := range tags {
  680. if v.Tagid == 0 {
  681. tagsCount[_defaultTagsStr] = append(tagsCount[_defaultTagsStr], v)
  682. } else if v.Tagid == -10 {
  683. tagsCount[_specialTagsStr][0].Count = v.Count
  684. } else {
  685. tagsCount[_listTagsStr] = append(tagsCount[_listTagsStr], v)
  686. }
  687. }
  688. return
  689. }
  690. // UserTag is.
  691. func (s *Service) UserTag(c context.Context, mid int64, fid int64) (tags map[int64]string, err error) {
  692. ip := metadata.String(c, metadata.RemoteIP)
  693. arg := &mrl.ArgRelation{Mid: mid, Fid: fid, RealIP: ip}
  694. if tags, err = s.relationRPC.UserTag(c, arg); err != nil {
  695. log.Error("s.relationRPC.Arg(%v) error(%v)", arg, err)
  696. return
  697. }
  698. if tags == nil {
  699. tags = _emptyTags
  700. }
  701. return
  702. }
  703. // CreateTag is.
  704. func (s *Service) CreateTag(c context.Context, mid int64, tag string) (tagInfo int64, err error) {
  705. ip := metadata.String(c, metadata.RemoteIP)
  706. arg := &mrl.ArgTag{Mid: mid, Tag: tag, RealIP: ip}
  707. if tagInfo, err = s.relationRPC.CreateTag(c, arg); err != nil {
  708. log.Error("s.relationRPC.Arg(%v) error(%v)", arg, err)
  709. return
  710. }
  711. return
  712. }
  713. // UpdateTag is.
  714. func (s *Service) UpdateTag(c context.Context, mid int64, tagID int64, new string) (err error) {
  715. ip := metadata.String(c, metadata.RemoteIP)
  716. arg := &mrl.ArgTagUpdate{Mid: mid, TagId: tagID, New: new, RealIP: ip}
  717. if err = s.relationRPC.UpdateTag(c, arg); err != nil {
  718. log.Error("s.relationRPC.Arg(%v) error(%v)", arg, err)
  719. return
  720. }
  721. return
  722. }
  723. // DelTag is.
  724. func (s *Service) DelTag(c context.Context, mid int64, tagID int64) (err error) {
  725. ip := metadata.String(c, metadata.RemoteIP)
  726. arg := &mrl.ArgTagDel{Mid: mid, TagId: tagID, RealIP: ip}
  727. if err = s.relationRPC.DelTag(c, arg); err != nil {
  728. log.Error("s.relationRPC.Arg(%v) error(%v)", arg, err)
  729. return
  730. }
  731. return
  732. }
  733. // TagsAddUsers is.
  734. func (s *Service) TagsAddUsers(c context.Context, mid int64, tagIds string, fids string) (err error) {
  735. ip := metadata.String(c, metadata.RemoteIP)
  736. arg := &mrl.ArgTagsMoveUsers{Mid: mid, BeforeID: 0, AfterTagIds: tagIds, Fids: fids, RealIP: ip}
  737. if err = s.relationRPC.TagsAddUsers(c, arg); err != nil {
  738. log.Error("s.relationRPC.Arg(%v) error(%v)", arg, err)
  739. return
  740. }
  741. return
  742. }
  743. // TagsCopyUsers is.
  744. func (s *Service) TagsCopyUsers(c context.Context, mid int64, tagIds string, fids string) (err error) {
  745. ip := metadata.String(c, metadata.RemoteIP)
  746. arg := &mrl.ArgTagsMoveUsers{Mid: mid, BeforeID: 0, AfterTagIds: tagIds, Fids: fids, RealIP: ip}
  747. if err = s.relationRPC.TagsCopyUsers(c, arg); err != nil {
  748. log.Error("s.relationRPC.Arg(%v) error(%v)", arg, err)
  749. return
  750. }
  751. return
  752. }
  753. // TagsMoveUsers is.
  754. func (s *Service) TagsMoveUsers(c context.Context, mid, beforeid int64, afterTagIdsStr, fidsStr string) (err error) {
  755. ip := metadata.String(c, metadata.RemoteIP)
  756. arg := &mrl.ArgTagsMoveUsers{Mid: mid, BeforeID: beforeid, AfterTagIds: afterTagIdsStr, Fids: fidsStr, RealIP: ip}
  757. if err = s.relationRPC.TagsMoveUsers(c, arg); err != nil {
  758. log.Error("s.relationRPC.Arg(%v) error(%v)", arg, err)
  759. return
  760. }
  761. return
  762. }
  763. // Prompt report and get prompt status.
  764. func (s *Service) Prompt(c context.Context, arg *mrl.ArgPrompt) (b bool, err error) {
  765. return s.relationRPC.Prompt(c, arg)
  766. }
  767. // ClosePrompt close prompt.
  768. func (s *Service) ClosePrompt(c context.Context, arg *mrl.ArgPrompt) (err error) {
  769. return s.relationRPC.ClosePrompt(c, arg)
  770. }
  771. // AddSpecial add fid into special.
  772. func (s *Service) AddSpecial(c context.Context, arg *mrl.ArgFollowing) (err error) {
  773. return s.relationRPC.AddSpecial(c, arg)
  774. }
  775. // DelSpecial del fid from sepcial.
  776. func (s *Service) DelSpecial(c context.Context, arg *mrl.ArgFollowing) (err error) {
  777. return s.relationRPC.DelSpecial(c, arg)
  778. }
  779. // Special get user special list.
  780. func (s *Service) Special(c context.Context, mid int64) (l []int64, err error) {
  781. arg := &mrl.ArgMid{
  782. Mid: mid,
  783. }
  784. l, err = s.relationRPC.Special(c, arg)
  785. if len(l) == 0 {
  786. l = _emptySpList
  787. }
  788. return
  789. }
  790. // Unread check unread status, for the 'show red point' function.
  791. func (s *Service) Unread(c context.Context, mid int64, disableAutoReset bool) (show bool, err error) {
  792. arg := &mrl.ArgMid{
  793. Mid: mid,
  794. }
  795. // if !disableAutoReset {
  796. // defer s.ResetUnread(c, mid)
  797. // }
  798. return s.relationRPC.FollowersUnread(c, arg)
  799. }
  800. // ResetUnread is
  801. func (s *Service) ResetUnread(c context.Context, mid int64) (err error) {
  802. arg := &mrl.ArgMid{
  803. Mid: mid,
  804. }
  805. return s.relationRPC.ResetFollowersUnread(c, arg)
  806. }
  807. // UnreadCount unread count.
  808. func (s *Service) UnreadCount(c context.Context, mid int64, disableAutoReset bool) (count int64, err error) {
  809. arg := &mrl.ArgMid{
  810. Mid: mid,
  811. }
  812. // if !disableAutoReset {
  813. // defer func() {
  814. // s.ResetUnread(c, mid)
  815. // s.ResetUnreadCount(c, mid)
  816. // }()
  817. // }
  818. return s.relationRPC.FollowersUnreadCount(c, arg)
  819. }
  820. // ResetUnreadCount is
  821. func (s *Service) ResetUnreadCount(c context.Context, mid int64) (err error) {
  822. arg := &mrl.ArgMid{
  823. Mid: mid,
  824. }
  825. return s.relationRPC.ResetFollowersUnreadCount(c, arg)
  826. }
  827. // RecommendTagSuggestDetail is
  828. func (s *Service) RecommendTagSuggestDetail(c context.Context, arg *model.ArgTagSuggestRecommend) (*model.TagSuggestRecommendInfo, error) {
  829. result, err := s.RecommendTagSuggest(c, arg)
  830. if err != nil {
  831. return nil, err
  832. }
  833. if len(result) <= 0 {
  834. empty := &model.TagSuggestRecommendInfo{
  835. TagName: arg.TagName,
  836. UpList: []*model.RecommendInfo{},
  837. MatchCnt: 0,
  838. }
  839. return empty, nil
  840. }
  841. detail := result[0]
  842. upMids := func() []int64 {
  843. mids := make([]int64, 0, len(detail.UpList))
  844. for _, up := range detail.UpList {
  845. mid, perr := strconv.ParseInt(up.Mid, 10, 64)
  846. if perr != nil {
  847. log.Warn("Failed to parse mid: %s: %+v", up.Mid, perr)
  848. continue
  849. }
  850. mids = append(mids, mid)
  851. }
  852. return mids
  853. }()
  854. rels, err := s.relationRPC.Relations(c, &mrl.ArgRelations{
  855. Mid: arg.Mid,
  856. Fids: upMids,
  857. RealIP: arg.RemoteIP,
  858. })
  859. if err != nil {
  860. return nil, err
  861. }
  862. for _, up := range detail.UpList {
  863. mid, err := strconv.ParseInt(up.Mid, 10, 64)
  864. if err != nil {
  865. log.Warn("Failed to parse mid: %s: %+v", err, up.Mid)
  866. continue
  867. }
  868. r, ok := rels[mid]
  869. if !ok {
  870. log.Warn("Failed to get relation between %d and %d", arg.Mid, mid)
  871. up.Relation = &mrl.Following{Mid: mid} // empty relation
  872. continue
  873. }
  874. up.Relation = r
  875. }
  876. return detail, nil
  877. }
  878. // RecommendTagSuggest is
  879. func (s *Service) RecommendTagSuggest(c context.Context, arg *model.ArgTagSuggestRecommend) ([]*model.TagSuggestRecommendInfo, error) {
  880. resp, err := s.dao.TagSuggestRecommend(c, arg.Mid, arg.ContextID, arg.TagName, arg.Device, arg.PageSize, arg.RemoteIP)
  881. if err != nil {
  882. return nil, err
  883. }
  884. allrecs := make([]*model.RecommendContent, 0)
  885. for _, rec := range resp.Data {
  886. allrecs = append(allrecs, rec.UpList...)
  887. }
  888. allrecinfos, err := s.collectionAsRecommendUserInfo(c, allrecs, resp.TrackID, arg.RemoteIP)
  889. if err != nil {
  890. return nil, err
  891. }
  892. allrecinfomap := make(map[string]*model.RecommendInfo, len(allrecinfos))
  893. for _, recinfo := range allrecinfos {
  894. allrecinfomap[recinfo.Mid] = recinfo
  895. }
  896. getRecInfos := func(mids ...int64) []*model.RecommendInfo {
  897. out := make([]*model.RecommendInfo, 0, len(mids))
  898. for _, mid := range mids {
  899. smid := strconv.FormatInt(mid, 10)
  900. recinfo, ok := allrecinfomap[smid]
  901. if !ok {
  902. log.Warn("Failed to get user info with mid: %d", mid)
  903. continue
  904. }
  905. out = append(out, recinfo)
  906. }
  907. return out
  908. }
  909. result := make([]*model.TagSuggestRecommendInfo, 0, len(resp.Data))
  910. for _, rec := range resp.Data {
  911. trecinfo := &model.TagSuggestRecommendInfo{
  912. TagName: rec.TagName,
  913. MatchCnt: rec.MatchCnt,
  914. }
  915. rinfos := getRecInfos(rec.UpIDs()...)
  916. trecinfo.UpList = rinfos
  917. if len(rinfos) != len(rec.UpIDs()) {
  918. log.Warn("Inconsistent user info and recommend match count: %d, %d", len(rinfos), len(rec.UpIDs()))
  919. trecinfo.MatchCnt -= int64(len(rec.UpIDs()) - len(rinfos))
  920. }
  921. result = append(result, trecinfo)
  922. }
  923. return result, nil
  924. }
  925. // RecommendFollowlistEmpty is
  926. func (s *Service) RecommendFollowlistEmpty(c context.Context, arg *model.ArgRecommend) ([]*model.RecommendInfo, error) {
  927. return s.recommend(c, "followlist_empty", arg)
  928. }
  929. // RecommendAnswerOK is
  930. func (s *Service) RecommendAnswerOK(c context.Context, arg *model.ArgRecommend) ([]*model.RecommendInfo, error) {
  931. return s.recommend(c, "answer_ok", arg)
  932. }
  933. func (s *Service) collectionAsRecommendUserInfo(c context.Context, recs []*model.RecommendContent, trackID string, ip string) ([]*model.RecommendInfo, error) {
  934. recmap := make(map[int64]*model.RecommendContent, len(recs))
  935. mids := make([]int64, 0, len(recs))
  936. for _, r := range recs {
  937. mids = append(mids, r.UpID)
  938. recmap[r.UpID] = r
  939. }
  940. cards, err := s.accountRPC.Cards3(c, &acml.ArgMids{Mids: mids})
  941. if err != nil {
  942. return nil, err
  943. }
  944. stats, err := s.relationRPC.Stats(c, &mrl.ArgMids{Mids: mids, RealIP: ip})
  945. if err != nil {
  946. return nil, err
  947. }
  948. // TODO: cache types
  949. types, err := s.archiveRPC.Types2(c)
  950. if err != nil {
  951. return nil, err
  952. }
  953. typeName := func(tid int16) string {
  954. t := types[tid]
  955. if t == nil {
  956. return ""
  957. }
  958. return t.Name
  959. }
  960. ris := make([]*model.RecommendInfo, 0, len(recs))
  961. for _, rec := range recs {
  962. if rec == nil {
  963. log.Warn("Invalid recommend content: %+v", rec)
  964. continue
  965. }
  966. card, ok := cards[rec.UpID]
  967. if !ok {
  968. log.Warn("Failed to get user card with mid: %d", rec.UpID)
  969. continue
  970. }
  971. stat, ok := stats[rec.UpID]
  972. if !ok {
  973. log.Warn("Failed to get stat with mid: %d", rec.UpID)
  974. continue
  975. }
  976. ri := &model.RecommendInfo{}
  977. ri.FromCard(card)
  978. ri.RecommendContent = *rec
  979. ri.TrackID = trackID
  980. ri.Fans = stat.Follower
  981. ri.TypeName = typeName(ri.Tid)
  982. ri.SecondTypeName = typeName(ri.SecondTid)
  983. // zhangsusu: 拼粉丝数作为推荐理由(后来又下线了)
  984. // fs := followerString(stat.Follower)
  985. // if fs != "" {
  986. // parts := []string{}
  987. // if ri.RecReason != "" {
  988. // parts = append(parts, ri.RecReason)
  989. // }
  990. // parts = append(parts, fs)
  991. // ri.RecReason = strings.Join(parts, ",")
  992. // }
  993. ris = append(ris, ri)
  994. }
  995. return ris, nil
  996. }
  997. func (s *Service) recommend(c context.Context, serviceArea string, arg *model.ArgRecommend) ([]*model.RecommendInfo, error) {
  998. resp, err := s.dao.Recommend(c, arg.Mid, serviceArea, arg.MainTids, arg.SubTids, arg.Device, arg.PageSize, arg.RemoteIP)
  999. if err != nil {
  1000. return nil, err
  1001. }
  1002. return s.collectionAsRecommendUserInfo(c, resp.Data, resp.TrackID, arg.RemoteIP)
  1003. }
  1004. // func followerString(follower int64) string {
  1005. // if follower <= 0 {
  1006. // return ""
  1007. // }
  1008. // if follower < 10000 {
  1009. // return fmt.Sprintf("%d粉丝", follower)
  1010. // }
  1011. // return fmt.Sprintf("%.1f万粉丝", float64(follower)/float64(10000))
  1012. // }
  1013. // AchieveGet is
  1014. func (s *Service) AchieveGet(c context.Context, arg *model.ArgAchieveGet) (*mrl.AchieveGetReply, error) {
  1015. rpcArg := &mrl.ArgAchieveGet{
  1016. Award: arg.Award,
  1017. Mid: arg.Mid,
  1018. }
  1019. return s.relationRPC.AchieveGet(c, rpcArg)
  1020. }
  1021. // Achieve is
  1022. func (s *Service) Achieve(c context.Context, arg *model.ArgAchieve) (*model.AchieveReply, error) {
  1023. rpcArg := &mrl.ArgAchieve{
  1024. AwardToken: arg.AwardToken,
  1025. }
  1026. achieve, err := s.relationRPC.Achieve(c, rpcArg)
  1027. if err != nil {
  1028. return nil, err
  1029. }
  1030. reply := &model.AchieveReply{
  1031. Achieve: *achieve,
  1032. Metadata: make(map[string]interface{}),
  1033. }
  1034. info, err := s.accountRPC.Info3(c, &acml.ArgMid{Mid: achieve.Mid})
  1035. if err != nil {
  1036. return nil, err
  1037. }
  1038. reply.Metadata["mid"] = info.Mid
  1039. reply.Metadata["name"] = info.Name
  1040. return reply, nil
  1041. }
  1042. // FollowerNotifySetting get new-follower-notification setting
  1043. func (s *Service) FollowerNotifySetting(c context.Context, mid int64) (followerNotify *mrl.FollowerNotifySetting, err error) {
  1044. arg := &mrl.ArgMid{
  1045. Mid: mid,
  1046. RealIP: metadata.String(c, metadata.RemoteIP),
  1047. }
  1048. return s.relationRPC.FollowerNotifySetting(c, arg)
  1049. }
  1050. // EnableFollowerNotify enable new-follower-notification
  1051. func (s *Service) EnableFollowerNotify(c context.Context, mid int64) (err error) {
  1052. arg := &mrl.ArgMid{
  1053. Mid: mid,
  1054. RealIP: metadata.String(c, metadata.RemoteIP),
  1055. }
  1056. return s.relationRPC.EnableFollowerNotify(c, arg)
  1057. }
  1058. // DisableFollowerNotify enable new-follower-notification
  1059. func (s *Service) DisableFollowerNotify(c context.Context, mid int64) (err error) {
  1060. arg := &mrl.ArgMid{
  1061. Mid: mid,
  1062. RealIP: metadata.String(c, metadata.RemoteIP),
  1063. }
  1064. return s.relationRPC.DisableFollowerNotify(c, arg)
  1065. }
  1066. // SameFollowings is
  1067. func (s *Service) SameFollowings(c context.Context, arg *model.ArgSameFollowing) (f []*model.Following, crc32v uint32, total int, err error) {
  1068. sfArg := &mrl.ArgSameFollowing{Mid1: arg.VMid, Mid2: arg.Mid}
  1069. fr, err := s.relationRPC.SameFollowings(c, sfArg)
  1070. if err != nil {
  1071. log.Error("s.SameFollowings(%+v) err(%v)", arg, err)
  1072. return
  1073. }
  1074. total = len(fr)
  1075. if arg.Order == "asc" {
  1076. // 直接倒序即可
  1077. for i := len(fr)/2 - 1; i >= 0; i-- {
  1078. opp := len(fr) - 1 - i
  1079. fr[i], fr[opp] = fr[opp], fr[i]
  1080. }
  1081. }
  1082. start, end := (arg.PN-1)*arg.PS, arg.PN*arg.PS
  1083. switch {
  1084. case start >= int64(len(fr)):
  1085. fr = fr[:0]
  1086. case end >= int64(len(fr)):
  1087. fr = fr[start:]
  1088. default:
  1089. fr = fr[start:end]
  1090. }
  1091. if len(fr) == 0 {
  1092. f = _emptyFollowings
  1093. return
  1094. }
  1095. mids := make([]int64, 0, len(fr))
  1096. for _, fi := range fr {
  1097. mids = append(mids, fi.Mid)
  1098. }
  1099. temp := []byte(fmt.Sprintf("%s", fr))
  1100. crc32v = crc32.Checksum(temp, crc32.IEEETable)
  1101. if uint64(crc32v) == arg.ReVersion {
  1102. err = ecode.NotModified
  1103. return
  1104. }
  1105. accArg := &acml.ArgMids{Mids: mids}
  1106. cards, err := s.accountRPC.Cards3(c, accArg)
  1107. if err != nil {
  1108. log.Error("s.accountRPC.Cards3(mid:%v) err(%v)", accArg, err)
  1109. return
  1110. }
  1111. for _, fi := range fr {
  1112. tmp := &model.Following{Following: fi}
  1113. card, ok := cards[fi.Mid]
  1114. if !ok {
  1115. log.Warn("Failed to fetch card with mid: %d", fi.Mid)
  1116. continue
  1117. }
  1118. tmp.Face = card.Face
  1119. tmp.Uname = card.Name
  1120. tmp.Sign = card.Sign
  1121. of := card.Official
  1122. if of.Role == 0 {
  1123. tmp.OfficialVerify.Type = -1
  1124. } else {
  1125. if of.Role <= 2 {
  1126. tmp.OfficialVerify.Type = 0
  1127. } else {
  1128. tmp.OfficialVerify.Type = 1
  1129. }
  1130. tmp.OfficialVerify.Desc = of.Title
  1131. }
  1132. tmp.Vip.Type = int(card.Vip.Type)
  1133. tmp.Vip.VipStatus = int(card.Vip.Status)
  1134. tmp.Vip.DueDate = card.Vip.DueDate
  1135. f = append(f, tmp)
  1136. }
  1137. return
  1138. }