Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 5ced143

Browse files
committed
用户活跃度排名
1 parent 0a22b7f commit 5ced143

File tree

11 files changed

+276
-12
lines changed

11 files changed

+276
-12
lines changed

src/http/controller/routes.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ func RegisterRoutes(g *echo.Group) {
3030
new(BookController).RegisterRoute(g)
3131
new(MissionController).RegisterRoute(g)
3232
new(UserRichController).RegisterRoute(g)
33+
new(TopController).RegisterRoute(g)
3334
new(WebsocketController).RegisterRoute(g)
3435

3536
new(InstallController).RegisterRoute(g)

src/http/controller/sidebar.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,9 @@ func (SidebarController) HotNodes(ctx echo.Context) error {
143143

144144
// ActiveUser 活跃会员
145145
func (SidebarController) ActiveUser(ctx echo.Context) error {
146-
activeUsers := logic.DefaultUser.FindActiveUsers(ctx, 9)
146+
// activeUsers := logic.DefaultUser.FindActiveUsers(ctx, 9)
147+
// return success(ctx, activeUsers)
148+
activeUsers := logic.DefaultRank.FindDAURank(ctx, 9)
147149
return success(ctx, activeUsers)
148150
}
149151

src/http/controller/top.go

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
// Copyright 2017 The StudyGolang Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style
3+
// license that can be found in the LICENSE file.
4+
// http://studygolang.com
5+
// Author: polaris [email protected]
6+
7+
package controller
8+
9+
import (
10+
"logic"
11+
12+
"github.com/labstack/echo"
13+
14+
"github.com/polaris1119/times"
15+
)
16+
17+
type TopController struct{}
18+
19+
// 注册路由
20+
func (self TopController) RegisterRoute(g *echo.Group) {
21+
g.Get("/top/dau", self.TopDAU)
22+
}
23+
24+
func (TopController) TopDAU(ctx echo.Context) error {
25+
data := map[string]interface{}{
26+
"today": times.Format("Ymd"),
27+
}
28+
29+
data["users"] = logic.DefaultRank.FindDAURank(ctx, 10)
30+
data["active_num"] = logic.DefaultRank.TotalDAUUser(ctx)
31+
32+
return render(ctx, "top/dau.html", data)
33+
}

src/http/controller/user.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@ func (UserController) Home(ctx echo.Context) error {
3131
return ctx.Redirect(http.StatusSeeOther, "/users")
3232
}
3333

34+
user.Weight = logic.DefaultRank.UserDAURank(ctx, user.Uid)
35+
3436
topics := logic.DefaultTopic.FindRecent(5, user.Uid)
3537

3638
resources := logic.DefaultResource.FindRecent(ctx, user.Uid)
@@ -47,7 +49,8 @@ func (UserController) Home(ctx echo.Context) error {
4749
// ReadList 会员列表
4850
func (UserController) ReadList(ctx echo.Context) error {
4951
// 获取活跃会员
50-
activeUsers := logic.DefaultUser.FindActiveUsers(ctx, 36)
52+
// activeUsers := logic.DefaultUser.FindActiveUsers(ctx, 36)
53+
activeUsers := logic.DefaultRank.FindDAURank(ctx, 36)
5154
// 获取最新加入会员
5255
newUsers := logic.DefaultUser.FindNewUsers(ctx, 36)
5356
// 获取会员总数

src/logic/rank.go

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,64 @@ func (self RankLogic) FindMonthRank(ctx context.Context, objtype, num int) (resu
118118
return self.findModelsByRank(resultSlice, objtype, num)
119119
}
120120

121+
func (self RankLogic) FindDAURank(ctx context.Context, num int) []*model.User {
122+
objLog := GetLogger(ctx)
123+
124+
redisClient := nosql.NewRedisClient()
125+
key := self.getDAURankKey(times.Format("ymd"))
126+
resultSlice, err := redisClient.ZREVRANGE(key, 0, num-1, true)
127+
redisClient.Close()
128+
if err != nil {
129+
objLog.Errorln("FindDAURank ZREVRANGE error:", err)
130+
return nil
131+
}
132+
133+
uids := make([]int, 0, num)
134+
weights := make([]int, 0, num)
135+
136+
for len(resultSlice) > 0 {
137+
var (
138+
uid, weight int
139+
err error
140+
)
141+
resultSlice, err = redis.Scan(resultSlice, &uid, &weight)
142+
if err != nil {
143+
logger.Errorln("FindDAURank redis Scan error:", err)
144+
return nil
145+
}
146+
147+
uids = append(uids, uid)
148+
weights = append(weights, weight)
149+
}
150+
151+
userMap := DefaultUser.FindDAUUsers(ctx, uids)
152+
users := make([]*model.User, len(userMap))
153+
for i, uid := range uids {
154+
user := userMap[uid]
155+
user.Weight = weights[i]
156+
users[i] = user
157+
}
158+
159+
return users
160+
}
161+
162+
// TotalDAUUser 今日活跃用户数
163+
func (self RankLogic) TotalDAUUser(ctx context.Context) int {
164+
redisClient := nosql.NewRedisClient()
165+
defer redisClient.Close()
166+
167+
key := self.getDAURankKey(times.Format("ymd"))
168+
return redisClient.ZCARD(key)
169+
}
170+
171+
func (self RankLogic) UserDAURank(ctx context.Context, uid int) int {
172+
redisClient := nosql.NewRedisClient()
173+
defer redisClient.Close()
174+
175+
key := self.getDAURankKey(times.Format("ymd"))
176+
return redisClient.ZREVRANK(key, uid)
177+
}
178+
121179
func (RankLogic) findModelsByRank(resultSlice []interface{}, objtype, num int) (result interface{}) {
122180
objids := make([]int, 0, num)
123181
viewNums := make([]int, 0, num)

src/logic/user.go

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -312,8 +312,10 @@ func (self UserLogic) FindCurrentUser(ctx context.Context, username interface{})
312312
MsgNum: DefaultMessage.FindNotReadMsgNum(ctx, user.Uid),
313313

314314
Balance: user.Balance,
315+
Gold: user.Gold,
316+
Silver: user.Silver,
317+
Copper: user.Copper,
315318
}
316-
me.SplitBalance()
317319

318320
// TODO: 先每次都记录登录时间
319321
go self.RecordLoginTime(user.Username)
@@ -519,6 +521,18 @@ func (UserLogic) FindActiveUsers(ctx context.Context, limit int, offset ...int)
519521
return activeUsers
520522
}
521523

524+
func (UserLogic) FindDAUUsers(ctx context.Context, uids []int) map[int]*model.User {
525+
objLog := GetLogger(ctx)
526+
527+
users := make(map[int]*model.User)
528+
err := MasterDB.In("uid", uids).Find(&users)
529+
if err != nil {
530+
objLog.Errorln("UserLogic FindDAUUsers error:", err)
531+
return nil
532+
}
533+
return users
534+
}
535+
522536
// FindNewUsers 最新加入会员
523537
func (UserLogic) FindNewUsers(ctx context.Context, limit int, offset ...int) []*model.User {
524538
objLog := GetLogger(ctx)

src/model/user.go

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import (
1212
"math/rand"
1313
"time"
1414

15+
"github.com/go-xorm/xorm"
1516
"github.com/polaris1119/goutils"
1617
)
1718

@@ -73,6 +74,12 @@ type User struct {
7374
// 非用户表中的信息,为了方便放在这里
7475
Roleids []int `xorm:"-"`
7576
Rolenames []string `xorm:"-"`
77+
78+
// 活跃度
79+
Weight int `json:"weight" xorm:"-"`
80+
Gold int `json:"gold" xorm:"-"`
81+
Silver int `json:"silver" xorm:"-"`
82+
Copper int `json:"copper" xorm:"-"`
7683
}
7784

7885
func (this *User) TableName() string {
@@ -86,6 +93,16 @@ func (this *User) String() string {
8693
return buffer.String()
8794
}
8895

96+
func (this *User) AfterSet(name string, cell xorm.Cell) {
97+
if name == "balance" {
98+
this.Gold = this.Balance / 10000
99+
balance := this.Balance % 10000
100+
101+
this.Silver = balance / 100
102+
this.Copper = balance % 100
103+
}
104+
}
105+
89106
// Me 代表当前用户
90107
type Me struct {
91108
Uid int `json:"uid"`
@@ -105,14 +122,6 @@ type Me struct {
105122
Copper int `json:"copper"`
106123
}
107124

108-
func (this *Me) SplitBalance() {
109-
this.Gold = this.Balance / 10000
110-
balance := this.Balance % 10000
111-
112-
this.Silver = balance / 100
113-
this.Copper = balance % 100
114-
}
115-
116125
// 活跃用户信息
117126
// 活跃度规则:
118127
// 1、注册成功后 +2

static/css/main.css

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -312,6 +312,9 @@ a.balance_area img { vertical-align: bottom; }
312312
.inner_content h2 { font-size: 18px; font-weight: 500; line-height: 100%; margin: 15px 0px 15px 0px; padding: 0px 0px 8px 0px; border-bottom: 1px solid #e2e2e2; }
313313
.sep20 { height: 20px; }
314314
.sep10 { height: 10px; }
315+
.sep5 { height: 5px; }
316+
317+
.f12 { font-size: 12px; }
315318

316319
.dock_area {background-color: #edf3f5; background-image: url(/static/img/dock_shadow.png); background-repeat: repeat-x; padding: 0px; }
317320
.chevron {font-family: "Lucida Grande"; font-weight: 500; }

template/top/dau.html

Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
{{define "title"}}今日最活跃会员 {{end}}
2+
{{define "seo"}}<meta name="keywords" content="{{.setting.SeoKeywords}}">
3+
<meta name="description" content="{{.setting.SeoDescription}}">{{end}}
4+
{{define "content"}}
5+
<div class="row banner">
6+
</div>
7+
<div class="row">
8+
<div class="col-lg-9 col-md-8 col-sm-7">
9+
<ol class="breadcrumb">
10+
<li><a href="/"><i class="glyphicon glyphicon-home"></i> 首页</a></li>
11+
<li class="active">今日最活跃会员</li>
12+
<li class="active">{{.today}}</li>
13+
</ol>
14+
<div class="page box_white">
15+
<div class="inner_content">
16+
<table cellpadding="5" cellspacing="0" border="0" width="100%"><tbody>
17+
{{range $i, $user := .users}}
18+
<tr>
19+
<td width="53" valign="top" align="center">
20+
<a href="/user/{{.Username}}"><img src="{{gravatar .Avatar .Email 48 $.is_https}}" class="avatar" border="0" align="default"></a>
21+
</td>
22+
<td width="auto" align="left">
23+
<h2 style="margin-bottom: 0px; margin-top: 0px; border-bottom: none;"><span class="gray">{{add $i 1}}.</span> <a href="/member/{{.Username}}">{{.Username}}</a></h2>
24+
25+
<span class="gray f12">{{.Monlog}}</span>
26+
<div class="sep5"></div>
27+
28+
<span class="gray f12"><a href="{{.Website}}" target="_blank">{{.Website}}</a></span>
29+
<div class="sep5"></div>
30+
31+
<span style="color: #ccc;">第 {{.Uid}} 号会员</span>
32+
33+
</td>
34+
<td width="200" align="center">
35+
<div class="balance_area" style="font-size: 24px; line-height: 24px;">&nbsp;{{.Weight}}&nbsp;</div>
36+
</td>
37+
</tr>
38+
<tr>
39+
<td colspan="3"><div style="height: 1px; background-color: #f0f0f0; border-bottom: 1px solid #eee;"></div></td>
40+
</tr>
41+
{{end}}
42+
43+
<tr>
44+
<td colspan="3" align="center"><div><span class="gray">{{.active_num}}</span></div></td>
45+
</tr>
46+
</tbody></table>
47+
</div>
48+
</div>
49+
50+
</div>
51+
<div class="col-lg-3 col-md-4 col-sm-5">
52+
<div class="row box_white sidebar">
53+
{{if .me.Uid}}
54+
<div class="box">
55+
<p style="margin-top: 10.5px; text-align: center;">欢迎您,<a href="/user/{{.me.Username}}">{{.me.Username}}</a></p>
56+
</div>
57+
<div class="box" style="margin: 0 5px;">
58+
<a class="btn btn-default btn-sm" href="/topics/new">发布主题</a>&nbsp;&nbsp;
59+
<a class="btn btn-default btn-sm" href="/articles/new">撰写文章</a>&nbsp;&nbsp;
60+
<a class="btn btn-default btn-sm" href="/resources/new">分享资源</a>&nbsp;&nbsp;
61+
</div>
62+
<div class="inner" style="margin-top: 25px;">
63+
<a href="/message/system">{{.me.MsgNum}} 条未读消息</a>
64+
<div class="pull-right">
65+
<a href="/balance" class="balance_area">
66+
{{if .me.Gold}}
67+
{{.me.Gold}} <img src="/static/img/gold_48.png" alt="" width="16px">
68+
{{end}}
69+
{{if .me.Silver}}
70+
{{.me.Silver}} <img src="/static/img/silver_48.png" alt="" width="16px">
71+
{{end}}
72+
{{.me.Copper}} <img src="/static/img/copper_48.png" alt="" width="16px">
73+
</a>
74+
</div>
75+
</div>
76+
77+
{{else}}
78+
<div class="top">
79+
<h3 class="title"><i class="glyphicon glyphicon-user"></i> 用户登录</h3>
80+
</div>
81+
<div class="sb-content">
82+
<form action="/account/login" method="post" class="form-horizontal login" role="form">
83+
<div class="form-group">
84+
<div class="col-sm-10">
85+
<input type="text" class="form-control input-sm" id="username" name="username" placeholder="请填写用户名或邮箱">
86+
</div>
87+
</div>
88+
<div class="form-group">
89+
<div class="col-sm-10">
90+
<input type="password" class="form-control input-sm" id="passwd" name="passwd" placeholder="请填写密码">
91+
</div>
92+
</div>
93+
<div class="form-group">
94+
<div class="col-sm-10">
95+
<div class="checkbox">
96+
<label>
97+
<input id="user_remember_me" name="remember_me" type="checkbox" value="1" checked="checked" /> 记住登录状态
98+
</label>
99+
<input class="btn btn-primary btn-sm" data-disable-with="正在登录" name="commit" type="submit" value="登录" />
100+
</div>
101+
</div>
102+
</div>
103+
</form>
104+
</div>
105+
{{end}}
106+
</div>
107+
108+
</div>
109+
</div>
110+
{{end}}
111+
{{define "css"}}
112+
<style type="text/css">
113+
table td {
114+
padding: 5px;
115+
}
116+
img.avatar {
117+
-moz-border-radius: 4px;
118+
border-radius: 4px;
119+
}
120+
</style>
121+
{{end}}
122+
{{define "js"}}
123+
{{end}}

template/user/profile.html

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,24 @@
5151
<label>注册时间:</label>
5252
<span>{{.user.Ctime}}</span>
5353
</li>
54+
{{if gt .user.Weight 0}}
55+
<li>
56+
<label>今日活跃度排名:</label>
57+
<span><a href="/top/dau">{{.user.Weight}}</a></span>
58+
</li>
59+
{{end}}
60+
<li>
61+
<label>财富:</label>
62+
<span class="balance_area">
63+
{{if .user.Gold}}
64+
{{.user.Gold}} <img src="/static/img/gold_48.png" alt="" width="16px">
65+
{{end}}
66+
{{if .user.Silver}}
67+
{{.user.Silver}} <img src="/static/img/silver_48.png" alt="" width="16px">
68+
{{end}}
69+
{{.user.Copper}} <img src="/static/img/copper_48.png" alt="" width="16px">
70+
</span>
71+
</li>
5472
</ul>
5573
</div>
5674
</div>

template/user/users.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
</ol>
1010
<div class="box_white">
1111
<div class="users">
12-
<div class="info text-right">目前已经有 {{.total}} 位会员加入了 Golang中文社区</div>
12+
<div class="info text-right">目前已经有 {{.total}} 位会员加入了 {{.setting.Name}}</div>
1313
<div id="hot_users" class="user-list clearfix">
1414
<h4>活跃会员</h4>
1515
{{with $root := .}}

0 commit comments

Comments
 (0)