/
like.go
191 lines (153 loc) · 4.55 KB
/
like.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
// Copyright 2016 The StudyGolang Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// http://studygolang.com
// Author:polaris polaris@studygolang.com
package logic
import (
"errors"
"fmt"
"time"
. "github.com/studygolang/studygolang/db"
"golang.org/x/net/context"
"github.com/studygolang/studygolang/internal/model"
)
type LikeLogic struct{}
var DefaultLike = LikeLogic{}
// HadLike 某个用户是否已经喜欢某个对象
func (LikeLogic) HadLike(ctx context.Context, uid, objid, objtype int) int {
objLog := GetLogger(ctx)
like := &model.Like{}
_, err := MasterDB.Where("uid=? AND objid=? AND objtype=?", uid, objid, objtype).Get(like)
if err != nil {
objLog.Errorln("LikeLogic HadLike error:", err)
return 0
}
return like.Flag
}
// FindUserLikeObjects 获取用户对一批对象是否喜欢的状态
// objids 两个值
func (LikeLogic) FindUserLikeObjects(ctx context.Context, uid, objtype int, objids ...int) (map[int]int, error) {
objLog := GetLogger(ctx)
if len(objids) < 2 {
return nil, errors.New("参数错误")
}
littleId, greatId := objids[0], objids[1]
if littleId > greatId {
littleId, greatId = greatId, littleId
}
likes := make([]*model.Like, 0)
err := MasterDB.Where("uid=? AND objtype=? AND objid BETWEEN ? AND ?", uid, objtype, littleId, greatId).
Find(&likes)
if err != nil {
objLog.Errorln("LikeLogic FindUserLikeObjects error:", err)
return nil, err
}
likeFlags := make(map[int]int, len(likes))
for _, like := range likes {
likeFlags[like.Objid] = like.Flag
}
return likeFlags, nil
}
// FindUserRecentLikes 获取用户最近喜欢的对象(不过滤对象)
func (LikeLogic) FindUserRecentLikes(ctx context.Context, uid, limit int) (map[int]map[int]int, error) {
objLog := GetLogger(ctx)
likes := make([]*model.Like, 0)
// 过去 7 天内的
err := MasterDB.Where("uid=? AND ctime>?", uid, time.Now().Add(-7*86400e9)).Limit(limit).Find(&likes)
if err != nil {
objLog.Errorln("LikeLogic FindUserRecentLikes error:", err)
return nil, err
}
likeFlags := make(map[int]map[int]int, len(likes))
for _, like := range likes {
if _, ok := likeFlags[like.Objid]; ok {
likeFlags[like.Objid][like.Objtype] = like.Flag
} else {
likeFlags[like.Objid] = map[int]int{
like.Objtype: like.Flag,
}
}
}
return likeFlags, nil
}
// LikeObject 喜欢或取消喜欢
// objid 注册的喜欢对象
// uid 喜欢的人
func (LikeLogic) LikeObject(ctx context.Context, uid, objid, objtype, likeFlag int) error {
objLog := GetLogger(ctx)
like := &model.Like{}
_, err := MasterDB.Where("uid=? AND objid=? AND objtype=?", uid, objid, objtype).Get(like)
if err != nil {
objLog.Errorln("LikeLogic LikeObject get error:", err)
return err
}
// 之前喜欢过
if like.Uid != 0 {
// 再喜欢直接返回
if likeFlag == model.FlagLike {
return nil
}
// 取消喜欢
if likeFlag == model.FlagCancel {
// MasterDB.Where("uid=? AND objid=? AND objtype=?", uid, objid,objtype).Delete(like)
_, err = MasterDB.Delete(like)
if err != nil {
objLog.Errorln("LikeLogic LikeObject delete error:", err)
return err
}
// 取消喜欢成功,更新对象的喜欢数
if liker, ok := likers[objtype]; ok {
go liker.UpdateLike(objid, -1)
DefaultFeed.updateLike(objid, objtype, uid, -1)
}
return nil
}
return nil
}
like.Uid = uid
like.Objid = objid
like.Objtype = objtype
like.Flag = likeFlag
affectedRows, err := MasterDB.Insert(like)
if err != nil {
objLog.Errorln("LikeLogic LikeObject error:", err)
return err
}
// 喜欢成功
if affectedRows > 0 {
if liker, ok := likers[objtype]; ok {
go liker.UpdateLike(objid, 1)
DefaultFeed.updateLike(objid, objtype, uid, 1)
}
go likeObservable.NotifyObservers(uid, objtype, objid)
}
// TODO: 给被喜欢对象所有者发系统消息
/*
ext := map[string]interface{}{
"objid": objid,
"objtype": objtype,
"cid": cid,
"uid": uid,
}
go SendSystemMsgTo(0, objtype, ext)
*/
return nil
}
var likers = make(map[int]Liker)
// 喜欢接口
type Liker interface {
fmt.Stringer
// 喜欢 回调接口,用于更新对象自身需要更新的数据
UpdateLike(int, int)
}
// 注册喜欢对象,使得某种类型(主题、博文等)被喜欢了可以回调
func RegisterLikeObject(objtype int, liker Liker) {
if liker == nil {
panic("logic: Register liker is nil")
}
if _, dup := likers[objtype]; dup {
panic("logic: Register called twice for liker " + liker.String())
}
likers[objtype] = liker
}