完善分类和标签

This commit is contained in:
xing 2022-09-16 17:59:17 +08:00
parent 8ab85040a5
commit 244fd5d60d
5 changed files with 105 additions and 46 deletions

View File

@ -19,44 +19,35 @@ type ParseWhere interface {
type SqlBuilder [][]string type SqlBuilder [][]string
func (w SqlBuilder) parseField(ss []string, s *strings.Builder) {
if strings.Contains(ss[0], ".") && !strings.Contains(ss[0], "(") {
s.WriteString("`")
sx := strings.Split(ss[0], ".")
s.WriteString(sx[0])
s.WriteString("`.`")
s.WriteString(sx[1])
s.WriteString("`")
} else if !strings.Contains(ss[0], ".") && !strings.Contains(ss[0], "(") {
s.WriteString("`")
s.WriteString(ss[0])
s.WriteString("`")
} else {
s.WriteString(ss[0])
}
}
func (w SqlBuilder) ParseWhere(in ...[]interface{}) (string, []interface{}) { func (w SqlBuilder) ParseWhere(in ...[]interface{}) (string, []interface{}) {
var s strings.Builder var s strings.Builder
args := make([]interface{}, 0, len(w)) args := make([]interface{}, 0, len(w))
c := 0 c := 0
for _, ss := range w { for _, ss := range w {
if len(ss) == 2 { if len(ss) == 2 {
if strings.Contains(ss[0], ".") && !strings.Contains(ss[0], "(") { w.parseField(ss, &s)
s.WriteString("`")
sx := strings.Split(ss[0], ".")
s.WriteString(sx[0])
s.WriteString("`.`")
s.WriteString(sx[1])
s.WriteString("`")
} else if !strings.Contains(ss[0], ".") && !strings.Contains(ss[0], "(") {
s.WriteString("`")
s.WriteString(ss[0])
s.WriteString("`")
} else {
s.WriteString(ss[0])
}
s.WriteString("=? and ") s.WriteString("=? and ")
args = append(args, ss[1]) args = append(args, ss[1])
} }
if len(ss) >= 3 { if len(ss) >= 3 {
if strings.Contains(ss[0], ".") && !strings.Contains(ss[0], "(") { w.parseField(ss, &s)
s.WriteString("`")
sx := strings.Split(ss[0], ".")
s.WriteString(sx[0])
s.WriteString("`.`")
s.WriteString(sx[1])
s.WriteString("`")
} else if !strings.Contains(ss[0], ".") && !strings.Contains(ss[0], "(") {
s.WriteString("`")
s.WriteString(ss[0])
s.WriteString("`")
} else {
s.WriteString(ss[0])
}
s.WriteString(ss[1]) s.WriteString(ss[1])
if ss[1] == "in" && len(in) > 0 { if ss[1] == "in" && len(in) > 0 {
s.WriteString(" (") s.WriteString(" (")
@ -131,16 +122,30 @@ func (w SqlBuilder) parseJoin() string {
return s.String() return s.String()
} }
func SimplePagination[T Model](where ParseWhere, fields string, page, pageSize int, order SqlBuilder, join SqlBuilder, in ...[]interface{}) (r []T, total int, err error) { func SimplePagination[T Model](where ParseWhere, fields, group string, page, pageSize int, order SqlBuilder, join SqlBuilder, in ...[]interface{}) (r []T, total int, err error) {
var rr T var rr T
w, args := where.ParseWhere(in...) w, args := where.ParseWhere(in...)
n := struct { n := struct {
N int `db:"n" json:"n"` N int `db:"n" json:"n"`
}{} }{}
groupBy := ""
if group != "" {
g := strings.Builder{}
g.WriteString(" group by ")
g.WriteString(group)
groupBy = g.String()
}
j := join.parseJoin() j := join.parseJoin()
if group == "" {
tpx := "select count(*) n from %s %s %s limit 1" tpx := "select count(*) n from %s %s %s limit 1"
sq := fmt.Sprintf(tpx, rr.Table(), j, w) sq := fmt.Sprintf(tpx, rr.Table(), j, w)
err = db.Db.Get(&n, sq, args...) err = db.Db.Get(&n, sq, args...)
} else {
tpx := "select count(*) n from (select %s from %s %s %s %s ) tx"
sq := fmt.Sprintf(tpx, group, rr.Table(), j, w, groupBy)
err = db.Db.Get(&n, sq, args...)
}
if err != nil { if err != nil {
return return
} }
@ -155,8 +160,8 @@ func SimplePagination[T Model](where ParseWhere, fields string, page, pageSize i
if offset >= total { if offset >= total {
return return
} }
tp := "select %s from %s %s %s %s limit %d,%d" tp := "select %s from %s %s %s %s %s limit %d,%d"
sql := fmt.Sprintf(tp, fields, rr.Table(), j, w, order.parseOrderBy(), offset, pageSize) sql := fmt.Sprintf(tp, fields, rr.Table(), j, w, groupBy, order.parseOrderBy(), offset, pageSize)
err = db.Db.Select(&r, sql, args...) err = db.Db.Select(&r, sql, args...)
if err != nil { if err != nil {
return return

View File

@ -28,7 +28,12 @@ type WpPosts struct {
CommentCount int64 `gorm:"column:comment_count" db:"comment_count" json:"comment_count" form:"comment_count"` CommentCount int64 `gorm:"column:comment_count" db:"comment_count" json:"comment_count" form:"comment_count"`
//扩展字段 //扩展字段
Taxonomy string `db:"taxonomy" json:"taxonomy"`
CategoryName string `db:"category_name" json:"category_name"` CategoryName string `db:"category_name" json:"category_name"`
Categories []string `json:"categories"`
Tags []string `json:"tags"`
CategoriesHtml string
TagsHtml string
} }
func (w WpPosts) PrimaryKey() string { func (w WpPosts) PrimaryKey() string {

View File

@ -20,7 +20,7 @@ func index(c *gin.Context) {
pageSize := 10 pageSize := 10
order := c.Query("order") order := c.Query("order")
if !helper.IsContainInArr(order, []string{"asc", "desc"}) { if !helper.IsContainInArr(order, []string{"asc", "desc"}) {
order = "desc" order = "asc"
} }
where := models.SqlBuilder{{ where := models.SqlBuilder{{
"post_type", "post", "post_type", "post",
@ -38,11 +38,28 @@ func index(c *gin.Context) {
"month(post_date)", month, "month(post_date)", month,
}) })
} }
tt := ""
category := c.Param("category") category := c.Param("category")
if category == "" {
category = c.Param("tag")
if category != "" { if category != "" {
/*where = append(where, []string{ tt = "post_tag"
}
} else {
tt = "category"
}
var join models.SqlBuilder
if category != "" {
where = append(where, []string{
"d.name", category, "d.name", category,
})*/ }, []string{"taxonomy", tt})
join = append(join, []string{
"a", "left join", "wp_term_relationships b", "a.Id=b.object_id",
}, []string{
"left join", "wp_term_taxonomy c", "b.term_taxonomy_id=c.term_taxonomy_id",
}, []string{
"left join", "wp_terms d", "c.term_id=d.term_id",
})
} }
if p == "" { if p == "" {
p = c.Param("page") p = c.Param("page")
@ -54,7 +71,7 @@ func index(c *gin.Context) {
} }
status := []interface{}{"publish", "private"} status := []interface{}{"publish", "private"}
posts, totalRaw, err := models.SimplePagination[models.WpPosts](where, "ID", page, pageSize, models.SqlBuilder{{"post_date", order}}, nil, status) postIds, totalRaw, err := models.SimplePagination[models.WpPosts](where, "ID", "", page, pageSize, models.SqlBuilder{{"post_date", order}}, join, status)
defer func() { defer func() {
if err != nil { if err != nil {
c.Error(err) c.Error(err)
@ -66,7 +83,7 @@ func index(c *gin.Context) {
var all []uint64 var all []uint64
var allPosts []models.WpPosts var allPosts []models.WpPosts
var needQuery []interface{} var needQuery []interface{}
for _, wpPosts := range posts { for _, wpPosts := range postIds {
all = append(all, wpPosts.Id) all = append(all, wpPosts.Id)
if _, ok := PostsCache.Load(wpPosts.Id); !ok { if _, ok := PostsCache.Load(wpPosts.Id); !ok {
needQuery = append(needQuery, wpPosts.Id) needQuery = append(needQuery, wpPosts.Id)
@ -75,7 +92,7 @@ func index(c *gin.Context) {
if len(needQuery) > 0 { if len(needQuery) > 0 {
rawPosts, err := models.Find[models.WpPosts](models.SqlBuilder{{ rawPosts, err := models.Find[models.WpPosts](models.SqlBuilder{{
"Id", "in", "", "Id", "in", "",
}}, "a.*,d.name category_name", "", nil, models.SqlBuilder{{ }}, "a.*,d.name category_name,taxonomy", "", nil, models.SqlBuilder{{
"a", "left join", "wp_term_relationships b", "a.Id=b.object_id", "a", "left join", "wp_term_relationships b", "a.Id=b.object_id",
}, { }, {
"left join", "wp_term_taxonomy c", "b.term_taxonomy_id=c.term_taxonomy_id", "left join", "wp_term_taxonomy c", "b.term_taxonomy_id=c.term_taxonomy_id",
@ -85,15 +102,42 @@ func index(c *gin.Context) {
if err != nil { if err != nil {
return return
} }
for _, post := range rawPosts { postsMap := make(map[uint64]*models.WpPosts)
PostsCache.Store(post.Id, post) for i, post := range rawPosts {
v, ok := postsMap[post.Id]
if !ok {
v = &rawPosts[i]
}
if post.Taxonomy == "category" {
v.Categories = append(v.Categories, post.CategoryName)
} else if post.Taxonomy == "post_tag" {
v.Tags = append(v.Tags, post.CategoryName)
}
postsMap[post.Id] = v
}
for _, pp := range postsMap {
if len(pp.Categories) > 0 {
t := make([]string, 0, len(pp.Categories))
for _, cat := range pp.Categories {
t = append(t, fmt.Sprintf(`<a href="/p/category/%s" rel="category tag">%s</a>`, cat, cat))
}
pp.CategoriesHtml = strings.Join(t, "、")
}
if len(pp.Tags) > 0 {
t := make([]string, 0, len(pp.Tags))
for _, cat := range pp.Tags {
t = append(t, fmt.Sprintf(`<a href="/p/tag/%s" rel="tag">%s</a>`, cat, cat))
}
pp.TagsHtml = strings.Join(t, "、")
}
PostsCache.Store(pp.Id, pp)
} }
} }
for _, id := range all { for _, id := range all {
post, _ := PostsCache.Load(id) post, _ := PostsCache.Load(id)
pp := post.(models.WpPosts) pp := post.(*models.WpPosts)
allPosts = append(allPosts, pp) allPosts = append(allPosts, *pp)
} }
recent, err := recentPosts() recent, err := recentPosts()
archive, err := archives() archive, err := archives()

View File

@ -37,6 +37,7 @@ func SetupRouter() *gin.Engine {
r.GET("/", index) r.GET("/", index)
r.GET("/page/:page", index) r.GET("/page/:page", index)
r.GET("/p/category/:category", index) r.GET("/p/category/:category", index)
r.GET("/p/tag/:tag", index)
r.GET("/p/date/:year/:month", index) r.GET("/p/date/:year/:month", index)
r.GET("/p/date/:year/:month/page/:page", index) r.GET("/p/date/:year/:month/page/:page", index)

View File

@ -26,7 +26,11 @@
</span> </span>
<span class="cat-links"> <span class="cat-links">
<span class="screen-reader-text">分类 </span> <span class="screen-reader-text">分类 </span>
<a href="/p/category/uncategorized" rel="category tag">{{$v.CategoryName}}</a> {{$v.CategoriesHtml|unescaped}}
</span>
<span class="tags-links">
<span class="screen-reader-text">标签 </span>
{{$v.TagsHtml|unescaped}}
</span> </span>
<span class="comments-link"> <span class="comments-link">
<a href="/p/1#comments"> <a href="/p/1#comments">