-
Notifications
You must be signed in to change notification settings - Fork 0
/
customer_service.go
259 lines (218 loc) · 5.36 KB
/
customer_service.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
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
package DB
import "sync"
import "database/sql"
import _ "github.com/go-sql-driver/mysql"
import log "github.com/golang/glog"
import "github.com/gomodule/redigo/redis"
import "fmt"
import "strconv"
import (
"ServerIM/config"
"time"
)
type Store struct {
id int64
group_id int64
mode int
}
type CustomerService struct {
mutex sync.Mutex
stores map[int64]*Store
sellers map[int64]int //销售员 sellerid:timestamp
online_sellers map[int64]int //在线的销售员 sellerid:timestamp
}
func NewCustomerService() *CustomerService {
cs := new(CustomerService)
cs.stores = make(map[int64]*Store)
cs.sellers = make(map[int64]int)
cs.online_sellers = make(map[int64]int)
return cs
}
func (cs *CustomerService) LoadStore(db *sql.DB, store_id int64) (*Store, error) {
stmtIns, err := db.Prepare("SELECT group_id, mode FROM store WHERE id=?")
if err != nil {
log.Info("error:", err)
return nil, err
}
defer stmtIns.Close()
row := stmtIns.QueryRow(store_id)
var group_id int64
var mode int
err = row.Scan(&group_id, &mode)
if err != nil {
log.Info("error:", err)
return nil, err
}
s := &Store{}
s.id = store_id
s.group_id = group_id
s.mode = mode
return s, nil
}
func (cs *CustomerService) GetStore(store_id int64) (*Store, error) {
cs.mutex.Lock()
if s, ok := cs.stores[store_id]; ok {
cs.mutex.Unlock()
return s, nil
}
cs.mutex.Unlock()
db, err := sql.Open("mysql", config.Config.Mysqldb_datasource)
if err != nil {
log.Info("error:", err)
return nil, err
}
defer db.Close()
s, err := cs.LoadStore(db, store_id)
if err != nil {
return nil, err
}
cs.mutex.Lock()
cs.stores[store_id] = s
cs.mutex.Unlock()
return s, nil
}
func (cs *CustomerService) GetLastSellerID(appid, uid, store_id int64) int64 {
conn := Redis_pool.Get()
defer conn.Close()
key := fmt.Sprintf("users_%d_%d_%d", appid, uid, store_id)
seller_id, err := redis.Int64(conn.Do("GET", key))
if err != nil {
log.Error("get last seller id err:", err)
return 0
}
return seller_id
}
func (cs *CustomerService) SetLastSellerID(appid, uid, store_id, seller_id int64) {
conn := Redis_pool.Get()
defer conn.Close()
key := fmt.Sprintf("users_%d_%d_%d", appid, uid, store_id)
_, err := conn.Do("SET", key, seller_id)
if err != nil {
log.Error("get last seller id err:", err)
return
}
}
//判断销售人员是否合法
func (cs *CustomerService) IsExist(store_id int64, seller_id int64) bool {
now := int(time.Now().Unix())
cs.mutex.Lock()
if t, ok := cs.sellers[seller_id]; ok {
if now-t < 10*60 {
cs.mutex.Unlock()
return true
}
//缓存超时
delete(cs.sellers, seller_id)
}
cs.mutex.Unlock()
conn := Redis_pool.Get()
defer conn.Close()
key := fmt.Sprintf("stores_seller_%d", store_id)
exists, err := redis.Bool(conn.Do("SISMEMBER", key, seller_id))
if err != nil {
log.Error("sismember err:", err)
return false
}
if exists {
cs.mutex.Lock()
cs.sellers[seller_id] = now
cs.mutex.Unlock()
}
return exists
}
//随机获取一个的销售人员
func (cs *CustomerService) GetSellerID(store_id int64) int64 {
conn := Redis_pool.Get()
defer conn.Close()
key := fmt.Sprintf("stores_seller_%d", store_id)
staff_id, err := redis.Int64(conn.Do("SRANDMEMBER", key))
if err != nil {
log.Error("srandmember err:", err)
return 0
}
return staff_id
}
func (cs *CustomerService) GetOrderSellerID(store_id int64) int64 {
conn := Redis_pool.Get()
defer conn.Close()
key := fmt.Sprintf("stores_zseller_%d", store_id)
r, err := redis.Values(conn.Do("ZRANGE", key, 0, 0))
if err != nil {
log.Error("srange err:", err)
return 0
}
log.Info("zrange:", r, key)
var seller_id int64
_, err = redis.Scan(r, &seller_id)
if err != nil {
log.Error("scan err:", err)
return 0
}
_, err = conn.Do("ZINCRBY", key, 1, seller_id)
if err != nil {
log.Error("zincrby err:", err)
}
return seller_id
}
//随机获取一个在线的销售人员
func (cs *CustomerService) GetOnlineSellerID(store_id int64) int64 {
conn := Redis_pool.Get()
defer conn.Close()
key := fmt.Sprintf("stores_online_seller_%d", store_id)
staff_id, err := redis.Int64(conn.Do("SRANDMEMBER", key))
if err != nil {
log.Error("srandmember err:", err)
return 0
}
return staff_id
}
func (cs *CustomerService) IsOnline(store_id int64, seller_id int64) bool {
now := int(time.Now().Unix())
cs.mutex.Lock()
if t, ok := cs.online_sellers[seller_id]; ok {
if now-t < 10*60 {
cs.mutex.Unlock()
return true
}
//缓存超时
delete(cs.online_sellers, seller_id)
}
cs.mutex.Unlock()
conn := Redis_pool.Get()
defer conn.Close()
key := fmt.Sprintf("stores_online_seller_%d", store_id)
on, err := redis.Bool(conn.Do("SISMEMBER", key, seller_id))
if err != nil {
log.Error("sismember err:", err)
return false
}
if on {
cs.mutex.Lock()
cs.online_sellers[seller_id] = now
cs.mutex.Unlock()
}
return on
}
func (cs *CustomerService) HandleUpdate(data string) {
store_id, err := strconv.ParseInt(data, 10, 64)
if err != nil {
log.Info("error:", err)
return
}
log.Infof("store:%d update", store_id)
cs.mutex.Lock()
defer cs.mutex.Unlock()
delete(cs.stores, store_id)
}
func (cs *CustomerService) Clear() {
cs.mutex.Lock()
defer cs.mutex.Unlock()
for k := range cs.stores {
delete(cs.stores, k)
}
}
func (cs *CustomerService) HandleMessage(v *redis.Message) {
if v.Channel == "store_update" {
cs.HandleUpdate(string(v.Data))
}
}