perf(expiry): 完成 #34 性能优化与缓存
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
package expiry
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"strings"
|
||||
"time"
|
||||
@@ -24,7 +25,8 @@ var (
|
||||
|
||||
// Service 封装保质期模块业务逻辑。
|
||||
type Service struct {
|
||||
repo *Repository
|
||||
repo *Repository
|
||||
summaryCache *SummaryCache
|
||||
}
|
||||
|
||||
// CreateItemRequest 创建物品请求。
|
||||
@@ -96,6 +98,11 @@ func NewService(repo *Repository) *Service {
|
||||
return &Service{repo: repo}
|
||||
}
|
||||
|
||||
// BindSummaryCache 绑定 summary 的 Redis 缓存(可选)。
|
||||
func (s *Service) BindSummaryCache(cache *SummaryCache) {
|
||||
s.summaryCache = cache
|
||||
}
|
||||
|
||||
// CreateItem 创建物品,并处理过期日期自动计算。
|
||||
func (s *Service) CreateItem(userID uint, req CreateItemRequest) (*ExpiryItem, error) {
|
||||
if req.MiniProgramID == 0 {
|
||||
@@ -135,6 +142,7 @@ func (s *Service) CreateItem(userID uint, req CreateItemRequest) (*ExpiryItem, e
|
||||
if err := s.repo.Create(item); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
s.invalidateSummaryCache(userID)
|
||||
|
||||
item.Status = item.CalculateStatus()
|
||||
return item, nil
|
||||
@@ -186,6 +194,7 @@ func (s *Service) UpdateItem(id, userID uint, req UpdateItemRequest) (*ExpiryIte
|
||||
if err := s.repo.Update(item); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
s.invalidateSummaryCache(userID)
|
||||
|
||||
item.Status = item.CalculateStatus()
|
||||
return item, nil
|
||||
@@ -193,7 +202,11 @@ func (s *Service) UpdateItem(id, userID uint, req UpdateItemRequest) (*ExpiryIte
|
||||
|
||||
// DeleteItem 删除物品。
|
||||
func (s *Service) DeleteItem(id, userID uint) error {
|
||||
return s.repo.Delete(id, userID)
|
||||
if err := s.repo.Delete(id, userID); err != nil {
|
||||
return err
|
||||
}
|
||||
s.invalidateSummaryCache(userID)
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetItem 获取单个物品。
|
||||
@@ -237,19 +250,26 @@ func (s *Service) GetItems(userID uint, filters ItemFilters) (*ItemListResponse,
|
||||
|
||||
// GetSummary 获取首页汇总。
|
||||
func (s *Service) GetSummary(userID uint) (*SummaryResponse, error) {
|
||||
if cached, ok := s.getSummaryFromCache(userID); ok {
|
||||
return cached, nil
|
||||
}
|
||||
|
||||
data, err := s.repo.GetSummary(userID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &SummaryResponse{
|
||||
summary := &SummaryResponse{
|
||||
TotalItems: data["total_items"],
|
||||
ExpiringSoon: data["expiring_soon"],
|
||||
Expired: data["expired"],
|
||||
Normal: data["normal"],
|
||||
Used: data["used"],
|
||||
Discarded: data["discarded"],
|
||||
}, nil
|
||||
}
|
||||
|
||||
s.setSummaryToCache(userID, summary)
|
||||
return summary, nil
|
||||
}
|
||||
|
||||
// UpdateItemStatus 标记物品状态。
|
||||
@@ -258,7 +278,11 @@ func (s *Service) UpdateItemStatus(id, userID uint, status string) error {
|
||||
if status != StatusUsed && status != StatusDiscarded {
|
||||
return ErrExpiryStatusInvalid
|
||||
}
|
||||
return s.repo.UpdateStatus(id, userID, status)
|
||||
if err := s.repo.UpdateStatus(id, userID, status); err != nil {
|
||||
return err
|
||||
}
|
||||
s.invalidateSummaryCache(userID)
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetSettings 获取用户提醒设置;若未配置则返回默认值。
|
||||
@@ -433,3 +457,28 @@ func validateRemindDays(days []int) ([]int, error) {
|
||||
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func (s *Service) getSummaryFromCache(userID uint) (*SummaryResponse, bool) {
|
||||
if s.summaryCache == nil {
|
||||
return nil, false
|
||||
}
|
||||
summary, ok, err := s.summaryCache.Get(context.Background(), userID)
|
||||
if err != nil || !ok || summary == nil {
|
||||
return nil, false
|
||||
}
|
||||
return summary, true
|
||||
}
|
||||
|
||||
func (s *Service) setSummaryToCache(userID uint, summary *SummaryResponse) {
|
||||
if s.summaryCache == nil || summary == nil {
|
||||
return
|
||||
}
|
||||
_ = s.summaryCache.Set(context.Background(), userID, summary)
|
||||
}
|
||||
|
||||
func (s *Service) invalidateSummaryCache(userID uint) {
|
||||
if s.summaryCache == nil {
|
||||
return
|
||||
}
|
||||
_ = s.summaryCache.Delete(context.Background(), userID)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user