cursor.go 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418
  1. package http
  2. import (
  3. "strconv"
  4. "go-common/app/interface/main/reply/conf"
  5. model "go-common/app/interface/main/reply/model/reply"
  6. xmodel "go-common/app/interface/main/reply/model/xreply"
  7. "go-common/library/ecode"
  8. "go-common/library/log"
  9. bm "go-common/library/net/http/blademaster"
  10. "go-common/library/net/metadata"
  11. )
  12. func subReplyByCursor(ctx *bm.Context) {
  13. params := ctx.Request.Form
  14. oid, err := strconv.ParseInt(params.Get("oid"), 10, 64)
  15. if err != nil {
  16. ctx.JSON(nil, ecode.RequestErr)
  17. return
  18. }
  19. var build int64
  20. appStr := params.Get("mobi_app")
  21. buildStr := params.Get("build")
  22. if buildStr != "" {
  23. build, err = strconv.ParseInt(buildStr, 10, 64)
  24. if err != nil {
  25. log.Warn("strconv.ParseInt(build %s) err(%v)", buildStr, err)
  26. err = ecode.RequestErr
  27. ctx.JSON(nil, err)
  28. return
  29. }
  30. }
  31. otyp, err := strconv.ParseInt(params.Get("type"), 10, 8)
  32. if err != nil {
  33. ctx.JSON(nil, ecode.RequestErr)
  34. return
  35. }
  36. var size int64
  37. if params.Get("size") != "" {
  38. size, err = strconv.ParseInt(params.Get("size"), 10, 64)
  39. if err != nil {
  40. ctx.JSON(nil, ecode.RequestErr)
  41. return
  42. }
  43. }
  44. if size <= 0 || size > int64(conf.Conf.Reply.MaxPageSize) {
  45. size = int64(conf.Conf.Reply.MaxPageSize)
  46. }
  47. var (
  48. rootID int64
  49. replyID int64
  50. cursor *model.Cursor
  51. )
  52. if params.Get("rpid") != "" {
  53. // jump subReply
  54. replyID, err = strconv.ParseInt(params.Get("rpid"), 10, 64)
  55. if err != nil {
  56. ctx.JSON(nil, ecode.RequestErr)
  57. return
  58. }
  59. rootID, cursor, err = rpSvr.NewSubCursorByReplyID(ctx, oid, int8(otyp), replyID, int(size), model.OrderASC)
  60. if err != nil {
  61. ctx.JSON(nil, err)
  62. return
  63. }
  64. } else {
  65. var maxID, minID int64
  66. if params.Get("min_id") != "" {
  67. minID, err = strconv.ParseInt(params.Get("min_id"), 10, 64)
  68. if err != nil {
  69. ctx.JSON(nil, ecode.RequestErr)
  70. return
  71. }
  72. }
  73. if params.Get("max_id") != "" {
  74. maxID, err = strconv.ParseInt(params.Get("max_id"), 10, 64)
  75. if err != nil {
  76. ctx.JSON(nil, ecode.RequestErr)
  77. return
  78. }
  79. }
  80. cursor, err = model.NewCursor(maxID, minID, int(size), model.OrderASC)
  81. if err != nil {
  82. ctx.JSON(nil, ecode.RequestErr)
  83. return
  84. }
  85. }
  86. if rootID <= 0 {
  87. rootID, err = strconv.ParseInt(params.Get("root"), 10, 64)
  88. if err != nil {
  89. ctx.JSON(nil, ecode.RequestErr)
  90. return
  91. }
  92. }
  93. var (
  94. showFolded bool
  95. scene int64
  96. )
  97. // 消息中心折叠的评论也要给加回来,这里约定他们传一个scene=1
  98. if params.Get("scene") != "" {
  99. scene, _ = strconv.ParseInt(params.Get("scene"), 10, 64)
  100. }
  101. if model.ShouldShowFolded(params.Get("mobi_app"), build, scene) {
  102. showFolded = true
  103. }
  104. // 这里老版本折叠评论也要显示
  105. cursorParams := &model.CursorParams{
  106. IP: metadata.String(ctx, metadata.RemoteIP),
  107. Oid: oid,
  108. RootID: rootID,
  109. OTyp: int8(otyp),
  110. HTMLEscape: params.Get("mobi_app") == "",
  111. Cursor: cursor,
  112. ShowFolded: showFolded,
  113. }
  114. if m, ok := ctx.Get("mid"); ok {
  115. cursorParams.Mid = m.(int64)
  116. }
  117. cursorRes, err := rpSvr.GetSubReplyListByCursor(ctx, cursorParams)
  118. if err != nil {
  119. ctx.JSON(nil, err)
  120. return
  121. }
  122. var blacklist, assist int
  123. if mid := cursorParams.Mid; mid > 0 {
  124. if !rpSvr.IsWhiteAid(cursorParams.Oid, int8(cursorParams.OTyp)) {
  125. if rpSvr.RelationBlocked(ctx, cursorRes.Subject.Mid, mid) {
  126. blacklist = 1
  127. }
  128. if ok, _ := rpSvr.CheckAssist(ctx, cursorRes.Subject.Mid, mid); ok {
  129. assist = 1
  130. }
  131. }
  132. }
  133. var config xmodel.ReplyConfig
  134. config.ShowFloor = 1
  135. if !rpSvr.ShowFloor(cursorParams.Oid, cursorParams.OTyp) {
  136. config.ShowFloor = 0
  137. }
  138. rootReply := cursorRes.Roots[0]
  139. if showFolded {
  140. rootReply.Folder.HasFolded = false
  141. }
  142. rpSvr.EmojiReplaceI(appStr, build, rootReply)
  143. data := map[string]interface{}{
  144. "assist": assist,
  145. "blacklist": blacklist,
  146. "upper": map[string]interface{}{
  147. "mid": cursorRes.Subject.Mid,
  148. },
  149. "root": rootReply,
  150. "cursor": map[string]interface{}{
  151. "all_count": rootReply.RCount,
  152. "max_id": cursorRes.CursorRangeMax,
  153. "min_id": cursorRes.CursorRangeMin,
  154. "size": len(rootReply.Replies),
  155. },
  156. "config": config,
  157. }
  158. ctx.JSON(data, err)
  159. }
  160. func replyByCursor(ctx *bm.Context) {
  161. params := ctx.Request.Form
  162. buvid := ctx.Request.Header.Get("buvid")
  163. oid, err := strconv.ParseInt(params.Get("oid"), 10, 64)
  164. if err != nil {
  165. log.Warn("%v", err)
  166. err = ecode.RequestErr
  167. ctx.JSON(nil, err)
  168. return
  169. }
  170. otyp, err := strconv.ParseInt(params.Get("type"), 10, 8)
  171. if err != nil {
  172. log.Warn("%v", err)
  173. err = ecode.RequestErr
  174. ctx.JSON(nil, err)
  175. return
  176. }
  177. var sort int64
  178. if params.Get("sort") != "" {
  179. sort, err = strconv.ParseInt(params.Get("sort"), 10, 8)
  180. if err != nil {
  181. log.Warn("%v", err)
  182. err = ecode.RequestErr
  183. ctx.JSON(nil, err)
  184. return
  185. }
  186. }
  187. plat := int64(model.PlatWeb)
  188. if params.Get("plat") != "" {
  189. plat, err = strconv.ParseInt(params.Get("plat"), 10, 8)
  190. if err != nil {
  191. log.Warn("%v", err)
  192. err = ecode.RequestErr
  193. ctx.JSON(nil, err)
  194. return
  195. }
  196. }
  197. var build int64
  198. if params.Get("build") != "" {
  199. build, err = strconv.ParseInt(params.Get("build"), 10, 64)
  200. if err != nil {
  201. log.Warn("%v", err)
  202. err = ecode.RequestErr
  203. ctx.JSON(nil, err)
  204. return
  205. }
  206. }
  207. var size int64
  208. if params.Get("size") != "" {
  209. size, err = strconv.ParseInt(params.Get("size"), 10, 32)
  210. if err != nil {
  211. log.Warn("%v", err)
  212. err = ecode.RequestErr
  213. ctx.JSON(nil, err)
  214. return
  215. }
  216. }
  217. if size <= 0 || size > int64(conf.Conf.Reply.MaxPageSize) {
  218. size = int64(conf.Conf.Reply.MaxPageSize)
  219. }
  220. var (
  221. replyID int64
  222. cursor *model.Cursor
  223. )
  224. if params.Get("rpid") != "" {
  225. // jump root reply
  226. replyID, err = strconv.ParseInt(params.Get("rpid"), 10, 64)
  227. if err != nil {
  228. log.Warn("%v", err)
  229. err = ecode.RequestErr
  230. ctx.JSON(nil, err)
  231. return
  232. }
  233. cursor, err = rpSvr.NewCursorByReplyID(ctx, oid, int8(otyp), replyID, int(size), model.OrderDESC)
  234. } else {
  235. var maxID, minID int64
  236. if params.Get("min_id") != "" {
  237. minID, err = strconv.ParseInt(params.Get("min_id"), 10, 64)
  238. if err != nil {
  239. log.Warn("%v", err)
  240. err = ecode.RequestErr
  241. ctx.JSON(nil, err)
  242. return
  243. }
  244. }
  245. if params.Get("max_id") != "" {
  246. maxID, err = strconv.ParseInt(params.Get("max_id"), 10, 64)
  247. if err != nil {
  248. log.Warn("%v", err)
  249. err = ecode.RequestErr
  250. ctx.JSON(nil, err)
  251. return
  252. }
  253. }
  254. cursor, err = model.NewCursor(maxID, minID, int(size), model.OrderDESC)
  255. }
  256. if err != nil {
  257. log.Warn("%v", err)
  258. err = ecode.RequestErr
  259. ctx.JSON(nil, err)
  260. return
  261. }
  262. appStr := params.Get("mobi_app")
  263. var showFolded bool
  264. // 对于根评论 scene传0, 只需要做版本的兼容即可
  265. if model.ShouldShowFolded(params.Get("mobi_app"), build, 0) {
  266. showFolded = true
  267. }
  268. cursorParams := &model.CursorParams{
  269. IP: metadata.String(ctx, metadata.RemoteIP),
  270. Oid: oid,
  271. OTyp: int8(otyp),
  272. Sort: int8(sort),
  273. HTMLEscape: appStr == "",
  274. Cursor: cursor,
  275. HotSize: 5,
  276. Mid: metadata.Int64(ctx, metadata.Mid),
  277. ShowFolded: showFolded,
  278. }
  279. if m, ok := ctx.Get("mid"); ok {
  280. cursorParams.Mid = m.(int64)
  281. }
  282. cursorRes, err := rpSvr.GetRootReplyListByCursor(ctx, cursorParams)
  283. if err != nil {
  284. ctx.JSON(nil, err)
  285. return
  286. }
  287. var blacklist, assist int
  288. if mid := cursorParams.Mid; mid > 0 {
  289. if !rpSvr.IsWhiteAid(cursorParams.Oid, int8(cursorParams.OTyp)) {
  290. if rpSvr.RelationBlocked(ctx, cursorRes.Subject.Mid, mid) {
  291. blacklist = 1
  292. }
  293. if ok, _ := rpSvr.CheckAssist(ctx, cursorRes.Subject.Mid, mid); ok {
  294. assist = 1
  295. }
  296. }
  297. }
  298. rpSvr.EmojiReplace(int8(plat), build, cursorRes.Roots...)
  299. rpSvr.EmojiReplaceI(appStr, build, cursorRes.Roots...)
  300. cursorRes.Roots = rpSvr.FilDelReply(cursorRes.Roots)
  301. m := map[string]interface{}{
  302. "assist": assist,
  303. "blacklist": blacklist,
  304. "replies": cursorRes.Roots,
  305. "upper": map[string]interface{}{
  306. "mid": cursorRes.Subject.Mid,
  307. },
  308. "cursor": map[string]interface{}{
  309. "all_count": cursorRes.Subject.ACount,
  310. "max_id": cursorRes.CursorRangeMax,
  311. "min_id": cursorRes.CursorRangeMin,
  312. "size": len(cursorRes.Roots),
  313. },
  314. }
  315. if cursorRes.Header != nil {
  316. rpSvr.EmojiReplace(int8(plat), build, cursorRes.Header.Hots...)
  317. rpSvr.EmojiReplace(int8(plat), build, cursorRes.Header.TopAdmin)
  318. rpSvr.EmojiReplace(int8(plat), build, cursorRes.Header.TopUpper)
  319. rpSvr.EmojiReplaceI(appStr, build, cursorRes.Header.Hots...)
  320. rpSvr.EmojiReplaceI(appStr, build, cursorRes.Header.TopAdmin)
  321. rpSvr.EmojiReplaceI(appStr, build, cursorRes.Header.TopUpper)
  322. cursorRes.Header.Hots = rpSvr.FilDelReply(cursorRes.Header.Hots)
  323. showEntry, showAdmin, showFloor := 1, 1, 1
  324. if config, _ := rpSvr.GetReplyLogConfig(ctx, cursorRes.Subject, 1); config != nil {
  325. showEntry = int(config.ShowEntry)
  326. showAdmin = int(config.ShowAdmin)
  327. }
  328. if !rpSvr.ShowFloor(cursorParams.Oid, cursorParams.OTyp) {
  329. showFloor = 0
  330. }
  331. m["config"] = map[string]int{
  332. "showentry": showEntry,
  333. "showadmin": showAdmin,
  334. "showfloor": showFloor,
  335. }
  336. if cursorRes.Subject.RCount <= 20 && len(cursorRes.Header.Hots) > 0 {
  337. cursorRes.Header.Hots = cursorRes.Header.Hots[:0]
  338. }
  339. m["hots"] = cursorRes.Header.Hots
  340. m["notice"] = rpSvr.RplyNotice(ctx, int8(plat), build, appStr, buvid)
  341. m["top"] = map[string]interface{}{
  342. "admin": cursorRes.Header.TopAdmin,
  343. "upper": cursorRes.Header.TopUpper,
  344. }
  345. }
  346. ctx.JSON(m, err)
  347. }
  348. func dialogByCursor(c *bm.Context) {
  349. var mid int64
  350. v := new(struct {
  351. Oid int64 `form:"oid" validate:"required"`
  352. Type int8 `form:"type" validate:"required"`
  353. Root int64 `form:"root" validate:"required"`
  354. Dialog int64 `form:"dialog" validate:"required"`
  355. Size int `form:"size" validate:"min=1"`
  356. MinFloor int64 `form:"min_floor"`
  357. MaxFloor int64 `form:"max_floor"`
  358. Plat int64 `form:"plat"`
  359. Build int64 `form:"build"`
  360. MobiApp string `form:"mobi_app"`
  361. })
  362. // buvid := c.Request.Header.Get("buvid")
  363. var err error
  364. err = c.Bind(v)
  365. if err != nil {
  366. return
  367. }
  368. if v.Size > conf.Conf.Reply.MaxPageSize {
  369. v.Size = conf.Conf.Reply.MaxPageSize
  370. }
  371. if m, ok := c.Get("mid"); ok {
  372. mid = m.(int64)
  373. }
  374. cursor, err := model.NewCursor(v.MaxFloor, v.MinFloor, v.Size, model.OrderASC)
  375. if err != nil {
  376. err = ecode.RequestErr
  377. c.JSON(nil, err)
  378. return
  379. }
  380. rps, dialogCursor, dialogMeta, err := rpSvr.DialogByCursor(c, mid, v.Oid, v.Type, v.Root, v.Dialog, cursor)
  381. if err != nil {
  382. log.Error("rpSvr.DialogByCursor error (%v)", err)
  383. c.JSON(nil, err)
  384. return
  385. }
  386. rpSvr.EmojiReplaceI(v.MobiApp, v.Build, rps...)
  387. var config xmodel.ReplyConfig
  388. config.ShowFloor = 1
  389. if !rpSvr.ShowFloor(v.Oid, v.Type) {
  390. config.ShowFloor = 0
  391. }
  392. data := map[string]interface{}{
  393. "cursor": dialogCursor,
  394. "dialog": dialogMeta,
  395. "replies": rps,
  396. "config": config,
  397. }
  398. c.JSON(data, nil)
  399. }