feat: 首页增加内存缓存(30s TTL)

- 新增 internal/cache/home_cache.go,实现带 TTL 的首页文章列表内存缓存
- frontend.go 首页 handler 优先读取缓存,未命中/过期时查询 DB 并回填
- PostService 注入失效回调,在 Create/Update/Delete/Approve 后自动失效缓存
- 减少首页每次请求都查 DB 的开销
This commit is contained in:
2026-06-02 17:20:59 +08:00
parent 3e0fed80ce
commit 593b52096f
6 changed files with 110 additions and 11 deletions

View File

@ -21,7 +21,11 @@ func (s *PostService) Update(postID uint, title, body string) error {
post.PendingTitle = title
post.PendingBody = body
post.RejectReason = "" // 清空旧退回理由
return s.repo.Update(post)
err := s.repo.Update(post)
if err == nil {
s.invalidateHomeCache()
}
return err
}
// 草稿/已退回:直接修改原文(现有逻辑)
@ -34,12 +38,20 @@ func (s *PostService) Update(postID uint, title, body string) error {
post.RejectReason = ""
}
return s.repo.Update(post)
err = s.repo.Update(post)
if err == nil {
s.invalidateHomeCache()
}
return err
}
// Delete 软删除(权限在 controller 层检查)
func (s *PostService) Delete(postID uint) error {
return s.repo.SoftDelete(postID)
if err := s.repo.SoftDelete(postID); err != nil {
return err
}
s.invalidateHomeCache()
return nil
}
// SubmitForAudit 提交审核draft → pending
@ -79,6 +91,7 @@ func (s *PostService) Approve(postID uint) error {
if err := s.repo.Update(post); err != nil {
return err
}
s.invalidateHomeCache()
// 通知作者修订审核通过
if s.notifier != nil {
s.notifier.NotifyPostApproved(post.UserID, post.Title, post.ID)
@ -95,6 +108,7 @@ func (s *PostService) Approve(postID uint) error {
if err := s.repo.Update(post); err != nil {
return err
}
s.invalidateHomeCache()
// 通知作者审核通过
if s.notifier != nil {
s.notifier.NotifyPostApproved(post.UserID, post.Title, post.ID)

View File

@ -13,10 +13,11 @@ import (
// PostService 帖子业务逻辑
type PostService struct {
repo postStore
ss *config.SiteSettings
notifier postNotifier
userRepo userExpReader
repo postStore
ss *config.SiteSettings
notifier postNotifier
userRepo userExpReader
onHomePageChanged func()
}
// NewPostService 构造函数
@ -29,6 +30,11 @@ func NewPostService(repo postStore, ss *config.SiteSettings, notifier postNotifi
}
}
// WithHomePageInvalidator 注入首页缓存失效回调(文章变更时触发)
func (s *PostService) WithHomePageInvalidator(fn func()) {
s.onHomePageChanged = fn
}
// auditEnabled 审核是否开启
func (s *PostService) auditEnabled() bool {
return s.ss.IsAuditEnabled()
@ -78,6 +84,7 @@ func (s *PostService) Create(userID uint, title, body string) (*model.Post, erro
if err := s.repo.Create(post); err != nil {
return nil, err
}
s.invalidateHomeCache()
return post, nil
}
@ -156,6 +163,13 @@ func (s *PostService) CanCreatePost(userID uint) bool {
return user.Exp >= 1
}
// invalidateHomeCache 失效首页缓存(异步安全调用)
func (s *PostService) invalidateHomeCache() {
if s.onHomePageChanged != nil {
s.onHomePageChanged()
}
}
// RecordRead 记录已登录用户阅读文章(已登录去重 + 防刷冷却)
func (s *PostService) RecordRead(userID, postID uint) {
firstRead, err := s.repo.RecordRead(userID, postID)