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

Skip to content

Commit e205ad6

Browse files
committed
博文搜索功能完成
1 parent 265e331 commit e205ad6

File tree

14 files changed

+426
-43
lines changed

14 files changed

+426
-43
lines changed
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
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+
"service"
15+
)
16+
17+
// search
18+
// uri: /search
19+
func SearchHandler(rw http.ResponseWriter, req *http.Request) {
20+
q := req.FormValue("q")
21+
field := req.FormValue("f")
22+
p, err := strconv.Atoi(req.FormValue("p"))
23+
if err != nil {
24+
p = 1
25+
}
26+
27+
rows := 20
28+
29+
respBody, err := service.DoSearch(q, field, (p-1)*rows, rows)
30+
if err != nil {
31+
// TODO:当作无结果处理?
32+
}
33+
34+
pageHtml := service.GenPageHtml(p, rows, respBody.NumFound, "/search?q="+q+"&f="+field)
35+
36+
req.Form.Set(filter.CONTENT_TPL_KEY, "/template/search.html")
37+
// 设置模板数据
38+
filter.SetData(req, map[string]interface{}{"respBody": respBody, "q": q, "f": field, "pageHtml": pageHtml})
39+
}

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

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,9 @@ func (this *ViewFilter) PostFilter(rw http.ResponseWriter, req *http.Request) bo
164164
}
165165

