notify.go 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568
  1. package service
  2. import (
  3. "context"
  4. "encoding/json"
  5. "fmt"
  6. "net/url"
  7. "strconv"
  8. artmdl "go-common/app/interface/openplatform/article/model"
  9. model "go-common/app/job/main/reply/model/reply"
  10. accmdl "go-common/app/service/main/account/api"
  11. "go-common/app/service/main/archive/api"
  12. arcmdl "go-common/app/service/main/archive/model/archive"
  13. epmdl "go-common/app/service/openplatform/pgc-season/api/grpc/episode/v1"
  14. "go-common/library/log"
  15. )
  16. const (
  17. _mcReply = "1_1_1"
  18. _mcCntArticle = "1_1_4"
  19. _mcCntDynamic = "1_1_5"
  20. _mcCntClip = "1_1_6"
  21. _mcCntAlbum = "1_1_7"
  22. _mcCntArchive = "1_1_8"
  23. _msgTitleSize = 40
  24. _msgContentSize = 80
  25. )
  26. func (s *Service) notifyReply(c context.Context, sub *model.Subject, rp *model.Reply) {
  27. s.notify.Do(c, func(c context.Context) {
  28. if len(rp.Content.Ats) > 0 {
  29. title, link, jump, nativeJump, msg := s.messageInfo(c, rp)
  30. if link != "" {
  31. atmt := fmt.Sprintf("#{%s}{\"%s\"}评论中@了你", title, link)
  32. cont := fmt.Sprintf("#{%s}{\"%s\"}", msg, jump)
  33. if err := s.messageDao.At(c, rp.Mid, rp.Content.Ats, atmt, cont, extraInfo(nativeJump), rp.CTime.Time()); err != nil {
  34. log.Error("s.messageDao.At failed , mid(%d) err(%v)", rp.Mid, err)
  35. }
  36. }
  37. }
  38. if err := s.notifyCnt(c, sub, rp); err != nil {
  39. log.Error("s.notifyCnt(%v,%v) error(%v)", sub, rp, err)
  40. }
  41. })
  42. }
  43. func (s *Service) notifyReplyReply(c context.Context, sub *model.Subject, rootRp, parentRp, rp *model.Reply) {
  44. s.notify.Do(c, func(c context.Context) {
  45. if err := s.notifyCnt(c, sub, rp); err != nil {
  46. log.Error("s.notifyCnt(%v,%v) error(%v)", sub, rp, err)
  47. }
  48. // notify parent reply
  49. if rp.Mid == rootRp.Mid && rp.Root == rp.Parent && len(rp.Content.Ats) == 0 {
  50. return
  51. }
  52. title, link, jump, nativeJump, msg := s.messageInfo(c, rp)
  53. if title == "" || link == "" {
  54. return
  55. }
  56. // 5.29 改为根评论内容推送
  57. //rpmt = fmt.Sprintf("#{%s}{\"%s\"}评论中回复了你", title, link)
  58. rpmt := []rune(parentRp.Content.Message)
  59. if len(rpmt) > _msgContentSize {
  60. rpmt = rpmt[:_msgContentSize]
  61. }
  62. atmt := fmt.Sprintf("#{%s}{\"%s\"}评论中@了你", title, link)
  63. cont := fmt.Sprintf("#{%s}{\"%s\"}", msg, jump)
  64. // notify
  65. if rp.Mid != rootRp.Mid && !s.getBlackListRelation(c, rootRp.Mid, rp.Mid) {
  66. if err := s.messageDao.Reply(c, _mcReply, "", rp.Mid, rootRp.Mid, string(rpmt), cont, extraInfo(nativeJump), rp.CTime.Time()); err != nil {
  67. log.Error("s.messageDao.Reply failed , mid(%d) Parent(%d), err(%v)", rp.Mid, rootRp.Mid, err)
  68. }
  69. }
  70. if rp.Root != rp.Parent {
  71. if parentRp != nil && rootRp.Mid != parentRp.Mid && rp.Mid != parentRp.Mid && !s.getBlackListRelation(c, parentRp.Mid, rp.Mid) {
  72. if err := s.messageDao.Reply(c, _mcReply, "", rp.Mid, parentRp.Mid, string(rpmt), cont, extraInfo(nativeJump), rp.CTime.Time()); err != nil {
  73. log.Error("s.messageDao.Reply failed , mid(%d) Parent(%d), err(%v)", rp.Mid, parentRp.Mid, err)
  74. }
  75. }
  76. }
  77. var ats []int64
  78. for _, mid := range rp.Content.Ats {
  79. if mid != parentRp.Mid {
  80. ats = append(ats, mid)
  81. }
  82. }
  83. if len(ats) > 0 {
  84. if err := s.messageDao.At(c, rp.Mid, ats, atmt, cont, extraInfo(nativeJump), rp.CTime.Time()); err != nil {
  85. log.Error("s.messageDao.At failed , mid(%d), err(%v)", rp.Mid, err)
  86. }
  87. }
  88. })
  89. }
  90. func (s *Service) notifyLike(c context.Context, mid int64, rp *model.Reply) {
  91. s.notify.Do(c, func(c context.Context) {
  92. if ok, num := s.notifyLikeNum(c, rp, mid); ok {
  93. _, _, jump, nativeJump, msg := s.messageInfo(c, rp)
  94. if jump == "" {
  95. return
  96. }
  97. // NOTE content and title is opposite
  98. cont := fmt.Sprintf("等%d人赞了你的回复", num)
  99. rpmt := fmt.Sprintf("#{%s}{\"%s\"}", msg, jump)
  100. if err := s.messageDao.Like(c, mid, rp.Mid, rpmt, cont, extraInfo(nativeJump), rp.CTime.Time()); err != nil {
  101. log.Error("s.messageDao.Reply failed , mid(%d) Parent(%d), err(%v)", mid, rp.Mid, err)
  102. }
  103. } else {
  104. log.Warn("Didn't satify notify condition, omit notify!")
  105. }
  106. })
  107. }
  108. // notifyLike check if need notify user when receive like
  109. func (s *Service) notifyLikeNum(c context.Context, rp *model.Reply, mid int64) (ok bool, num int64) {
  110. if rp.Mid == mid || rp.Like <= 0 {
  111. ok = false
  112. return
  113. }
  114. num = int64(rp.Like)
  115. // NOTE if num >1000 send when num%1000==0
  116. if num < 10 || (num < 100 && num%10 == 0) || (num < 1000 && num%100 == 0) || num%1000 == 0 {
  117. ok = true
  118. }
  119. return
  120. }
  121. func (s *Service) notifyCnt(c context.Context, sub *model.Subject, rp *model.Reply) (err error) {
  122. max, err := s.dao.Redis.NotifyCnt(c, sub.Oid, sub.Type)
  123. if err != nil {
  124. log.Error("redis.NotifyCnt(%d,%d) error(%v)", sub.Oid, sub.Type, err)
  125. return
  126. }
  127. if sub.ACount <= max {
  128. log.Warn("notifyCnt ignore oid:%d type:%d current:%d max:%d", sub.Oid, sub.Type, sub.ACount, max)
  129. return
  130. }
  131. if err = s.dao.Redis.SetNotifyCnt(c, sub.Oid, sub.Type, sub.ACount); err != nil {
  132. log.Error("redis.SetNotifyCnt(%d,%d,%d) error(%v)", sub.Oid, sub.Type, sub.ACount, err)
  133. return
  134. }
  135. switch sub.Type {
  136. case model.SubTypeVideo:
  137. return s.notifyArchiveCnt(c, sub, rp)
  138. case model.SubTypeArticle:
  139. return s.notifyArticleCnt(c, sub, rp)
  140. case model.SubTypeDynamic:
  141. return s.notifyDynamicCnt(c, sub, rp, _mcCntDynamic)
  142. case model.SubTypeLiveVideo:
  143. return s.notifyDynamicCnt(c, sub, rp, _mcCntClip)
  144. case model.SubTypeLivePicture:
  145. return s.notifyDynamicCnt(c, sub, rp, _mcCntAlbum)
  146. default:
  147. return
  148. }
  149. }
  150. func (s *Service) notifyDynamicCnt(c context.Context, sub *model.Subject, rp *model.Reply, mc string) (err error) {
  151. if !shouldNotifyLow(sub.ACount) {
  152. return
  153. }
  154. title, link, _, nativeJump, msg := s.messageInfo(c, rp)
  155. if title == "" || link == "" {
  156. return
  157. }
  158. resID := fmt.Sprintf("%d_%d", rp.Oid, rp.Type)
  159. notifyTitle := fmt.Sprintf("#{%s}{\"%s\"}收到了第%d条评论", title, link, sub.ACount)
  160. notifyContent := fmt.Sprintf("#{%s}{\"%s\"}", msg, link)
  161. if err = s.messageDao.Reply(c, mc, resID, rp.Mid, sub.Mid, notifyTitle, notifyContent, extraInfo(nativeJump), rp.CTime.Time()); err != nil {
  162. log.Error("s.messageDao.Reply(mid:%d,oid:%d,type:%d,acount:%d) error(%v)", rp.Mid, rp.Oid, rp.Type, sub.ACount, err)
  163. }
  164. return
  165. }
  166. func (s *Service) notifyArchiveCnt(c context.Context, sub *model.Subject, rp *model.Reply) (err error) {
  167. if !shouldNotifyLow(sub.ACount) {
  168. return
  169. }
  170. title, link, _, nativeJump, msg := s.messageInfo(c, rp)
  171. if title == "" || link == "" {
  172. return
  173. }
  174. resID := fmt.Sprintf("%d_%d", rp.Oid, rp.Type)
  175. notifyTitle := fmt.Sprintf("你的投稿收到了第%d条评论", sub.ACount)
  176. notifyContent := fmt.Sprintf("你投稿的视频“#{%s}{\"%s\"}”收到了第%d条评论:『%s』", title, link, sub.ACount, msg)
  177. if err = s.messageDao.System(c, _mcCntArchive, resID, sub.Mid, notifyTitle, notifyContent, extraInfo(nativeJump), rp.CTime.Time()); err != nil {
  178. log.Error("s.messageDao.System(mid:%d,oid:%d,type:%d,acount:%d) error(%v)", rp.Mid, rp.Oid, rp.Type, sub.ACount, err)
  179. }
  180. return
  181. }
  182. func (s *Service) notifyArticleCnt(c context.Context, sub *model.Subject, rp *model.Reply) (err error) {
  183. if !shouldNotifyMiddle(sub.ACount) {
  184. return
  185. }
  186. title, link, _, nativeJump, _ := s.messageInfo(c, rp)
  187. if title == "" || link == "" {
  188. return
  189. }
  190. resID := fmt.Sprintf("%d_%d", rp.Oid, rp.Type)
  191. notifyTitle := fmt.Sprintf("你的专栏文章评论数达到了%d", sub.ACount)
  192. notifyContent := fmt.Sprintf("你投稿的专栏文章“#{%s}{\"%s\"}”评论数达到了%d!去回应一下大家的评论吧~ #{点击前往}{\"%s\"}", title, link, sub.ACount, link)
  193. if err = s.messageDao.System(c, _mcCntArticle, resID, sub.Mid, notifyTitle, notifyContent, extraInfo(nativeJump), rp.CTime.Time()); err != nil {
  194. log.Error("s.messageDao.System(mid:%d,oid:%d,type:%d,acount:%d) error(%v)", rp.Mid, rp.Oid, rp.Type, sub.ACount, err)
  195. }
  196. return
  197. }
  198. func shouldNotifyLow(n int) (ok bool) {
  199. switch {
  200. case n <= 0:
  201. ok = false
  202. case n == 1 || n == 10 || n == 30 || n == 50:
  203. ok = true
  204. case n <= 1000:
  205. ok = (n%100 == 0)
  206. default:
  207. ok = (n%10000 == 0)
  208. }
  209. return
  210. }
  211. func shouldNotifyMiddle(n int) (ok bool) {
  212. switch {
  213. case n <= 0:
  214. ok = false
  215. case n <= 10:
  216. ok = true
  217. case n <= 100:
  218. ok = (n%10 == 0)
  219. case n <= 1000:
  220. ok = (n%100 == 0)
  221. default:
  222. ok = (n%10000 == 0)
  223. }
  224. return
  225. }
  226. // filterViolationMsg every two characters, the third character processing for *.
  227. func filterViolationMsg(msg string) string {
  228. s := []rune(msg)
  229. for i := 0; i < len(s); i++ {
  230. if i%3 != 0 {
  231. s[i] = '*'
  232. }
  233. }
  234. return string(s)
  235. }
  236. // moralAndNotify del moral and notify user.
  237. func (s *Service) moralAndNotify(c context.Context, rp *model.Reply, moral int, notify bool, rptMid, adid int64, adname, remark string, reason, freason int8, ftime int64, isPunish bool) (err error) {
  238. title, link, _, _, msg := s.messageInfo(c, rp)
  239. smsg := []rune(msg)
  240. if len(smsg) > 50 {
  241. smsg = smsg[:50]
  242. }
  243. if moral > 0 {
  244. reason := "发布的评论违规并被管理员删除 - " + string(smsg)
  245. if rptMid > 0 {
  246. reason = "发布的评论被举报并被管理员删除 - " + string(smsg)
  247. }
  248. arg := &accmdl.MoralReq{
  249. Mid: rp.Mid,
  250. Moral: -float64(moral),
  251. Oper: adname,
  252. Reason: reason,
  253. Remark: remark,
  254. }
  255. if _, err = s.accSrv.AddMoral3(c, arg); err != nil {
  256. log.Error("s.accSrv.AddMoral3(%d) error(%v)", rp.Mid, err)
  257. }
  258. }
  259. msg = filterViolationMsg(msg)
  260. if title != "" && link != "" && rptMid > 0 {
  261. if err = s.reportNotify(c, rp, title, link, msg, ftime, reason, freason, isPunish); err != nil {
  262. log.Error("s.reportNotify(%d,%d,%d) error(%v)", rp.Oid, rp.Type, rp.RpID, err)
  263. }
  264. }
  265. if !notify {
  266. return
  267. }
  268. if title != "" && link != "" {
  269. // notify message
  270. mt := "评论违规处理通知"
  271. mc := fmt.Sprintf("您好,您在#{%s}{\"%s\"}下的评论 『%s』 ", title, link, msg)
  272. if rptMid > 0 {
  273. mc = fmt.Sprintf("您好,根据用户举报,您在#{%s}{\"%s\"}下的评论 『%s』 ", title, link, msg)
  274. }
  275. if isPunish {
  276. mc += ",已被处罚"
  277. } else {
  278. mc += ",已被移除"
  279. }
  280. // forbidden
  281. if ftime > 0 {
  282. mc += fmt.Sprintf(",并被封禁%d天。", ftime)
  283. } else if ftime == -1 {
  284. mc += ",并被永久封禁。"
  285. } else {
  286. mc += "。"
  287. }
  288. // forbid reason
  289. if ar, ok := model.ForbidReason[freason]; ok {
  290. mc += "理由:" + ar + "。"
  291. // community rules
  292. switch {
  293. case freason == model.ForbidReasonSpoiler || freason == model.ForbidReasonAd || freason == model.ForbidReasonUnlimitedSign || freason == model.ForbidReasonMeaningless:
  294. mc += model.NotifyComRules
  295. case freason == model.ForbidReasonProvoke || freason == model.ForbidReasonAttack:
  296. mc += model.NotifyComProvoke
  297. default:
  298. mc += model.NofityComProhibited
  299. }
  300. } else { // report reason
  301. if ar, ok := model.ReportReason[reason]; ok {
  302. mc += "理由:" + ar + "。"
  303. }
  304. // community rules
  305. switch {
  306. case reason == model.ReportReasonSpoiler || reason == model.ReportReasonAd || reason == model.ReportReasonUnlimitedSign || reason == model.ReportReasonMeaningless:
  307. mc += model.NotifyComRules
  308. case reason == model.ReportReasonUnrelated:
  309. mc += model.NotifyComUnrelated
  310. case reason == model.ReportReasonProvoke || reason == model.ReportReasonAttack:
  311. mc += model.NotifyComProvoke
  312. default:
  313. mc += model.NofityComProhibited
  314. }
  315. }
  316. // send the message
  317. if err = s.messageDao.DeleteReply(c, rp.Mid, mt, mc, rp.MTime.Time()); err != nil {
  318. log.Error("s.messageDao.DeleteReply failed, (%d) error(%v)", rp.Mid, err)
  319. }
  320. log.Info("notify oid:%d type:%d rpID:%d reason:%d content:%s", rp.Oid, rp.Type, rp.RpID, reason, mc)
  321. } else {
  322. log.Warn("no notify oid:%d type:%d rpid:%d", rp.Oid, rp.Type, rp.RpID)
  323. }
  324. return
  325. }
  326. func (s *Service) reportNotify(c context.Context, rp *model.Reply, title, link, msg string, ftime int64, reason, freason int8, isPunish bool) (err error) {
  327. var (
  328. rptUser *model.ReportUser
  329. rptUsers map[int64]*model.ReportUser
  330. )
  331. mt := "举报处理结果通知"
  332. mc := fmt.Sprintf("您好,您在#{%s}{\"%s\"}下举报的评论 『%s』 ", title, link, msg)
  333. if isPunish {
  334. mc += "已被处罚"
  335. } else {
  336. mc += "已被移除"
  337. }
  338. // forbidden
  339. if ftime > 0 {
  340. mc += fmt.Sprintf(",并被封禁%d天。", ftime)
  341. } else if ftime == -1 {
  342. mc += ",该用户已被永久封禁。"
  343. } else {
  344. mc += "。"
  345. }
  346. // forbid reason
  347. if ar, ok := model.ForbidReason[freason]; ok {
  348. mc += "理由:" + ar + "。"
  349. } else if ar, ok := model.ReportReason[reason]; ok {
  350. mc += "理由:" + ar + "。"
  351. }
  352. // community rules
  353. mc += model.NotifyComRulesReport
  354. if rptUsers, err = s.dao.Report.GetUsers(c, rp.Oid, rp.Type, rp.RpID); err != nil {
  355. log.Error("reportUser.GetUsers(%d,%d,%d) error(%v)", rp.Oid, rp.Type, rp.RpID, err)
  356. return
  357. }
  358. for _, rptUser = range rptUsers {
  359. // send the message
  360. if err = s.messageDao.AcceptReport(c, rptUser.Mid, mt, mc, rp.MTime.Time()); err != nil {
  361. log.Error("s.messageDao.DeleteReply failed, (%d) error(%v)", rp.Mid, err)
  362. }
  363. }
  364. if _, err = s.dao.Report.SetUserReported(c, rp.Oid, rp.Type, rp.RpID, rp.MTime.Time()); err != nil {
  365. log.Error("s.dao.Report.SetUserReported(%d, %d, %d) error(%v)", rp.Oid, rp.Type, rp.RpID)
  366. }
  367. return
  368. }
  369. func (s *Service) messageInfo(c context.Context, rp *model.Reply) (title, link, jump, nativeJump, msg string) {
  370. var (
  371. err error
  372. native bool
  373. subType int
  374. extraIntentID int64
  375. )
  376. switch rp.Type {
  377. case model.SubTypeVideo:
  378. var (
  379. m *api.Arc
  380. uri *url.URL
  381. )
  382. arg := &arcmdl.ArgAid2{
  383. Aid: rp.Oid,
  384. }
  385. m, err = s.arcSrv.Archive3(c, arg)
  386. if err != nil || m == nil {
  387. log.Error("s.arcSrv.Archive3(%v) ret:%v error(%v)", arg, m, err)
  388. return
  389. }
  390. if m.AttrVal(arcmdl.AttrBitIsBangumi) == 1 {
  391. req := &epmdl.EpAidReq{
  392. Aids: []int32{int32(rp.Oid)},
  393. }
  394. resp, err1 := s.bangumiSrv.ListByAids(c, req)
  395. if err1 != nil {
  396. log.Error("s.bangumiSrv.ListByAids(%v, %v) error(%v)", c, req, err1)
  397. return
  398. }
  399. if resp.Infos[int32(rp.Oid)] != nil {
  400. extraIntentID = int64(resp.Infos[int32(rp.Oid)].EpisodeId)
  401. }
  402. subType = 1
  403. }
  404. if m.RedirectURL != "" {
  405. // NOTE mobile jump
  406. if uri, err = url.Parse(m.RedirectURL); err == nil {
  407. q := uri.Query()
  408. q.Set("aid", strconv.FormatInt(rp.Oid, 10))
  409. uri.RawQuery = q.Encode()
  410. link = uri.String()
  411. }
  412. } else {
  413. link = fmt.Sprintf("http://www.bilibili.com/video/av%d/", rp.Oid)
  414. }
  415. title = m.Title
  416. native = true
  417. case model.SubTypeTopic:
  418. if title, link, err = s.noticeDao.Topic(c, rp.Oid); err != nil {
  419. log.Error("s.noticeDao.Topic(%d) error(%v)", rp.Oid, err)
  420. return
  421. }
  422. case model.SubTypeDrawyoo:
  423. if title, link, err = s.noticeDao.Drawyoo(c, rp.Oid); err != nil {
  424. log.Error("s.noticeDao.Drawyoo(%d) error(%v)", rp.Oid, err)
  425. return
  426. }
  427. case model.SubTypeActivity:
  428. if title, link, err = s.noticeDao.Activity(c, rp.Oid); err != nil {
  429. log.Error("s.noticeDao.Activity(%d) error(%v)", rp.Oid, err)
  430. return
  431. }
  432. case model.SubTypeForbiden:
  433. title, link, err = s.noticeDao.Ban(c, rp.Oid)
  434. if err != nil {
  435. return
  436. }
  437. case model.SubTypeNotice:
  438. title, link, err = s.noticeDao.Notice(c, rp.Oid)
  439. if err != nil {
  440. return
  441. }
  442. case model.SubTypeActArc:
  443. if title, link, err = s.noticeDao.ActivitySub(c, rp.Oid); err != nil {
  444. log.Error("s.noticeDao.ActivitySub(%d) error(%v)", rp.Oid, err)
  445. return
  446. }
  447. case model.SubTypeArticle:
  448. var m map[int64]*artmdl.Meta
  449. arg := &artmdl.ArgAids{
  450. Aids: []int64{rp.Oid},
  451. }
  452. m, err = s.articleSrv.ArticleMetas(c, arg)
  453. if err != nil || m == nil {
  454. log.Error("s.articleSrv.ArticleMetas(%v) ret:%v error(%v)", arg, m, err)
  455. return
  456. }
  457. if meta, ok := m[rp.Oid]; ok {
  458. title = meta.Title
  459. link = fmt.Sprintf("http://www.bilibili.com/read/cv%d", rp.Oid)
  460. }
  461. case model.SubTypeLiveVideo:
  462. if title, link, err = s.noticeDao.LiveSmallVideo(c, rp.Oid); err != nil {
  463. log.Error("s.noticeDao.LiveSmallVideo(%d) error(%v)", rp.Oid, err)
  464. return
  465. }
  466. native = true
  467. case model.SubTypeLiveAct:
  468. if title, link, err = s.noticeDao.LiveActivity(c, rp.Oid); err != nil {
  469. log.Error("s.noticeDao.LiveActivity(%d) error(%v)", rp.Oid, err)
  470. return
  471. }
  472. case model.SubTypeLiveNotice:
  473. //if title, link, err = s.noticeDao.LiveNotice(c, rp.Oid); err != nil {
  474. // log.Error("s.noticeDao.LiveNotice(%d) error(%v)", rp.Oid, err)
  475. // return
  476. //}
  477. // NOTE 忽略直播公告跳转链接
  478. return
  479. case model.SubTypeLivePicture:
  480. if title, link, err = s.noticeDao.LivePicture(c, rp.Oid); err != nil {
  481. log.Error("s.noticeDao.LivePiture(%d) error(%v)", rp.Oid, err)
  482. return
  483. }
  484. native = true
  485. case model.SubTypeCredit:
  486. if title, link, err = s.noticeDao.Credit(c, rp.Oid); err != nil {
  487. log.Error("s.noticeDao.Credit(%d) error(%v)", rp.Oid, err)
  488. return
  489. }
  490. case model.SubTypeDynamic:
  491. if title, link, err = s.noticeDao.Dynamic(c, rp.Oid); err != nil {
  492. log.Error("s.noticeDao.Dynamic(%d) error(%v)", rp.Oid, err)
  493. return
  494. }
  495. native = true
  496. case model.SubTypeAudio:
  497. if title, link, err = s.noticeDao.Audio(c, rp.Oid); err != nil {
  498. log.Error("s.noticeDao.Audio(%d) error(%v)", rp.Oid, err)
  499. return
  500. }
  501. native = true
  502. case model.SubTypeAudioPlaylist:
  503. if title, link, err = s.noticeDao.AudioPlayList(c, rp.Oid); err != nil {
  504. log.Error("s.noticeDao.AudioPlayList(%d) error(%v)", rp.Oid, err)
  505. return
  506. }
  507. native = true
  508. default:
  509. return
  510. }
  511. tmp := []rune(title)
  512. if len(tmp) > _msgTitleSize {
  513. title = string(tmp[:_msgTitleSize])
  514. }
  515. jump = fmt.Sprintf("%s#reply%d", link, rp.RpID)
  516. tmp = []rune(rp.Content.Message)
  517. if len(tmp) > _msgContentSize {
  518. msg = string(tmp[:_msgContentSize])
  519. } else {
  520. msg = rp.Content.Message
  521. }
  522. if native {
  523. rootID := rp.Root
  524. if rootID == 0 {
  525. rootID = rp.RpID
  526. }
  527. nativeJump = fmt.Sprintf("bilibili://comment/detail/%d/%d/%d/?subType=%d&anchor=%d&showEnter=1&extraIntentId=%d", rp.Type, rp.Oid, rootID, subType, rp.RpID, extraIntentID)
  528. }
  529. return
  530. }
  531. func extraInfo(newJump string) string {
  532. var a = struct {
  533. CmNewURL struct {
  534. Title string `json:"title"`
  535. Content string `json:"content"`
  536. } `json:"cm_new_url"`
  537. }{
  538. CmNewURL: struct {
  539. Title string `json:"title"`
  540. Content string `json:"content"`
  541. }{
  542. Title: newJump,
  543. Content: newJump,
  544. },
  545. }
  546. b, _ := json.Marshal(a)
  547. return string(b)
  548. }