From a656ea3fd5d79554923d0c42d2352ce874371f5c Mon Sep 17 00:00:00 2001 From: xing Date: Tue, 20 Sep 2022 21:16:51 +0800 Subject: [PATCH] =?UTF-8?q?=E5=B7=A6=E4=BE=A7=E6=A0=8F=E8=AF=84=E8=AE=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- actions/common/common.go | 15 ++++++++ actions/detail.go | 2 ++ actions/index.go | 2 ++ cache/map.go | 1 + config.example.yaml | 2 ++ helper/func.go | 15 +++++++- helper/func_test.go | 64 +++++++++++++++++++++++++++++++++ models/wp_comments.go | 2 ++ templates/layout/sidebar.gohtml | 8 ++++- vars/config.go | 11 +++--- 10 files changed, 115 insertions(+), 7 deletions(-) diff --git a/actions/common/common.go b/actions/common/common.go index 4954e20..2387bf6 100644 --- a/actions/common/common.go +++ b/actions/common/common.go @@ -20,6 +20,7 @@ var archivesCaches *Arch var categoryCaches *cache.SliceCache[models.WpTermsMy] var recentPostsCaches *cache.SliceCache[models.WpPosts] var monthCaches *cache.MapCache[string, []models.WpPosts] +var recentCommentsCaches *cache.SliceCache[models.WpComments] func InitCache() { archivesCaches = &Arch{ @@ -29,6 +30,7 @@ func InitCache() { categoryCaches = cache.NewSliceCache[models.WpTermsMy](categories, vars.Conf.CategoryCacheTime) recentPostsCaches = cache.NewSliceCache[models.WpPosts](recentPosts, vars.Conf.RecentPostCacheTime) monthCaches = cache.NewMapCache[string, []models.WpPosts](getMonthPost, 30*time.Minute) + recentCommentsCaches = cache.NewSliceCache[models.WpComments](recentComments, vars.Conf.RecentCommentsCacheTime) } type Arch struct { @@ -66,6 +68,19 @@ func GetMonthPost(ctx context.Context, year, month string) ([]models.WpPosts, er return monthCaches.GetCache(ctx, fmt.Sprintf("%s%s", year, month), time.Second, year, month) } +func RecentComments(ctx context.Context) (r []models.WpComments) { + r, _ = recentCommentsCaches.GetCache(ctx, time.Second) + return +} +func recentComments(...any) (r []models.WpComments, err error) { + return models.Find[models.WpComments](models.SqlBuilder{ + {"comment_approved", "1"}, + {"post_status", "publish"}, + }, "comment_ID,comment_author,comment_post_ID,post_title", "", models.SqlBuilder{{"comment_date_gmt", "desc"}}, models.SqlBuilder{ + {"a", "left join", "wp_posts b", "a.comment_post_ID=b.ID"}, + }, 5) +} + func getMonthPost(args ...any) ([]models.WpPosts, error) { y := args[0].(string) m := args[1].(string) diff --git a/actions/detail.go b/actions/detail.go index 9baf140..870267a 100644 --- a/actions/detail.go +++ b/actions/detail.go @@ -17,12 +17,14 @@ func Detail(c *gin.Context) { recent := common.RecentPosts(ctx) archive := common.Archives() categoryItems := common.Categories(ctx) + comments := common.RecentComments(ctx) var h = gin.H{ "title": models.Options["blogname"], "options": models.Options, "recentPosts": recent, "archives": archive, "categories": categoryItems, + "comments": comments, } defer func() { c.HTML(http.StatusOK, "posts/detail.gohtml", h) diff --git a/actions/index.go b/actions/index.go index fb473f2..8657d50 100644 --- a/actions/index.go +++ b/actions/index.go @@ -153,6 +153,7 @@ func Index(c *gin.Context) { archive := common.Archives() recent := common.RecentPosts(ctx) categoryItems := common.Categories(ctx) + comments := common.RecentComments(ctx) ginH := gin.H{ "options": models.Options, "recentPosts": recent, @@ -161,6 +162,7 @@ func Index(c *gin.Context) { "search": h.search, "header": h.header, "title": h.getTitle(), + "comments": comments, } postIds, totalRaw, err := models.SimplePagination[models.WpPosts](h.where, "ID", "", h.page, h.pageSize, h.orderBy, h.join, h.postType, h.status) defer func() { diff --git a/cache/map.go b/cache/map.go index 4516997..cf9956d 100644 --- a/cache/map.go +++ b/cache/map.go @@ -37,6 +37,7 @@ func (c *MapCache[K, V]) GetCache(ctx context.Context, key K, timeout time.Durat _, ok := c.data[key] var err error expired := time.Duration(c.setTime.Unix())+c.expireTime/time.Second < time.Duration(time.Now().Unix()) + //todo 这里应该判断下取出的值是否为零值,不过怎么操作呢? if !ok || (c.expireTime >= 0 && expired) { t := c.incr call := func() { diff --git a/config.example.yaml b/config.example.yaml index ae6d2f6..b4ce843 100644 --- a/config.example.yaml +++ b/config.example.yaml @@ -21,3 +21,5 @@ recentPostCacheTime: 30m categoryCacheTime: 30m # 上下篇缓存时间 contextPostCacheTime: 1h +# 最近评论缓存时间 +recentCommentsCacheTime: 10m diff --git a/helper/func.go b/helper/func.go index 848a6e2..dfc81a7 100644 --- a/helper/func.go +++ b/helper/func.go @@ -25,7 +25,7 @@ func StructColumn[T any, M any](arr []M, field string) (r []T) { } func RangeSlice[T ~int | ~uint | ~int64 | ~int8 | ~int16 | ~int32 | ~uint64](start, end, step T) []T { - r := make([]T, 0, int(end/step+1)) + r := make([]T, 0, int((end-start+1)/step+1)) for i := start; i <= end; { r = append(r, i) i = i + step @@ -45,3 +45,16 @@ func StrJoin(s ...string) (str string) { } return } + +func SlicePagination[T any](arr []T, page, pageSize int) []T { + start := (page - 1) * pageSize + l := len(arr) + if start > l { + start = l + } + end := page * pageSize + if l < end { + end = l + } + return arr[start:end] +} diff --git a/helper/func_test.go b/helper/func_test.go index f58c5fc..47c21f7 100644 --- a/helper/func_test.go +++ b/helper/func_test.go @@ -103,6 +103,15 @@ func TestRangeSlice(t *testing.T) { }, want: []int{0, 2, 4}, }, + { + name: "t3", + args: args{ + start: 1, + end: 11, + step: 3, + }, + want: []int{1, 4, 7, 10}, + }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { @@ -132,3 +141,58 @@ func TestStrJoin(t *testing.T) { }) } } + +func TestSlicePagination(t *testing.T) { + arr := RangeSlice[int](1, 10, 1) + type args struct { + arr []int + page int + pageSize int + } + tests := []struct { + name string + args args + want []int + }{ + { + name: "t1", + args: args{ + arr: arr, + page: 1, + pageSize: 2, + }, + want: RangeSlice[int](1, 2, 1), + }, { + name: "t2", + args: args{ + arr: arr, + page: 2, + pageSize: 2, + }, + want: RangeSlice[int](3, 4, 1), + }, { + name: "t3", + args: args{ + arr: arr, + page: 4, + pageSize: 3, + }, + want: []int{10}, + }, { + name: "t4", + args: args{ + arr: arr, + page: 5, + pageSize: 3, + }, + want: []int{}, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := SlicePagination(tt.args.arr, tt.args.page, tt.args.pageSize); !reflect.DeepEqual(got, tt.want) { + t.Errorf("SlicePagination() = %v, want %v", got, tt.want) + } + }) + } +} diff --git a/models/wp_comments.go b/models/wp_comments.go index c276ba5..b0a478b 100644 --- a/models/wp_comments.go +++ b/models/wp_comments.go @@ -18,6 +18,8 @@ type WpComments struct { CommentType string `gorm:"column:comment_type" db:"comment_type" json:"comment_type" form:"comment_type"` CommentParent uint64 `gorm:"column:comment_parent" db:"comment_parent" json:"comment_parent" form:"comment_parent"` UserId uint64 `gorm:"column:user_id" db:"user_id" json:"user_id" form:"user_id"` + //扩展字段 + PostTitle string `db:"post_title"` } func (w WpComments) PrimaryKey() string { diff --git a/templates/layout/sidebar.gohtml b/templates/layout/sidebar.gohtml index 972f38f..798c96a 100644 --- a/templates/layout/sidebar.gohtml +++ b/templates/layout/sidebar.gohtml @@ -24,7 +24,13 @@