reply.go 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363
  1. package model
  2. import (
  3. "encoding/binary"
  4. "encoding/json"
  5. "net"
  6. "strconv"
  7. "strings"
  8. "time"
  9. rl "go-common/app/service/main/relation/model"
  10. xtime "go-common/library/time"
  11. )
  12. // State 评论状态
  13. const (
  14. StateNormal int32 = 0 // 正常
  15. StateHidden int32 = 1 // up主隐藏
  16. StateFiltered int32 = 2 // 敏感词过滤 @Deprecated to use attr 3
  17. StateDelAdmin int32 = 3 // 管理员删除
  18. StateDelUser int32 = 4 // 用户删除
  19. StateMonitor int32 = 5 // 监控中
  20. StateGarbage int32 = 6 // 大数据过虑 @Deprecated to use attr 2
  21. StateTopAdmin int32 = 7 // 管理员置顶 @Deprecated to use attr 1
  22. StateDelUpper int32 = 8 // up主删除
  23. StateBlacklist int32 = 9 // 黑名单屏蔽
  24. StateDelAssist int32 = 10 // 协管删除
  25. StatePending int32 = 11 // 先审后发
  26. StateFolded int32 = 12 // 被折叠
  27. )
  28. // Attr 评论属性
  29. const (
  30. AttrTopAdmin uint32 = 0 // 管理员置顶
  31. AttrTopUpper uint32 = 1 // up主置顶
  32. AttrGarbage uint32 = 2 // 大数据过滤
  33. AttrFiltered uint32 = 3 // 敏感词过滤
  34. // 有子评论被折叠
  35. AttrFolded uint32 = 7
  36. )
  37. // SortBy 排序方式
  38. const (
  39. SortByFloor int32 = 0 // 按楼层排序
  40. SortByCount int32 = 1 // 按评论数排序
  41. SortByLike int32 = 2 // 按点赞数排序
  42. )
  43. // 折叠评论类型
  44. const (
  45. FolderKindSub = "s"
  46. FolderKindRoot = "r"
  47. )
  48. // SearchParams reply params.
  49. type SearchParams struct {
  50. Type int32
  51. Oid int64
  52. TypeIds string
  53. Keyword string
  54. KeywordHigh string
  55. UID int64
  56. Uname string
  57. AdminID int64
  58. AdminName string
  59. Begin time.Time
  60. End time.Time
  61. States string
  62. IP int64
  63. Attr string
  64. Sort string
  65. Order string
  66. }
  67. // ReplySearchResponse ReplySearchResponse
  68. type ReplySearchResponse struct {
  69. SearchResult
  70. Pager Pager `json:"pager"`
  71. }
  72. // SearchResult search result.
  73. type SearchResult struct {
  74. Code int `json:"code"`
  75. Message string `json:"msg,omitempty"`
  76. Order string `json:"order"`
  77. Page int64 `json:"page"`
  78. PageSize int64 `json:"pagesize"`
  79. PageCount int64 `json:"pagecount"`
  80. Total int64 `json:"total"`
  81. Result []*SearchReply `json:"result"`
  82. }
  83. // SearchReply search reply.
  84. type SearchReply struct {
  85. // 评论基础信息
  86. ID int64 `json:"id"`
  87. Type int8 `json:"type"`
  88. Oid int64 `json:"oid"`
  89. OidStr string `json:"oid_str"`
  90. State int8 `json:"state"`
  91. Floor int64 `json:"floor"`
  92. Ctime string `json:"ctime"`
  93. Mtime string `json:"mtime"`
  94. Attr Attr `json:"attr"`
  95. Title string `json:"title"`
  96. // 评论人的相关信息
  97. Mid int64 `json:"mid"`
  98. Stat *rl.Stat `json:"stat"`
  99. Replier string `json:"replier"`
  100. IP IP `json:"ip"`
  101. Message string `json:"message"`
  102. Typeid int `json:"typeid"`
  103. Root int `json:"root"`
  104. // 后台操作信息
  105. AdminID int64 `json:"adminid"`
  106. AdminName string `json:"admin_name"`
  107. Opremark string `json:"opremark"`
  108. Opresult string `json:"opresult"`
  109. OpCtime string `json:"opctime"`
  110. RedirectURL string `json:"redirect_url"`
  111. // 搜索返回的额外数据
  112. DocID string `json:"doc_id"`
  113. }
  114. type IP int64
  115. func (ip *IP) UnmarshalJSON(b []byte) error {
  116. if string(b) == "" {
  117. return nil
  118. }
  119. str := strings.Trim(string(b), `"`)
  120. ipI := net.ParseIP(str).To4()
  121. if ipI == nil {
  122. return nil
  123. }
  124. *ip = IP(int64(binary.BigEndian.Uint32(ipI)))
  125. return nil
  126. }
  127. type Attr []int32
  128. func (a *Attr) UnmarshalJSON(b []byte) error {
  129. var s []int32
  130. err := json.Unmarshal(b, &s)
  131. if err != nil {
  132. attr, err := strconv.ParseInt(string(b), 10, 64)
  133. if err != nil {
  134. return err
  135. }
  136. var i int32 = 1
  137. for attr != 0 && i < 64 {
  138. if attr&1 == 1 {
  139. *a = append(*a, i)
  140. }
  141. attr = attr >> 1
  142. i++
  143. }
  144. } else {
  145. *a = s
  146. }
  147. return nil
  148. }
  149. // Reply info.b
  150. type ReplyEx struct {
  151. Reply
  152. IsUp bool `json:"is_up"`
  153. RootFloor int32 `json:"root_floor"`
  154. }
  155. // Reply info.
  156. type Reply struct {
  157. ID int64 `json:"rpid"`
  158. Oid int64 `json:"oid"`
  159. Type int32 `json:"type"`
  160. Mid int64 `json:"mid"`
  161. Root int64 `json:"root"`
  162. Parent int64 `json:"parent"`
  163. Dialog int64 `json:"dialog"`
  164. Count int32 `json:"count"`
  165. MCount int32 `json:"mcount"`
  166. RCount int32 `json:"rcount"`
  167. Floor int32 `json:"floor"`
  168. State int32 `json:"state"`
  169. Attr uint32 `json:"attr"`
  170. CTime xtime.Time `json:"ctime"`
  171. MTime xtime.Time `json:"-"`
  172. // action info
  173. Like int32 `json:"like"`
  174. Hate int32 `json:"hate"`
  175. Action int32 `json:"action"`
  176. Content *ReplyContent `json:"content"`
  177. }
  178. // HasFolded ...
  179. func (r *Reply) HasFolded() bool {
  180. return r.AttrVal(AttrFolded) == AttrYes
  181. }
  182. // MarkHasFolded ...
  183. func (r *Reply) MarkHasFolded() {
  184. r.AttrSet(AttrYes, AttrFolded)
  185. }
  186. // UnmarkHasFolded ...
  187. func (r *Reply) UnmarkHasFolded() {
  188. r.AttrSet(AttrNo, AttrFolded)
  189. }
  190. // DenyFolded ...
  191. func (r *Reply) DenyFolded() bool {
  192. return r.IsTop() || !r.AllowFoldState() || r.Type == SubTypeArticle
  193. }
  194. // AllowFoldState ...
  195. func (r *Reply) AllowFoldState() bool {
  196. return r.State == StateNormal || r.State == StateHidden || r.State == StateFiltered || r.State == StateGarbage
  197. }
  198. // IsFolded .
  199. func (r *Reply) IsFolded() bool {
  200. return r.State == StateFolded
  201. }
  202. // IsRoot root.
  203. func (r *Reply) IsRoot() bool {
  204. return r.Root == 0
  205. }
  206. // IsTop top.
  207. func (r *Reply) IsTop() bool {
  208. if r.Attr != 0 && (r.AttrVal(AttrTopAdmin) == 1 || r.AttrVal(AttrTopUpper) == 1) {
  209. return true
  210. }
  211. return false
  212. }
  213. // IsDeleted deleted.
  214. func (r *Reply) IsDeleted() bool {
  215. return r.State == StateDelUser || r.State == StateDelUpper || r.State == StateDelAdmin
  216. }
  217. // AttrVal return val of reply'attr
  218. func (r *Reply) AttrVal(bit uint32) uint32 {
  219. if r.Attr == 0 {
  220. return uint32(0)
  221. }
  222. return (r.Attr >> bit) & uint32(1)
  223. }
  224. // AttrSet set attr of reply'attr
  225. func (r *Reply) AttrSet(v uint32, bit uint32) {
  226. r.Attr = r.Attr&(^(1 << bit)) | (v << bit)
  227. }
  228. // IsNormal IsNormal
  229. func (r *Reply) IsNormal() bool {
  230. return r.State == StateNormal || r.State == StateHidden || r.State == StateFiltered || r.State == StateMonitor || r.State == StateGarbage || r.State == StateTopAdmin || r.State == StateFolded
  231. }
  232. func (r *Reply) IsPending() bool {
  233. return r.State == StatePending
  234. }
  235. // LegalSubjectType LegalSubjectType
  236. func LegalSubjectType(tp int32) bool {
  237. return SubTypeArchive <= tp && tp <= SubTypeComicEpisode
  238. }
  239. // ReplyContent define reply content
  240. type ReplyContent struct {
  241. ID int64 `json:"-"`
  242. Message string `json:"message"`
  243. Ats Int64Bytes `json:"ats,omitempty"`
  244. IP uint32 `json:"ipi,omitempty"`
  245. Plat int8 `json:"plat"`
  246. Device string `json:"device"`
  247. Version string `json:"version,omitempty"`
  248. CTime xtime.Time `json:"-"`
  249. MTime xtime.Time `json:"-"`
  250. }
  251. // LogSearchParam LogSearchParam
  252. type LogSearchParam struct {
  253. Oid int64
  254. Type int32
  255. Mid int64
  256. CtimeFrom string
  257. CtimeTo string
  258. Action string
  259. Pn int64
  260. Ps int64
  261. Other int64
  262. Sort string
  263. Order string
  264. Group string
  265. Appid string
  266. }
  267. // ReplyTopLogResult ReplyTopLogResult
  268. type ReplyTopLogResult struct {
  269. Logs []*ReplyTopLog `json:"logs"`
  270. Page Page `json:"page"`
  271. Order string `json:"order"`
  272. Sort string `json:"sort"`
  273. }
  274. // ReplyTopLog ReplyTopLog
  275. type ReplyTopLog struct {
  276. AdminID int64 `json:"adminid"`
  277. AdminName string `json:"admin_name"`
  278. Oid int64 `json:"oid"`
  279. Type int32 `json:"type"`
  280. Title string `json:"title"`
  281. RedirectURL string `json:"redirect_url"`
  282. Remark string `json:"remark"`
  283. UserName string `json:"username"`
  284. Mid int64 `json:"mid"`
  285. CTime string `json:"ctime"`
  286. RpID int64 `json:"rpid"`
  287. Action int64 `json:"action"`
  288. }
  289. // ExportedReply exported reply struct
  290. type ExportedReply struct {
  291. ID int64 `json:"rpid"`
  292. Oid int64 `json:"oid"`
  293. Type int32 `json:"type"`
  294. Mid int64 `json:"mid"`
  295. Root int64 `json:"root"`
  296. Parent int64 `json:"parent"`
  297. Count int32 `json:"count"`
  298. RCount int32 `json:"rcount"`
  299. Like int32 `json:"like"`
  300. Hate int32 `json:"hate"`
  301. Floor int32 `json:"floor"`
  302. State int32 `json:"state"`
  303. Attr int32 `json:"attr"`
  304. CTime time.Time `json:"ctime"`
  305. Message string `json:"message"`
  306. }
  307. // String convert ExportedReply to string
  308. func (e *ExportedReply) String() (s []string) {
  309. s = append(s, strconv.FormatInt(e.ID, 10))
  310. s = append(s, strconv.FormatInt(e.Oid, 10))
  311. s = append(s, strconv.FormatInt(int64(e.Type), 10))
  312. s = append(s, strconv.FormatInt(e.Mid, 10))
  313. s = append(s, strconv.FormatInt(e.Root, 10))
  314. s = append(s, strconv.FormatInt(e.Parent, 10))
  315. s = append(s, strconv.FormatInt(int64(e.Count), 10))
  316. s = append(s, strconv.FormatInt(int64(e.RCount), 10))
  317. s = append(s, strconv.FormatInt(int64(e.Like), 10))
  318. s = append(s, strconv.FormatInt(int64(e.Hate), 10))
  319. s = append(s, strconv.FormatInt(int64(e.Floor), 10))
  320. s = append(s, strconv.FormatInt(int64(e.State), 10))
  321. s = append(s, strconv.FormatInt(int64(e.Attr), 10))
  322. s = append(s, e.CTime.String())
  323. s = append(s, e.Message)
  324. return
  325. }