You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
363 lines
9.0 KiB
363 lines
9.0 KiB
package model |
|
|
|
import ( |
|
"encoding/binary" |
|
"encoding/json" |
|
"net" |
|
"strconv" |
|
"strings" |
|
"time" |
|
|
|
rl "go-common/app/service/main/relation/model" |
|
xtime "go-common/library/time" |
|
) |
|
|
|
// State 评论状态 |
|
const ( |
|
StateNormal int32 = 0 // 正常 |
|
StateHidden int32 = 1 // up主隐藏 |
|
StateFiltered int32 = 2 // 敏感词过滤 @Deprecated to use attr 3 |
|
StateDelAdmin int32 = 3 // 管理员删除 |
|
StateDelUser int32 = 4 // 用户删除 |
|
StateMonitor int32 = 5 // 监控中 |
|
StateGarbage int32 = 6 // 大数据过虑 @Deprecated to use attr 2 |
|
StateTopAdmin int32 = 7 // 管理员置顶 @Deprecated to use attr 1 |
|
StateDelUpper int32 = 8 // up主删除 |
|
StateBlacklist int32 = 9 // 黑名单屏蔽 |
|
StateDelAssist int32 = 10 // 协管删除 |
|
StatePending int32 = 11 // 先审后发 |
|
StateFolded int32 = 12 // 被折叠 |
|
) |
|
|
|
// Attr 评论属性 |
|
const ( |
|
AttrTopAdmin uint32 = 0 // 管理员置顶 |
|
AttrTopUpper uint32 = 1 // up主置顶 |
|
AttrGarbage uint32 = 2 // 大数据过滤 |
|
AttrFiltered uint32 = 3 // 敏感词过滤 |
|
|
|
// 有子评论被折叠 |
|
AttrFolded uint32 = 7 |
|
) |
|
|
|
// SortBy 排序方式 |
|
const ( |
|
SortByFloor int32 = 0 // 按楼层排序 |
|
SortByCount int32 = 1 // 按评论数排序 |
|
SortByLike int32 = 2 // 按点赞数排序 |
|
) |
|
|
|
// 折叠评论类型 |
|
const ( |
|
FolderKindSub = "s" |
|
FolderKindRoot = "r" |
|
) |
|
|
|
// SearchParams reply params. |
|
type SearchParams struct { |
|
Type int32 |
|
Oid int64 |
|
TypeIds string |
|
Keyword string |
|
KeywordHigh string |
|
UID int64 |
|
Uname string |
|
AdminID int64 |
|
AdminName string |
|
Begin time.Time |
|
End time.Time |
|
States string |
|
IP int64 |
|
Attr string |
|
Sort string |
|
Order string |
|
} |
|
|
|
// ReplySearchResponse ReplySearchResponse |
|
type ReplySearchResponse struct { |
|
SearchResult |
|
Pager Pager `json:"pager"` |
|
} |
|
|
|
// SearchResult search result. |
|
type SearchResult struct { |
|
Code int `json:"code"` |
|
Message string `json:"msg,omitempty"` |
|
Order string `json:"order"` |
|
Page int64 `json:"page"` |
|
PageSize int64 `json:"pagesize"` |
|
PageCount int64 `json:"pagecount"` |
|
Total int64 `json:"total"` |
|
Result []*SearchReply `json:"result"` |
|
} |
|
|
|
// SearchReply search reply. |
|
type SearchReply struct { |
|
// 评论基础信息 |
|
ID int64 `json:"id"` |
|
Type int8 `json:"type"` |
|
Oid int64 `json:"oid"` |
|
OidStr string `json:"oid_str"` |
|
State int8 `json:"state"` |
|
Floor int64 `json:"floor"` |
|
Ctime string `json:"ctime"` |
|
Mtime string `json:"mtime"` |
|
Attr Attr `json:"attr"` |
|
Title string `json:"title"` |
|
|
|
// 评论人的相关信息 |
|
Mid int64 `json:"mid"` |
|
Stat *rl.Stat `json:"stat"` |
|
Replier string `json:"replier"` |
|
IP IP `json:"ip"` |
|
Message string `json:"message"` |
|
Typeid int `json:"typeid"` |
|
Root int `json:"root"` |
|
|
|
// 后台操作信息 |
|
AdminID int64 `json:"adminid"` |
|
AdminName string `json:"admin_name"` |
|
Opremark string `json:"opremark"` |
|
Opresult string `json:"opresult"` |
|
OpCtime string `json:"opctime"` |
|
RedirectURL string `json:"redirect_url"` |
|
// 搜索返回的额外数据 |
|
DocID string `json:"doc_id"` |
|
} |
|
type IP int64 |
|
|
|
func (ip *IP) UnmarshalJSON(b []byte) error { |
|
if string(b) == "" { |
|
return nil |
|
} |
|
str := strings.Trim(string(b), `"`) |
|
ipI := net.ParseIP(str).To4() |
|
if ipI == nil { |
|
return nil |
|
} |
|
*ip = IP(int64(binary.BigEndian.Uint32(ipI))) |
|
return nil |
|
} |
|
|
|
type Attr []int32 |
|
|
|
func (a *Attr) UnmarshalJSON(b []byte) error { |
|
var s []int32 |
|
err := json.Unmarshal(b, &s) |
|
if err != nil { |
|
attr, err := strconv.ParseInt(string(b), 10, 64) |
|
if err != nil { |
|
return err |
|
} |
|
var i int32 = 1 |
|
for attr != 0 && i < 64 { |
|
if attr&1 == 1 { |
|
*a = append(*a, i) |
|
} |
|
attr = attr >> 1 |
|
i++ |
|
} |
|
} else { |
|
*a = s |
|
} |
|
return nil |
|
} |
|
|
|
// Reply info.b |
|
type ReplyEx struct { |
|
Reply |
|
IsUp bool `json:"is_up"` |
|
RootFloor int32 `json:"root_floor"` |
|
} |
|
|
|
// Reply info. |
|
type Reply struct { |
|
ID int64 `json:"rpid"` |
|
Oid int64 `json:"oid"` |
|
Type int32 `json:"type"` |
|
Mid int64 `json:"mid"` |
|
Root int64 `json:"root"` |
|
Parent int64 `json:"parent"` |
|
Dialog int64 `json:"dialog"` |
|
Count int32 `json:"count"` |
|
MCount int32 `json:"mcount"` |
|
RCount int32 `json:"rcount"` |
|
Floor int32 `json:"floor"` |
|
State int32 `json:"state"` |
|
Attr uint32 `json:"attr"` |
|
CTime xtime.Time `json:"ctime"` |
|
MTime xtime.Time `json:"-"` |
|
// action info |
|
Like int32 `json:"like"` |
|
Hate int32 `json:"hate"` |
|
Action int32 `json:"action"` |
|
Content *ReplyContent `json:"content"` |
|
} |
|
|
|
// HasFolded ... |
|
func (r *Reply) HasFolded() bool { |
|
return r.AttrVal(AttrFolded) == AttrYes |
|
} |
|
|
|
// MarkHasFolded ... |
|
func (r *Reply) MarkHasFolded() { |
|
r.AttrSet(AttrYes, AttrFolded) |
|
} |
|
|
|
// UnmarkHasFolded ... |
|
func (r *Reply) UnmarkHasFolded() { |
|
r.AttrSet(AttrNo, AttrFolded) |
|
} |
|
|
|
// DenyFolded ... |
|
func (r *Reply) DenyFolded() bool { |
|
return r.IsTop() || !r.AllowFoldState() || r.Type == SubTypeArticle |
|
} |
|
|
|
// AllowFoldState ... |
|
func (r *Reply) AllowFoldState() bool { |
|
return r.State == StateNormal || r.State == StateHidden || r.State == StateFiltered || r.State == StateGarbage |
|
} |
|
|
|
// IsFolded . |
|
func (r *Reply) IsFolded() bool { |
|
return r.State == StateFolded |
|
} |
|
|
|
// IsRoot root. |
|
func (r *Reply) IsRoot() bool { |
|
return r.Root == 0 |
|
} |
|
|
|
// IsTop top. |
|
func (r *Reply) IsTop() bool { |
|
if r.Attr != 0 && (r.AttrVal(AttrTopAdmin) == 1 || r.AttrVal(AttrTopUpper) == 1) { |
|
return true |
|
} |
|
return false |
|
} |
|
|
|
// IsDeleted deleted. |
|
func (r *Reply) IsDeleted() bool { |
|
return r.State == StateDelUser || r.State == StateDelUpper || r.State == StateDelAdmin |
|
} |
|
|
|
// AttrVal return val of reply'attr |
|
func (r *Reply) AttrVal(bit uint32) uint32 { |
|
if r.Attr == 0 { |
|
return uint32(0) |
|
} |
|
return (r.Attr >> bit) & uint32(1) |
|
} |
|
|
|
// AttrSet set attr of reply'attr |
|
func (r *Reply) AttrSet(v uint32, bit uint32) { |
|
r.Attr = r.Attr&(^(1 << bit)) | (v << bit) |
|
} |
|
|
|
// IsNormal IsNormal |
|
func (r *Reply) IsNormal() bool { |
|
return r.State == StateNormal || r.State == StateHidden || r.State == StateFiltered || r.State == StateMonitor || r.State == StateGarbage || r.State == StateTopAdmin || r.State == StateFolded |
|
} |
|
|
|
func (r *Reply) IsPending() bool { |
|
return r.State == StatePending |
|
} |
|
|
|
// LegalSubjectType LegalSubjectType |
|
func LegalSubjectType(tp int32) bool { |
|
return SubTypeArchive <= tp && tp <= SubTypeComicEpisode |
|
} |
|
|
|
// ReplyContent define reply content |
|
type ReplyContent struct { |
|
ID int64 `json:"-"` |
|
Message string `json:"message"` |
|
Ats Int64Bytes `json:"ats,omitempty"` |
|
IP uint32 `json:"ipi,omitempty"` |
|
Plat int8 `json:"plat"` |
|
Device string `json:"device"` |
|
Version string `json:"version,omitempty"` |
|
CTime xtime.Time `json:"-"` |
|
MTime xtime.Time `json:"-"` |
|
} |
|
|
|
// LogSearchParam LogSearchParam |
|
type LogSearchParam struct { |
|
Oid int64 |
|
Type int32 |
|
Mid int64 |
|
CtimeFrom string |
|
CtimeTo string |
|
Action string |
|
Pn int64 |
|
Ps int64 |
|
Other int64 |
|
Sort string |
|
Order string |
|
Group string |
|
Appid string |
|
} |
|
|
|
// ReplyTopLogResult ReplyTopLogResult |
|
type ReplyTopLogResult struct { |
|
Logs []*ReplyTopLog `json:"logs"` |
|
Page Page `json:"page"` |
|
Order string `json:"order"` |
|
Sort string `json:"sort"` |
|
} |
|
|
|
// ReplyTopLog ReplyTopLog |
|
type ReplyTopLog struct { |
|
AdminID int64 `json:"adminid"` |
|
AdminName string `json:"admin_name"` |
|
Oid int64 `json:"oid"` |
|
Type int32 `json:"type"` |
|
Title string `json:"title"` |
|
RedirectURL string `json:"redirect_url"` |
|
Remark string `json:"remark"` |
|
UserName string `json:"username"` |
|
Mid int64 `json:"mid"` |
|
CTime string `json:"ctime"` |
|
RpID int64 `json:"rpid"` |
|
Action int64 `json:"action"` |
|
} |
|
|
|
// ExportedReply exported reply struct |
|
type ExportedReply struct { |
|
ID int64 `json:"rpid"` |
|
Oid int64 `json:"oid"` |
|
Type int32 `json:"type"` |
|
Mid int64 `json:"mid"` |
|
Root int64 `json:"root"` |
|
Parent int64 `json:"parent"` |
|
Count int32 `json:"count"` |
|
RCount int32 `json:"rcount"` |
|
Like int32 `json:"like"` |
|
Hate int32 `json:"hate"` |
|
Floor int32 `json:"floor"` |
|
State int32 `json:"state"` |
|
Attr int32 `json:"attr"` |
|
CTime time.Time `json:"ctime"` |
|
Message string `json:"message"` |
|
} |
|
|
|
// String convert ExportedReply to string |
|
func (e *ExportedReply) String() (s []string) { |
|
s = append(s, strconv.FormatInt(e.ID, 10)) |
|
s = append(s, strconv.FormatInt(e.Oid, 10)) |
|
s = append(s, strconv.FormatInt(int64(e.Type), 10)) |
|
s = append(s, strconv.FormatInt(e.Mid, 10)) |
|
s = append(s, strconv.FormatInt(e.Root, 10)) |
|
s = append(s, strconv.FormatInt(e.Parent, 10)) |
|
s = append(s, strconv.FormatInt(int64(e.Count), 10)) |
|
s = append(s, strconv.FormatInt(int64(e.RCount), 10)) |
|
s = append(s, strconv.FormatInt(int64(e.Like), 10)) |
|
s = append(s, strconv.FormatInt(int64(e.Hate), 10)) |
|
s = append(s, strconv.FormatInt(int64(e.Floor), 10)) |
|
s = append(s, strconv.FormatInt(int64(e.State), 10)) |
|
s = append(s, strconv.FormatInt(int64(e.Attr), 10)) |
|
s = append(s, e.CTime.String()) |
|
s = append(s, e.Message) |
|
return |
|
}
|
|
|