166166
// TODO: 新模版过度
167-
if strings.Contains(req.RequestURI, "articles") || req.RequestURI == "/" {
167+
if strings.Contains(req.RequestURI, "articles") ||
168+
req.RequestURI == "/" ||
169+
strings.Contains(req.RequestURI, "search") {
168170
this.commonHtmlFiles = []string{config.ROOT + "/template/common/layout.html"}
169171
this.baseTplName = "layout.html"
170172
} else if !this.isBackView {

websites/code/studygolang/src/model/document.go

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,9 @@ type Document struct {
2525
Viewnum int `json:"viewnum"`
2626
Cmtnum int `json:"cmtnum"`
2727
Likenum int `json:"likenum"`
28+
29+
HlTitle string // 高亮的标题
30+
HlContent string // 高亮的内容
2831
}
2932

3033
func NewDocument(object interface{}, objectExt interface{}) *Document {
@@ -85,3 +88,20 @@ func NewAddCommand(doc *Document, boost float64, overwrite bool, commitWithin in
8588
CommitWithin: commitWithin,
8689
}
8790
}
91+
92+
type ResponseBody struct {
93+
NumFound int `json:"numFound"`
94+
Start int `json:"start"`
95+
Docs []*Document `json:"docs"`
96+
}
97+
98+
type Highlighting struct {
99+
Title []string `json:"title"`
100+
Content []string `json:"content"`
101+
}
102+
103+
type SearchResponse struct {
104+
RespHeader map[string]interface{} `json:"responseHeader"`
105+
RespBody *ResponseBody `json:"response"`
106+
Highlight map[string]*Highlighting `json:"highlighting"`
107+
}
Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
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+
// 搜索词统计
15+
type SearchStat struct {
16+
Id int `json:"id"`
17+
Keyword string `json:"keyword"`
18+
Times int `json:"times"`
19+
Ctime string `json:"ctime"`
20+
21+
// 数据库访问对象
22+
*Dao
23+
}
24+
25+
func NewSearchStat() *SearchStat {
26+
return &SearchStat{
27+
Dao: &Dao{tablename: "search_stat"},
28+
}
29+
}
30+
31+
func (this *SearchStat) Insert() (int64, error) {
32+
this.prepareInsertData()
33+
result, err := this.Dao.Insert()
34+
if err != nil {
35+
return 0, err
36+
}
37+
return result.LastInsertId()
38+
}
39+
40+
func (this *SearchStat) Find(selectCol ...string) error {
41+
return this.Dao.Find(this.colFieldMap(), selectCol...)
42+
}
43+
44+
func (this *SearchStat) FindAll(selectCol ...string) ([]*SearchStat, error) {
45+
if len(selectCol) == 0 {
46+
selectCol = util.MapKeys(this.colFieldMap())
47+
}
48+
rows, err := this.Dao.FindAll(selectCol...)
49+
if err != nil {
50+
return nil, err
51+
}
52+
// TODO:
53+
searchStatList := make([]*SearchStat, 0, 10)
54+
logger.Debugln("selectCol", selectCol)
55+
colNum := len(selectCol)
56+
for rows.Next() {
57+
searchStat := NewSearchStat()
58+
err = this.Scan(rows, colNum, searchStat.colFieldMap(), selectCol...)
59+
if err != nil {
60+
logger.Errorln("SearchStat FindAll Scan Error:", err)
61+
continue
62+
}
63+
searchStatList = append(searchStatList, searchStat)
64+
}
65+
return searchStatList, nil
66+
}
67+
68+
// 为了支持连写
69+
func (this *SearchStat) Where(condition string, args ...interface{}) *SearchStat {
70+
this.Dao.Where(condition, args...)
71+
return this
72+
}
73+
74+
// 为了支持连写
75+
func (this *SearchStat) Set(clause string, args ...interface{}) *SearchStat {
76+
this.Dao.Set(clause, args...)
77+
return this
78+
}
79+
80+
// 为了支持连写
81+
func (this *SearchStat) Limit(limit string) *SearchStat {
82+
this.Dao.Limit(limit)
83+
return this
84+
}
85+
86+
// 为了支持连写
87+
func (this *SearchStat) Order(order string) *SearchStat {
88+
this.Dao.Order(order)
89+
return this
90+
}
91+
92+
func (this *SearchStat) prepareInsertData() {
93+
this.columns = []string{"keyword", "times"}
94+
this.colValues = []interface{}{this.Keyword, this.Times}
95+
}
96+
97+
func (this *SearchStat) colFieldMap() map[string]interface{} {
98+
return map[string]interface{}{
99+
"id": &this.Id,
100+
"keyword": &this.Keyword,
101+
"times": &this.Times,
102+
"ctime": &this.Ctime,
103+
}
104+
}

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

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

62+
// 搜索
63+
router.HandleFunc("/search", SearchHandler)
64+
6265
// wiki
6366
router.HandleFunc("/wiki", WikisHandler)
6467
router.HandleFunc("/wiki/new{json:(|.json)}", NewWikiPageHandler).AppendFilterChain(loginFilterChain)

websites/code/studygolang/src/service/article.go

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -244,15 +244,13 @@ func FindArticlesById(idstr string) (curArticle *model.Article, prevNext []*mode
244244
prevNext = make([]*model.Article, 2)
245245
prevId, nextId := id, id
246246
for _, article := range articles {
247-
if prevId > article.Id {
247+
if article.Id < id {
248248
prevId = article.Id
249249
prevNext[0] = article
250-
} else if nextId < article.Id {
250+
} else if article.Id > id {
251251
nextId = article.Id
252252
prevNext[1] = article
253-
}
254-
255-
if id == article.Id {
253+
} else {
256254
curArticle = article
257255
}
258256
}

websites/code/studygolang/src/service/page.go

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
package service
88

99
import (
10+
"strings"
1011
"util"
1112
)
1213

@@ -65,3 +66,92 @@ func GetPageHtml(curPage, total int, uri string) string {
6566
stringBuilder.Append(`</li>`)
6667
return stringBuilder.String()
6768
}
69+
70+
// 构造分页html(new)
71+
// curPage 当前页码;pageNum 每页记录数;total总记录数;uri 当前uri
72+
func GenPageHtml(curPage, pageNum, total int, uri string) string {
73+
// 总页数
74+
pageCount := total / pageNum
75+
if total%pageNum != 0 {
76+
pageCount++
77+
}
78+
if pageCount < 2 {
79+
return ""
80+
}
81+
82+
needQues := true
83+
if strings.Contains(uri, "?") {
84+
needQues = false
85+
}
86+
87+
// 显示5页,然后显示...,接着显示最后两页
88+
stringBuilder := util.NewBuffer()
89+
// 当前是第一页
90+
if curPage != 1 {
91+
stringBuilder.Append(`<li><a href="`).Append(uri)
92+
if needQues {
93+
stringBuilder.Append("?")
94+
} else {
95+
stringBuilder.Append("&")
96+
}
97+
stringBuilder.Append("p=").AppendInt(curPage - 1).Append(`">&laquo;</a>`)
98+
} else {
99+
stringBuilder.Append(`<li class="disabled"><a href="#">&laquo;</a>`)
100+
}
101+
stringBuilder.Append(`</li>`)
102+
103+
before := 5
104+
showPages := 8
105+
for i := 0; i < pageCount; i++ {
106+
if i >= showPages {
107+
break
108+
}
109+
if curPage == i+1 {
110+
stringBuilder.Append(`<li class="active"><a href="`).Append(uri)
111+
if needQues {
112+
stringBuilder.Append("?")
113+
} else {
114+
stringBuilder.Append("&")
115+
}
116+
117+
stringBuilder.Append("p=").AppendInt(i + 1).Append(`">`).AppendInt(i + 1).Append("</a></li>")
118+
continue
119+
}
120+
// 分界点
121+
if curPage >= before {
122+
if curPage >= 7 {
123+
before = 2
124+
} else {
125+
before = curPage + 2
126+
}
127+
showPages += 2
128+
}
129+
if i == before {
130+
stringBuilder.Append(`<li class="disabled"><a href="#"><span class="gap">…</span></a></li>`)
131+
continue
132+
}
133+
stringBuilder.Append(`<li><a href="`).Append(uri)
134+
if needQues {
135+
stringBuilder.Append("?")
136+
} else {
137+
stringBuilder.Append("&")
138+
}
139+
stringBuilder.Append("p=").AppendInt(i + 1).Append(`">`).AppendInt(i + 1).Append("</a></li>")
140+
}
141+
142+
// 最后一页
143+
if curPage < pageCount {
144+
stringBuilder.Append(`<li><a href="`).Append(uri)
145+
if needQues {
146+
stringBuilder.Append("?")
147+
} else {
148+
stringBuilder.Append("&")
149+
}
150+
stringBuilder.Append("p=").AppendInt(curPage + 1).Append(`">&raquo;</a>`)
151+
} else {
152+
stringBuilder.Append(`<li class="disabled"><a href="#">&raquo;</a>`)
153+
}
154+
stringBuilder.Append(`</li>`)
155+
156+
return stringBuilder.String()
157+
}

0 commit comments

Comments
 (0)