Create & Init Project...
This commit is contained in:
66
app/service/main/favorite/model/BUILD
Normal file
66
app/service/main/favorite/model/BUILD
Normal file
@ -0,0 +1,66 @@
|
||||
load(
|
||||
"@io_bazel_rules_go//proto:def.bzl",
|
||||
"go_proto_library",
|
||||
)
|
||||
|
||||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
load(
|
||||
"@io_bazel_rules_go//go:def.bzl",
|
||||
"go_library",
|
||||
)
|
||||
|
||||
proto_library(
|
||||
name = "model_proto",
|
||||
srcs = ["fav.proto"],
|
||||
tags = ["automanaged"],
|
||||
deps = ["@gogo_special_proto//github.com/gogo/protobuf/gogoproto"],
|
||||
)
|
||||
|
||||
go_proto_library(
|
||||
name = "model_go_proto",
|
||||
compilers = ["@io_bazel_rules_go//proto:gogofast_proto"],
|
||||
importpath = "go-common/app/service/main/favorite/model",
|
||||
proto = ":model_proto",
|
||||
tags = ["automanaged"],
|
||||
deps = [
|
||||
"//library/time:go_default_library",
|
||||
"@com_github_gogo_protobuf//gogoproto:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = [
|
||||
"archive.go",
|
||||
"fav.go",
|
||||
"job.go",
|
||||
"rpc.go",
|
||||
"topic.go",
|
||||
"video.go",
|
||||
],
|
||||
embed = [":model_go_proto"],
|
||||
importpath = "go-common/app/service/main/favorite/model",
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
"//app/service/main/archive/api:go_default_library",
|
||||
"//library/time:go_default_library",
|
||||
"@com_github_gogo_protobuf//gogoproto:go_default_library",
|
||||
"@com_github_gogo_protobuf//proto:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "package-srcs",
|
||||
srcs = glob(["**"]),
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "all-srcs",
|
||||
srcs = [":package-srcs"],
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
66
app/service/main/favorite/model/archive.go
Normal file
66
app/service/main/favorite/model/archive.go
Normal file
@ -0,0 +1,66 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"go-common/app/service/main/archive/api"
|
||||
xtime "go-common/library/time"
|
||||
)
|
||||
|
||||
type Archive struct {
|
||||
Id int64 `json:"id"`
|
||||
Mid int64 `json:"mid"`
|
||||
Fid int64 `json:"fid"`
|
||||
Aid int64 `json:"aid"`
|
||||
CTime xtime.Time `json:"-"`
|
||||
MTime xtime.Time `json:"-"`
|
||||
}
|
||||
|
||||
type SearchArchive struct {
|
||||
Code int `json:"code,omitempty"`
|
||||
Seid string `json:"seid"`
|
||||
Page int `json:"page"`
|
||||
PageSize int `json:"pagesize"`
|
||||
NumPages int `json:"numPages,omitempty"`
|
||||
PageCount int `json:"pagecount"`
|
||||
NumResults int `json:"numResults,omitempty"`
|
||||
Total int `json:"total"`
|
||||
SuggestKeyword string `json:"suggest_keyword"`
|
||||
Mid int64 `json:"mid"`
|
||||
Fid int64 `json:"fid"`
|
||||
Tid int `json:"tid"`
|
||||
Order string `json:"order"`
|
||||
Keyword string `json:"keyword"`
|
||||
TList []struct {
|
||||
Tid int `json:"tid"`
|
||||
Name string `json:"name"`
|
||||
Count int `json:"count"`
|
||||
} `json:"tlist,omitempty"`
|
||||
Result []*SearchArchiveResult `json:"result,omitempty"`
|
||||
Archives []*FavArchive `json:"archives"`
|
||||
}
|
||||
|
||||
type SearchArchiveResult struct {
|
||||
ID int64 `json:"id"`
|
||||
Title string `json:"title"`
|
||||
Play string `json:"play"`
|
||||
FavTime int64 `json:"fav_time"`
|
||||
}
|
||||
|
||||
type FavArchive struct {
|
||||
*api.Arc
|
||||
FavAt int64 `json:"fav_at"`
|
||||
PlayNum string `json:"play_num"`
|
||||
HighlightTitle string `json:"highlight_title"`
|
||||
}
|
||||
|
||||
type AppInfo struct {
|
||||
Platform string
|
||||
Build string
|
||||
MobiApp string
|
||||
Device string
|
||||
}
|
||||
|
||||
type Partition struct {
|
||||
Tid int `json:"tid"`
|
||||
Name string `json:"name"`
|
||||
Count int `json:"count"`
|
||||
}
|
360
app/service/main/favorite/model/fav.go
Normal file
360
app/service/main/favorite/model/fav.go
Normal file
@ -0,0 +1,360 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
"go-common/library/time"
|
||||
)
|
||||
|
||||
const (
|
||||
// default name of folder
|
||||
InitFolderName = "默认收藏夹"
|
||||
// state
|
||||
StateNormal = int8(0)
|
||||
StateIsDel = int8(1)
|
||||
// attr bit bit from left
|
||||
AttrBitPublic = uint(0)
|
||||
AttrBitDefault = uint(1)
|
||||
AttrBitAudit = uint(2)
|
||||
AttrBitAdminDelete = uint(3)
|
||||
AttrBitName = uint(4)
|
||||
AttrBitDesc = uint(5)
|
||||
AttrBitCover = uint(6)
|
||||
AttrBitSensitive = uint(7)
|
||||
|
||||
AttrIsPublic = int32(0) // 公开
|
||||
AttrIsDefault = int32(0) // 默认
|
||||
// foler attr
|
||||
AttrBitPrivate = int32(1)
|
||||
AttrBitNoDefault = int32(1) << AttrBitDefault
|
||||
AttrBitNeedAudit = int32(1) << AttrBitAudit
|
||||
AttrBitHitSensitive = int32(1) << AttrBitSensitive
|
||||
|
||||
AttrDefaultPublic = 0 // binary 0 / int 0
|
||||
AttrDefaultNoPublic = AttrBitPrivate // binary 01 / int 1
|
||||
AttrNormalPublic = AttrBitNoDefault // binary 10 / int 2
|
||||
AttrNormalNoPublic = AttrBitNoDefault | AttrBitPrivate // binary 11 / int 3
|
||||
// limit
|
||||
DefaultFolderLimit = 50000
|
||||
NormalFolderLimit = 999
|
||||
// cache
|
||||
CacheNotFound = -1
|
||||
// max type
|
||||
TypeMax = 20
|
||||
// sort field
|
||||
SortPubtime = "pubtime"
|
||||
SortMtime = "mtime"
|
||||
SortView = "view"
|
||||
)
|
||||
|
||||
func (r *Resource) ResourceID() int64 {
|
||||
return r.Oid*100 + int64(r.Typ)
|
||||
}
|
||||
|
||||
func IsMediaList(typ int32) bool {
|
||||
return typ == int32(TypeVideo) || typ == int32(TypeMusicNew)
|
||||
}
|
||||
|
||||
type Favorite struct {
|
||||
ID int64 `json:"id"`
|
||||
Oid int64 `json:"oid"`
|
||||
Mid int64 `json:"mid"`
|
||||
Fid int64 `json:"fid"`
|
||||
Type int8 `json:"type"`
|
||||
State int8 `json:"state"`
|
||||
CTime time.Time `json:"ctime"`
|
||||
MTime time.Time `json:"mtime"`
|
||||
Sequence uint64 `json:"sequence"`
|
||||
}
|
||||
|
||||
func (f *Favorite) ResourceID() int64 {
|
||||
return int64(f.Oid)*100 + int64(f.Type)
|
||||
}
|
||||
|
||||
type Favorites struct {
|
||||
Page struct {
|
||||
Num int `json:"num"`
|
||||
Size int `json:"size"`
|
||||
Count int `json:"count"`
|
||||
} `json:"page"`
|
||||
List []*Favorite `json:"list"`
|
||||
}
|
||||
|
||||
type User struct {
|
||||
ID int64 `json:"id"`
|
||||
Oid int64 `json:"oid"`
|
||||
Mid int64 `json:"mid"`
|
||||
Type int8 `json:"type"`
|
||||
State int8 `json:"state"`
|
||||
CTime time.Time `json:"ctime"`
|
||||
MTime time.Time `json:"mtime"`
|
||||
}
|
||||
type UserList struct {
|
||||
Page struct {
|
||||
Num int `json:"num"`
|
||||
Size int `json:"size"`
|
||||
Total int `json:"total"`
|
||||
} `json:"page"`
|
||||
List []*User `json:"list"`
|
||||
}
|
||||
|
||||
// AttrVal get attr val by bit.
|
||||
func (f *Folder) AttrVal(bit uint) int32 {
|
||||
return (f.Attr >> bit) & int32(1)
|
||||
}
|
||||
|
||||
// AttrSet set attr value by bit.
|
||||
func (f *Folder) AttrSet(v int32, bit uint) {
|
||||
f.Attr = f.Attr&(^(1 << bit)) | (v << bit)
|
||||
}
|
||||
|
||||
// IsDefault return true if folder is default.
|
||||
func (f *Folder) IsDefault() bool {
|
||||
return f.Attr&AttrBitNoDefault == int32(0)
|
||||
}
|
||||
|
||||
// IsPublic return true if folder is public.
|
||||
func (f *Folder) IsPublic() bool {
|
||||
return f.AttrVal(AttrBitPublic) == AttrIsPublic
|
||||
}
|
||||
|
||||
// Access return true if the user has the access permission to the folder.
|
||||
func (f *Folder) Access(mid int64) bool {
|
||||
return f.IsPublic() || f.Mid == mid
|
||||
}
|
||||
|
||||
// IsLimited return true if folder count is eq or gt conf limit.
|
||||
func (f *Folder) IsLimited(cnt int, defaultLimit int, normalLimit int) bool {
|
||||
switch f.IsDefault() {
|
||||
case true:
|
||||
return f.Count+cnt > defaultLimit
|
||||
case false:
|
||||
return f.Count+cnt > normalLimit
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func (f *Folder) MediaID() int64 {
|
||||
return f.ID*100 + f.Mid%100
|
||||
}
|
||||
|
||||
func CheckArg(tp int8, oid int64) error {
|
||||
if tp <= 0 || oid <= 0 {
|
||||
return errors.New("negative number and zero not allowed")
|
||||
}
|
||||
return CheckType(tp)
|
||||
}
|
||||
|
||||
func CheckType(typ int8) error {
|
||||
if typ < Article || typ > TypeMax {
|
||||
return errors.New("type code out of range")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// CompleteURL adds host on path.
|
||||
func CompleteURL(path string) (url string) {
|
||||
if path == "" {
|
||||
// url = "http://static.hdslb.com/images/transparent.gif"
|
||||
return
|
||||
}
|
||||
url = path
|
||||
if strings.Index(path, "//") == 0 || strings.Index(path, "http://") == 0 || strings.Index(path, "https://") == 0 {
|
||||
return
|
||||
}
|
||||
url = "https://i0.hdslb.com" + url
|
||||
return
|
||||
}
|
||||
|
||||
// CleanURL cuts host.
|
||||
func CleanURL(url string) (path string) {
|
||||
path = url
|
||||
if strings.Index(url, "//") == 0 {
|
||||
path = url[14:]
|
||||
} else if strings.Index(url, "http://") == 0 {
|
||||
path = url[19:]
|
||||
} else if strings.Index(url, "https://") == 0 {
|
||||
path = url[20:]
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// Folders .
|
||||
type Folders []*Folder
|
||||
|
||||
func (f Folders) Len() int { return len(f) }
|
||||
|
||||
func (f Folders) Less(i, j int) bool {
|
||||
if f[i].IsDefault() {
|
||||
return true
|
||||
}
|
||||
if f[j].IsDefault() {
|
||||
return false
|
||||
}
|
||||
if f[i].ID > f[j].ID {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (f Folders) Swap(i, j int) { f[i], f[j] = f[j], f[i] }
|
||||
|
||||
// FolderSort folder index.
|
||||
type FolderSort struct {
|
||||
ID int64 `json:"id"`
|
||||
Type int8 `json:"type"`
|
||||
Mid int64 `json:"mid"`
|
||||
Sort []int64 `json:"sort"`
|
||||
Map map[int64]struct{} `json:"-"`
|
||||
CTime time.Time `json:"ctime"`
|
||||
MTime time.Time `json:"mtime"`
|
||||
}
|
||||
|
||||
// Index return index for fids.
|
||||
func (f *FolderSort) Index() []byte {
|
||||
var (
|
||||
i int
|
||||
v int64
|
||||
fs = f.Sort
|
||||
n = len(fs) * 8
|
||||
b = make([]byte, n)
|
||||
)
|
||||
for i = 0; i < n; i += 8 {
|
||||
v = fs[i/8]
|
||||
b[i] = byte(v >> 56)
|
||||
b[i+1] = byte(v >> 48)
|
||||
b[i+2] = byte(v >> 40)
|
||||
b[i+3] = byte(v >> 32)
|
||||
b[i+4] = byte(v >> 24)
|
||||
b[i+5] = byte(v >> 16)
|
||||
b[i+6] = byte(v >> 8)
|
||||
b[i+7] = byte(v)
|
||||
}
|
||||
return b
|
||||
}
|
||||
|
||||
// SetIndex set sort fids.
|
||||
func (f *FolderSort) SetIndex(b []byte) (err error) {
|
||||
var (
|
||||
i int
|
||||
id int64
|
||||
n = len(b)
|
||||
ids = make([]int64, n/8)
|
||||
)
|
||||
if len(b)%8 != 0 {
|
||||
err = fmt.Errorf("invalid sort index:%v", b)
|
||||
return
|
||||
}
|
||||
f.Map = make(map[int64]struct{}, n)
|
||||
for i = 0; i < n; i += 8 {
|
||||
id = int64(b[i+7]) |
|
||||
int64(b[i+6])<<8 |
|
||||
int64(b[i+5])<<16 |
|
||||
int64(b[i+4])<<24 |
|
||||
int64(b[i+3])<<32 |
|
||||
int64(b[i+2])<<40 |
|
||||
int64(b[i+1])<<48 |
|
||||
int64(b[i])<<56
|
||||
ids[i/8] = id
|
||||
f.Map[id] = struct{}{}
|
||||
}
|
||||
f.Sort = ids
|
||||
return
|
||||
}
|
||||
|
||||
// ToBytes return []byte for ids.
|
||||
func ToBytes(ids []int64) []byte {
|
||||
var (
|
||||
i int
|
||||
v int64
|
||||
n = len(ids) * 8
|
||||
b = make([]byte, n)
|
||||
)
|
||||
for i = 0; i < n; i += 8 {
|
||||
v = ids[i/8]
|
||||
b[i] = byte(v >> 56)
|
||||
b[i+1] = byte(v >> 48)
|
||||
b[i+2] = byte(v >> 40)
|
||||
b[i+3] = byte(v >> 32)
|
||||
b[i+4] = byte(v >> 24)
|
||||
b[i+5] = byte(v >> 16)
|
||||
b[i+6] = byte(v >> 8)
|
||||
b[i+7] = byte(v)
|
||||
}
|
||||
return b
|
||||
}
|
||||
|
||||
// ToInt64s bytes to int64s.
|
||||
func ToInt64s(b []byte) (ids []int64, err error) {
|
||||
var (
|
||||
i int
|
||||
id int64
|
||||
n = len(b)
|
||||
)
|
||||
ids = make([]int64, n/8)
|
||||
if len(b)%8 != 0 {
|
||||
err = fmt.Errorf("invalid bytes:%v", b)
|
||||
return
|
||||
}
|
||||
for i = 0; i < n; i += 8 {
|
||||
id = int64(b[i+7]) |
|
||||
int64(b[i+6])<<8 |
|
||||
int64(b[i+5])<<16 |
|
||||
int64(b[i+4])<<24 |
|
||||
int64(b[i+3])<<32 |
|
||||
int64(b[i+2])<<40 |
|
||||
int64(b[i+1])<<48 |
|
||||
int64(b[i])<<56
|
||||
ids[i/8] = id
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// SortFolders sort the favorites by index.
|
||||
func (f *FolderSort) SortFolders(fs map[int64]*Folder, isSelf bool) (res []*Folder, update bool) {
|
||||
var (
|
||||
ok bool
|
||||
id int64
|
||||
sorted []int64
|
||||
fav *Folder
|
||||
idx = f.Sort
|
||||
)
|
||||
res = make([]*Folder, 0, len(fs))
|
||||
if len(f.Sort) == 0 {
|
||||
for _, fav = range fs {
|
||||
if !isSelf && !fav.IsPublic() {
|
||||
continue
|
||||
}
|
||||
res = append(res, fav)
|
||||
}
|
||||
sort.Sort(Folders(res))
|
||||
return
|
||||
}
|
||||
if len(idx) != len(fs) {
|
||||
sorted = append(sorted, idx[0])
|
||||
for id = range fs {
|
||||
if _, ok = f.Map[id]; !ok {
|
||||
sorted = append(sorted, id)
|
||||
}
|
||||
}
|
||||
for _, id := range idx[1:] {
|
||||
if _, ok = fs[id]; ok {
|
||||
sorted = append(sorted, id)
|
||||
}
|
||||
}
|
||||
update = true
|
||||
f.Sort = sorted
|
||||
}
|
||||
for _, id = range f.Sort {
|
||||
if fav, ok = fs[id]; ok {
|
||||
if !isSelf && !fav.IsPublic() {
|
||||
continue
|
||||
}
|
||||
res = append(res, fav)
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
1211
app/service/main/favorite/model/fav.pb.go
Normal file
1211
app/service/main/favorite/model/fav.pb.go
Normal file
File diff suppressed because it is too large
Load Diff
45
app/service/main/favorite/model/fav.proto
Normal file
45
app/service/main/favorite/model/fav.proto
Normal file
@ -0,0 +1,45 @@
|
||||
syntax = "proto3";
|
||||
|
||||
/*
|
||||
* v0.1.0
|
||||
* 收藏夹信息
|
||||
*/
|
||||
package model;
|
||||
|
||||
import "github.com/gogo/protobuf/gogoproto/gogo.proto";
|
||||
|
||||
option (gogoproto.goproto_enum_prefix_all) = false;
|
||||
option (gogoproto.goproto_getters_all) = false;
|
||||
option (gogoproto.unmarshaler_all) = true;
|
||||
option (gogoproto.marshaler_all) = true;
|
||||
option (gogoproto.sizer_all) = true;
|
||||
option (gogoproto.goproto_stringer_all) = false;
|
||||
option (gogoproto.stringer_all) = true;
|
||||
|
||||
|
||||
message Folder {
|
||||
int64 ID = 1 [(gogoproto.jsontag) = "id"];
|
||||
int64 Mid = 2 [(gogoproto.jsontag) = "mid"];
|
||||
int32 Count = 3 [(gogoproto.jsontag) = "count",(gogoproto.casttype) = "int"];
|
||||
string Name = 4 [(gogoproto.jsontag) = "name"];
|
||||
string Cover = 5 [(gogoproto.jsontag) = "cover"];
|
||||
string Description = 6 [(gogoproto.jsontag) = "description"];
|
||||
int32 Type = 7 [(gogoproto.jsontag) = "type",(gogoproto.casttype) = "int8"];
|
||||
int32 Attr = 8 [(gogoproto.jsontag) = "attr"];
|
||||
int32 State = 9 [(gogoproto.jsontag) = "state",(gogoproto.casttype) = "int8"];
|
||||
int32 Favored = 10 [(gogoproto.jsontag) = "favored",(gogoproto.casttype) = "int8"];
|
||||
int64 CTime = 11 [(gogoproto.jsontag) = "ctime", (gogoproto.casttype) = "go-common/library/time.Time"];
|
||||
int64 MTime = 12 [(gogoproto.jsontag) = "mtime", (gogoproto.casttype) = "go-common/library/time.Time"];
|
||||
repeated int64 RecentOids = 13 [(gogoproto.jsontag) = "recent_oids"];
|
||||
int32 FavedCount = 14 [(gogoproto.jsontag) = "faved_count"];
|
||||
int32 PlayCount = 15 [(gogoproto.jsontag) = "play_count"];
|
||||
int32 ShareCount = 16 [(gogoproto.jsontag) = "share_count"];
|
||||
int32 LikeCount = 17 [(gogoproto.jsontag) = "like_count"];
|
||||
int32 ReplyCount = 18 [(gogoproto.jsontag) = "reply_count"];
|
||||
repeated Resource RecentRes = 19 [(gogoproto.jsontag) = "recent_res"];
|
||||
}
|
||||
|
||||
message Resource {
|
||||
int64 Oid = 1[(gogoproto.jsontag) = "oid"];
|
||||
int32 Typ = 2[(gogoproto.jsontag) = "typ"];
|
||||
}
|
56
app/service/main/favorite/model/job.go
Normal file
56
app/service/main/favorite/model/job.go
Normal file
@ -0,0 +1,56 @@
|
||||
package model
|
||||
|
||||
const (
|
||||
// type
|
||||
FieldFav = "folder"
|
||||
FieldArc = "video"
|
||||
FieldResource = "resource"
|
||||
// action
|
||||
ActionAdd = "add"
|
||||
ActionDel = "del"
|
||||
ActionMove = "move"
|
||||
ActionCopy = "copy"
|
||||
ActionMdel = "mdel"
|
||||
ActionIndef = "indef"
|
||||
ActionIncol = "incol"
|
||||
ActionClean = "clean"
|
||||
ActionInitRelationFids = "initRelationFids"
|
||||
ActionInitFolderRelations = "initFolderRelations"
|
||||
ActionInitAllFolderRelations = "initAllFolderRelations"
|
||||
ActionMultiAdd = "multiAdd"
|
||||
ActionMultiDel = "multiDel"
|
||||
ActionFolderAdd = "folderAdd"
|
||||
ActionFolderDel = "folderDel"
|
||||
ActionSortFavs = "sortFavs"
|
||||
)
|
||||
|
||||
type Message struct {
|
||||
Field string `json:"field,omitempty"`
|
||||
Action string `json:"action,omitempty"`
|
||||
Oid int64 `json:"oid,omitempty"`
|
||||
Otype int8 `json:"otype,omitempty"`
|
||||
Type int8 `json:"type,omitempty"`
|
||||
Mid int64 `json:"mid,omitempty"`
|
||||
OldMid int64 `json:"old_mid,omitempty"`
|
||||
Fid int64 `json:"fid,omitempty"`
|
||||
FidState int8 `json:"fid_state,omitempty"`
|
||||
FolderAttr int32 `json:"folder_attr,omitempty"`
|
||||
OldFolderAttr int32 `json:"old_folder_attr,omitempty"`
|
||||
NewFolderAttr int32 `json:"new_folder_attr,omitempty"`
|
||||
Aid int64 `json:"aid,omitempty"`
|
||||
OldFid int64 `json:"old_fid,omitempty"`
|
||||
OldFidState int8 `json:"old_fid_state,omitempty"`
|
||||
NewFid int64 `json:"new_fid,omitempty"`
|
||||
NewFidState int8 `json:"new_fid_state,omitempty"`
|
||||
Affected int64 `json:"affected,omitempty"`
|
||||
Aids []int64 `json:"aids,omitempty"`
|
||||
Oids []int64 `json:"oids,omitempty"`
|
||||
Mids []int64 `json:"mids,omitempty"`
|
||||
FTime int64 `json:"ftime,omitempty"`
|
||||
SortFavs []SortFav `json:"sort_favs,omitempty"`
|
||||
}
|
||||
|
||||
type SortFav struct {
|
||||
Pre *Resource `json:"preID,omitempty"`
|
||||
Insert *Resource `json:"id,omitempty"`
|
||||
}
|
214
app/service/main/favorite/model/rpc.go
Normal file
214
app/service/main/favorite/model/rpc.go
Normal file
@ -0,0 +1,214 @@
|
||||
package model
|
||||
|
||||
const (
|
||||
Article = int8(1)
|
||||
TypeVideo = int8(2)
|
||||
TypeMusic = int8(3)
|
||||
TypeTopic = int8(4)
|
||||
TypePlayVideo = int8(5)
|
||||
TypePlayList = int8(6)
|
||||
TypeBangumi = int8(7)
|
||||
TypeMoe = int8(8)
|
||||
TypeComic = int8(9)
|
||||
TypeEsports = int8(10)
|
||||
TypeMediaList = int8(11)
|
||||
TypeMusicNew = int8(12)
|
||||
)
|
||||
|
||||
type ArgAllFolders struct {
|
||||
Type int8
|
||||
Mid int64
|
||||
Vmid int64
|
||||
Oid int64
|
||||
RealIP string
|
||||
}
|
||||
|
||||
type ArgFolder struct {
|
||||
Type int8
|
||||
Fid int64
|
||||
Mid int64
|
||||
Vmid int64
|
||||
RealIP string
|
||||
}
|
||||
|
||||
type ArgFVmid struct {
|
||||
Fid int64
|
||||
Vmid int64
|
||||
}
|
||||
|
||||
func (f *ArgFVmid) MediaID() int64 {
|
||||
return f.Fid*100 + f.Vmid%100
|
||||
}
|
||||
|
||||
type ArgFolders struct {
|
||||
Type int8
|
||||
Mid int64
|
||||
FVmids []*ArgFVmid
|
||||
RealIP string
|
||||
}
|
||||
|
||||
type ArgAddFolder struct {
|
||||
Type int8
|
||||
Mid int64
|
||||
Name string
|
||||
Description string
|
||||
Cover string
|
||||
Public int8
|
||||
Cookie string
|
||||
AccessKey string
|
||||
RealIP string
|
||||
}
|
||||
|
||||
type ArgUpdateFolder struct {
|
||||
Type int8
|
||||
Fid int64
|
||||
Mid int64
|
||||
Name string
|
||||
Description string
|
||||
Cover string
|
||||
Public int8
|
||||
Cookie string
|
||||
AccessKey string
|
||||
RealIP string
|
||||
}
|
||||
|
||||
type ArgDelFolder struct {
|
||||
Type int8
|
||||
Mid int64
|
||||
Fid int64
|
||||
RealIP string
|
||||
}
|
||||
|
||||
type ArgFavs struct {
|
||||
Type int8
|
||||
Mid int64
|
||||
Vmid int64
|
||||
Fid int64
|
||||
Tv int
|
||||
Tid int
|
||||
Pn int
|
||||
Ps int
|
||||
Keyword string
|
||||
Order string
|
||||
RealIP string
|
||||
}
|
||||
|
||||
type ArgAdd struct {
|
||||
Type int8
|
||||
Mid int64
|
||||
Oid int64
|
||||
Fid int64
|
||||
RealIP string
|
||||
}
|
||||
|
||||
type ArgDel struct {
|
||||
Type int8
|
||||
Mid int64
|
||||
Oid int64
|
||||
Fid int64
|
||||
RealIP string
|
||||
}
|
||||
|
||||
type ArgAdds struct {
|
||||
Type int8
|
||||
Mid int64
|
||||
Oid int64
|
||||
Fids []int64
|
||||
RealIP string
|
||||
}
|
||||
|
||||
type ArgDels struct {
|
||||
Type int8
|
||||
Mid int64
|
||||
Oid int64
|
||||
Fids []int64
|
||||
RealIP string
|
||||
}
|
||||
|
||||
type ArgMultiAdd struct {
|
||||
Type int8
|
||||
Mid int64
|
||||
Oids []int64
|
||||
Fid int64
|
||||
RealIP string
|
||||
}
|
||||
|
||||
type ArgMultiDel struct {
|
||||
Type int8
|
||||
Mid int64
|
||||
Oids []int64
|
||||
Fid int64
|
||||
RealIP string
|
||||
}
|
||||
|
||||
type ArgIsFav struct {
|
||||
Type int8
|
||||
Mid int64
|
||||
Oid int64
|
||||
RealIP string
|
||||
}
|
||||
type ArgIsFavs struct {
|
||||
Type int8
|
||||
Mid int64
|
||||
Oids []int64
|
||||
RealIP string
|
||||
}
|
||||
type ArgInDefaultFolder struct {
|
||||
Type int8
|
||||
Mid int64
|
||||
Oid int64
|
||||
RealIP string
|
||||
}
|
||||
|
||||
type ArgIsFavedByFid struct {
|
||||
Type int8
|
||||
Mid int64
|
||||
Oid int64
|
||||
Fid int64
|
||||
RealIP string
|
||||
}
|
||||
|
||||
type ArgCntUserFolders struct {
|
||||
Type int8
|
||||
Mid int64
|
||||
Vmid int64
|
||||
RealIP string
|
||||
}
|
||||
|
||||
type ArgAddVideo struct {
|
||||
Mid int64
|
||||
Fids []int64
|
||||
Aid int64
|
||||
Cookie string
|
||||
AccessKey string
|
||||
RealIP string
|
||||
}
|
||||
|
||||
type ArgFavoredVideos struct {
|
||||
Mid int64
|
||||
Aids []int64
|
||||
RealIP string
|
||||
}
|
||||
|
||||
type ArgUsers struct {
|
||||
Type int8
|
||||
Oid int64
|
||||
Pn int
|
||||
Ps int
|
||||
RealIP string
|
||||
}
|
||||
|
||||
type ArgTlists struct {
|
||||
Type int8
|
||||
Mid int64
|
||||
Vmid int64
|
||||
Fid int64
|
||||
RealIP string
|
||||
}
|
||||
|
||||
type ArgRecents struct {
|
||||
Type int8
|
||||
Mid int64
|
||||
Size int
|
||||
RealIP string
|
||||
}
|
56
app/service/main/favorite/model/topic.go
Normal file
56
app/service/main/favorite/model/topic.go
Normal file
@ -0,0 +1,56 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"go-common/library/time"
|
||||
)
|
||||
|
||||
const (
|
||||
TopicCacheMiss = -1
|
||||
// http mode
|
||||
HttpMode4Http = 1 // eg "http://a.bilibili.com"
|
||||
HttpMode4Https = 2 // eg "https://a.bilibili.com"
|
||||
HttpMode4Both = 3 // eg "//a.bilibili.com"
|
||||
)
|
||||
|
||||
type TopicFav struct {
|
||||
ID int64 `json:"id"`
|
||||
Mid int64 `json:"mid"`
|
||||
TpID int64 `json:"tpid"`
|
||||
Ctime time.Time `json:"ctime"`
|
||||
Mtime time.Time `json:"mtime"`
|
||||
}
|
||||
|
||||
type Topic struct {
|
||||
ID int64 `json:"id"`
|
||||
TpID int64 `json:"tp_id"`
|
||||
MID int64 `json:"mid"`
|
||||
FavAt time.Time `json:"fav_at"`
|
||||
State int64 `json:"state"`
|
||||
Stime string `json:"stime"`
|
||||
Etime string `json:"etime"`
|
||||
Ctime string `json:"ctime"`
|
||||
Mtime string `json:"mtime"`
|
||||
Name string `json:"name"`
|
||||
Author string `json:"author"`
|
||||
PCUrl string `json:"pc_url"`
|
||||
H5Url string `json:"h5_url"`
|
||||
PCCover string `json:"pc_cover"`
|
||||
H5Cover string `json:"h5_cover"`
|
||||
Rank int64 `json:"rank"`
|
||||
PageName string `json:"page_name"`
|
||||
Plat int64 `json:"plat"`
|
||||
Desc string `json:"desc"`
|
||||
Click int64 `json:"click"`
|
||||
TPType int64 `json:"type"`
|
||||
Mold int64 `json:"mold"`
|
||||
Series int64 `json:"series"`
|
||||
Dept int64 `json:"dept"`
|
||||
ReplyID int64 `json:"reply_id"`
|
||||
}
|
||||
|
||||
type TopicList struct {
|
||||
PageNum int `json:"page"`
|
||||
PageSize int `json:"pagesize"`
|
||||
Total int64 `json:"total"`
|
||||
List []*Topic `json:"list"`
|
||||
}
|
208
app/service/main/favorite/model/video.go
Normal file
208
app/service/main/favorite/model/video.go
Normal file
@ -0,0 +1,208 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"sort"
|
||||
|
||||
xtime "go-common/library/time"
|
||||
)
|
||||
|
||||
const (
|
||||
bit1 = int8(1)
|
||||
bit2 = int8(1) << 1
|
||||
StateDefaultPublic = int8(0) // binary 00 / int 0
|
||||
StateDefaultNoPublic = int8(0) | bit1 // binary 01 / int 1
|
||||
StateNormalPublic = bit2 | int8(0) // binary 10 / int 2
|
||||
StateNormalNoPublic = bit2 | bit1 // binary 11 / int 3
|
||||
// DefaultFolderName default name of favorite folder
|
||||
DefaultFolderName = "默认收藏夹"
|
||||
// AllFidFlag all folder id flag
|
||||
AllFidFlag = -1
|
||||
// CDFlag cool down flag
|
||||
CDFlag = -1
|
||||
// search error code
|
||||
SearchErrWordIllegal = -110 // 非法搜索词错误
|
||||
// clean state
|
||||
StateAllowToClean = 0
|
||||
StateCleaning = 1
|
||||
StateCleanCD = 2
|
||||
)
|
||||
|
||||
type VideoFolder struct {
|
||||
MediaId int64 `json:"media_id"`
|
||||
Fid int64 `json:"fid"`
|
||||
Mid int64 `json:"mid"`
|
||||
Name string `json:"name"`
|
||||
MaxCount int `json:"max_count"`
|
||||
CurCount int `json:"cur_count"`
|
||||
AttenCount int `json:"atten_count"`
|
||||
Favoured int8 `json:"favoured"`
|
||||
State int8 `json:"state"`
|
||||
CTime xtime.Time `json:"ctime"`
|
||||
MTime xtime.Time `json:"mtime"`
|
||||
Cover []*Cover `json:"cover,omitempty"`
|
||||
}
|
||||
|
||||
// IsPublic return true if folder is public.
|
||||
func (f *VideoFolder) IsPublic() bool {
|
||||
return f.State&bit1 == int8(0)
|
||||
}
|
||||
|
||||
// IsDefault return true if folder is default.
|
||||
func (f *VideoFolder) IsDefault() bool {
|
||||
return f.State&bit2 == int8(0)
|
||||
}
|
||||
|
||||
// StatePub return folder's public state.
|
||||
func (f *VideoFolder) StatePub() int8 {
|
||||
return f.State & bit1
|
||||
}
|
||||
|
||||
// StateDef return folder's default state.
|
||||
func (f *VideoFolder) StateDef() int8 {
|
||||
return f.State & bit2
|
||||
}
|
||||
|
||||
// IsDefault return true if state is default state.
|
||||
func IsDefault(state int8) bool {
|
||||
return (state&(int8(1)<<1) == int8(0))
|
||||
}
|
||||
|
||||
// CheckPublic check user update public value in [0, 1].
|
||||
func CheckPublic(state int8) bool {
|
||||
return state == int8(0) || state == bit1
|
||||
}
|
||||
|
||||
type VideoFolders []*VideoFolder
|
||||
|
||||
func (f VideoFolders) Len() int { return len(f) }
|
||||
|
||||
func (f VideoFolders) Less(i, j int) bool {
|
||||
if f[i].IsDefault() {
|
||||
return true
|
||||
}
|
||||
if f[j].IsDefault() {
|
||||
return false
|
||||
}
|
||||
if f[i].Fid > f[j].Fid {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (f VideoFolders) Swap(i, j int) { f[i], f[j] = f[j], f[i] }
|
||||
|
||||
// Cover image
|
||||
type Cover struct {
|
||||
Aid int64 `json:"aid"`
|
||||
Pic string `json:"pic"`
|
||||
Type int32 `json:"type"`
|
||||
}
|
||||
|
||||
// VideoFolderSort folder index.
|
||||
type VideoFolderSort struct {
|
||||
ID int64 `json:"id"`
|
||||
Mid int64 `json:"mid"`
|
||||
Sort []int64 `json:"sort"`
|
||||
Map map[int64]struct{} `json:"map"`
|
||||
CTime xtime.Time `json:"ctime"`
|
||||
MTime xtime.Time `json:"mtime"`
|
||||
}
|
||||
|
||||
// Index return index for fids.
|
||||
func (f *VideoFolderSort) Index() []byte {
|
||||
var (
|
||||
i int
|
||||
v int64
|
||||
fs = f.Sort
|
||||
n = len(fs) * 8
|
||||
b = make([]byte, n)
|
||||
)
|
||||
for i = 0; i < n; i += 8 {
|
||||
v = fs[i/8]
|
||||
b[i] = byte(v >> 56)
|
||||
b[i+1] = byte(v >> 48)
|
||||
b[i+2] = byte(v >> 40)
|
||||
b[i+3] = byte(v >> 32)
|
||||
b[i+4] = byte(v >> 24)
|
||||
b[i+5] = byte(v >> 16)
|
||||
b[i+6] = byte(v >> 8)
|
||||
b[i+7] = byte(v)
|
||||
}
|
||||
return b
|
||||
}
|
||||
|
||||
// SetIndex set sort fids.
|
||||
func (f *VideoFolderSort) SetIndex(b []byte) (err error) {
|
||||
var (
|
||||
i int
|
||||
id int64
|
||||
n = len(b)
|
||||
ids = make([]int64, n)
|
||||
)
|
||||
if len(b)%8 != 0 {
|
||||
err = fmt.Errorf("invalid sort index:%v", b)
|
||||
return
|
||||
}
|
||||
f.Map = make(map[int64]struct{}, n)
|
||||
for i = 0; i < n; i += 8 {
|
||||
id = int64(b[i+7]) |
|
||||
int64(b[i+6])<<8 |
|
||||
int64(b[i+5])<<16 |
|
||||
int64(b[i+4])<<24 |
|
||||
int64(b[i+3])<<32 |
|
||||
int64(b[i+2])<<40 |
|
||||
int64(b[i+1])<<48 |
|
||||
int64(b[i])<<56
|
||||
ids[i/8] = id
|
||||
f.Map[id] = struct{}{}
|
||||
}
|
||||
f.Sort = ids
|
||||
return
|
||||
}
|
||||
|
||||
// SortFavs sort the favorites by index.
|
||||
func (f *VideoFolderSort) SortFavs(fs map[int64]*VideoFolder, isSelf bool) (res []*VideoFolder, update bool) {
|
||||
var (
|
||||
ok bool
|
||||
id int64
|
||||
sorted []int64
|
||||
fav *VideoFolder
|
||||
idx = f.Sort
|
||||
)
|
||||
res = make([]*VideoFolder, 0, len(fs))
|
||||
if len(f.Sort) == 0 {
|
||||
for _, fav = range fs {
|
||||
if !isSelf && !fav.IsPublic() {
|
||||
continue
|
||||
}
|
||||
res = append(res, fav)
|
||||
}
|
||||
sort.Sort(VideoFolders(res))
|
||||
return
|
||||
}
|
||||
if len(idx) != len(fs) {
|
||||
sorted = append(sorted, idx[0])
|
||||
for id = range fs {
|
||||
if _, ok = f.Map[id]; !ok {
|
||||
sorted = append(sorted, id)
|
||||
}
|
||||
}
|
||||
for _, id := range idx[1:] {
|
||||
if _, ok = fs[id]; ok {
|
||||
sorted = append(sorted, id)
|
||||
}
|
||||
}
|
||||
update = true
|
||||
f.Sort = sorted
|
||||
}
|
||||
for _, id = range f.Sort {
|
||||
if fav, ok = fs[id]; ok {
|
||||
if !isSelf && !fav.IsPublic() {
|
||||
continue
|
||||
}
|
||||
res = append(res, fav)
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
Reference in New Issue
Block a user