comment.go 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292
  1. package service
  2. import (
  3. "context"
  4. "fmt"
  5. "go-common/app/interface/bbq/app-bbq/api/http/v1"
  6. "go-common/app/interface/bbq/app-bbq/dao"
  7. "go-common/app/interface/bbq/app-bbq/model"
  8. notice "go-common/app/service/bbq/notice-service/api/v1"
  9. "go-common/library/ecode"
  10. "go-common/library/log"
  11. bm "go-common/library/net/http/blademaster"
  12. "net/url"
  13. "strconv"
  14. )
  15. //CommentSubCursor 游标评论列表
  16. func (s *Service) CommentSubCursor(c context.Context, mid int64, arg *v1.CommentSubCursorReq, device *bm.Device) (res *model.SubCursorRes, err error) {
  17. res = new(model.SubCursorRes)
  18. if _, err = s.dao.VideoBase(c, mid, arg.SvID); err != nil {
  19. log.Warnw(c, "log", "get video base fail", "svid", arg.SvID)
  20. return
  21. }
  22. req := map[string]interface{}{
  23. "oid": arg.SvID,
  24. "type": arg.Type,
  25. "sort": arg.Sort,
  26. "root": arg.Root,
  27. }
  28. if len(arg.Access) != 0 {
  29. req["access_key"] = arg.Access
  30. }
  31. if arg.RpID != 0 {
  32. req["rpid"] = arg.RpID
  33. }
  34. if arg.Size != 0 {
  35. req["size"] = arg.Size
  36. }
  37. if arg.MinID > 0 && arg.MaxID > 0 {
  38. err = ecode.ParamInvalid
  39. return
  40. }
  41. if arg.MinID != 0 {
  42. req["min_id"] = arg.MinID
  43. }
  44. if arg.MaxID != 0 {
  45. req["max_id"] = arg.MaxID
  46. }
  47. res, err = s.dao.ReplySubCursor(c, req)
  48. return
  49. }
  50. //CommentList 游标评论列表
  51. func (s *Service) CommentList(c context.Context, arg *v1.CommentListReq, device *bm.Device) (res *model.ReplyList, err error) {
  52. res = new(model.ReplyList)
  53. if _, err = s.dao.VideoBase(c, arg.MID, arg.SvID); err != nil {
  54. log.Warnw(c, "log", "get video base fail", "svid", arg.SvID)
  55. return
  56. }
  57. req := map[string]interface{}{
  58. "oid": arg.SvID,
  59. "type": arg.Type,
  60. "sort": arg.Sort,
  61. "nohot": arg.NoHot,
  62. }
  63. if len(arg.Access) != 0 {
  64. req["access_key"] = arg.Access
  65. }
  66. if arg.Pn != 0 {
  67. req["pn"] = arg.Pn
  68. }
  69. if arg.Ps != 0 {
  70. req["ps"] = arg.Ps
  71. }
  72. if device.Build != 0 {
  73. req["build"] = arg.Build
  74. }
  75. if device.RawPlatform != "" {
  76. req["plat"] = arg.Plat
  77. }
  78. if device.RawMobiApp != "" {
  79. req["mobi_app"] = device.RawMobiApp
  80. }
  81. res, err = s.dao.ReplyList(c, req)
  82. return
  83. }
  84. //CommentCursor 游标评论列表
  85. func (s *Service) CommentCursor(c context.Context, arg *v1.CommentCursorReq, device *bm.Device) (res *model.CursorRes, err error) {
  86. res = new(model.CursorRes)
  87. if _, err = s.dao.VideoBase(c, arg.MID, arg.SvID); err != nil {
  88. log.Warnw(c, "log", "get video base fail", "svid", arg.SvID)
  89. return
  90. }
  91. req := map[string]interface{}{
  92. "oid": arg.SvID,
  93. "type": arg.Type,
  94. "sort": arg.Sort,
  95. "max_id": arg.MaxID,
  96. "min_id": arg.MinID,
  97. "size": arg.Size,
  98. }
  99. if arg.RpID != 0 {
  100. req["rpid"] = arg.RpID
  101. }
  102. if len(arg.Access) != 0 {
  103. req["access_key"] = arg.Access
  104. }
  105. res, err = s.dao.ReplyCursor(c, req)
  106. return
  107. }
  108. //CommentAdd 发表评论评论服务
  109. func (s *Service) CommentAdd(c context.Context, mid int64, arg *v1.CommentAddReq, device *bm.Device) (res *model.AddRes, err error) {
  110. res = new(model.AddRes)
  111. // 屏蔽词
  112. level, filterErr := s.dao.Filter(c, arg.Message, dao.FilterAreaReply)
  113. if filterErr != nil {
  114. log.Errorv(c, log.KV("log", "filter fail"))
  115. } else if level >= dao.FilterLevel {
  116. err = ecode.CommentFilterErr
  117. log.Warnv(c, log.KV("log", fmt.Sprintf("content filter fail: content=%s, level=%d", arg.Message, level)))
  118. return
  119. }
  120. var upMid int64
  121. videoBase, err := s.dao.VideoBase(c, mid, arg.SvID)
  122. if err != nil {
  123. log.Warnw(c, "log", "get video base fail", "svid", arg.SvID)
  124. return
  125. }
  126. upMid = videoBase.Mid
  127. parentMid := upMid
  128. req := map[string]interface{}{
  129. "oid": arg.SvID,
  130. "type": arg.Type,
  131. "message": arg.Message,
  132. "access_key": arg.AccessKey,
  133. }
  134. if arg.At != "" {
  135. req["at"] = arg.At
  136. }
  137. if arg.Parent != 0 {
  138. req["parent"] = arg.Parent
  139. req["root"] = arg.Root
  140. } else if arg.Root != 0 {
  141. req["root"] = arg.Root
  142. }
  143. if arg.Plat != 0 {
  144. req["plat"] = arg.Plat
  145. }
  146. if arg.Device != "" {
  147. req["device"] = arg.Plat
  148. }
  149. if arg.Code != "" {
  150. req["code"] = arg.Code
  151. }
  152. res, err = s.dao.ReplyAdd(c, req)
  153. //wrap error
  154. switch ecode.Cause(err).Code() {
  155. case ecode.ReplyDeniedAsCaptcha.Code():
  156. err = ecode.CommentForbidden
  157. case ecode.ReplyContentOver.Code():
  158. err = ecode.CommentLengthIllegal
  159. }
  160. // 推送评论给通知中心
  161. if err == nil {
  162. title := "评论了你的作品"
  163. bizType := int32(notice.NoticeBizTypeSv)
  164. rootID := res.RpID
  165. if arg.Parent != 0 {
  166. title = "回复了你的评论"
  167. bizType = int32(notice.NoticeBizTypeComment)
  168. rootID = arg.Parent
  169. // get root comment's owner
  170. list, tmpErr := s.dao.ReplyMinfo(c, arg.SvID, []int64{arg.Parent})
  171. if tmpErr != nil || len(list) == 0 {
  172. log.Warnv(c, log.KV("log", "get root reply rpid info fail"), log.KV("rsp_size", len(list)))
  173. return
  174. }
  175. reply, exists := list[arg.Parent]
  176. if !exists {
  177. log.Errorv(c, log.KV("log", "not found reply rpid's info"))
  178. return
  179. } else if reply.Mid == 0 {
  180. log.Errorv(c, log.KV("log", "reply rpid's owner mid=0"))
  181. return
  182. }
  183. parentMid = reply.Mid
  184. }
  185. if parentMid == mid {
  186. log.V(1).Infov(c, log.KV("log", "action_mid=mid"), log.KV("mid", mid))
  187. return
  188. }
  189. urlVal := make(url.Values)
  190. urlVal.Add("svid", strconv.FormatInt(arg.SvID, 10))
  191. urlVal.Add("rootid", strconv.FormatInt(rootID, 10))
  192. urlVal.Add("rpid", strconv.FormatInt(res.RpID, 10))
  193. jumpURL := fmt.Sprintf("qing://commentdetail?%s", urlVal.Encode())
  194. notice := &notice.NoticeBase{
  195. Mid: parentMid, ActionMid: mid, SvId: arg.SvID, NoticeType: notice.NoticeTypeComment, Title: title, Text: arg.Message,
  196. JumpUrl: jumpURL, BizType: bizType, BizId: res.RpID}
  197. tmpErr := s.dao.CreateNotice(c, notice)
  198. if tmpErr != nil {
  199. log.Error("create comment notice fail: notice_msg=%s", notice.String())
  200. }
  201. }
  202. return
  203. }
  204. //CommentLike 评论点赞服务
  205. func (s *Service) CommentLike(c context.Context, mid int64, arg *v1.CommentLikeReq, device *bm.Device) (err error) {
  206. if _, err = s.dao.VideoBase(c, mid, arg.SvID); err != nil {
  207. log.Warnw(c, "log", "get video base fail", "svid", arg.SvID)
  208. return
  209. }
  210. req := map[string]interface{}{
  211. "oid": arg.SvID,
  212. "type": arg.Type,
  213. "rpid": arg.RpID,
  214. "action": arg.Action,
  215. "access_key": arg.AccessKey,
  216. }
  217. err = s.dao.ReplyLike(c, req)
  218. if ecode.Cause(err).Code() == ecode.ReplyForbidAction.Code() {
  219. err = ecode.CommentForbidLike
  220. return
  221. }
  222. // TODO: 推送评论给通知中心
  223. if arg.Action == 1 && err == nil {
  224. // get root comment's owner
  225. list, tmpErr := s.dao.ReplyMinfo(c, arg.SvID, []int64{arg.RpID})
  226. if tmpErr != nil || len(list) == 0 {
  227. log.Warnv(c, log.KV("log", "get root rpid info fail"))
  228. return
  229. }
  230. reply, exists := list[arg.RpID]
  231. if !exists {
  232. log.Errorv(c, log.KV("log", "not found reply rpid's info"))
  233. return
  234. } else if reply.Mid == 0 {
  235. log.Errorv(c, log.KV("log", "reply rpid's owner mid=0"))
  236. return
  237. }
  238. parentMid := reply.Mid
  239. if parentMid == mid {
  240. log.V(1).Infov(c, log.KV("log", "action_mid=mid"), log.KV("mid", mid))
  241. return
  242. }
  243. text := ""
  244. if reply.Content != nil {
  245. text = reply.Content.Message
  246. }
  247. title := "点赞了你的评论"
  248. bizType := int32(notice.NoticeBizTypeComment)
  249. notice := &notice.NoticeBase{
  250. Mid: parentMid, ActionMid: mid, SvId: arg.SvID, NoticeType: notice.NoticeTypeLike, Title: title, Text: text,
  251. BizType: bizType, BizId: arg.RpID}
  252. tmpErr = s.dao.CreateNotice(c, notice)
  253. if tmpErr != nil {
  254. log.Errorv(c, log.KV("log", "create like notice fail: notice_msg="+notice.String()+", err="+err.Error()))
  255. return
  256. }
  257. }
  258. return
  259. }
  260. //CommentReport 评论举报服务
  261. func (s *Service) CommentReport(c context.Context, arg *v1.CommentReportReq) (err error) {
  262. req := map[string]interface{}{
  263. "oid": arg.SvID,
  264. "type": arg.Type,
  265. "rpid": arg.RpID,
  266. "reason": arg.Reason,
  267. "access_key": arg.AccessKey,
  268. }
  269. if arg.Content != "" {
  270. req["content"] = arg.Content
  271. }
  272. err = s.dao.ReplyReport(c, req)
  273. return
  274. }