目录调整
This commit is contained in:
parent
9a288a4861
commit
c66b0080af
|
@ -6,9 +6,9 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
"github/fthvgb1/wp-go/cache"
|
"github/fthvgb1/wp-go/cache"
|
||||||
"github/fthvgb1/wp-go/config"
|
|
||||||
"github/fthvgb1/wp-go/helper"
|
"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/internal/wpconfig"
|
||||||
"github/fthvgb1/wp-go/logs"
|
"github/fthvgb1/wp-go/logs"
|
||||||
"github/fthvgb1/wp-go/mail"
|
"github/fthvgb1/wp-go/mail"
|
||||||
|
@ -99,7 +99,7 @@ func PostComment(c *gin.Context) {
|
||||||
logs.ErrPrintln(err, "获取文档id", i)
|
logs.ErrPrintln(err, "获取文档id", i)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
post, err := common.GetPostById(cc, id)
|
post, err := cache2.GetPostById(cc, id)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logs.ErrPrintln(err, "获取文档", id)
|
logs.ErrPrintln(err, "获取文档", id)
|
||||||
return
|
return
|
||||||
|
|
|
@ -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
|
|
||||||
}
|
|
|
@ -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 := `
|
|
||||||
<form action="/login" class="post-password-form" method="post">
|
|
||||||
<p>此内容受密码保护。如需查阅,请在下列字段中输入您的密码。</p>
|
|
||||||
<p><label for="pwbox-%d">密码: <input name="post_password" id="pwbox-%d" type="password" size="20"></label> <input type="submit" name="Submit" value="提交"></p>
|
|
||||||
</form>`
|
|
||||||
post.PostContent = fmt.Sprintf(format, post.Id, post.Id)
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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(`<a href="/p/category/%s" rel="category tag">%s</a>`, 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(`<a href="/p/tag/%s" rel="tag">%s</a>`, 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
|
|
||||||
}
|
|
|
@ -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
|
|
||||||
}
|
|
|
@ -5,11 +5,11 @@ import (
|
||||||
"github.com/gin-contrib/sessions"
|
"github.com/gin-contrib/sessions"
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
"github/fthvgb1/wp-go/helper"
|
"github/fthvgb1/wp-go/helper"
|
||||||
common2 "github/fthvgb1/wp-go/internal/actions/common"
|
"github/fthvgb1/wp-go/internal/cache"
|
||||||
"github/fthvgb1/wp-go/internal/wp"
|
"github/fthvgb1/wp-go/internal/models"
|
||||||
|
"github/fthvgb1/wp-go/internal/plugins"
|
||||||
"github/fthvgb1/wp-go/internal/wpconfig"
|
"github/fthvgb1/wp-go/internal/wpconfig"
|
||||||
"github/fthvgb1/wp-go/logs"
|
"github/fthvgb1/wp-go/logs"
|
||||||
"github/fthvgb1/wp-go/plugins"
|
|
||||||
"math/rand"
|
"math/rand"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/url"
|
"net/url"
|
||||||
|
@ -28,10 +28,10 @@ func Detail(c *gin.Context) {
|
||||||
hh := detailHandler{
|
hh := detailHandler{
|
||||||
c,
|
c,
|
||||||
}
|
}
|
||||||
recent := common2.RecentPosts(c, 5)
|
recent := cache.RecentPosts(c, 5)
|
||||||
archive := common2.Archives(c)
|
archive := cache.Archives(c)
|
||||||
categoryItems := common2.Categories(c)
|
categoryItems := cache.Categories(c)
|
||||||
recentComments := common2.RecentComments(c, 5)
|
recentComments := cache.RecentComments(c, 5)
|
||||||
var h = gin.H{
|
var h = gin.H{
|
||||||
"title": wpconfig.Options.Value("blogname"),
|
"title": wpconfig.Options.Value("blogname"),
|
||||||
"options": wpconfig.Options,
|
"options": wpconfig.Options,
|
||||||
|
@ -62,12 +62,12 @@ func Detail(c *gin.Context) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ID := uint64(Id)
|
ID := uint64(Id)
|
||||||
maxId, err := common2.GetMaxPostId(c)
|
maxId, err := cache.GetMaxPostId(c)
|
||||||
logs.ErrPrintln(err, "get max post id")
|
logs.ErrPrintln(err, "get max post id")
|
||||||
if ID > maxId || err != nil {
|
if ID > maxId || err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
post, err := common2.GetPostById(c, ID)
|
post, err := cache.GetPostById(c, ID)
|
||||||
if post.Id == 0 || err != nil {
|
if post.Id == 0 || err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -76,10 +76,10 @@ func Detail(c *gin.Context) {
|
||||||
if post.CommentCount > 0 || post.CommentStatus == "open" {
|
if post.CommentCount > 0 || post.CommentStatus == "open" {
|
||||||
showComment = true
|
showComment = true
|
||||||
}
|
}
|
||||||
user := common2.GetUserById(c, post.PostAuthor)
|
user := cache.GetUserById(c, post.PostAuthor)
|
||||||
common2.PasswordProjectTitle(&post)
|
plugins.PasswordProjectTitle(&post)
|
||||||
if post.PostPassword != "" && pw != post.PostPassword {
|
if post.PostPassword != "" && pw != post.PostPassword {
|
||||||
common2.PasswdProjectContent(&post)
|
plugins.PasswdProjectContent(&post)
|
||||||
showComment = false
|
showComment = false
|
||||||
} else if s, ok := commentCache.Get(c.Request.URL.RawQuery); ok && s != "" && (post.PostPassword == "" || post.PostPassword != "" && pw == post.PostPassword) {
|
} else if s, ok := commentCache.Get(c.Request.URL.RawQuery); ok && s != "" && (post.PostPassword == "" || post.PostPassword != "" && pw == post.PostPassword) {
|
||||||
c.Writer.WriteHeader(http.StatusOK)
|
c.Writer.WriteHeader(http.StatusOK)
|
||||||
|
@ -89,10 +89,10 @@ func Detail(c *gin.Context) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
plugins.ApplyPlugin(plugins.NewPostPlugin(c, plugins.Detail), &post)
|
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)
|
logs.ErrPrintln(err, "get post comment", post.Id)
|
||||||
commentss := treeComments(comments)
|
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)
|
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["title"] = fmt.Sprintf("%s-%s", post.PostTitle, wpconfig.Options.Value("blogname"))
|
||||||
h["post"] = post
|
h["post"] = post
|
||||||
|
@ -110,7 +110,7 @@ func Detail(c *gin.Context) {
|
||||||
}
|
}
|
||||||
|
|
||||||
type Comment struct {
|
type Comment struct {
|
||||||
wp.Comments
|
models.Comments
|
||||||
Children []*Comment
|
Children []*Comment
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -177,10 +177,10 @@ func findComments(comments Comments) Comments {
|
||||||
return r
|
return r
|
||||||
}
|
}
|
||||||
|
|
||||||
func treeComments(comments []wp.Comments) Comments {
|
func treeComments(comments []models.Comments) Comments {
|
||||||
var r = map[uint64]*Comment{
|
var r = map[uint64]*Comment{
|
||||||
0: {
|
0: {
|
||||||
Comments: wp.Comments{},
|
Comments: models.Comments{},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
var top []*Comment
|
var top []*Comment
|
||||||
|
@ -204,7 +204,7 @@ func treeComments(comments []wp.Comments) Comments {
|
||||||
return top
|
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 := `
|
li := `
|
||||||
<li id="comment-{{CommentId}}" class="comment {{eo}} thread-even depth-{{Depth}} {{parent}}">
|
<li id="comment-{{CommentId}}" class="comment {{eo}} thread-even depth-{{Depth}} {{parent}}">
|
||||||
<article id="div-comment-{{CommentId}}" class="comment-body">
|
<article id="div-comment-{{CommentId}}" class="comment-body">
|
||||||
|
|
|
@ -5,11 +5,12 @@ import (
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
"github/fthvgb1/wp-go/cache"
|
"github/fthvgb1/wp-go/cache"
|
||||||
"github/fthvgb1/wp-go/helper"
|
"github/fthvgb1/wp-go/helper"
|
||||||
common2 "github/fthvgb1/wp-go/internal/actions/common"
|
cache2 "github/fthvgb1/wp-go/internal/cache"
|
||||||
wp2 "github/fthvgb1/wp-go/internal/wp"
|
"github/fthvgb1/wp-go/internal/models"
|
||||||
|
"github/fthvgb1/wp-go/internal/plugins"
|
||||||
"github/fthvgb1/wp-go/internal/wpconfig"
|
"github/fthvgb1/wp-go/internal/wpconfig"
|
||||||
"github/fthvgb1/wp-go/logs"
|
"github/fthvgb1/wp-go/logs"
|
||||||
"github/fthvgb1/wp-go/plugins"
|
"github/fthvgb1/wp-go/plugin/digest"
|
||||||
"github/fthvgb1/wp-go/rss2"
|
"github/fthvgb1/wp-go/rss2"
|
||||||
"net/http"
|
"net/http"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
@ -77,23 +78,23 @@ func Feed(c *gin.Context) {
|
||||||
|
|
||||||
func feed(arg ...any) (xml []string, err error) {
|
func feed(arg ...any) (xml []string, err error) {
|
||||||
c := arg[0].(*gin.Context)
|
c := arg[0].(*gin.Context)
|
||||||
r := common2.RecentPosts(c, 10)
|
r := cache2.RecentPosts(c, 10)
|
||||||
ids := helper.SliceMap(r, func(t wp2.Posts) uint64 {
|
ids := helper.SliceMap(r, func(t models.Posts) uint64 {
|
||||||
return t.Id
|
return t.Id
|
||||||
})
|
})
|
||||||
posts, err := common2.GetPostsByIds(c, ids)
|
posts, err := cache2.GetPostsByIds(c, ids)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
rs := templateRss
|
rs := templateRss
|
||||||
rs.LastBuildDate = time.Now().Format(timeFormat)
|
rs.LastBuildDate = time.Now().Format(timeFormat)
|
||||||
rs.Items = helper.SliceMap(posts, func(t wp2.Posts) rss2.Item {
|
rs.Items = helper.SliceMap(posts, func(t models.Posts) rss2.Item {
|
||||||
desc := "无法提供摘要。这是一篇受保护的文章。"
|
desc := "无法提供摘要。这是一篇受保护的文章。"
|
||||||
common2.PasswordProjectTitle(&t)
|
plugins.PasswordProjectTitle(&t)
|
||||||
if t.PostPassword != "" {
|
if t.PostPassword != "" {
|
||||||
common2.PasswdProjectContent(&t)
|
plugins.PasswdProjectContent(&t)
|
||||||
} else {
|
} else {
|
||||||
desc = plugins.DigestRaw(t.PostContent, 55, fmt.Sprintf("/p/%d", t.Id))
|
desc = digest.Raw(t.PostContent, 55, fmt.Sprintf("/p/%d", t.Id))
|
||||||
}
|
}
|
||||||
l := ""
|
l := ""
|
||||||
if t.CommentStatus == "open" && t.CommentCount > 0 {
|
if t.CommentStatus == "open" && t.CommentCount > 0 {
|
||||||
|
@ -101,7 +102,7 @@ func feed(arg ...any) (xml []string, err error) {
|
||||||
} else if t.CommentStatus == "open" && t.CommentCount == 0 {
|
} else if t.CommentStatus == "open" && t.CommentCount == 0 {
|
||||||
l = fmt.Sprintf("%s/p/%d#respond", wpconfig.Options.Value("siteurl"), t.Id)
|
l = fmt.Sprintf("%s/p/%d#respond", wpconfig.Options.Value("siteurl"), t.Id)
|
||||||
}
|
}
|
||||||
user := common2.GetUserById(c, t.PostAuthor)
|
user := cache2.GetUserById(c, t.PostAuthor)
|
||||||
|
|
||||||
return rss2.Item{
|
return rss2.Item{
|
||||||
Title: t.PostTitle,
|
Title: t.PostTitle,
|
||||||
|
@ -157,17 +158,17 @@ func postFeed(arg ...any) (x string, err error) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ID := uint64(Id)
|
ID := uint64(Id)
|
||||||
maxId, err := common2.GetMaxPostId(c)
|
maxId, err := cache2.GetMaxPostId(c)
|
||||||
logs.ErrPrintln(err, "get max post id")
|
logs.ErrPrintln(err, "get max post id")
|
||||||
if ID > maxId || err != nil {
|
if ID > maxId || err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
post, err := common2.GetPostById(c, ID)
|
post, err := cache2.GetPostById(c, ID)
|
||||||
if post.Id == 0 || err != nil {
|
if post.Id == 0 || err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
common2.PasswordProjectTitle(&post)
|
plugins.PasswordProjectTitle(&post)
|
||||||
comments, err := common2.PostComments(c, post.Id)
|
comments, err := cache2.PostComments(c, post.Id)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -179,7 +180,7 @@ func postFeed(arg ...any) (x string, err error) {
|
||||||
rs.LastBuildDate = time.Now().Format(timeFormat)
|
rs.LastBuildDate = time.Now().Format(timeFormat)
|
||||||
if post.PostPassword != "" {
|
if post.PostPassword != "" {
|
||||||
if len(comments) > 0 {
|
if len(comments) > 0 {
|
||||||
common2.PasswdProjectContent(&post)
|
plugins.PasswdProjectContent(&post)
|
||||||
t := comments[len(comments)-1]
|
t := comments[len(comments)-1]
|
||||||
rs.Items = []rss2.Item{
|
rs.Items = []rss2.Item{
|
||||||
{
|
{
|
||||||
|
@ -194,7 +195,7 @@ func postFeed(arg ...any) (x string, err error) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
rs.Items = helper.SliceMap(comments, func(t wp2.Comments) rss2.Item {
|
rs.Items = helper.SliceMap(comments, func(t models.Comments) rss2.Item {
|
||||||
return rss2.Item{
|
return rss2.Item{
|
||||||
Title: fmt.Sprintf("评价者:%s", t.CommentAuthor),
|
Title: fmt.Sprintf("评价者:%s", t.CommentAuthor),
|
||||||
Link: fmt.Sprintf("%s/p/%d#comment-%d", wpconfig.Options.Value("siteurl"), post.Id, t.CommentId),
|
Link: fmt.Sprintf("%s/p/%d#comment-%d", wpconfig.Options.Value("siteurl"), post.Id, t.CommentId),
|
||||||
|
@ -227,27 +228,27 @@ func CommentsFeed(c *gin.Context) {
|
||||||
|
|
||||||
func commentsFeed(args ...any) (r []string, err error) {
|
func commentsFeed(args ...any) (r []string, err error) {
|
||||||
c := args[0].(*gin.Context)
|
c := args[0].(*gin.Context)
|
||||||
commens := common2.RecentComments(c, 10)
|
commens := cache2.RecentComments(c, 10)
|
||||||
rs := templateRss
|
rs := templateRss
|
||||||
rs.Title = fmt.Sprintf("\"%s\"的评论", wpconfig.Options.Value("blogname"))
|
rs.Title = fmt.Sprintf("\"%s\"的评论", wpconfig.Options.Value("blogname"))
|
||||||
rs.LastBuildDate = time.Now().Format(timeFormat)
|
rs.LastBuildDate = time.Now().Format(timeFormat)
|
||||||
rs.AtomLink = fmt.Sprintf("%s/comments/feed", wpconfig.Options.Value("siteurl"))
|
rs.AtomLink = fmt.Sprintf("%s/comments/feed", wpconfig.Options.Value("siteurl"))
|
||||||
com, err := common2.GetCommentByIds(c, helper.SliceMap(commens, func(t wp2.Comments) uint64 {
|
com, err := cache2.GetCommentByIds(c, helper.SliceMap(commens, func(t models.Comments) uint64 {
|
||||||
return t.CommentId
|
return t.CommentId
|
||||||
}))
|
}))
|
||||||
if nil != err {
|
if nil != err {
|
||||||
return []string{}, err
|
return []string{}, err
|
||||||
}
|
}
|
||||||
rs.Items = helper.SliceMap(com, func(t wp2.Comments) rss2.Item {
|
rs.Items = helper.SliceMap(com, func(t models.Comments) rss2.Item {
|
||||||
post, _ := common2.GetPostById(c, t.CommentPostId)
|
post, _ := cache2.GetPostById(c, t.CommentPostId)
|
||||||
common2.PasswordProjectTitle(&post)
|
plugins.PasswordProjectTitle(&post)
|
||||||
desc := "评论受保护:要查看请输入密码。"
|
desc := "评论受保护:要查看请输入密码。"
|
||||||
content := t.CommentContent
|
content := t.CommentContent
|
||||||
if post.PostPassword != "" {
|
if post.PostPassword != "" {
|
||||||
common2.PasswdProjectContent(&post)
|
plugins.PasswdProjectContent(&post)
|
||||||
content = post.PostContent
|
content = post.PostContent
|
||||||
} else {
|
} else {
|
||||||
desc = plugins.ClearHtml(t.CommentContent)
|
desc = digest.ClearHtml(t.CommentContent)
|
||||||
content = desc
|
content = desc
|
||||||
}
|
}
|
||||||
return rss2.Item{
|
return rss2.Item{
|
||||||
|
|
|
@ -5,11 +5,12 @@ import (
|
||||||
"github.com/gin-contrib/sessions"
|
"github.com/gin-contrib/sessions"
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
"github/fthvgb1/wp-go/helper"
|
"github/fthvgb1/wp-go/helper"
|
||||||
common2 "github/fthvgb1/wp-go/internal/actions/common"
|
"github/fthvgb1/wp-go/internal/cache"
|
||||||
"github/fthvgb1/wp-go/internal/wp"
|
dao "github/fthvgb1/wp-go/internal/dao"
|
||||||
|
"github/fthvgb1/wp-go/internal/models"
|
||||||
|
"github/fthvgb1/wp-go/internal/plugins"
|
||||||
"github/fthvgb1/wp-go/internal/wpconfig"
|
"github/fthvgb1/wp-go/internal/wpconfig"
|
||||||
"github/fthvgb1/wp-go/models"
|
"github/fthvgb1/wp-go/model"
|
||||||
"github/fthvgb1/wp-go/plugins"
|
|
||||||
"math"
|
"math"
|
||||||
"net/http"
|
"net/http"
|
||||||
"regexp"
|
"regexp"
|
||||||
|
@ -31,10 +32,10 @@ type indexHandle struct {
|
||||||
totalPage int
|
totalPage int
|
||||||
category string
|
category string
|
||||||
categoryType string
|
categoryType string
|
||||||
where models.SqlBuilder
|
where model.SqlBuilder
|
||||||
orderBy string
|
orderBy string
|
||||||
order string
|
order string
|
||||||
join models.SqlBuilder
|
join model.SqlBuilder
|
||||||
postType []any
|
postType []any
|
||||||
status []any
|
status []any
|
||||||
header string
|
header string
|
||||||
|
@ -53,12 +54,12 @@ func newIndexHandle(ctx *gin.Context) *indexHandle {
|
||||||
paginationStep: 1,
|
paginationStep: 1,
|
||||||
titleL: wpconfig.Options.Value("blogname"),
|
titleL: wpconfig.Options.Value("blogname"),
|
||||||
titleR: wpconfig.Options.Value("blogdescription"),
|
titleR: wpconfig.Options.Value("blogdescription"),
|
||||||
where: models.SqlBuilder{
|
where: model.SqlBuilder{
|
||||||
{"post_type", "in", ""},
|
{"post_type", "in", ""},
|
||||||
{"post_status", "in", ""},
|
{"post_status", "in", ""},
|
||||||
},
|
},
|
||||||
orderBy: "post_date",
|
orderBy: "post_date",
|
||||||
join: models.SqlBuilder{},
|
join: model.SqlBuilder{},
|
||||||
postType: []any{"post"},
|
postType: []any{"post"},
|
||||||
status: []any{"publish"},
|
status: []any{"publish"},
|
||||||
scene: plugins.Home,
|
scene: plugins.Home,
|
||||||
|
@ -113,7 +114,7 @@ func (h *indexHandle) parseParams() (err error) {
|
||||||
h.category = category
|
h.category = category
|
||||||
username := h.c.Param("author")
|
username := h.c.Param("author")
|
||||||
if username != "" {
|
if username != "" {
|
||||||
user, er := common2.GetUserByName(h.c, username)
|
user, er := cache.GetUserByName(h.c, username)
|
||||||
if er != nil {
|
if er != nil {
|
||||||
err = er
|
err = er
|
||||||
return
|
return
|
||||||
|
@ -160,7 +161,7 @@ func (h *indexHandle) parseParams() (err error) {
|
||||||
h.page = pa
|
h.page = pa
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
total := int(atomic.LoadInt64(&common2.TotalRaw))
|
total := int(atomic.LoadInt64(&dao.TotalRaw))
|
||||||
if total > 0 && total < (h.page-1)*h.pageSize {
|
if total > 0 && total < (h.page-1)*h.pageSize {
|
||||||
h.page = 1
|
h.page = 1
|
||||||
}
|
}
|
||||||
|
@ -177,13 +178,13 @@ func (h *indexHandle) getTotalPage(totalRaws int) int {
|
||||||
|
|
||||||
func Index(c *gin.Context) {
|
func Index(c *gin.Context) {
|
||||||
h := newIndexHandle(c)
|
h := newIndexHandle(c)
|
||||||
var postIds []wp.Posts
|
var postIds []models.Posts
|
||||||
var totalRaw int
|
var totalRaw int
|
||||||
var err error
|
var err error
|
||||||
archive := common2.Archives(c)
|
archive := cache.Archives(c)
|
||||||
recent := common2.RecentPosts(c, 5)
|
recent := cache.RecentPosts(c, 5)
|
||||||
categoryItems := common2.Categories(c)
|
categoryItems := cache.Categories(c)
|
||||||
recentComments := common2.RecentComments(c, 5)
|
recentComments := cache.RecentComments(c, 5)
|
||||||
ginH := gin.H{
|
ginH := gin.H{
|
||||||
"options": wpconfig.Options,
|
"options": wpconfig.Options,
|
||||||
"recentPosts": recent,
|
"recentPosts": recent,
|
||||||
|
@ -208,14 +209,14 @@ func Index(c *gin.Context) {
|
||||||
}
|
}
|
||||||
ginH["title"] = h.getTitle()
|
ginH["title"] = h.getTitle()
|
||||||
if c.Param("month") != "" {
|
if c.Param("month") != "" {
|
||||||
postIds, totalRaw, err = common2.GetMonthPostIds(c, c.Param("year"), c.Param("month"), h.page, h.pageSize, h.order)
|
postIds, totalRaw, err = cache.GetMonthPostIds(c, c.Param("year"), c.Param("month"), h.page, h.pageSize, h.order)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
} else if h.search != "" {
|
} else if h.search != "" {
|
||||||
postIds, totalRaw, err = common2.SearchPost(c, h.getSearchKey(), c, h.where, h.page, h.pageSize, models.SqlBuilder{{h.orderBy, h.order}}, h.join, h.postType, h.status)
|
postIds, totalRaw, err = cache.SearchPost(c, h.getSearchKey(), c, h.where, h.page, h.pageSize, model.SqlBuilder{{h.orderBy, h.order}}, h.join, h.postType, h.status)
|
||||||
} else {
|
} else {
|
||||||
postIds, totalRaw, err = common2.PostLists(c, h.getSearchKey(), c, h.where, h.page, h.pageSize, models.SqlBuilder{{h.orderBy, h.order}}, h.join, h.postType, h.status)
|
postIds, totalRaw, err = cache.PostLists(c, h.getSearchKey(), c, h.where, h.page, h.pageSize, model.SqlBuilder{{h.orderBy, h.order}}, h.join, h.postType, h.status)
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
|
@ -227,16 +228,16 @@ func Index(c *gin.Context) {
|
||||||
pw := h.session.Get("post_password")
|
pw := h.session.Get("post_password")
|
||||||
plug := plugins.NewPostPlugin(c, h.scene)
|
plug := plugins.NewPostPlugin(c, h.scene)
|
||||||
for i, post := range postIds {
|
for i, post := range postIds {
|
||||||
common2.PasswordProjectTitle(&postIds[i])
|
plugins.PasswordProjectTitle(&postIds[i])
|
||||||
if post.PostPassword != "" && pw != post.PostPassword {
|
if post.PostPassword != "" && pw != post.PostPassword {
|
||||||
common2.PasswdProjectContent(&postIds[i])
|
plugins.PasswdProjectContent(&postIds[i])
|
||||||
} else {
|
} else {
|
||||||
plugins.ApplyPlugin(plug, &postIds[i])
|
plugins.ApplyPlugin(plug, &postIds[i])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for i, post := range recent {
|
for i, post := range recent {
|
||||||
if post.PostPassword != "" && pw != post.PostPassword {
|
if post.PostPassword != "" && pw != post.PostPassword {
|
||||||
common2.PasswdProjectContent(&recent[i])
|
plugins.PasswdProjectContent(&recent[i])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
q := c.Request.URL.Query().Encode()
|
q := c.Request.URL.Query().Encode()
|
||||||
|
|
124
internal/cache/cache.go
vendored
Normal file
124
internal/cache/cache.go
vendored
Normal file
|
@ -0,0 +1,124 @@
|
||||||
|
package cache
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"github/fthvgb1/wp-go/cache"
|
||||||
|
"github/fthvgb1/wp-go/internal/config"
|
||||||
|
dao "github/fthvgb1/wp-go/internal/dao"
|
||||||
|
"github/fthvgb1/wp-go/internal/models"
|
||||||
|
"github/fthvgb1/wp-go/logs"
|
||||||
|
"sync"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
var postContextCache *cache.MapCache[uint64, dao.PostContext]
|
||||||
|
var archivesCaches *Arch
|
||||||
|
var categoryCaches *cache.SliceCache[models.TermsMy]
|
||||||
|
var recentPostsCaches *cache.SliceCache[models.Posts]
|
||||||
|
var recentCommentsCaches *cache.SliceCache[models.Comments]
|
||||||
|
var postCommentCaches *cache.MapCache[uint64, []uint64]
|
||||||
|
var postsCache *cache.MapCache[uint64, models.Posts]
|
||||||
|
|
||||||
|
var postMetaCache *cache.MapCache[uint64, map[string]any]
|
||||||
|
|
||||||
|
var monthPostsCache *cache.MapCache[string, []uint64]
|
||||||
|
var postListIdsCache *cache.MapCache[string, dao.PostIds]
|
||||||
|
var searchPostIdsCache *cache.MapCache[string, dao.PostIds]
|
||||||
|
var maxPostIdCache *cache.SliceCache[uint64]
|
||||||
|
|
||||||
|
var usersCache *cache.MapCache[uint64, models.Users]
|
||||||
|
var usersNameCache *cache.MapCache[string, models.Users]
|
||||||
|
var commentsCache *cache.MapCache[uint64, models.Comments]
|
||||||
|
|
||||||
|
func InitActionsCommonCache() {
|
||||||
|
c := config.Conf.Load()
|
||||||
|
archivesCaches = &Arch{
|
||||||
|
mutex: &sync.Mutex{},
|
||||||
|
setCacheFunc: dao.Archives,
|
||||||
|
}
|
||||||
|
|
||||||
|
searchPostIdsCache = cache.NewMapCacheByFn[string, dao.PostIds](dao.SearchPostIds, c.SearchPostCacheTime)
|
||||||
|
|
||||||
|
postListIdsCache = cache.NewMapCacheByFn[string, dao.PostIds](dao.SearchPostIds, c.PostListCacheTime)
|
||||||
|
|
||||||
|
monthPostsCache = cache.NewMapCacheByFn[string, []uint64](dao.MonthPost, c.MonthPostCacheTime)
|
||||||
|
|
||||||
|
postContextCache = cache.NewMapCacheByFn[uint64, dao.PostContext](dao.GetPostContext, c.ContextPostCacheTime)
|
||||||
|
|
||||||
|
postsCache = cache.NewMapCacheByBatchFn[uint64, models.Posts](dao.GetPostsByIds, c.PostDataCacheTime)
|
||||||
|
|
||||||
|
postMetaCache = cache.NewMapCacheByBatchFn[uint64, map[string]any](dao.GetPostMetaByPostIds, c.PostDataCacheTime)
|
||||||
|
|
||||||
|
categoryCaches = cache.NewSliceCache[models.TermsMy](dao.Categories, c.CategoryCacheTime)
|
||||||
|
|
||||||
|
recentPostsCaches = cache.NewSliceCache[models.Posts](dao.RecentPosts, c.RecentPostCacheTime)
|
||||||
|
|
||||||
|
recentCommentsCaches = cache.NewSliceCache[models.Comments](dao.RecentComments, c.RecentCommentsCacheTime)
|
||||||
|
|
||||||
|
postCommentCaches = cache.NewMapCacheByFn[uint64, []uint64](dao.PostComments, c.PostCommentsCacheTime)
|
||||||
|
|
||||||
|
maxPostIdCache = cache.NewSliceCache[uint64](dao.GetMaxPostId, c.MaxPostIdCacheTime)
|
||||||
|
|
||||||
|
usersCache = cache.NewMapCacheByFn[uint64, models.Users](dao.GetUserById, c.UserInfoCacheTime)
|
||||||
|
|
||||||
|
usersNameCache = cache.NewMapCacheByFn[string, models.Users](dao.GetUserByName, c.UserInfoCacheTime)
|
||||||
|
|
||||||
|
commentsCache = cache.NewMapCacheByBatchFn[uint64, models.Comments](dao.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()
|
||||||
|
}
|
||||||
|
|
||||||
|
func Archives(ctx context.Context) (r []models.PostArchive) {
|
||||||
|
return archivesCaches.getArchiveCache(ctx)
|
||||||
|
}
|
||||||
|
|
||||||
|
type Arch struct {
|
||||||
|
data []models.PostArchive
|
||||||
|
mutex *sync.Mutex
|
||||||
|
setCacheFunc func(context.Context) ([]models.PostArchive, error)
|
||||||
|
month time.Month
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Arch) getArchiveCache(ctx context.Context) []models.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
|
||||||
|
}
|
||||||
|
|
||||||
|
func Categories(ctx context.Context) []models.TermsMy {
|
||||||
|
r, err := categoryCaches.GetCache(ctx, time.Second, ctx)
|
||||||
|
logs.ErrPrintln(err, "get category ")
|
||||||
|
return r
|
||||||
|
}
|
33
internal/cache/comments.go
vendored
Normal file
33
internal/cache/comments.go
vendored
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
package cache
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"github/fthvgb1/wp-go/internal/models"
|
||||||
|
"github/fthvgb1/wp-go/logs"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
func RecentComments(ctx context.Context, n int) (r []models.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 PostComments(ctx context.Context, Id uint64) ([]models.Comments, error) {
|
||||||
|
ids, err := postCommentCaches.GetCache(ctx, Id, time.Second, ctx, Id)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return GetCommentByIds(ctx, ids)
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetCommentById(ctx context.Context, id uint64) (models.Comments, error) {
|
||||||
|
return commentsCache.GetCache(ctx, id, time.Second, ctx, id)
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetCommentByIds(ctx context.Context, ids []uint64) ([]models.Comments, error) {
|
||||||
|
return commentsCache.GetCacheBatch(ctx, ids, time.Second, ctx, ids)
|
||||||
|
}
|
|
@ -1,12 +1,9 @@
|
||||||
package common
|
package cache
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"github.com/leeqvip/gophp"
|
|
||||||
"github/fthvgb1/wp-go/helper"
|
"github/fthvgb1/wp-go/helper"
|
||||||
wp2 "github/fthvgb1/wp-go/internal/wp"
|
wp2 "github/fthvgb1/wp-go/internal/models"
|
||||||
"github/fthvgb1/wp-go/logs"
|
|
||||||
"github/fthvgb1/wp-go/models"
|
|
||||||
"strconv"
|
"strconv"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
@ -59,35 +56,3 @@ func ToPostThumbnail(c context.Context, postId uint64) (r wp2.PostThumbnail) {
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func getPostMetaByPostIds(args ...any) (r map[uint64]map[string]any, err error) {
|
|
||||||
r = make(map[uint64]map[string]any)
|
|
||||||
ctx := args[0].(context.Context)
|
|
||||||
ids := args[1].([]uint64)
|
|
||||||
rr, err := models.Find[wp2.Postmeta](ctx, models.SqlBuilder{
|
|
||||||
{"post_id", "in", ""},
|
|
||||||
}, "*", "", nil, nil, nil, 0, helper.SliceMap(ids, helper.ToAny[uint64]))
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
for _, postmeta := range rr {
|
|
||||||
if _, ok := r[postmeta.PostId]; !ok {
|
|
||||||
r[postmeta.PostId] = make(map[string]any)
|
|
||||||
}
|
|
||||||
if postmeta.MetaKey == "_wp_attachment_metadata" {
|
|
||||||
meta, err := gophp.Unserialize([]byte(postmeta.MetaValue))
|
|
||||||
if err != nil {
|
|
||||||
logs.ErrPrintln(err, "反序列化postmeta失败", postmeta.MetaValue)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
metaVal, ok := meta.(map[string]any)
|
|
||||||
if ok {
|
|
||||||
r[postmeta.PostId][postmeta.MetaKey] = metaVal
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
r[postmeta.PostId][postmeta.MetaKey] = postmeta.MetaValue
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
77
internal/cache/posts.go
vendored
Normal file
77
internal/cache/posts.go
vendored
Normal file
|
@ -0,0 +1,77 @@
|
||||||
|
package cache
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
"github/fthvgb1/wp-go/helper"
|
||||||
|
"github/fthvgb1/wp-go/internal/models"
|
||||||
|
"github/fthvgb1/wp-go/logs"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
func GetPostById(ctx context.Context, id uint64) (models.Posts, error) {
|
||||||
|
return postsCache.GetCache(ctx, id, time.Second, ctx, id)
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetPostsByIds(ctx context.Context, ids []uint64) ([]models.Posts, error) {
|
||||||
|
return postsCache.GetCacheBatch(ctx, ids, time.Second, ctx, ids)
|
||||||
|
}
|
||||||
|
|
||||||
|
func SearchPost(ctx context.Context, key string, args ...any) (r []models.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 PostLists(ctx context.Context, key string, args ...any) (r []models.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 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 []models.Posts) {
|
||||||
|
r, err := recentPostsCaches.GetCache(ctx, time.Second, ctx)
|
||||||
|
if n < len(r) {
|
||||||
|
r = r[:n]
|
||||||
|
}
|
||||||
|
logs.ErrPrintln(err, "get recent post")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetContextPost(ctx context.Context, id uint64, date time.Time) (prev, next models.Posts, err error) {
|
||||||
|
postCtx, err := postContextCache.GetCache(ctx, id, time.Second, ctx, date)
|
||||||
|
if err != nil {
|
||||||
|
return models.Posts{}, models.Posts{}, err
|
||||||
|
}
|
||||||
|
prev = postCtx.Prev
|
||||||
|
next = postCtx.Next
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetMonthPostIds(ctx context.Context, year, month string, page, limit int, order string) (r []models.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
|
||||||
|
}
|
26
internal/cache/users.go
vendored
Normal file
26
internal/cache/users.go
vendored
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
package cache
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"github/fthvgb1/wp-go/internal/models"
|
||||||
|
"github/fthvgb1/wp-go/logs"
|
||||||
|
"github/fthvgb1/wp-go/model"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
func getUserById(a ...any) (r models.Users, err error) {
|
||||||
|
ctx := a[0].(context.Context)
|
||||||
|
uid := a[1].(uint64)
|
||||||
|
r, err = model.FindOneById[models.Users](ctx, uid)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetUserByName(ctx context.Context, username string) (models.Users, error) {
|
||||||
|
return usersNameCache.GetCache(ctx, username, time.Second, ctx, username)
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetUserById(ctx context.Context, uid uint64) models.Users {
|
||||||
|
r, err := usersCache.GetCache(ctx, uid, time.Second, ctx, uid)
|
||||||
|
logs.ErrPrintln(err, "get user", uid)
|
||||||
|
return r
|
||||||
|
}
|
57
internal/dao/comments.go
Normal file
57
internal/dao/comments.go
Normal file
|
@ -0,0 +1,57 @@
|
||||||
|
package common
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"github/fthvgb1/wp-go/helper"
|
||||||
|
"github/fthvgb1/wp-go/internal/models"
|
||||||
|
"github/fthvgb1/wp-go/model"
|
||||||
|
"strconv"
|
||||||
|
)
|
||||||
|
|
||||||
|
// RecentComments
|
||||||
|
// param context.Context
|
||||||
|
func RecentComments(a ...any) (r []models.Comments, err error) {
|
||||||
|
ctx := a[0].(context.Context)
|
||||||
|
return model.Find[models.Comments](ctx, model.SqlBuilder{
|
||||||
|
{"comment_approved", "1"},
|
||||||
|
{"post_status", "publish"},
|
||||||
|
}, "comment_ID,comment_author,comment_post_ID,post_title", "", model.SqlBuilder{{"comment_date_gmt", "desc"}}, model.SqlBuilder{
|
||||||
|
{"a", "left join", "wp_posts b", "a.comment_post_ID=b.ID"},
|
||||||
|
}, nil, 10)
|
||||||
|
}
|
||||||
|
|
||||||
|
// PostComments
|
||||||
|
// param1 context.Context
|
||||||
|
// param2 postId
|
||||||
|
func PostComments(args ...any) ([]uint64, error) {
|
||||||
|
ctx := args[0].(context.Context)
|
||||||
|
postId := args[1].(uint64)
|
||||||
|
r, err := model.Find[models.Comments](ctx, model.SqlBuilder{
|
||||||
|
{"comment_approved", "1"},
|
||||||
|
{"comment_post_ID", "=", strconv.FormatUint(postId, 10), "int"},
|
||||||
|
}, "comment_ID", "", model.SqlBuilder{
|
||||||
|
{"comment_date_gmt", "asc"},
|
||||||
|
{"comment_ID", "asc"},
|
||||||
|
}, nil, nil, 0)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return helper.SliceMap(r, func(t models.Comments) uint64 {
|
||||||
|
return t.CommentId
|
||||||
|
}), err
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetCommentByIds(args ...any) (map[uint64]models.Comments, error) {
|
||||||
|
ctx := args[0].(context.Context)
|
||||||
|
ids := args[1].([]uint64)
|
||||||
|
m := make(map[uint64]models.Comments)
|
||||||
|
r, err := model.SimpleFind[models.Comments](ctx, model.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 models.Comments) uint64 {
|
||||||
|
return t.CommentId
|
||||||
|
}), err
|
||||||
|
}
|
55
internal/dao/common.go
Normal file
55
internal/dao/common.go
Normal file
|
@ -0,0 +1,55 @@
|
||||||
|
package common
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
"github/fthvgb1/wp-go/internal/models"
|
||||||
|
"github/fthvgb1/wp-go/internal/wpconfig"
|
||||||
|
"github/fthvgb1/wp-go/model"
|
||||||
|
)
|
||||||
|
|
||||||
|
var TotalRaw int64
|
||||||
|
|
||||||
|
type PostIds struct {
|
||||||
|
Ids []uint64
|
||||||
|
Length int
|
||||||
|
}
|
||||||
|
|
||||||
|
type PostContext struct {
|
||||||
|
Prev models.Posts
|
||||||
|
Next models.Posts
|
||||||
|
}
|
||||||
|
|
||||||
|
func PasswordProjectTitle(post *models.Posts) {
|
||||||
|
if post.PostPassword != "" {
|
||||||
|
post.PostTitle = fmt.Sprintf("密码保护:%s", post.PostTitle)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func Categories(a ...any) (terms []models.TermsMy, err error) {
|
||||||
|
ctx := a[0].(context.Context)
|
||||||
|
var in = []any{"category"}
|
||||||
|
terms, err = model.Find[models.TermsMy](ctx, model.SqlBuilder{
|
||||||
|
{"tt.count", ">", "0", "int"},
|
||||||
|
{"tt.taxonomy", "in", ""},
|
||||||
|
}, "t.term_id", "", model.SqlBuilder{
|
||||||
|
{"t.name", "asc"},
|
||||||
|
}, model.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 Archives(ctx context.Context) ([]models.PostArchive, error) {
|
||||||
|
return model.Find[models.PostArchive](ctx, model.SqlBuilder{
|
||||||
|
{"post_type", "post"}, {"post_status", "publish"},
|
||||||
|
}, "YEAR(post_date) AS `year`, MONTH(post_date) AS `month`, count(ID) as posts", "year,month", model.SqlBuilder{{"year", "desc"}, {"month", "desc"}}, nil, nil, 0)
|
||||||
|
}
|
85
internal/dao/postmeta.go
Normal file
85
internal/dao/postmeta.go
Normal file
|
@ -0,0 +1,85 @@
|
||||||
|
package common
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"github.com/leeqvip/gophp"
|
||||||
|
"github/fthvgb1/wp-go/helper"
|
||||||
|
"github/fthvgb1/wp-go/internal/models"
|
||||||
|
"github/fthvgb1/wp-go/logs"
|
||||||
|
"github/fthvgb1/wp-go/model"
|
||||||
|
"strconv"
|
||||||
|
)
|
||||||
|
|
||||||
|
func GetPostMetaByPostIds(args ...any) (r map[uint64]map[string]any, err error) {
|
||||||
|
r = make(map[uint64]map[string]any)
|
||||||
|
ctx := args[0].(context.Context)
|
||||||
|
ids := args[1].([]uint64)
|
||||||
|
rr, err := model.Find[models.Postmeta](ctx, model.SqlBuilder{
|
||||||
|
{"post_id", "in", ""},
|
||||||
|
}, "*", "", nil, nil, nil, 0, helper.SliceMap(ids, helper.ToAny[uint64]))
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
for _, postmeta := range rr {
|
||||||
|
if _, ok := r[postmeta.PostId]; !ok {
|
||||||
|
r[postmeta.PostId] = make(map[string]any)
|
||||||
|
}
|
||||||
|
if postmeta.MetaKey == "_wp_attachment_metadata" {
|
||||||
|
meta, err := gophp.Unserialize([]byte(postmeta.MetaValue))
|
||||||
|
if err != nil {
|
||||||
|
logs.ErrPrintln(err, "反序列化postmeta失败", postmeta.MetaValue)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
metaVal, ok := meta.(map[string]any)
|
||||||
|
if ok {
|
||||||
|
r[postmeta.PostId][postmeta.MetaKey] = metaVal
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
r[postmeta.PostId][postmeta.MetaKey] = postmeta.MetaValue
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func ToPostThumb(c context.Context, meta map[string]any, postId uint64) (r models.PostThumbnail) {
|
||||||
|
if meta != nil {
|
||||||
|
m, ok := meta["_thumbnail_id"]
|
||||||
|
if ok {
|
||||||
|
id, err := strconv.ParseUint(m.(string), 10, 64)
|
||||||
|
if err == nil {
|
||||||
|
mx, err := GetPostMetaByPostIds(c, []uint64{id})
|
||||||
|
if err == nil && mx != nil {
|
||||||
|
mm, ok := mx[id]
|
||||||
|
if ok && mm != nil {
|
||||||
|
f, ok := mm["_wp_attached_file"]
|
||||||
|
if ok {
|
||||||
|
ff, ok := f.(string)
|
||||||
|
if ok && ff != "" {
|
||||||
|
r.Path = ff
|
||||||
|
}
|
||||||
|
}
|
||||||
|
tt, ok := helper.GetStrMapAnyVal[map[string]any]("_wp_attachment_metadata.sizes.post-thumbnail", mm)
|
||||||
|
if ok && tt != nil {
|
||||||
|
width, ok := tt["width"]
|
||||||
|
if ok {
|
||||||
|
w, ok := width.(int)
|
||||||
|
if ok {
|
||||||
|
r.Width = w
|
||||||
|
}
|
||||||
|
}
|
||||||
|
height, ok := tt["height"]
|
||||||
|
if ok {
|
||||||
|
h, ok := height.(int)
|
||||||
|
if ok {
|
||||||
|
r.Height = h
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
169
internal/dao/posts.go
Normal file
169
internal/dao/posts.go
Normal file
|
@ -0,0 +1,169 @@
|
||||||
|
package common
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"database/sql"
|
||||||
|
"fmt"
|
||||||
|
"github/fthvgb1/wp-go/helper"
|
||||||
|
"github/fthvgb1/wp-go/internal/models"
|
||||||
|
"github/fthvgb1/wp-go/model"
|
||||||
|
"strings"
|
||||||
|
"sync/atomic"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
func GetPostsByIds(ids ...any) (m map[uint64]models.Posts, err error) {
|
||||||
|
ctx := ids[0].(context.Context)
|
||||||
|
m = make(map[uint64]models.Posts)
|
||||||
|
id := ids[1].([]uint64)
|
||||||
|
arg := helper.SliceMap(id, helper.ToAny[uint64])
|
||||||
|
rawPosts, err := model.Find[models.Posts](ctx, model.SqlBuilder{{
|
||||||
|
"Id", "in", "",
|
||||||
|
}}, "a.*,ifnull(d.name,'') category_name,ifnull(taxonomy,'') `taxonomy`", "", nil, model.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]models.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(`<a href="/p/category/%s" rel="category tag">%s</a>`, cat, cat))
|
||||||
|
}
|
||||||
|
pp.CategoriesHtml = strings.Join(t, "、")
|
||||||
|
mm, ok := meta[pp.Id]
|
||||||
|
if ok {
|
||||||
|
thumb := ToPostThumb(ctx, mm, 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(`<a href="/p/tag/%s" rel="tag">%s</a>`, cat, cat))
|
||||||
|
}
|
||||||
|
pp.TagsHtml = strings.Join(t, "、")
|
||||||
|
}
|
||||||
|
m[k] = pp
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func SearchPostIds(args ...any) (ids PostIds, err error) {
|
||||||
|
ctx := args[0].(context.Context)
|
||||||
|
where := args[1].(model.SqlBuilder)
|
||||||
|
page := args[2].(int)
|
||||||
|
limit := args[3].(int)
|
||||||
|
order := args[4].(model.SqlBuilder)
|
||||||
|
join := args[5].(model.SqlBuilder)
|
||||||
|
postType := args[6].([]any)
|
||||||
|
postStatus := args[7].([]any)
|
||||||
|
res, total, err := model.SimplePagination[models.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 := model.SimpleFind[models.Posts](ctx, model.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 RecentPosts(a ...any) (r []models.Posts, err error) {
|
||||||
|
ctx := a[0].(context.Context)
|
||||||
|
r, err = model.Find[models.Posts](ctx, model.SqlBuilder{{
|
||||||
|
"post_type", "post",
|
||||||
|
}, {"post_status", "publish"}}, "ID,post_title,post_password", "", model.SqlBuilder{{"post_date", "desc"}}, nil, nil, 10)
|
||||||
|
for i, post := range r {
|
||||||
|
if post.PostPassword != "" {
|
||||||
|
PasswordProjectTitle(&r[i])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetPostContext(arg ...any) (r PostContext, err error) {
|
||||||
|
ctx := arg[0].(context.Context)
|
||||||
|
t := arg[1].(time.Time)
|
||||||
|
next, err := model.FirstOne[models.Posts](ctx, model.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 := model.FirstOne[models.Posts](ctx, model.SqlBuilder{
|
||||||
|
{"post_date", "<", t.Format("2006-01-02 15:04:05")},
|
||||||
|
{"post_status", "in", ""},
|
||||||
|
{"post_type", "post"},
|
||||||
|
}, "ID,post_title", model.SqlBuilder{{"post_date", "desc"}}, []any{"publish"})
|
||||||
|
if err == sql.ErrNoRows {
|
||||||
|
err = nil
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
r = PostContext{
|
||||||
|
Prev: prev,
|
||||||
|
Next: next,
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func MonthPost(args ...any) (r []uint64, err error) {
|
||||||
|
ctx := args[0].(context.Context)
|
||||||
|
year, month := args[1].(string), args[2].(string)
|
||||||
|
where := model.SqlBuilder{
|
||||||
|
{"post_type", "in", ""},
|
||||||
|
{"post_status", "in", ""},
|
||||||
|
{"year(post_date)", year},
|
||||||
|
{"month(post_date)", month},
|
||||||
|
}
|
||||||
|
postType := []any{"post"}
|
||||||
|
status := []any{"publish"}
|
||||||
|
ids, err := model.Find[models.Posts](ctx, where, "ID", "", model.SqlBuilder{{"Id", "asc"}}, nil, nil, 0, postType, status)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
for _, post := range ids {
|
||||||
|
r = append(r, post.Id)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
23
internal/dao/users.go
Normal file
23
internal/dao/users.go
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
package common
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"github/fthvgb1/wp-go/internal/models"
|
||||||
|
"github/fthvgb1/wp-go/model"
|
||||||
|
)
|
||||||
|
|
||||||
|
func GetUserById(a ...any) (r models.Users, err error) {
|
||||||
|
ctx := a[0].(context.Context)
|
||||||
|
uid := a[1].(uint64)
|
||||||
|
r, err = model.FindOneById[models.Users](ctx, uid)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetUserByName(a ...any) (r models.Users, err error) {
|
||||||
|
u := a[1].(string)
|
||||||
|
ctx := a[0].(context.Context)
|
||||||
|
r, err = model.FirstOne[models.Users](ctx, model.SqlBuilder{{
|
||||||
|
"user_login", u,
|
||||||
|
}}, "*", nil)
|
||||||
|
return
|
||||||
|
}
|
|
@ -5,7 +5,7 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
_ "github.com/go-sql-driver/mysql"
|
_ "github.com/go-sql-driver/mysql"
|
||||||
"github.com/jmoiron/sqlx"
|
"github.com/jmoiron/sqlx"
|
||||||
"github/fthvgb1/wp-go/config"
|
"github/fthvgb1/wp-go/internal/config"
|
||||||
"log"
|
"log"
|
||||||
"os"
|
"os"
|
||||||
"strconv"
|
"strconv"
|
|
@ -4,7 +4,7 @@ import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
"github/fthvgb1/wp-go/config"
|
"github/fthvgb1/wp-go/internal/config"
|
||||||
"github/fthvgb1/wp-go/internal/wpconfig"
|
"github/fthvgb1/wp-go/internal/wpconfig"
|
||||||
"github/fthvgb1/wp-go/logs"
|
"github/fthvgb1/wp-go/logs"
|
||||||
"github/fthvgb1/wp-go/mail"
|
"github/fthvgb1/wp-go/mail"
|
||||||
|
|
|
@ -2,7 +2,7 @@ package middleware
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
"github/fthvgb1/wp-go/config"
|
"github/fthvgb1/wp-go/internal/config"
|
||||||
"github/fthvgb1/wp-go/safety"
|
"github/fthvgb1/wp-go/safety"
|
||||||
"net/http"
|
"net/http"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
package wp
|
package models
|
||||||
|
|
||||||
import "time"
|
import "time"
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
package wp
|
package models
|
||||||
|
|
||||||
type Options struct {
|
type Options struct {
|
||||||
OptionId uint64 `gorm:"column:option_id" db:"option_id" json:"option_id" form:"option_id"`
|
OptionId uint64 `gorm:"column:option_id" db:"option_id" json:"option_id" form:"option_id"`
|
|
@ -1,4 +1,4 @@
|
||||||
package wp
|
package models
|
||||||
|
|
||||||
type Postmeta struct {
|
type Postmeta struct {
|
||||||
MetaId uint64 `db:"meta_id" json:"meta_id" form:"meta_id"`
|
MetaId uint64 `db:"meta_id" json:"meta_id" form:"meta_id"`
|
|
@ -1,4 +1,4 @@
|
||||||
package wp
|
package models
|
||||||
|
|
||||||
import "time"
|
import "time"
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
package wp
|
package models
|
||||||
|
|
||||||
type TermTaxonomy struct {
|
type TermTaxonomy struct {
|
||||||
TermTaxonomyId uint64 `gorm:"column:term_taxonomy_id" db:"term_taxonomy_id" json:"term_taxonomy_id" form:"term_taxonomy_id"`
|
TermTaxonomyId uint64 `gorm:"column:term_taxonomy_id" db:"term_taxonomy_id" json:"term_taxonomy_id" form:"term_taxonomy_id"`
|
|
@ -1,4 +1,4 @@
|
||||||
package wp
|
package models
|
||||||
|
|
||||||
type Terms struct {
|
type Terms struct {
|
||||||
TermId uint64 `gorm:"column:term_id" db:"term_id" json:"term_id" form:"term_id"`
|
TermId uint64 `gorm:"column:term_id" db:"term_id" json:"term_id" form:"term_id"`
|
|
@ -1,4 +1,4 @@
|
||||||
package wp
|
package models
|
||||||
|
|
||||||
import "time"
|
import "time"
|
||||||
|
|
55
internal/plugins/digest.go
Normal file
55
internal/plugins/digest.go
Normal file
|
@ -0,0 +1,55 @@
|
||||||
|
package plugins
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
"github/fthvgb1/wp-go/cache"
|
||||||
|
"github/fthvgb1/wp-go/internal/config"
|
||||||
|
"github/fthvgb1/wp-go/internal/models"
|
||||||
|
"github/fthvgb1/wp-go/plugin/digest"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
var digestCache *cache.MapCache[uint64, string]
|
||||||
|
|
||||||
|
func InitDigestCache() {
|
||||||
|
digestCache = cache.NewMapCacheByFn[uint64](digestRaw, config.Conf.Load().DigestCacheTime)
|
||||||
|
}
|
||||||
|
|
||||||
|
func ClearDigestCache() {
|
||||||
|
digestCache.ClearExpired()
|
||||||
|
}
|
||||||
|
func FlushCache() {
|
||||||
|
digestCache.Flush()
|
||||||
|
}
|
||||||
|
|
||||||
|
func digestRaw(arg ...any) (string, error) {
|
||||||
|
str := arg[0].(string)
|
||||||
|
id := arg[1].(uint64)
|
||||||
|
limit := config.Conf.Load().DigestWordCount
|
||||||
|
if limit < 0 {
|
||||||
|
return str, nil
|
||||||
|
} else if limit == 0 {
|
||||||
|
return "", nil
|
||||||
|
}
|
||||||
|
return digest.Raw(str, limit, fmt.Sprintf("/p/%d", id)), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func Digest(p *Plugin[models.Posts], c *gin.Context, post *models.Posts, scene uint) {
|
||||||
|
if scene == Detail {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if post.PostExcerpt != "" {
|
||||||
|
post.PostContent = strings.Replace(post.PostExcerpt, "\n", "<br/>", -1)
|
||||||
|
} else {
|
||||||
|
post.PostContent = DigestCache(c, post.Id, post.PostContent)
|
||||||
|
|
||||||
|
}
|
||||||
|
p.Next()
|
||||||
|
}
|
||||||
|
|
||||||
|
func DigestCache(ctx *gin.Context, id uint64, str string) string {
|
||||||
|
content, _ := digestCache.GetCache(ctx, id, time.Second, str, id)
|
||||||
|
return content
|
||||||
|
}
|
|
@ -12,21 +12,21 @@ const (
|
||||||
Detail
|
Detail
|
||||||
)
|
)
|
||||||
|
|
||||||
type PluginFunc[T any] func(*Plugin[T], *gin.Context, *T, uint)
|
type Func[T any] func(*Plugin[T], *gin.Context, *T, uint)
|
||||||
|
|
||||||
type Plugin[T any] struct {
|
type Plugin[T any] struct {
|
||||||
calls []PluginFunc[T]
|
calls []Func[T]
|
||||||
index int
|
index int
|
||||||
post *T
|
post *T
|
||||||
scene uint
|
scene uint
|
||||||
c *gin.Context
|
c *gin.Context
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewPlugin[T any](calls []PluginFunc[T], index int, post *T, scene uint, c *gin.Context) *Plugin[T] {
|
func NewPlugin[T any](calls []Func[T], index int, post *T, scene uint, c *gin.Context) *Plugin[T] {
|
||||||
return &Plugin[T]{calls: calls, index: index, post: post, scene: scene, c: c}
|
return &Plugin[T]{calls: calls, index: index, post: post, scene: scene, c: c}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *Plugin[T]) Push(call ...PluginFunc[T]) {
|
func (p *Plugin[T]) Push(call ...Func[T]) {
|
||||||
p.calls = append(p.calls, call...)
|
p.calls = append(p.calls, call...)
|
||||||
}
|
}
|
||||||
|
|
36
internal/plugins/posts.go
Normal file
36
internal/plugins/posts.go
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
package plugins
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
"github/fthvgb1/wp-go/internal/models"
|
||||||
|
)
|
||||||
|
|
||||||
|
func NewPostPlugin(ctx *gin.Context, scene uint) *Plugin[models.Posts] {
|
||||||
|
p := NewPlugin[models.Posts](nil, -1, nil, scene, ctx)
|
||||||
|
p.Push(Digest)
|
||||||
|
return p
|
||||||
|
}
|
||||||
|
|
||||||
|
func ApplyPlugin(p *Plugin[models.Posts], post *models.Posts) {
|
||||||
|
p.post = post
|
||||||
|
p.Next()
|
||||||
|
p.index = -1
|
||||||
|
}
|
||||||
|
|
||||||
|
func PasswordProjectTitle(post *models.Posts) {
|
||||||
|
if post.PostPassword != "" {
|
||||||
|
post.PostTitle = fmt.Sprintf("密码保护:%s", post.PostTitle)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func PasswdProjectContent(post *models.Posts) {
|
||||||
|
if post.PostContent != "" {
|
||||||
|
format := `
|
||||||
|
<form action="/login" class="post-password-form" method="post">
|
||||||
|
<p>此内容受密码保护。如需查阅,请在下列字段中输入您的密码。</p>
|
||||||
|
<p><label for="pwbox-%d">密码: <input name="post_password" id="pwbox-%d" type="password" size="20"></label> <input type="submit" name="Submit" value="提交"></p>
|
||||||
|
</form>`
|
||||||
|
post.PostContent = fmt.Sprintf(format, post.Id, post.Id)
|
||||||
|
}
|
||||||
|
}
|
|
@ -6,8 +6,8 @@ import (
|
||||||
"github.com/gin-contrib/sessions"
|
"github.com/gin-contrib/sessions"
|
||||||
"github.com/gin-contrib/sessions/cookie"
|
"github.com/gin-contrib/sessions/cookie"
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
"github/fthvgb1/wp-go/config"
|
|
||||||
actions2 "github/fthvgb1/wp-go/internal/actions"
|
actions2 "github/fthvgb1/wp-go/internal/actions"
|
||||||
|
"github/fthvgb1/wp-go/internal/config"
|
||||||
middleware2 "github/fthvgb1/wp-go/internal/middleware"
|
middleware2 "github/fthvgb1/wp-go/internal/middleware"
|
||||||
"github/fthvgb1/wp-go/internal/static"
|
"github/fthvgb1/wp-go/internal/static"
|
||||||
"github/fthvgb1/wp-go/internal/templates"
|
"github/fthvgb1/wp-go/internal/templates"
|
||||||
|
|
|
@ -2,8 +2,8 @@ package wpconfig
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"github/fthvgb1/wp-go/internal/wp"
|
"github/fthvgb1/wp-go/internal/models"
|
||||||
"github/fthvgb1/wp-go/models"
|
"github/fthvgb1/wp-go/model"
|
||||||
"github/fthvgb1/wp-go/safety"
|
"github/fthvgb1/wp-go/safety"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -11,12 +11,12 @@ var Options safety.Map[string, string]
|
||||||
|
|
||||||
func InitOptions() error {
|
func InitOptions() error {
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
ops, err := models.SimpleFind[wp.Options](ctx, models.SqlBuilder{{"autoload", "yes"}}, "option_name, option_value")
|
ops, err := model.SimpleFind[models.Options](ctx, model.SqlBuilder{{"autoload", "yes"}}, "option_name, option_value")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if len(ops) == 0 {
|
if len(ops) == 0 {
|
||||||
ops, err = models.SimpleFind[wp.Options](ctx, nil, "option_name, option_value")
|
ops, err = model.SimpleFind[models.Options](ctx, nil, "option_name, option_value")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,8 +2,8 @@ package wpconfig
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
wp2 "github/fthvgb1/wp-go/internal/wp"
|
wp2 "github/fthvgb1/wp-go/internal/models"
|
||||||
"github/fthvgb1/wp-go/models"
|
"github/fthvgb1/wp-go/model"
|
||||||
"github/fthvgb1/wp-go/safety"
|
"github/fthvgb1/wp-go/safety"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -12,14 +12,14 @@ var TermTaxonomies safety.Map[uint64, wp2.TermTaxonomy]
|
||||||
|
|
||||||
func InitTerms() (err error) {
|
func InitTerms() (err error) {
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
terms, err := models.SimpleFind[wp2.Terms](ctx, nil, "*")
|
terms, err := model.SimpleFind[wp2.Terms](ctx, nil, "*")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
for _, wpTerms := range terms {
|
for _, wpTerms := range terms {
|
||||||
Terms.Store(wpTerms.TermId, wpTerms)
|
Terms.Store(wpTerms.TermId, wpTerms)
|
||||||
}
|
}
|
||||||
termTax, err := models.SimpleFind[wp2.TermTaxonomy](ctx, nil, "*")
|
termTax, err := model.SimpleFind[wp2.TermTaxonomy](ctx, nil, "*")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,7 @@ import (
|
||||||
"crypto/tls"
|
"crypto/tls"
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/soxfmr/gomail"
|
"github.com/soxfmr/gomail"
|
||||||
"github/fthvgb1/wp-go/config"
|
"github/fthvgb1/wp-go/internal/config"
|
||||||
"mime"
|
"mime"
|
||||||
"path"
|
"path"
|
||||||
)
|
)
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
package mail
|
package mail
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github/fthvgb1/wp-go/config"
|
"github/fthvgb1/wp-go/internal/config"
|
||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
28
main.go
28
main.go
|
@ -3,16 +3,16 @@ package main
|
||||||
import (
|
import (
|
||||||
"flag"
|
"flag"
|
||||||
"fmt"
|
"fmt"
|
||||||
"github/fthvgb1/wp-go/config"
|
|
||||||
"github/fthvgb1/wp-go/db"
|
|
||||||
"github/fthvgb1/wp-go/internal/actions"
|
"github/fthvgb1/wp-go/internal/actions"
|
||||||
"github/fthvgb1/wp-go/internal/actions/common"
|
"github/fthvgb1/wp-go/internal/cache"
|
||||||
|
"github/fthvgb1/wp-go/internal/config"
|
||||||
|
"github/fthvgb1/wp-go/internal/db"
|
||||||
|
"github/fthvgb1/wp-go/internal/plugins"
|
||||||
"github/fthvgb1/wp-go/internal/route"
|
"github/fthvgb1/wp-go/internal/route"
|
||||||
wpconfig2 "github/fthvgb1/wp-go/internal/wpconfig"
|
"github/fthvgb1/wp-go/internal/wpconfig"
|
||||||
"github/fthvgb1/wp-go/logs"
|
"github/fthvgb1/wp-go/logs"
|
||||||
"github/fthvgb1/wp-go/mail"
|
"github/fthvgb1/wp-go/mail"
|
||||||
"github/fthvgb1/wp-go/models"
|
"github/fthvgb1/wp-go/model"
|
||||||
"github/fthvgb1/wp-go/plugins"
|
|
||||||
"log"
|
"log"
|
||||||
"math/rand"
|
"math/rand"
|
||||||
"os"
|
"os"
|
||||||
|
@ -44,7 +44,7 @@ func init() {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
actions.InitFeed()
|
actions.InitFeed()
|
||||||
common.InitActionsCommonCache()
|
cache.InitActionsCommonCache()
|
||||||
plugins.InitDigestCache()
|
plugins.InitDigestCache()
|
||||||
go cronClearCache()
|
go cronClearCache()
|
||||||
}
|
}
|
||||||
|
@ -59,12 +59,12 @@ func initConf(c string) (err error) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
models.InitDB(db.NewSqlxDb(db.Db))
|
model.InitDB(db.NewSqlxDb(db.Db))
|
||||||
err = wpconfig2.InitOptions()
|
err = wpconfig.InitOptions()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
err = wpconfig2.InitTerms()
|
err = wpconfig.InitTerms()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -76,7 +76,7 @@ func cronClearCache() {
|
||||||
for {
|
for {
|
||||||
select {
|
select {
|
||||||
case <-t.C:
|
case <-t.C:
|
||||||
common.ClearCache()
|
cache.ClearCache()
|
||||||
plugins.ClearDigestCache()
|
plugins.ClearDigestCache()
|
||||||
actions.ClearCache()
|
actions.ClearCache()
|
||||||
}
|
}
|
||||||
|
@ -90,7 +90,7 @@ func flushCache() {
|
||||||
logs.ErrPrintln(err, "发邮件失败")
|
logs.ErrPrintln(err, "发邮件失败")
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
common.FlushCache()
|
cache.FlushCache()
|
||||||
plugins.FlushCache()
|
plugins.FlushCache()
|
||||||
actions.FlushCache()
|
actions.FlushCache()
|
||||||
log.Println("all cache flushed")
|
log.Println("all cache flushed")
|
||||||
|
@ -104,9 +104,9 @@ func reload() {
|
||||||
}()
|
}()
|
||||||
err := config.InitConfig(confPath)
|
err := config.InitConfig(confPath)
|
||||||
logs.ErrPrintln(err, "获取配置文件失败", confPath)
|
logs.ErrPrintln(err, "获取配置文件失败", confPath)
|
||||||
err = wpconfig2.InitOptions()
|
err = wpconfig.InitOptions()
|
||||||
logs.ErrPrintln(err, "获取网站设置WpOption失败")
|
logs.ErrPrintln(err, "获取网站设置WpOption失败")
|
||||||
err = wpconfig2.InitTerms()
|
err = wpconfig.InitTerms()
|
||||||
logs.ErrPrintln(err, "获取WpTerms表失败")
|
logs.ErrPrintln(err, "获取WpTerms表失败")
|
||||||
if middleWareReloadFn != nil {
|
if middleWareReloadFn != nil {
|
||||||
middleWareReloadFn()
|
middleWareReloadFn()
|
||||||
|
|
28
model/model.go
Normal file
28
model/model.go
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
package model
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
)
|
||||||
|
|
||||||
|
var _ ParseWhere = SqlBuilder{}
|
||||||
|
var globalBb dbQuery
|
||||||
|
|
||||||
|
func InitDB(db dbQuery) {
|
||||||
|
globalBb = db
|
||||||
|
}
|
||||||
|
|
||||||
|
type Model interface {
|
||||||
|
PrimaryKey() string
|
||||||
|
Table() string
|
||||||
|
}
|
||||||
|
|
||||||
|
type ParseWhere interface {
|
||||||
|
ParseWhere(*[][]any) (string, []any, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
type dbQuery interface {
|
||||||
|
Select(context.Context, any, string, ...any) error
|
||||||
|
Get(context.Context, any, string, ...any) error
|
||||||
|
}
|
||||||
|
|
||||||
|
type SqlBuilder [][]string
|
|
@ -1,36 +1,12 @@
|
||||||
package models
|
package model
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"github/fthvgb1/wp-go/helper"
|
"github/fthvgb1/wp-go/helper"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
var _ ParseWhere = SqlBuilder{}
|
|
||||||
var globalBb dbQuery
|
|
||||||
|
|
||||||
func InitDB(db dbQuery) {
|
|
||||||
globalBb = db
|
|
||||||
}
|
|
||||||
|
|
||||||
type Model interface {
|
|
||||||
PrimaryKey() string
|
|
||||||
Table() string
|
|
||||||
}
|
|
||||||
|
|
||||||
type ParseWhere interface {
|
|
||||||
ParseWhere(*[][]any) (string, []any, error)
|
|
||||||
}
|
|
||||||
|
|
||||||
type dbQuery interface {
|
|
||||||
Select(context.Context, any, string, ...any) error
|
|
||||||
Get(context.Context, any, string, ...any) error
|
|
||||||
}
|
|
||||||
|
|
||||||
type SqlBuilder [][]string
|
|
||||||
|
|
||||||
func (w SqlBuilder) parseField(ss []string, s *strings.Builder) {
|
func (w SqlBuilder) parseField(ss []string, s *strings.Builder) {
|
||||||
if strings.Contains(ss[0], ".") && !strings.Contains(ss[0], "(") {
|
if strings.Contains(ss[0], ".") && !strings.Contains(ss[0], "(") {
|
||||||
s.WriteString("`")
|
s.WriteString("`")
|
|
@ -1,4 +1,4 @@
|
||||||
package models
|
package model
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
|
@ -1,10 +1,10 @@
|
||||||
package models
|
package model
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"github/fthvgb1/wp-go/config"
|
"github/fthvgb1/wp-go/internal/config"
|
||||||
"github/fthvgb1/wp-go/db"
|
"github/fthvgb1/wp-go/internal/db"
|
||||||
wp2 "github/fthvgb1/wp-go/internal/wp"
|
wp2 "github/fthvgb1/wp-go/internal/models"
|
||||||
"reflect"
|
"reflect"
|
||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
|
@ -1,51 +1,18 @@
|
||||||
package plugins
|
package digest
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"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/helper"
|
||||||
"github/fthvgb1/wp-go/internal/wp"
|
|
||||||
"regexp"
|
"regexp"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
|
||||||
"unicode/utf8"
|
"unicode/utf8"
|
||||||
)
|
)
|
||||||
|
|
||||||
var removeWpBlock = regexp.MustCompile("<!-- /?wp:.*-->")
|
var removeWpBlock = regexp.MustCompile("<!-- /?wp:.*-->")
|
||||||
var more = regexp.MustCompile("<!--more(.*?)?-->")
|
var more = regexp.MustCompile("<!--more(.*?)?-->")
|
||||||
var digestCache *cache.MapCache[uint64, string]
|
|
||||||
var quto = regexp.MustCompile(`" *|& *|< *|> ?| *`)
|
var quto = regexp.MustCompile(`" *|& *|< *|> ?| *`)
|
||||||
|
|
||||||
func InitDigestCache() {
|
|
||||||
digestCache = cache.NewMapCacheByFn[uint64](digestRaw, config.Conf.Load().DigestCacheTime)
|
|
||||||
}
|
|
||||||
|
|
||||||
func ClearDigestCache() {
|
|
||||||
digestCache.ClearExpired()
|
|
||||||
}
|
|
||||||
func FlushCache() {
|
|
||||||
digestCache.Flush()
|
|
||||||
}
|
|
||||||
|
|
||||||
func digestRaw(arg ...any) (string, error) {
|
|
||||||
str := arg[0].(string)
|
|
||||||
id := arg[1].(uint64)
|
|
||||||
limit := config.Conf.Load().DigestWordCount
|
|
||||||
if limit < 0 {
|
|
||||||
return str, nil
|
|
||||||
} else if limit == 0 {
|
|
||||||
return "", nil
|
|
||||||
}
|
|
||||||
return DigestRaw(str, limit, fmt.Sprintf("/p/%d", id)), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func DigestCache(ctx *gin.Context, id uint64, str string) string {
|
|
||||||
content, _ := digestCache.GetCache(ctx, id, time.Second, str, id)
|
|
||||||
return content
|
|
||||||
}
|
|
||||||
|
|
||||||
func ClearHtml(str string) string {
|
func ClearHtml(str string) string {
|
||||||
content := removeWpBlock.ReplaceAllString(str, "")
|
content := removeWpBlock.ReplaceAllString(str, "")
|
||||||
content = strings.Trim(content, " \t\n\r\000\x0B")
|
content = strings.Trim(content, " \t\n\r\000\x0B")
|
||||||
|
@ -54,7 +21,7 @@ func ClearHtml(str string) string {
|
||||||
return str
|
return str
|
||||||
}
|
}
|
||||||
|
|
||||||
func DigestRaw(str string, limit int, u string) string {
|
func Raw(str string, limit int, u string) string {
|
||||||
if r := more.FindString(str); r != "" {
|
if r := more.FindString(str); r != "" {
|
||||||
m := strings.Split(str, r)
|
m := strings.Split(str, r)
|
||||||
str = m[0]
|
str = m[0]
|
||||||
|
@ -115,19 +82,5 @@ func DigestRaw(str string, limit int, u string) string {
|
||||||
}
|
}
|
||||||
content = fmt.Sprintf(tmp, content, closeTag, u)
|
content = fmt.Sprintf(tmp, content, closeTag, u)
|
||||||
}
|
}
|
||||||
|
|
||||||
return content
|
return content
|
||||||
}
|
}
|
||||||
|
|
||||||
func Digest(p *Plugin[wp.Posts], c *gin.Context, post *wp.Posts, scene uint) {
|
|
||||||
if scene == Detail {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if post.PostExcerpt != "" {
|
|
||||||
post.PostContent = strings.Replace(post.PostExcerpt, "\n", "<br/>", -1)
|
|
||||||
} else {
|
|
||||||
post.PostContent = DigestCache(c, post.Id, post.PostContent)
|
|
||||||
|
|
||||||
}
|
|
||||||
p.Next()
|
|
||||||
}
|
|
|
@ -1,18 +0,0 @@
|
||||||
package plugins
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/gin-gonic/gin"
|
|
||||||
"github/fthvgb1/wp-go/internal/wp"
|
|
||||||
)
|
|
||||||
|
|
||||||
func NewPostPlugin(ctx *gin.Context, scene uint) *Plugin[wp.Posts] {
|
|
||||||
p := NewPlugin[wp.Posts](nil, -1, nil, scene, ctx)
|
|
||||||
p.Push(Digest)
|
|
||||||
return p
|
|
||||||
}
|
|
||||||
|
|
||||||
func ApplyPlugin(p *Plugin[wp.Posts], post *wp.Posts) {
|
|
||||||
p.post = post
|
|
||||||
p.Next()
|
|
||||||
p.index = -1
|
|
||||||
}
|
|
Loading…
Reference in New Issue
Block a user