From c842c3a2939340e8d6495d08327ed60bdc712510 Mon Sep 17 00:00:00 2001 From: xing Date: Sat, 21 Jan 2023 22:56:41 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0tag=E7=9A=84=E9=AA=8C?= =?UTF-8?q?=E8=AF=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- LICENSE | 2 +- helper/slice/slice.go | 12 +++++++++- internal/actions/index.go | 4 ++++ internal/pkg/cache/cache.go | 45 +++++++++++++++++++++++++++---------- internal/pkg/dao/common.go | 4 ++-- 5 files changed, 51 insertions(+), 16 deletions(-) diff --git a/LICENSE b/LICENSE index 5253484..c31b392 100644 --- a/LICENSE +++ b/LICENSE @@ -1,4 +1,4 @@ - Copyright (c) 2013, Jason Moiron + Copyright (c) 2023 星 Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation diff --git a/helper/slice/slice.go b/helper/slice/slice.go index cc0f8ef..7a96fb2 100644 --- a/helper/slice/slice.go +++ b/helper/slice/slice.go @@ -116,6 +116,17 @@ func Slice[T any](arr []T, offset, length int) (r []T) { return } +func FilterAndToMap[K comparable, V, T any](arr []T, fn func(T) (K, V, bool)) map[K]V { + r := make(map[K]V) + for _, t := range arr { + k, v, ok := fn(t) + if ok { + r[k] = v + } + } + return r +} + func Comb[T any](arr []T, m int) (r [][]T) { if m == 1 { for _, t := range arr { @@ -135,7 +146,6 @@ func Comb[T any](arr []T, m int) (r [][]T) { return r } - func IsContained[T comparable](a T, arr []T) bool { for _, v := range arr { if a == v { diff --git a/internal/actions/index.go b/internal/actions/index.go index 6708c64..7d8af97 100644 --- a/internal/actions/index.go +++ b/internal/actions/index.go @@ -132,6 +132,10 @@ func (h *indexHandle) parseParams() (err error) { if category == "" { category = h.c.Param("tag") if category != "" { + allNames := cache.AllTagsNames(h.c) + if _, ok := allNames[category]; !ok { + return errors.New(str.Join("not exists tag ", category)) + } h.categoryType = "post_tag" h.header = fmt.Sprintf("标签: %s", category) } diff --git a/internal/pkg/cache/cache.go b/internal/pkg/cache/cache.go index aa7b469..52c4182 100644 --- a/internal/pkg/cache/cache.go +++ b/internal/pkg/cache/cache.go @@ -14,7 +14,7 @@ import ( var postContextCache *cache.MapCache[uint64, dao.PostContext] var archivesCaches *Arch -var categoryCaches *cache.VarCache[[]models.TermsMy] +var categoryAndTagsCaches *cache.VarCache[[]models.TermsMy] var recentPostsCaches *cache.VarCache[[]models.Posts] var recentCommentsCaches *cache.VarCache[[]models.Comments] var postCommentCaches *cache.MapCache[uint64, []uint64] @@ -62,7 +62,7 @@ func InitActionsCommonCache() { postMetaCache = cache.NewMapCacheByBatchFn(dao.GetPostMetaByPostIds, c.PostDataCacheTime) - categoryCaches = cache.NewVarCache(dao.Categories, c.CategoryCacheTime) + categoryAndTagsCaches = cache.NewVarCache(dao.CategoriesAndTags, c.CategoryCacheTime) recentPostsCaches = cache.NewVarCache(dao.RecentPosts, c.RecentPostCacheTime) @@ -88,13 +88,6 @@ func InitActionsCommonCache() { allUsernameCache = cache.NewVarCache(dao.AllUsername, c.UserInfoCacheTime) - allCategories = cache.NewVarCache(func(a ...any) (map[string]struct{}, error) { - ctx := a[0].(context.Context) - return slice.ToMap(Categories(ctx), func(v models.TermsMy) (string, struct{}) { - return v.Name, struct{}{} - }, true), nil - }, c.CategoryCacheTime) - InitFeed() } @@ -154,12 +147,40 @@ func (c *Arch) getArchiveCache(ctx context.Context) []models.PostArchive { } func Categories(ctx context.Context) []models.TermsMy { - r, err := categoryCaches.GetCache(ctx, time.Second, ctx) + r, err := categoryAndTagsCaches.GetCache(ctx, time.Second, ctx) logs.ErrPrintln(err, "get category err") + r = slice.Filter(r, func(my models.TermsMy) bool { + return my.Taxonomy == "category" + }) return r } -func AllCategoryNames(ctx context.Context) map[string]struct{} { - r, _ := allCategories.GetCache(ctx, time.Second, ctx) +func Tags(ctx context.Context) []models.TermsMy { + r, err := categoryAndTagsCaches.GetCache(ctx, time.Second, ctx) + logs.ErrPrintln(err, "get category err") + r = slice.Filter(r, func(my models.TermsMy) bool { + return my.Taxonomy == "post_tag" + }) return r } +func AllTagsNames(ctx context.Context) map[string]struct{} { + r, err := categoryAndTagsCaches.GetCache(ctx, time.Second, ctx) + logs.ErrPrintln(err, "get category err") + return slice.FilterAndToMap(r, func(t models.TermsMy) (string, struct{}, bool) { + if t.Taxonomy == "post_tag" { + return t.Name, struct{}{}, true + } + return "", struct{}{}, false + }) +} + +func AllCategoryNames(ctx context.Context) map[string]struct{} { + r, err := categoryAndTagsCaches.GetCache(ctx, time.Second, ctx) + logs.ErrPrintln(err, "get category err") + return slice.FilterAndToMap(r, func(t models.TermsMy) (string, struct{}, bool) { + if t.Taxonomy == "category" { + return t.Name, struct{}{}, true + } + return "", struct{}{}, false + }) +} diff --git a/internal/pkg/dao/common.go b/internal/pkg/dao/common.go index abb819e..710e8ee 100644 --- a/internal/pkg/dao/common.go +++ b/internal/pkg/dao/common.go @@ -26,9 +26,9 @@ func PasswordProjectTitle(post *models.Posts) { } } -func Categories(a ...any) (terms []models.TermsMy, err error) { +func CategoriesAndTags(a ...any) (terms []models.TermsMy, err error) { ctx := a[0].(context.Context) - var in = []any{"category"} + var in = []any{"category", "post_tag"} terms, err = model.Find[models.TermsMy](ctx, model.SqlBuilder{ {"tt.count", ">", "0", "int"}, {"tt.taxonomy", "in", ""},