Files
AShareView/server/service/dashboard_svc.go
T
曾志威 f2c75c89f1
continuous-integration/drone Build is passing
init
2026-05-10 21:31:57 +08:00

95 lines
2.0 KiB
Go

package service
import (
"ashareview-server/model"
"ashareview-server/repository"
"sync"
"time"
)
type cacheEntry[T any] struct {
data T
expires time.Time
}
type DashboardService struct {
repo *repository.StockRepo
mu sync.RWMutex
summary *cacheEntry[*model.DashboardSummary]
daily map[int]*cacheEntry[[]model.DailySummary]
consec *cacheEntry[[]model.ConsecutiveLimit]
}
func NewDashboardService(repo *repository.StockRepo) *DashboardService {
return &DashboardService{repo: repo, daily: make(map[int]*cacheEntry[[]model.DailySummary])}
}
const cacheTTL = 3 * time.Minute
func (s *DashboardService) GetSummary() (*model.DashboardSummary, error) {
s.mu.RLock()
if s.summary != nil && time.Now().Before(s.summary.expires) {
data := s.summary.data
s.mu.RUnlock()
return data, nil
}
s.mu.RUnlock()
date, err := s.repo.GetLatestTradeDate()
if err != nil {
return nil, err
}
summary, err := s.repo.GetSummaryByDate(date)
if err != nil {
return nil, err
}
s.mu.Lock()
s.summary = &cacheEntry[*model.DashboardSummary]{data: summary, expires: time.Now().Add(cacheTTL)}
s.mu.Unlock()
return summary, nil
}
func (s *DashboardService) GetDailySummary(days int) ([]model.DailySummary, error) {
s.mu.RLock()
if e, ok := s.daily[days]; ok && time.Now().Before(e.expires) {
data := e.data
s.mu.RUnlock()
return data, nil
}
s.mu.RUnlock()
data, err := s.repo.GetDailySummary(days)
if err != nil {
return nil, err
}
s.mu.Lock()
s.daily[days] = &cacheEntry[[]model.DailySummary]{data: data, expires: time.Now().Add(cacheTTL)}
s.mu.Unlock()
return data, nil
}
func (s *DashboardService) GetConsecutiveLimits() ([]model.ConsecutiveLimit, error) {
s.mu.RLock()
if s.consec != nil && time.Now().Before(s.consec.expires) {
data := s.consec.data
s.mu.RUnlock()
return data, nil
}
s.mu.RUnlock()
data, err := s.repo.GetConsecutiveLimits()
if err != nil {
return nil, err
}
s.mu.Lock()
s.consec = &cacheEntry[[]model.ConsecutiveLimit]{data: data, expires: time.Now().Add(cacheTTL)}
s.mu.Unlock()
return data, nil
}