diff --git a/actions/common/common.go b/actions/common/common.go index 03a8ae0..bd3b769 100644 --- a/actions/common/common.go +++ b/actions/common/common.go @@ -25,6 +25,7 @@ var searchPostIdsCache *cache.MapCache[string, PostIds] var maxPostIdCache *cache.SliceCache[uint64] var TotalRaw int var usersCache *cache.MapCache[uint64, wp.Users] +var usersNameCache *cache.MapCache[string, wp.Users] var commentsCache *cache.MapCache[uint64, wp.Comments] func InitActionsCommonCache() { @@ -54,7 +55,9 @@ func InitActionsCommonCache() { 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) } @@ -68,6 +71,7 @@ func ClearCache() { postContextCache.ClearExpired() usersCache.ClearExpired() commentsCache.ClearExpired() + usersNameCache.ClearExpired() } func FlushCache() { searchPostIdsCache.Flush() @@ -78,6 +82,7 @@ func FlushCache() { postContextCache.Flush() usersCache.Flush() commentsCache.Flush() + usersCache.Flush() } type PostIds struct { diff --git a/actions/common/users.go b/actions/common/users.go index 390dc66..d677946 100644 --- a/actions/common/users.go +++ b/actions/common/users.go @@ -2,24 +2,33 @@ package common import ( "context" - "github.com/gin-gonic/gin" "github/fthvgb1/wp-go/logs" "github/fthvgb1/wp-go/models" "github/fthvgb1/wp-go/models/wp" "time" ) -func getUsers(a ...any) (m map[uint64]wp.Users, err error) { - m = make(map[uint64]wp.Users) +func getUserById(a ...any) (r wp.Users, err error) { ctx := a[0].(context.Context) - r, err := models.SimpleFind[wp.Users](ctx, nil, "*") - for _, user := range r { - m[user.Id] = user - } + uid := a[1].(uint64) + r, err = models.FindOneById[wp.Users](ctx, uid) 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) logs.ErrPrintln(err, "get user", uid) return r diff --git a/actions/detail.go b/actions/detail.go index baef1a3..c7b1573 100644 --- a/actions/detail.go +++ b/actions/detail.go @@ -75,6 +75,7 @@ func Detail(c *gin.Context) { if post.CommentCount > 0 || post.CommentStatus == "open" { showComment = true } + user := common.GetUserById(c, post.PostAuthor) common.PasswordProjectTitle(&post) if post.PostPassword != "" && pw != post.PostPassword { common.PasswdProjectContent(&post) @@ -104,6 +105,7 @@ func Detail(c *gin.Context) { } h["comments"] = hh.formatComment(commentss, 1, d) h["next"] = next + h["user"] = user } type Comment struct { diff --git a/actions/feed.go b/actions/feed.go index e8c9752..1c075f4 100644 --- a/actions/feed.go +++ b/actions/feed.go @@ -101,7 +101,7 @@ func feed(arg ...any) (xml []string, err error) { } else if t.CommentStatus == "open" && t.CommentCount == 0 { 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{ Title: t.PostTitle, diff --git a/actions/index.go b/actions/index.go index 93032be..980c0a7 100644 --- a/actions/index.go +++ b/actions/index.go @@ -26,6 +26,7 @@ type indexHandle struct { titleL string titleR string search string + author string totalPage int category string categoryType string @@ -73,10 +74,10 @@ func (h *indexHandle) getTitle() 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") if !helper.IsContainInArr(h.order, []string{"asc", "desc"}) { h.order = "asc" @@ -109,7 +110,18 @@ func (h *indexHandle) parseParams() { h.header = fmt.Sprintf("分类: %s", 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 != "" { h.where = append(h.where, []string{ "d.name", category, @@ -153,6 +165,7 @@ func (h *indexHandle) parseParams() { if h.page > 1 && (h.category != "" || h.search != "" || month != "") { h.setTitleLR(fmt.Sprintf("%s-第%d页", h.titleL, h.page), config.Options.Value("blogname")) } + return } func (h *indexHandle) getTotalPage(totalRaws int) int { @@ -162,7 +175,9 @@ func (h *indexHandle) getTotalPage(totalRaws int) int { func Index(c *gin.Context) { h := newIndexHandle(c) - h.parseParams() + var postIds []wp.Posts + var totalRaw int + var err error archive := common.Archives(c) recent := common.RecentPosts(c, 5) categoryItems := common.Categories(c) @@ -174,12 +189,21 @@ func Index(c *gin.Context) { "categories": categoryItems, "search": h.search, "header": h.header, - "title": h.getTitle(), "recentComments": recentComments, } - var postIds []wp.Posts - var totalRaw int - var err error + defer func() { + stat := http.StatusOK + 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") != "" { postIds, totalRaw, err = common.GetMonthPostIds(c, c.Param("year"), c.Param("month"), h.page, h.pageSize, h.order) if err != nil { @@ -190,15 +214,6 @@ func Index(c *gin.Context) { } 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) } - - 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 { return } diff --git a/db/db.go b/db/db.go index 43c3451..2e92206 100644 --- a/db/db.go +++ b/db/db.go @@ -2,11 +2,13 @@ package db import ( "context" + "fmt" _ "github.com/go-sql-driver/mysql" "github.com/jmoiron/sqlx" "github/fthvgb1/wp-go/config" "log" "os" + "strconv" "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 { 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...) } func (r SqlxDb) Get(ctx context.Context, dest any, sql string, params ...any) error { 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...) } +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 { c := config.Conf.Load() dsn := c.Mysql.Dsn.GetDsn() diff --git a/route/route.go b/route/route.go index 44cbbd2..fdc57ee 100644 --- a/route/route.go +++ b/route/route.go @@ -73,6 +73,8 @@ func SetupRouter() (*gin.Engine, func()) { r.GET("/p/tag/:tag/page/:page", actions.Index) r.GET("/p/date/:year/:month", 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.GET("/p/:id", actions.Detail) r.GET("/p/:id/feed", actions.PostFeed) diff --git a/templates/twentyfifteen/posts/detail.gohtml b/templates/twentyfifteen/posts/detail.gohtml index ef9c8b2..4ba434b 100644 --- a/templates/twentyfifteen/posts/detail.gohtml +++ b/templates/twentyfifteen/posts/detail.gohtml @@ -22,6 +22,12 @@ datetime="{{.post.PostDateGmt}}">{{.post.PostDate|dateCh}} + + + + 作者 + {{.user.UserLogin}} + {{if .post.CategoriesHtml}}