mirror of
https://github.com/ctwj/urldb.git
synced 2025-11-25 19:37:33 +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()
|