mirror of
https://github.com/ctwj/urldb.git
synced 2025-11-25 03:15:04 +08:00
231 lines
5.1 KiB
Go
231 lines
5.1 KiB
Go
package services
|
||
|
||
import (
|
||
"sync"
|
||
"time"
|
||
|
||
"github.com/ctwj/urldb/db/entity"
|
||
)
|
||
|
||
// SearchSession 搜索会话
|
||
type SearchSession struct {
|
||
UserID string // 用户ID
|
||
Keyword string // 搜索关键字
|
||
Resources []entity.Resource // 搜索结果
|
||
PageSize int // 每页数量
|
||
CurrentPage int // 当前页码
|
||
TotalPages int // 总页数
|
||
LastAccess time.Time // 最后访问时间
|
||
}
|
||
|
||
// SearchSessionManager 搜索会话管理器
|
||
type SearchSessionManager struct {
|
||
sessions map[string]*SearchSession // 用户ID -> 搜索会话
|
||
mutex sync.RWMutex
|
||
}
|
||
|
||
// NewSearchSessionManager 创建搜索会话管理器
|
||
func NewSearchSessionManager() *SearchSessionManager {
|
||
manager := &SearchSessionManager{
|
||
sessions: make(map[string]*SearchSession),
|
||
}
|
||
|
||
// 启动清理过期会话的goroutine
|
||
go manager.cleanupExpiredSessions()
|
||
|
||
return manager
|
||
}
|
||
|
||
// CreateSession 创建或更新搜索会话
|
||
func (m *SearchSessionManager) CreateSession(userID, keyword string, resources []entity.Resource, pageSize int) *SearchSession {
|
||
m.mutex.Lock()
|
||
defer m.mutex.Unlock()
|
||
|
||
session := &SearchSession{
|
||
UserID: userID,
|
||
Keyword: keyword,
|
||
Resources: resources,
|
||
PageSize: pageSize,
|
||
CurrentPage: 1,
|
||
TotalPages: (len(resources) + pageSize - 1) / pageSize,
|
||
LastAccess: time.Now(),
|
||
}
|
||
|
||
m.sessions[userID] = session
|
||
return session
|
||
}
|
||
|
||
// GetSession 获取搜索会话
|
||
func (m *SearchSessionManager) GetSession(userID string) *SearchSession {
|
||
m.mutex.RLock()
|
||
defer m.mutex.RUnlock()
|
||
|
||
session, exists := m.sessions[userID]
|
||
if !exists {
|
||
return nil
|
||
}
|
||
|
||
// 更新最后访问时间
|
||
m.mutex.RUnlock()
|
||
m.mutex.Lock()
|
||
session.LastAccess = time.Now()
|
||
m.mutex.Unlock()
|
||
m.mutex.RLock()
|
||
|
||
return session
|
||
}
|
||
|
||
// SetCurrentPage 设置当前页
|
||
func (m *SearchSessionManager) SetCurrentPage(userID string, page int) bool {
|
||
m.mutex.Lock()
|
||
defer m.mutex.Unlock()
|
||
|
||
session, exists := m.sessions[userID]
|
||
if !exists {
|
||
return false
|
||
}
|
||
|
||
if page < 1 || page > session.TotalPages {
|
||
return false
|
||
}
|
||
|
||
session.CurrentPage = page
|
||
session.LastAccess = time.Now()
|
||
return true
|
||
}
|
||
|
||
// GetPageResources 获取指定页的资源
|
||
func (m *SearchSessionManager) GetPageResources(userID string, page int) []entity.Resource {
|
||
m.mutex.RLock()
|
||
session, exists := m.sessions[userID]
|
||
m.mutex.RUnlock()
|
||
|
||
if !exists {
|
||
return nil
|
||
}
|
||
|
||
if page < 1 || page > session.TotalPages {
|
||
return nil
|
||
}
|
||
|
||
start := (page - 1) * session.PageSize
|
||
end := start + session.PageSize
|
||
if end > len(session.Resources) {
|
||
end = len(session.Resources)
|
||
}
|
||
|
||
// 更新当前页和最后访问时间
|
||
m.mutex.Lock()
|
||
session.CurrentPage = page
|
||
session.LastAccess = time.Now()
|
||
m.mutex.Unlock()
|
||
|
||
return session.Resources[start:end]
|
||
}
|
||
|
||
// GetCurrentPageResources 获取当前页的资源
|
||
func (m *SearchSessionManager) GetCurrentPageResources(userID string) []entity.Resource {
|
||
m.mutex.RLock()
|
||
session, exists := m.sessions[userID]
|
||
m.mutex.RUnlock()
|
||
|
||
if !exists {
|
||
return nil
|
||
}
|
||
|
||
return m.GetPageResources(userID, session.CurrentPage)
|
||
}
|
||
|
||
// HasNextPage 是否有下一页
|
||
func (m *SearchSessionManager) HasNextPage(userID string) bool {
|
||
m.mutex.RLock()
|
||
defer m.mutex.RUnlock()
|
||
|
||
session, exists := m.sessions[userID]
|
||
if !exists {
|
||
return false
|
||
}
|
||
|
||
return session.CurrentPage < session.TotalPages
|
||
}
|
||
|
||
// HasPrevPage 是否有上一页
|
||
func (m *SearchSessionManager) HasPrevPage(userID string) bool {
|
||
m.mutex.RLock()
|
||
defer m.mutex.RUnlock()
|
||
|
||
session, exists := m.sessions[userID]
|
||
if !exists {
|
||
return false
|
||
}
|
||
|
||
return session.CurrentPage > 1
|
||
}
|
||
|
||
// NextPage 下一页
|
||
func (m *SearchSessionManager) NextPage(userID string) []entity.Resource {
|
||
m.mutex.Lock()
|
||
session, exists := m.sessions[userID]
|
||
m.mutex.Unlock()
|
||
|
||
if !exists {
|
||
return nil
|
||
}
|
||
|
||
if session.CurrentPage >= session.TotalPages {
|
||
return nil
|
||
}
|
||
|
||
return m.GetPageResources(userID, session.CurrentPage+1)
|
||
}
|
||
|
||
// PrevPage 上一页
|
||
func (m *SearchSessionManager) PrevPage(userID string) []entity.Resource {
|
||
m.mutex.Lock()
|
||
session, exists := m.sessions[userID]
|
||
m.mutex.Unlock()
|
||
|
||
if !exists {
|
||
return nil
|
||
}
|
||
|
||
if session.CurrentPage <= 1 {
|
||
return nil
|
||
}
|
||
|
||
return m.GetPageResources(userID, session.CurrentPage-1)
|
||
}
|
||
|
||
// GetPageInfo 获取分页信息
|
||
func (m *SearchSessionManager) GetPageInfo(userID string) (currentPage, totalPages int, hasPrev, hasNext bool) {
|
||
m.mutex.RLock()
|
||
defer m.mutex.RUnlock()
|
||
|
||
session, exists := m.sessions[userID]
|
||
if !exists {
|
||
return 0, 0, false, false
|
||
}
|
||
|
||
return session.CurrentPage, session.TotalPages, session.CurrentPage > 1, session.CurrentPage < session.TotalPages
|
||
}
|
||
|
||
// cleanupExpiredSessions 清理过期会话(超过1小时未访问)
|
||
func (m *SearchSessionManager) cleanupExpiredSessions() {
|
||
ticker := time.NewTicker(10 * time.Minute)
|
||
defer ticker.Stop()
|
||
|
||
for range ticker.C {
|
||
m.mutex.Lock()
|
||
now := time.Now()
|
||
for userID, session := range m.sessions {
|
||
// 如果超过1小时未访问,清理该会话
|
||
if now.Sub(session.LastAccess) > time.Hour {
|
||
delete(m.sessions, userID)
|
||
}
|
||
}
|
||
m.mutex.Unlock()
|
||
}
|
||
}
|
||
|
||
// GlobalSearchSessionManager 全局搜索会话管理器
|
||
var GlobalSearchSessionManager = NewSearchSessionManager() |