按作者搜索文档

This commit is contained in:
xing 2022-11-17 11:22:29 +08:00
parent fc10308df6
commit 1a72552b41
8 changed files with 88 additions and 29 deletions

View File

@ -25,6 +25,7 @@ var searchPostIdsCache *cache.MapCache[string, PostIds]
var maxPostIdCache *cache.SliceCache[uint64] var maxPostIdCache *cache.SliceCache[uint64]
var TotalRaw int var TotalRaw int
var usersCache *cache.MapCache[uint64, wp.Users] var usersCache *cache.MapCache[uint64, wp.Users]
var usersNameCache *cache.MapCache[string, wp.Users]
var commentsCache *cache.MapCache[uint64, wp.Comments] var commentsCache *cache.MapCache[uint64, wp.Comments]
func InitActionsCommonCache() { func InitActionsCommonCache() {
@ -54,7 +55,9 @@ func InitActionsCommonCache() {
maxPostIdCache = cache.NewSliceCache[uint64](getMaxPostId, c.MaxPostIdCacheTime) maxPostIdCache = cache.NewSliceCache[uint64](getMaxPostId, c.MaxPostIdCacheTime)
usersCache = cache.NewMapCacheByBatchFn[uint64, wp.Users](getUsers, c.UserInfoCacheTime) usersCache = cache.NewMapCacheByFn[uint64, wp.Users](getUserById, c.UserInfoCacheTime)
usersNameCache = cache.NewMapCacheByFn[string, wp.Users](getUserByName, c.UserInfoCacheTime)
commentsCache = cache.NewMapCacheByBatchFn[uint64, wp.Comments](getCommentByIds, c.CommentsCacheTime) commentsCache = cache.NewMapCacheByBatchFn[uint64, wp.Comments](getCommentByIds, c.CommentsCacheTime)
} }
@ -68,6 +71,7 @@ func ClearCache() {
postContextCache.ClearExpired() postContextCache.ClearExpired()
usersCache.ClearExpired() usersCache.ClearExpired()
commentsCache.ClearExpired() commentsCache.ClearExpired()
usersNameCache.ClearExpired()
} }
func FlushCache() { func FlushCache() {
searchPostIdsCache.Flush() searchPostIdsCache.Flush()
@ -78,6 +82,7 @@ func FlushCache() {
postContextCache.Flush() postContextCache.Flush()
usersCache.Flush() usersCache.Flush()
commentsCache.Flush() commentsCache.Flush()
usersCache.Flush()
} }
type PostIds struct { type PostIds struct {

View File

@ -2,24 +2,33 @@ package common
import ( import (
"context" "context"
"github.com/gin-gonic/gin"
"github/fthvgb1/wp-go/logs" "github/fthvgb1/wp-go/logs"
"github/fthvgb1/wp-go/models" "github/fthvgb1/wp-go/models"
"github/fthvgb1/wp-go/models/wp" "github/fthvgb1/wp-go/models/wp"
"time" "time"
) )
func getUsers(a ...any) (m map[uint64]wp.Users, err error) { func getUserById(a ...any) (r wp.Users, err error) {
m = make(map[uint64]wp.Users)
ctx := a[0].(context.Context) ctx := a[0].(context.Context)
r, err := models.SimpleFind[wp.Users](ctx, nil, "*") uid := a[1].(uint64)
for _, user := range r { r, err = models.FindOneById[wp.Users](ctx, uid)
m[user.Id] = user
}
return return
} }
func GetUser(ctx *gin.Context, uid uint64) wp.Users { 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) r, err := usersCache.GetCache(ctx, uid, time.Second, ctx, uid)
logs.ErrPrintln(err, "get user", uid) logs.ErrPrintln(err, "get user", uid)
return r return r

View File

@ -75,6 +75,7 @@ func Detail(c *gin.Context) {
if post.CommentCount > 0 || post.CommentStatus == "open" { if post.CommentCount > 0 || post.CommentStatus == "open" {
showComment = true showComment = true
} }
user := common.GetUserById(c, post.PostAuthor)
common.PasswordProjectTitle(&post) common.PasswordProjectTitle(&post)
if post.PostPassword != "" && pw != post.PostPassword { if post.PostPassword != "" && pw != post.PostPassword {
common.PasswdProjectContent(&post) common.PasswdProjectContent(&post)
@ -104,6 +105,7 @@ func Detail(c *gin.Context) {
} }
h["comments"] = hh.formatComment(commentss, 1, d) h["comments"] = hh.formatComment(commentss, 1, d)
h["next"] = next h["next"] = next
h["user"] = user
} }
type Comment struct { type Comment struct {

View File

@ -101,7 +101,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", config.Options.Value("siteurl"), t.Id) l = fmt.Sprintf("%s/p/%d#respond", config.Options.Value("siteurl"), t.Id)
} }
user := common.GetUser(c, t.PostAuthor) user := common.GetUserById(c, t.PostAuthor)
return rss2.Item{ return rss2.Item{
Title: t.PostTitle, Title: t.PostTitle,

View File

@ -26,6 +26,7 @@ type indexHandle struct {
titleL string titleL string
titleR string titleR string
search string search string
author string
totalPage int totalPage int
category string category string
categoryType string categoryType string
@ -73,10 +74,10 @@ func (h *indexHandle) getTitle() string {
} }
func (h *indexHandle) getSearchKey() string { func (h *indexHandle) getSearchKey() string {
return fmt.Sprintf("action:%s|%s|%s|%s|%s|%d|%d", h.search, h.orderBy, h.order, h.category, h.categoryType, h.page, h.pageSize) return fmt.Sprintf("action:%s|%s|%s|%s|%s|%s|%d|%d", h.author, h.search, h.orderBy, h.order, h.category, h.categoryType, h.page, h.pageSize)
} }
func (h *indexHandle) parseParams() { func (h *indexHandle) parseParams() (err error) {
h.order = h.c.Query("order") h.order = h.c.Query("order")
if !helper.IsContainInArr(h.order, []string{"asc", "desc"}) { if !helper.IsContainInArr(h.order, []string{"asc", "desc"}) {
h.order = "asc" h.order = "asc"
@ -109,7 +110,18 @@ func (h *indexHandle) parseParams() {
h.header = fmt.Sprintf("分类: <span>%s</span>", category) h.header = fmt.Sprintf("分类: <span>%s</span>", category)
} }
h.category = category h.category = category
username := h.c.Param("author")
if username != "" {
user, er := common.GetUserByName(h.c, username)
if er != nil {
err = er
return
}
h.author = username
h.where = append(h.where, []string{
"post_author", "=", strconv.FormatUint(user.Id, 10), "int",
})
}
if category != "" { if category != "" {
h.where = append(h.where, []string{ h.where = append(h.where, []string{
"d.name", category, "d.name", category,
@ -153,6 +165,7 @@ func (h *indexHandle) parseParams() {
if h.page > 1 && (h.category != "" || h.search != "" || month != "") { if h.page > 1 && (h.category != "" || h.search != "" || month != "") {
h.setTitleLR(fmt.Sprintf("%s-第%d页", h.titleL, h.page), config.Options.Value("blogname")) h.setTitleLR(fmt.Sprintf("%s-第%d页", h.titleL, h.page), config.Options.Value("blogname"))
} }
return
} }
func (h *indexHandle) getTotalPage(totalRaws int) int { func (h *indexHandle) getTotalPage(totalRaws int) int {
@ -162,7 +175,9 @@ func (h *indexHandle) getTotalPage(totalRaws int) int {
func Index(c *gin.Context) { func Index(c *gin.Context) {
h := newIndexHandle(c) h := newIndexHandle(c)
h.parseParams() var postIds []wp.Posts
var totalRaw int
var err error
archive := common.Archives(c) archive := common.Archives(c)
recent := common.RecentPosts(c, 5) recent := common.RecentPosts(c, 5)
categoryItems := common.Categories(c) categoryItems := common.Categories(c)
@ -174,12 +189,21 @@ func Index(c *gin.Context) {
"categories": categoryItems, "categories": categoryItems,
"search": h.search, "search": h.search,
"header": h.header, "header": h.header,
"title": h.getTitle(),
"recentComments": recentComments, "recentComments": recentComments,
} }
var postIds []wp.Posts defer func() {
var totalRaw int stat := http.StatusOK
var err error if err != nil {
c.Error(err)
stat = http.StatusInternalServerError
}
c.HTML(stat, "twentyfifteen/posts/index.gohtml", ginH)
}()
err = h.parseParams()
if err != nil {
return
}
ginH["title"] = h.getTitle()
if c.Param("month") != "" { if c.Param("month") != "" {
postIds, totalRaw, err = common.GetMonthPostIds(c, c.Param("year"), c.Param("month"), h.page, h.pageSize, h.order) postIds, totalRaw, err = common.GetMonthPostIds(c, c.Param("year"), c.Param("month"), h.page, h.pageSize, h.order)
if err != nil { if err != nil {
@ -190,15 +214,6 @@ func Index(c *gin.Context) {
} else { } else {
postIds, totalRaw, err = common.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 = common.PostLists(c, h.getSearchKey(), c, h.where, h.page, h.pageSize, models.SqlBuilder{{h.orderBy, h.order}}, h.join, h.postType, h.status)
} }
defer func() {
stat := http.StatusOK
if err != nil {
c.Error(err)
stat = http.StatusInternalServerError
}
c.HTML(stat, "twentyfifteen/posts/index.gohtml", ginH)
}()
if err != nil { if err != nil {
return return
} }

View File

@ -2,11 +2,13 @@ package db
import ( import (
"context" "context"
"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/config"
"log" "log"
"os" "os"
"strconv"
"strings" "strings"
) )
@ -22,18 +24,36 @@ func NewSqlxDb(sqlx *sqlx.DB) *SqlxDb {
func (r SqlxDb) Select(ctx context.Context, dest any, sql string, params ...any) error { func (r SqlxDb) Select(ctx context.Context, dest any, sql string, params ...any) error {
if os.Getenv("SHOW_SQL") == "true" { if os.Getenv("SHOW_SQL") == "true" {
log.Printf(strings.Replace(sql, "?", "'%v'", -1), params...) go log.Println(formatSql(sql, params))
} }
return r.sqlx.Select(dest, sql, params...) return r.sqlx.Select(dest, sql, params...)
} }
func (r SqlxDb) Get(ctx context.Context, dest any, sql string, params ...any) error { func (r SqlxDb) Get(ctx context.Context, dest any, sql string, params ...any) error {
if os.Getenv("SHOW_SQL") == "true" { if os.Getenv("SHOW_SQL") == "true" {
log.Printf(strings.Replace(sql, "?", "'%v'", -1), params...) go log.Println(formatSql(sql, params))
} }
return r.sqlx.Get(dest, sql, params...) return r.sqlx.Get(dest, sql, params...)
} }
func formatSql(sql string, params []any) string {
for _, param := range params {
switch param.(type) {
case string:
sql = strings.Replace(sql, "?", fmt.Sprintf("'%s'", param.(string)), 1)
case int64:
sql = strings.Replace(sql, "?", strconv.FormatInt(param.(int64), 10), 1)
case int:
sql = strings.Replace(sql, "?", strconv.Itoa(param.(int)), 1)
case uint64:
sql = strings.Replace(sql, "?", strconv.FormatUint(param.(uint64), 10), 1)
case float64:
sql = strings.Replace(sql, "?", fmt.Sprintf("%f", param.(float64)), 1)
}
}
return sql
}
func InitDb() error { func InitDb() error {
c := config.Conf.Load() c := config.Conf.Load()
dsn := c.Mysql.Dsn.GetDsn() dsn := c.Mysql.Dsn.GetDsn()

View File

@ -73,6 +73,8 @@ func SetupRouter() (*gin.Engine, func()) {
r.GET("/p/tag/:tag/page/:page", actions.Index) r.GET("/p/tag/:tag/page/:page", actions.Index)
r.GET("/p/date/:year/:month", actions.Index) r.GET("/p/date/:year/:month", actions.Index)
r.GET("/p/date/:year/:month/page/:page", actions.Index) r.GET("/p/date/:year/:month/page/:page", actions.Index)
r.GET("/p/author/:author", actions.Index)
r.GET("/p/author/:author/page/:page", actions.Index)
r.POST("/login", actions.Login) r.POST("/login", actions.Login)
r.GET("/p/:id", actions.Detail) r.GET("/p/:id", actions.Detail)
r.GET("/p/:id/feed", actions.PostFeed) r.GET("/p/:id/feed", actions.PostFeed)

View File

@ -22,6 +22,12 @@
datetime="{{.post.PostDateGmt}}">{{.post.PostDate|dateCh}} datetime="{{.post.PostDateGmt}}">{{.post.PostDate|dateCh}}
</time> </time>
</a> </a>
</span>
<span class="byline">
<span class="author vcard">
<span class="screen-reader-text">作者 </span>
<a class="url fn n" href="/p/author/{{.user.UserLogin}}">{{.user.UserLogin}}</a>
</span>
</span> </span>
{{if .post.CategoriesHtml}} {{if .post.CategoriesHtml}}
<span class="cat-links"> <span class="cat-links">