diff --git a/internal/actions/comment.go b/internal/actions/comment.go index 351c34f..d637297 100644 --- a/internal/actions/comment.go +++ b/internal/actions/comment.go @@ -6,9 +6,9 @@ import ( "fmt" "github.com/gin-gonic/gin" "github/fthvgb1/wp-go/cache" - "github/fthvgb1/wp-go/config" "github/fthvgb1/wp-go/helper" - "github/fthvgb1/wp-go/internal/actions/common" + cache2 "github/fthvgb1/wp-go/internal/cache" + "github/fthvgb1/wp-go/internal/config" "github/fthvgb1/wp-go/internal/wpconfig" "github/fthvgb1/wp-go/logs" "github/fthvgb1/wp-go/mail" @@ -99,7 +99,7 @@ func PostComment(c *gin.Context) { logs.ErrPrintln(err, "获取文档id", i) return } - post, err := common.GetPostById(cc, id) + post, err := cache2.GetPostById(cc, id) if err != nil { logs.ErrPrintln(err, "获取文档", id) return diff --git a/internal/actions/common/comments.go b/internal/actions/common/comments.go deleted file mode 100644 index b987a76..0000000 --- a/internal/actions/common/comments.go +++ /dev/null @@ -1,78 +0,0 @@ -package common - -import ( - "context" - "github/fthvgb1/wp-go/helper" - "github/fthvgb1/wp-go/internal/wp" - "github/fthvgb1/wp-go/logs" - "github/fthvgb1/wp-go/models" - "strconv" - "time" -) - -func RecentComments(ctx context.Context, n int) (r []wp.Comments) { - r, err := recentCommentsCaches.GetCache(ctx, time.Second, ctx) - if len(r) > n { - r = r[0:n] - } - logs.ErrPrintln(err, "get recent comment") - return -} -func recentComments(a ...any) (r []wp.Comments, err error) { - ctx := a[0].(context.Context) - return models.Find[wp.Comments](ctx, 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"}, - }, nil, 10) -} - -func PostComments(ctx context.Context, Id uint64) ([]wp.Comments, error) { - ids, err := postCommentCaches.GetCache(ctx, Id, time.Second, ctx, Id) - if err != nil { - return nil, err - } - return GetCommentByIds(ctx, ids) -} - -func postComments(args ...any) ([]uint64, error) { - ctx := args[0].(context.Context) - postId := args[1].(uint64) - r, err := models.Find[wp.Comments](ctx, models.SqlBuilder{ - {"comment_approved", "1"}, - {"comment_post_ID", "=", strconv.FormatUint(postId, 10), "int"}, - }, "comment_ID", "", models.SqlBuilder{ - {"comment_date_gmt", "asc"}, - {"comment_ID", "asc"}, - }, nil, nil, 0) - if err != nil { - return nil, err - } - return helper.SliceMap(r, func(t wp.Comments) uint64 { - return t.CommentId - }), err -} - -func GetCommentById(ctx context.Context, id uint64) (wp.Comments, error) { - return commentsCache.GetCache(ctx, id, time.Second, ctx, id) -} - -func GetCommentByIds(ctx context.Context, ids []uint64) ([]wp.Comments, error) { - return commentsCache.GetCacheBatch(ctx, ids, time.Second, ctx, ids) -} - -func getCommentByIds(args ...any) (map[uint64]wp.Comments, error) { - ctx := args[0].(context.Context) - ids := args[1].([]uint64) - m := make(map[uint64]wp.Comments) - r, err := models.SimpleFind[wp.Comments](ctx, models.SqlBuilder{ - {"comment_ID", "in", ""}, {"comment_approved", "1"}, - }, "*", helper.SliceMap(ids, helper.ToAny[uint64])) - if err != nil { - return m, err - } - return helper.SimpleSliceToMap(r, func(t wp.Comments) uint64 { - return t.CommentId - }), err -} diff --git a/internal/actions/common/common.go b/internal/actions/common/common.go deleted file mode 100644 index b5c7320..0000000 --- a/internal/actions/common/common.go +++ /dev/null @@ -1,181 +0,0 @@ -package common - -import ( - "context" - "fmt" - "github/fthvgb1/wp-go/cache" - "github/fthvgb1/wp-go/config" - wp2 "github/fthvgb1/wp-go/internal/wp" - "github/fthvgb1/wp-go/internal/wpconfig" - "github/fthvgb1/wp-go/logs" - "github/fthvgb1/wp-go/models" - "sync" - "time" -) - -var postContextCache *cache.MapCache[uint64, PostContext] -var archivesCaches *Arch -var categoryCaches *cache.SliceCache[wp2.TermsMy] -var recentPostsCaches *cache.SliceCache[wp2.Posts] -var recentCommentsCaches *cache.SliceCache[wp2.Comments] -var postCommentCaches *cache.MapCache[uint64, []uint64] -var postsCache *cache.MapCache[uint64, wp2.Posts] - -var postMetaCache *cache.MapCache[uint64, map[string]any] - -var monthPostsCache *cache.MapCache[string, []uint64] -var postListIdsCache *cache.MapCache[string, PostIds] -var searchPostIdsCache *cache.MapCache[string, PostIds] -var maxPostIdCache *cache.SliceCache[uint64] -var TotalRaw int64 -var usersCache *cache.MapCache[uint64, wp2.Users] -var usersNameCache *cache.MapCache[string, wp2.Users] -var commentsCache *cache.MapCache[uint64, wp2.Comments] - -func InitActionsCommonCache() { - c := config.Conf.Load() - archivesCaches = &Arch{ - mutex: &sync.Mutex{}, - setCacheFunc: archives, - } - - searchPostIdsCache = cache.NewMapCacheByFn[string, PostIds](searchPostIds, c.SearchPostCacheTime) - - postListIdsCache = cache.NewMapCacheByFn[string, PostIds](searchPostIds, c.PostListCacheTime) - - monthPostsCache = cache.NewMapCacheByFn[string, []uint64](monthPost, c.MonthPostCacheTime) - - postContextCache = cache.NewMapCacheByFn[uint64, PostContext](getPostContext, c.ContextPostCacheTime) - - postsCache = cache.NewMapCacheByBatchFn[uint64, wp2.Posts](getPostsByIds, c.PostDataCacheTime) - - postMetaCache = cache.NewMapCacheByBatchFn[uint64, map[string]any](getPostMetaByPostIds, c.PostDataCacheTime) - - categoryCaches = cache.NewSliceCache[wp2.TermsMy](categories, c.CategoryCacheTime) - - recentPostsCaches = cache.NewSliceCache[wp2.Posts](recentPosts, c.RecentPostCacheTime) - - recentCommentsCaches = cache.NewSliceCache[wp2.Comments](recentComments, c.RecentCommentsCacheTime) - - postCommentCaches = cache.NewMapCacheByFn[uint64, []uint64](postComments, c.PostCommentsCacheTime) - - maxPostIdCache = cache.NewSliceCache[uint64](getMaxPostId, c.MaxPostIdCacheTime) - - usersCache = cache.NewMapCacheByFn[uint64, wp2.Users](getUserById, c.UserInfoCacheTime) - - usersNameCache = cache.NewMapCacheByFn[string, wp2.Users](getUserByName, c.UserInfoCacheTime) - - commentsCache = cache.NewMapCacheByBatchFn[uint64, wp2.Comments](getCommentByIds, c.CommentsCacheTime) -} - -func ClearCache() { - searchPostIdsCache.ClearExpired() - postsCache.ClearExpired() - postMetaCache.ClearExpired() - postListIdsCache.ClearExpired() - monthPostsCache.ClearExpired() - postContextCache.ClearExpired() - usersCache.ClearExpired() - commentsCache.ClearExpired() - usersNameCache.ClearExpired() -} -func FlushCache() { - searchPostIdsCache.Flush() - postsCache.Flush() - postMetaCache.Flush() - postListIdsCache.Flush() - monthPostsCache.Flush() - postContextCache.Flush() - usersCache.Flush() - commentsCache.Flush() - usersCache.Flush() -} - -type PostIds struct { - Ids []uint64 - Length int -} - -type Arch struct { - data []wp2.PostArchive - mutex *sync.Mutex - setCacheFunc func(context.Context) ([]wp2.PostArchive, error) - month time.Month -} - -func (c *Arch) getArchiveCache(ctx context.Context) []wp2.PostArchive { - l := len(c.data) - m := time.Now().Month() - if l > 0 && c.month != m || l < 1 { - r, err := c.setCacheFunc(ctx) - if err != nil { - logs.ErrPrintln(err, "set cache err[%s]") - return nil - } - c.mutex.Lock() - defer c.mutex.Unlock() - c.month = m - c.data = r - } - return c.data -} - -type PostContext struct { - prev wp2.Posts - next wp2.Posts -} - -func archives(ctx context.Context) ([]wp2.PostArchive, error) { - return models.Find[wp2.PostArchive](ctx, models.SqlBuilder{ - {"post_type", "post"}, {"post_status", "publish"}, - }, "YEAR(post_date) AS `year`, MONTH(post_date) AS `month`, count(ID) as posts", "year,month", models.SqlBuilder{{"year", "desc"}, {"month", "desc"}}, nil, nil, 0) -} - -func Archives(ctx context.Context) (r []wp2.PostArchive) { - return archivesCaches.getArchiveCache(ctx) -} - -func Categories(ctx context.Context) []wp2.TermsMy { - r, err := categoryCaches.GetCache(ctx, time.Second, ctx) - logs.ErrPrintln(err, "get category ") - return r -} - -func categories(a ...any) (terms []wp2.TermsMy, err error) { - ctx := a[0].(context.Context) - var in = []any{"category"} - terms, err = models.Find[wp2.TermsMy](ctx, models.SqlBuilder{ - {"tt.count", ">", "0", "int"}, - {"tt.taxonomy", "in", ""}, - }, "t.term_id", "", models.SqlBuilder{ - {"t.name", "asc"}, - }, models.SqlBuilder{ - {"t", "inner join", "wp_term_taxonomy tt", "t.term_id = tt.term_id"}, - }, nil, 0, in) - for i := 0; i < len(terms); i++ { - if v, ok := wpconfig.Terms.Load(terms[i].Terms.TermId); ok { - terms[i].Terms = v - } - if v, ok := wpconfig.TermTaxonomies.Load(terms[i].Terms.TermId); ok { - terms[i].TermTaxonomy = v - } - } - return -} - -func PasswordProjectTitle(post *wp2.Posts) { - if post.PostPassword != "" { - post.PostTitle = fmt.Sprintf("密码保护:%s", post.PostTitle) - } -} - -func PasswdProjectContent(post *wp2.Posts) { - if post.PostContent != "" { - format := ` -
` - post.PostContent = fmt.Sprintf(format, post.Id, post.Id) - } -} diff --git a/internal/actions/common/posts.go b/internal/actions/common/posts.go deleted file mode 100644 index 54f2d28..0000000 --- a/internal/actions/common/posts.go +++ /dev/null @@ -1,236 +0,0 @@ -package common - -import ( - "context" - "database/sql" - "fmt" - "github.com/gin-gonic/gin" - "github/fthvgb1/wp-go/helper" - "github/fthvgb1/wp-go/internal/wp" - "github/fthvgb1/wp-go/logs" - "github/fthvgb1/wp-go/models" - "strings" - "sync/atomic" - "time" -) - -func GetPostById(ctx context.Context, id uint64) (wp.Posts, error) { - return postsCache.GetCache(ctx, id, time.Second, ctx, id) -} - -func GetPostsByIds(ctx context.Context, ids []uint64) ([]wp.Posts, error) { - return postsCache.GetCacheBatch(ctx, ids, time.Second, ctx, ids) -} - -func SearchPost(ctx context.Context, key string, args ...any) (r []wp.Posts, total int, err error) { - ids, err := searchPostIdsCache.GetCache(ctx, key, time.Second, args...) - if err != nil { - return - } - total = ids.Length - r, err = GetPostsByIds(ctx, ids.Ids) - return -} - -func getPostsByIds(ids ...any) (m map[uint64]wp.Posts, err error) { - ctx := ids[0].(context.Context) - m = make(map[uint64]wp.Posts) - id := ids[1].([]uint64) - arg := helper.SliceMap(id, helper.ToAny[uint64]) - rawPosts, err := models.Find[wp.Posts](ctx, models.SqlBuilder{{ - "Id", "in", "", - }}, "a.*,ifnull(d.name,'') category_name,ifnull(taxonomy,'') `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", - }, { - "left join", "wp_terms d", "c.term_id=d.term_id", - }}, nil, 0, arg) - if err != nil { - return m, err - } - postsMap := make(map[uint64]wp.Posts) - 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 - } - meta, _ := getPostMetaByPostIds(ctx, id) - for k, 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, "、") - _, ok := meta[pp.Id] - if ok { - thumb := ToPostThumbnail(ctx, pp.Id) - if thumb.Path != "" { - pp.Thumbnail = thumb - } - } - } - if len(pp.Tags) > 0 { - t := make([]string, 0, len(pp.Tags)) - for _, cat := range pp.Tags { - t = append(t, fmt.Sprintf(`%s`, cat, cat)) - } - pp.TagsHtml = strings.Join(t, "、") - } - m[k] = pp - } - return -} - -func PostLists(ctx context.Context, key string, args ...any) (r []wp.Posts, total int, err error) { - ids, err := postListIdsCache.GetCache(ctx, key, time.Second, args...) - if err != nil { - return - } - total = ids.Length - r, err = GetPostsByIds(ctx, ids.Ids) - return -} - -func searchPostIds(args ...any) (ids PostIds, err error) { - ctx := args[0].(context.Context) - where := args[1].(models.SqlBuilder) - page := args[2].(int) - limit := args[3].(int) - order := args[4].(models.SqlBuilder) - join := args[5].(models.SqlBuilder) - postType := args[6].([]any) - postStatus := args[7].([]any) - res, total, err := models.SimplePagination[wp.Posts](ctx, where, "ID", "", page, limit, order, join, nil, postType, postStatus) - for _, posts := range res { - ids.Ids = append(ids.Ids, posts.Id) - } - ids.Length = total - totalR := int(atomic.LoadInt64(&TotalRaw)) - if total > totalR { - tt := int64(total) - atomic.StoreInt64(&TotalRaw, tt) - } - return -} - -func getMaxPostId(a ...any) ([]uint64, error) { - ctx := a[0].(context.Context) - r, err := models.SimpleFind[wp.Posts](ctx, models.SqlBuilder{{"post_type", "post"}, {"post_status", "publish"}}, "max(ID) ID") - var id uint64 - if len(r) > 0 { - id = r[0].Id - } - return []uint64{id}, err -} - -func GetMaxPostId(ctx *gin.Context) (uint64, error) { - Id, err := maxPostIdCache.GetCache(ctx, time.Second, ctx) - return Id[0], err -} - -func RecentPosts(ctx context.Context, n int) (r []wp.Posts) { - r, err := recentPostsCaches.GetCache(ctx, time.Second, ctx) - if n < len(r) { - r = r[:n] - } - logs.ErrPrintln(err, "get recent post") - return -} -func recentPosts(a ...any) (r []wp.Posts, err error) { - ctx := a[0].(context.Context) - r, err = models.Find[wp.Posts](ctx, models.SqlBuilder{{ - "post_type", "post", - }, {"post_status", "publish"}}, "ID,post_title,post_password", "", models.SqlBuilder{{"post_date", "desc"}}, nil, nil, 10) - for i, post := range r { - if post.PostPassword != "" { - PasswordProjectTitle(&r[i]) - } - } - return -} - -func GetContextPost(ctx context.Context, id uint64, date time.Time) (prev, next wp.Posts, err error) { - postCtx, err := postContextCache.GetCache(ctx, id, time.Second, ctx, date) - if err != nil { - return wp.Posts{}, wp.Posts{}, err - } - prev = postCtx.prev - next = postCtx.next - return -} - -func getPostContext(arg ...any) (r PostContext, err error) { - ctx := arg[0].(context.Context) - t := arg[1].(time.Time) - next, err := models.FirstOne[wp.Posts](ctx, models.SqlBuilder{ - {"post_date", ">", t.Format("2006-01-02 15:04:05")}, - {"post_status", "in", ""}, - {"post_type", "post"}, - }, "ID,post_title,post_password", nil, []any{"publish"}) - if err == sql.ErrNoRows { - err = nil - } - if err != nil { - return - } - prev, err := models.FirstOne[wp.Posts](ctx, models.SqlBuilder{ - {"post_date", "<", t.Format("2006-01-02 15:04:05")}, - {"post_status", "in", ""}, - {"post_type", "post"}, - }, "ID,post_title", models.SqlBuilder{{"post_date", "desc"}}, []any{"publish"}) - if err == sql.ErrNoRows { - err = nil - } - if err != nil { - return - } - r = PostContext{ - prev: prev, - next: next, - } - return -} - -func GetMonthPostIds(ctx context.Context, year, month string, page, limit int, order string) (r []wp.Posts, total int, err error) { - res, err := monthPostsCache.GetCache(ctx, fmt.Sprintf("%s%s", year, month), time.Second, ctx, year, month) - if err != nil { - return - } - if order == "desc" { - res = helper.SliceReverse(res) - } - total = len(res) - rr := helper.SlicePagination(res, page, limit) - r, err = GetPostsByIds(ctx, rr) - return -} - -func monthPost(args ...any) (r []uint64, err error) { - ctx := args[0].(context.Context) - year, month := args[1].(string), args[2].(string) - where := models.SqlBuilder{ - {"post_type", "in", ""}, - {"post_status", "in", ""}, - {"year(post_date)", year}, - {"month(post_date)", month}, - } - postType := []any{"post"} - status := []any{"publish"} - ids, err := models.Find[wp.Posts](ctx, where, "ID", "", models.SqlBuilder{{"Id", "asc"}}, nil, nil, 0, postType, status) - if err != nil { - return - } - for _, post := range ids { - r = append(r, post.Id) - } - return -} diff --git a/internal/actions/common/users.go b/internal/actions/common/users.go deleted file mode 100644 index 505083b..0000000 --- a/internal/actions/common/users.go +++ /dev/null @@ -1,35 +0,0 @@ -package common - -import ( - "context" - "github/fthvgb1/wp-go/internal/wp" - "github/fthvgb1/wp-go/logs" - "github/fthvgb1/wp-go/models" - "time" -) - -func getUserById(a ...any) (r wp.Users, err error) { - ctx := a[0].(context.Context) - uid := a[1].(uint64) - r, err = models.FindOneById[wp.Users](ctx, uid) - return -} - -func GetUserByName(ctx context.Context, username string) (wp.Users, error) { - return usersNameCache.GetCache(ctx, username, time.Second, ctx, username) -} - -func getUserByName(a ...any) (r wp.Users, err error) { - u := a[1].(string) - ctx := a[0].(context.Context) - r, err = models.FirstOne[wp.Users](ctx, models.SqlBuilder{{ - "user_login", u, - }}, "*", nil) - return -} - -func GetUserById(ctx context.Context, uid uint64) wp.Users { - r, err := usersCache.GetCache(ctx, uid, time.Second, ctx, uid) - logs.ErrPrintln(err, "get user", uid) - return r -} diff --git a/internal/actions/detail.go b/internal/actions/detail.go index d02ef66..6f3b9c2 100644 --- a/internal/actions/detail.go +++ b/internal/actions/detail.go @@ -5,11 +5,11 @@ import ( "github.com/gin-contrib/sessions" "github.com/gin-gonic/gin" "github/fthvgb1/wp-go/helper" - common2 "github/fthvgb1/wp-go/internal/actions/common" - "github/fthvgb1/wp-go/internal/wp" + "github/fthvgb1/wp-go/internal/cache" + "github/fthvgb1/wp-go/internal/models" + "github/fthvgb1/wp-go/internal/plugins" "github/fthvgb1/wp-go/internal/wpconfig" "github/fthvgb1/wp-go/logs" - "github/fthvgb1/wp-go/plugins" "math/rand" "net/http" "net/url" @@ -28,10 +28,10 @@ func Detail(c *gin.Context) { hh := detailHandler{ c, } - recent := common2.RecentPosts(c, 5) - archive := common2.Archives(c) - categoryItems := common2.Categories(c) - recentComments := common2.RecentComments(c, 5) + recent := cache.RecentPosts(c, 5) + archive := cache.Archives(c) + categoryItems := cache.Categories(c) + recentComments := cache.RecentComments(c, 5) var h = gin.H{ "title": wpconfig.Options.Value("blogname"), "options": wpconfig.Options, @@ -62,12 +62,12 @@ func Detail(c *gin.Context) { } } ID := uint64(Id) - maxId, err := common2.GetMaxPostId(c) + maxId, err := cache.GetMaxPostId(c) logs.ErrPrintln(err, "get max post id") if ID > maxId || err != nil { return } - post, err := common2.GetPostById(c, ID) + post, err := cache.GetPostById(c, ID) if post.Id == 0 || err != nil { return } @@ -76,10 +76,10 @@ func Detail(c *gin.Context) { if post.CommentCount > 0 || post.CommentStatus == "open" { showComment = true } - user := common2.GetUserById(c, post.PostAuthor) - common2.PasswordProjectTitle(&post) + user := cache.GetUserById(c, post.PostAuthor) + plugins.PasswordProjectTitle(&post) if post.PostPassword != "" && pw != post.PostPassword { - common2.PasswdProjectContent(&post) + plugins.PasswdProjectContent(&post) showComment = false } else if s, ok := commentCache.Get(c.Request.URL.RawQuery); ok && s != "" && (post.PostPassword == "" || post.PostPassword != "" && pw == post.PostPassword) { c.Writer.WriteHeader(http.StatusOK) @@ -89,10 +89,10 @@ func Detail(c *gin.Context) { return } plugins.ApplyPlugin(plugins.NewPostPlugin(c, plugins.Detail), &post) - comments, err := common2.PostComments(c, post.Id) + comments, err := cache.PostComments(c, post.Id) logs.ErrPrintln(err, "get post comment", post.Id) commentss := treeComments(comments) - prev, next, err := common2.GetContextPost(c, post.Id, post.PostDate) + prev, next, err := cache.GetContextPost(c, post.Id, post.PostDate) logs.ErrPrintln(err, "get pre and next post", post.Id, post.PostDate) h["title"] = fmt.Sprintf("%s-%s", post.PostTitle, wpconfig.Options.Value("blogname")) h["post"] = post @@ -110,7 +110,7 @@ func Detail(c *gin.Context) { } type Comment struct { - wp.Comments + models.Comments Children []*Comment } @@ -177,10 +177,10 @@ func findComments(comments Comments) Comments { return r } -func treeComments(comments []wp.Comments) Comments { +func treeComments(comments []models.Comments) Comments { var r = map[uint64]*Comment{ 0: { - Comments: wp.Comments{}, + Comments: models.Comments{}, }, } var top []*Comment @@ -204,7 +204,7 @@ func treeComments(comments []wp.Comments) Comments { return top } -func (d detailHandler) formatLi(comments wp.Comments, depth int, eo, parent string) string { +func (d detailHandler) formatLi(comments models.Comments, depth int, eo, parent string) string { li := `