Files
backend/internal/service/channel_service.go
lafay c6848aba06
All checks were successful
Build Backend / build (push) Successful in 12m45s
Build Backend / build-docker (push) Successful in 2m40s
refactor: update repository interfaces and improve dependency injection
- Refactored repository structures to use interfaces instead of concrete types, enhancing flexibility and testability.
- Updated various repository methods to accept interfaces, allowing for better dependency management.
- Modified wire generation to accommodate new repository interfaces, ensuring proper service injection throughout the application.
- Enhanced handler methods to utilize DTOs for filtering and data handling, improving code clarity and maintainability.
2026-03-26 18:14:16 +08:00

130 lines
3.3 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package service
import (
"time"
"carrot_bbs/internal/cache"
"carrot_bbs/internal/model"
"carrot_bbs/internal/repository"
)
// 频道全量列表缓存 TTL频道变更少可较长管理端写入后会主动失效
const channelAllListCacheTTL = 10 * time.Minute
type ChannelService interface {
ListActive() ([]*model.Channel, error)
ListAll() ([]*model.Channel, error)
MapByIDs(ids []string) (map[string]*model.Channel, error)
Create(name, slug, description string, sortOrder int, isActive bool) (*model.Channel, error)
Update(id, name, slug, description string, sortOrder int, isActive bool) (*model.Channel, error)
Delete(id string) error
}
type channelServiceImpl struct {
channelRepo repository.ChannelRepository
cache cache.Cache
}
func NewChannelService(channelRepo repository.ChannelRepository, c cache.Cache) ChannelService {
return &channelServiceImpl{channelRepo: channelRepo, cache: c}
}
func (s *channelServiceImpl) invalidateChannelListCache() {
if s.cache != nil {
cache.InvalidateChannelList(s.cache)
}
}
func (s *channelServiceImpl) listAllFromDB() ([]*model.Channel, error) {
return s.channelRepo.ListAll()
}
func (s *channelServiceImpl) ListAll() ([]*model.Channel, error) {
if s.cache == nil {
return s.listAllFromDB()
}
cs := cache.GetSettings()
return cache.GetOrLoadTyped(s.cache, cache.ChannelsAllListKey(), channelAllListCacheTTL, cs.JitterRatio, cs.NullTTL, s.listAllFromDB)
}
func (s *channelServiceImpl) ListActive() ([]*model.Channel, error) {
all, err := s.ListAll()
if err != nil {
return nil, err
}
out := make([]*model.Channel, 0, len(all))
for _, ch := range all {
if ch != nil && ch.IsActive {
c := *ch
out = append(out, &c)
}
}
return out, nil
}
// MapByIDs 始终基于全量频道列表Redis 命中则零 SQL否则一次 ListAll与 ListActive / 公开列表共用同一缓存快照。
func (s *channelServiceImpl) MapByIDs(ids []string) (map[string]*model.Channel, error) {
if len(ids) == 0 {
return nil, nil
}
all, err := s.ListAll()
if err != nil {
return nil, err
}
byID := make(map[string]*model.Channel, len(all))
for _, ch := range all {
if ch != nil {
byID[ch.ID] = ch
}
}
out := make(map[string]*model.Channel, len(ids))
for _, id := range ids {
if ch, ok := byID[id]; ok {
out[id] = ch
}
}
return out, nil
}
func (s *channelServiceImpl) Create(name, slug, description string, sortOrder int, isActive bool) (*model.Channel, error) {
channel := &model.Channel{
Name: name,
Slug: slug,
Description: description,
SortOrder: sortOrder,
IsActive: isActive,
}
if err := s.channelRepo.Create(channel); err != nil {
return nil, err
}
s.invalidateChannelListCache()
return channel, nil
}
func (s *channelServiceImpl) Update(id, name, slug, description string, sortOrder int, isActive bool) (*model.Channel, error) {
channel, err := s.channelRepo.GetByID(id)
if err != nil {
return nil, err
}
channel.Name = name
channel.Slug = slug
channel.Description = description
channel.SortOrder = sortOrder
channel.IsActive = isActive
if err := s.channelRepo.Update(channel); err != nil {
return nil, err
}
s.invalidateChannelListCache()
return channel, nil
}
func (s *channelServiceImpl) Delete(id string) error {
err := s.channelRepo.Delete(id)
if err != nil {
return err
}
s.invalidateChannelListCache()
return nil
}