diff --git a/models/model.go b/models/model.go index 15e6736..92fd8f0 100644 --- a/models/model.go +++ b/models/model.go @@ -19,44 +19,35 @@ type ParseWhere interface { 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{}) { var s strings.Builder args := make([]interface{}, 0, len(w)) c := 0 for _, ss := range w { if len(ss) == 2 { - 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]) - } + w.parseField(ss, &s) s.WriteString("=? and ") args = append(args, ss[1]) } if len(ss) >= 3 { - 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]) - } + w.parseField(ss, &s) s.WriteString(ss[1]) if ss[1] == "in" && len(in) > 0 { s.WriteString(" (") @@ -131,16 +122,30 @@ func (w SqlBuilder) parseJoin() 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 w, args := where.ParseWhere(in...) n := struct { 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() - tpx := "select count(*) n from %s %s %s limit 1" - sq := fmt.Sprintf(tpx, rr.Table(), j, w) - err = db.Db.Get(&n, sq, args...) + if group == "" { + tpx := "select count(*) n from %s %s %s limit 1" + sq := fmt.Sprintf(tpx, rr.Table(), j, w) + 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 { return } @@ -155,8 +160,8 @@ func SimplePagination[T Model](where ParseWhere, fields string, page, pageSize i if offset >= total { return } - tp := "select %s from %s %s %s %s limit %d,%d" - sql := fmt.Sprintf(tp, fields, rr.Table(), j, w, order.parseOrderBy(), offset, pageSize) + tp := "select %s from %s %s %s %s %s limit %d,%d" + sql := fmt.Sprintf(tp, fields, rr.Table(), j, w, groupBy, order.parseOrderBy(), offset, pageSize) err = db.Db.Select(&r, sql, args...) if err != nil { return diff --git a/models/wp_posts.go b/models/wp_posts.go index e82808a..3e5449b 100644 --- a/models/wp_posts.go +++ b/models/wp_posts.go @@ -28,7 +28,12 @@ type WpPosts struct { CommentCount int64 `gorm:"column:comment_count" db:"comment_count" json:"comment_count" form:"comment_count"` //扩展字段 - CategoryName string `db:"category_name" json:"category_name"` + Taxonomy string `db:"taxonomy" json:"taxonomy"` + 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 { diff --git a/route/actions.go b/route/actions.go index ba18d1c..4214719 100644 --- a/route/actions.go +++ b/route/actions.go @@ -20,7 +20,7 @@ func index(c *gin.Context) { pageSize := 10 order := c.Query("order") if !helper.IsContainInArr(order, []string{"asc", "desc"}) { - order = "desc" + order = "asc" } where := models.SqlBuilder{{ "post_type", "post", @@ -38,11 +38,28 @@ func index(c *gin.Context) { "month(post_date)", month, }) } + tt := "" category := c.Param("category") + if category == "" { + category = c.Param("tag") + if category != "" { + tt = "post_tag" + } + } else { + tt = "category" + } + var join models.SqlBuilder if category != "" { - /*where = append(where, []string{ + where = append(where, []string{ "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 == "" { p = c.Param("page") @@ -54,7 +71,7 @@ func index(c *gin.Context) { } 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() { if err != nil { c.Error(err) @@ -66,7 +83,7 @@ func index(c *gin.Context) { var all []uint64 var allPosts []models.WpPosts var needQuery []interface{} - for _, wpPosts := range posts { + for _, wpPosts := range postIds { all = append(all, wpPosts.Id) if _, ok := PostsCache.Load(wpPosts.Id); !ok { needQuery = append(needQuery, wpPosts.Id) @@ -75,7 +92,7 @@ func index(c *gin.Context) { if len(needQuery) > 0 { rawPosts, err := models.Find[models.WpPosts](models.SqlBuilder{{ "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", }, { "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 { return } - for _, post := range rawPosts { - PostsCache.Store(post.Id, post) + postsMap := make(map[uint64]*models.WpPosts) + 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(`%s`, 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(``, cat, cat)) + } + pp.TagsHtml = strings.Join(t, "、") + } + PostsCache.Store(pp.Id, pp) } } for _, id := range all { post, _ := PostsCache.Load(id) - pp := post.(models.WpPosts) - allPosts = append(allPosts, pp) + pp := post.(*models.WpPosts) + allPosts = append(allPosts, *pp) } recent, err := recentPosts() archive, err := archives() diff --git a/route/route.go b/route/route.go index 9b51d26..2018300 100644 --- a/route/route.go +++ b/route/route.go @@ -37,6 +37,7 @@ func SetupRouter() *gin.Engine { r.GET("/", index) r.GET("/page/:page", 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/page/:page", index) diff --git a/templates/index/index.html b/templates/index/index.html index 0aa5f0b..863ae8f 100644 --- a/templates/index/index.html +++ b/templates/index/index.html @@ -26,7 +26,11 @@ 分类 - {{$v.CategoryName}} + {{$v.CategoriesHtml|unescaped}} + + + 标签 + {{$v.TagsHtml|unescaped}}