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

Skip to content

Commit 1f04a6f

Browse files
committed
技术晨读专栏
1 parent c648e33 commit 1f04a6f

File tree

11 files changed

+458
-1
lines changed

11 files changed

+458
-1
lines changed

websites/code/studygolang/src/controller/ajax.go

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,24 @@ import (
2626

2727
// 侧边栏的内容通过异步请求获取
2828

29+
// 技术晨读
30+
// uri: /readings/recent.json
31+
func RecentReadingHandler(rw http.ResponseWriter, req *http.Request) {
32+
limit := req.FormValue("limit")
33+
if limit == "" {
34+
limit = "7"
35+
}
36+
37+
readings := service.FindReadings("0", limit)
38+
buf, err := json.Marshal(readings)
39+
if err != nil {
40+
logger.Errorln("[RecentReadingHandler] json.marshal error:", err)
41+
fmt.Fprint(rw, `{"ok": 0, "error":"解析json出错"}`)
42+
return
43+
}
44+
fmt.Fprint(rw, `{"ok": 1, "data":`+string(buf)+`}`)
45+
}
46+
2947
// 某节点下其他帖子
3048
func OtherTopicsHandler(rw http.ResponseWriter, req *http.Request) {
3149
vars := mux.Vars(req)
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
// Copyright 2014 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+
"net/http"
11+
"strconv"
12+
13+
"filter"
14+
"github.com/studygolang/mux"
15+
"service"
16+
"util"
17+
)
18+
19+
// 晨读列表页
20+
// uri: /readings
21+
func ReadingsHandler(rw http.ResponseWriter, req *http.Request) {
22+
limit := 20
23+
24+
lastId := req.FormValue("lastid")
25+
if lastId == "" {
26+
lastId = "0"
27+
}
28+
29+
readings := service.FindReadings(lastId, "25")
30+
if readings == nil {
31+
// TODO:服务暂时不可用?
32+
}
33+
34+
num := len(readings)
35+
if num == 0 {
36+
if lastId == "0" {
37+
util.Redirect(rw, req, "/")
38+
} else {
39+
util.Redirect(rw, req, "/readings")
40+
}
41+
42+
return
43+
}
44+
45+
var (
46+
hasPrev, hasNext bool
47+
prevId, nextId int
48+
)
49+
50+
if lastId != "0" {
51+
prevId, _ = strconv.Atoi(lastId)
52+
53+
// 避免因为项目下线,导致判断错误(所以 > 5)
54+
if prevId-readings[0].Id > 5 {
55+
hasPrev = false
56+
} else {
57+
prevId += limit
58+
hasPrev = true
59+
}
60+
}
61+
62+
if num > limit {
63+
hasNext = true
64+
readings = readings[:limit]
65+
nextId = readings[limit-1].Id
66+
} else {
67+
nextId = readings[num-1].Id
68+
}
69+
70+
pageInfo := map[string]interface{}{
71+
"has_prev": hasPrev,
72+
"prev_id": prevId,
73+
"has_next": hasNext,
74+
"next_id": nextId,
75+
}
76+
77+
req.Form.Set(filter.CONTENT_TPL_KEY, "/template/readings/list.html")
78+
// 设置模板数据
79+
filter.SetData(req, map[string]interface{}{"readings": readings, "page": pageInfo})
80+
}
81+
82+
// 点击 【我要晨读】,记录点击数,跳转
83+
// uri: /readings/{id:[0-9]+}
84+
func IReadingHandler(rw http.ResponseWriter, req *http.Request) {
85+
vars := mux.Vars(req)
86+
url := service.IReading(vars["id"])
87+
88+
util.Redirect(rw, req, url)
89+
return
90+
}

websites/code/studygolang/src/filter/view.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,7 @@ func (this *ViewFilter) PostFilter(rw http.ResponseWriter, req *http.Request) bo
169169
strings.Contains(req.RequestURI, "favorites") ||
170170
strings.Contains(req.RequestURI, "project") ||
171171
strings.HasPrefix(req.RequestURI, "/p/") ||
172+
strings.Contains(req.RequestURI, "reading") ||
172173
req.RequestURI == "/" ||
173174
strings.Contains(req.RequestURI, "search") {
174175
this.commonHtmlFiles = []string{config.ROOT + "/template/common/layout.html"}
Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
// Copyright 2014 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 model
8+
9+
import (
10+
"logger"
11+
"util"
12+
)
13+
14+
// Go技术晨读
15+
type MorningReading struct {
16+
Id int `json:"id" pk:"1"`
17+
Content string `json:"content"`
18+
Url string `json:"url"`
19+
Username string `json:"username"`
20+
Clicknum int `json:"clicknum,omitempty"`
21+
Ctime string `json:"ctime,omitempty"`
22+
23+
// 晨读日期,从 ctime 中提取
24+
Rdate string `json:"rdate"`
25+
26+
// 数据库访问对象
27+
*Dao
28+
}
29+
30+
func NewMorningReading() *MorningReading {
31+
return &MorningReading{
32+
Dao: &Dao{tablename: "morning_reading"},
33+
}
34+
}
35+
36+
func (this *MorningReading) Insert() (int64, error) {
37+
this.prepareInsertData()
38+
result, err := this.Dao.Insert()
39+
if err != nil {
40+
return 0, err
41+
}
42+
return result.LastInsertId()
43+
}
44+
45+
func (this *MorningReading) Find(selectCol ...string) error {
46+
return this.Dao.Find(this.colFieldMap(), selectCol...)
47+
}
48+
49+
func (this *MorningReading) FindAll(selectCol ...string) ([]*MorningReading, error) {
50+
if len(selectCol) == 0 {
51+
selectCol = util.MapKeys(this.colFieldMap())
52+
}
53+
rows, err := this.Dao.FindAll(selectCol...)
54+
if err != nil {
55+
return nil, err
56+
}
57+
// TODO:
58+
readingList := make([]*MorningReading, 0, 10)
59+
logger.Debugln("selectCol", selectCol)
60+
colNum := len(selectCol)
61+
for rows.Next() {
62+
reading := NewMorningReading()
63+
err = this.Scan(rows, colNum, reading.colFieldMap(), selectCol...)
64+
if err != nil {
65+
logger.Errorln("MorningReading FindAll Scan Error:", err)
66+
continue
67+
}
68+
reading.Rdate = reading.Ctime[:10]
69+
readingList = append(readingList, reading)
70+
}
71+
return readingList, nil
72+
}
73+
74+
// 为了支持连写
75+
func (this *MorningReading) Where(condition string, args ...interface{}) *MorningReading {
76+
this.Dao.Where(condition, args...)
77+
return this
78+
}
79+
80+
// 为了支持连写
81+
func (this *MorningReading) Set(clause string, args ...interface{}) *MorningReading {
82+
this.Dao.Set(clause, args...)
83+
return this
84+
}
85+
86+
// 为了支持连写
87+
func (this *MorningReading) Limit(limit string) *MorningReading {
88+
this.Dao.Limit(limit)
89+
return this
90+
}
91+
92+
// 为了支持连写
93+
func (this *MorningReading) Order(order string) *MorningReading {
94+
this.Dao.Order(order)
95+
return this
96+
}
97+
98+
func (this *MorningReading) prepareInsertData() {
99+
this.columns = []string{"content", "url", "username"}
100+
this.colValues = []interface{}{this.Content, this.Url, this.Username}
101+
}
102+
103+
func (this *MorningReading) colFieldMap() map[string]interface{} {
104+
return map[string]interface{}{
105+
"id": &this.Id,
106+
"content": &this.Content,
107+
"url": &this.Url,
108+
"clicknum": &this.Clicknum,
109+
"username": &this.Username,
110+
"ctime": &this.Ctime,
111+
}
112+
}

websites/code/studygolang/src/server/studygolang/router.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,10 @@ func initRouter() *mux.Router {
5959
router.HandleFunc("/articles", ArticlesHandler)
6060
router.HandleFunc("/articles/{id:[0-9]+}", ArticleDetailHandler)
6161

62+
// 技术晨读
63+
router.HandleFunc("/readings", ReadingsHandler)
64+
router.HandleFunc("/readings/{id:[0-9]+}", IReadingHandler)
65+
6266
// 搜索
6367
router.HandleFunc("/search", SearchHandler)
6468

@@ -121,6 +125,8 @@ func initRouter() *mux.Router {
121125
router.HandleFunc("/users/active.json", ActiveUserHandler)
122126
// 新会员
123127
router.HandleFunc("/users/newest.json", NewestUserHandler)
128+
// 最新晨读
129+
router.HandleFunc("/readings/recent.json", RecentReadingHandler)
124130

125131
// 文件上传(图片)
126132
router.HandleFunc("/upload/image.json", UploadImageHandler).AppendFilterChain(loginFilterChain)
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
// Copyright 2014 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 service
8+
9+
import (
10+
"strconv"
11+
12+
"logger"
13+
"model"
14+
)
15+
16+
// 获取晨读列表(分页)
17+
func FindReadings(lastId, limit string) []*model.MorningReading {
18+
reading := model.NewMorningReading()
19+
20+
cond := ""
21+
if lastId != "0" {
22+
cond = " AND id<" + lastId
23+
}
24+
25+
readingList, err := reading.Where(cond).Order("id DESC").Limit(limit).
26+
FindAll()
27+
if err != nil {
28+
logger.Errorln("reading service FindReadings Error:", err)
29+
return nil
30+
}
31+
32+
return readingList
33+
}
34+
35+
// 【我要晨读】
36+
func IReading(id string) string {
37+
_, err := strconv.Atoi(id)
38+
if err != nil {
39+
return "/readings"
40+
}
41+
42+
reading := model.NewMorningReading()
43+
err = reading.Where("id=?", id).Find()
44+
45+
if err != nil {
46+
logger.Errorln("reading service IReading error:", err)
47+
return "/readings"
48+
}
49+
50+
if reading.Id == 0 {
51+
return "/readings"
52+
}
53+
54+
reading.Where("id=?", id).Increment("clicknum", 1)
55+
56+
return reading.Url
57+
}

websites/code/studygolang/static/css/main.css

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,10 @@ html, body { background: #F2F2F2; font-family: "Helvetica Neue", Helvetica, Aria
106106
.sidebar .sb-content .image-list ul { margin: 2px 15px; }
107107
.sidebar .sb-content .image-list ul li { height: 95px; margin-top: 10px; }
108108

109+
.sidebar .sb-content .reading-list ul {margin: 2px 15px;}
110+
.sidebar .sb-content .reading-list ul li a {text-decoration: none;color: #0F2ED1;}
111+
.sidebar .sb-content .reading-list ul li a:hover { color: #d54f4b; }
112+
109113
/* blog 详情页 */
110114
.page {}
111115
.page .title { padding-top: 21px }

websites/code/studygolang/static/js/sidebar.js

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -213,6 +213,33 @@ $(function(){
213213
}
214214
}
215215

216+
var readingRecent = function(data) {
217+
if (data.ok) {
218+
data = data.data;
219+
220+
var content = '';
221+
if (data.length == 1) {
222+
data = data[0];
223+
content = '<li><a href="/readings/'+data.id+'" target="_blank">'+data.content+'</a></li>';
224+
} else {
225+
for(var i in data) {
226+
content += '<li>'+
227+
'<a href="/readings/'+data[i].id+'">'+
228+
'<div class="time"><span>10-25</span></div>'+
229+
'</a>'+
230+
'<div class="title">'+
231+
'<h4>'+
232+
'<a href="/readings/'+data[i].id+'">'+data[i].content+'</a>'+
233+
'</h4>'+
234+
'</div>'+
235+
'</li>';
236+
}
237+
}
238+
239+
$('.sb-content .reading-list ul').html(content);
240+
}
241+
}
242+
216243
var sidebar_callback = {
217244
"/topics/recent.json": {"func": topicRecent, "class": ".topic-list"},
218245
"/articles/recent.json": {"func": articleRecent, "class": ".article-list"},
@@ -222,6 +249,7 @@ $(function(){
222249
"/users/active.json": {"func": userActive, "class": "#active-list"},
223250
"/users/newest.json": {"func": userNewest, "class": "#newest-list"},
224251
"/websites/stat.json": {"func": websiteStat, "class": ".stat-list"},
252+
"/readings/recent.json": {"func": readingRecent, "class": ".reading-list"},
225253
};
226254

227255
if (typeof SG.SIDE_BARS != "undefined") {

websites/code/studygolang/template/index.html

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -274,6 +274,19 @@ <h3 class="title"><i class="glyphicon glyphicon-user"></i> 用户登录</h3>
274274
</div>
275275
{{end}}
276276
</div>
277+
<div class="row box_white sidebar">
278+
<div class="top">
279+
<h3 class="title"><i class="glyphicon glyphicon-book"></i>&nbsp;<a href="/readings" target="_blank" title="点击更多">今日晨读</a></h3>
280+
</div>
281+
<div class="sb-content">
282+
<div class="reading-list" data-limit="1">
283+
<ul class="list-unstyled">
284+
<img src="/static/img/loaders/loader7.gif" alt="加载中" />
285+
</ul>
286+
</div>
287+
</div>
288+
</div>
289+
277290
<div class="row box_white sidebar">
278291
<div class="top">
279292
<h3 class="title"><i class="glyphicon glyphicon-fire"></i>&nbsp;<a href="/projects" target="_blank" title="点击更多">开源项目</a></h3>
@@ -378,6 +391,7 @@ <h3 class="title"><i class="glyphicon glyphicon-link"></i>&nbsp;友情链接</h3
378391
"/users/active.json",
379392
"/users/newest.json",
380393
"/websites/stat.json",
394+
"/readings/recent.json"
381395
];
382396
</script>
383397
{{end}}

0 commit comments

Comments
 (0)