Files
backend/internal/repository/system_notification_repo.go
lafay 1a48bb440c
Some checks failed
Build Backend / build-docker (push) Has been cancelled
Build Backend / build (push) Has been cancelled
feat(api): add cursor-based pagination for system messages
- Add SystemMessageCursorPageResponse DTO for cursor pagination
- Implement GetSystemMessagesByCursor handler method
- Add GetByReceiverIDCursor repository method with cursor decoding
- Maintain backward compatibility with existing offset-based pagination
2026-03-21 02:48:06 +08:00

150 lines
4.7 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 repository
import (
"carrot_bbs/internal/model"
"gorm.io/gorm"
)
// SystemNotificationRepository 系统通知仓储
type SystemNotificationRepository struct {
db *gorm.DB
}
// NewSystemNotificationRepository 创建系统通知仓储
func NewSystemNotificationRepository(db *gorm.DB) *SystemNotificationRepository {
return &SystemNotificationRepository{db: db}
}
// Create 创建系统通知
func (r *SystemNotificationRepository) Create(notification *model.SystemNotification) error {
return r.db.Create(notification).Error
}
// GetByID 根据ID获取通知
func (r *SystemNotificationRepository) GetByID(id int64) (*model.SystemNotification, error) {
var notification model.SystemNotification
err := r.db.First(&notification, "id = ?", id).Error
if err != nil {
return nil, err
}
return &notification, nil
}
// GetByReceiverID 获取用户的通知列表
func (r *SystemNotificationRepository) GetByReceiverID(receiverID string, page, pageSize int) ([]*model.SystemNotification, int64, error) {
var notifications []*model.SystemNotification
var total int64
query := r.db.Model(&model.SystemNotification{}).Where("receiver_id = ?", receiverID)
query.Count(&total)
offset := (page - 1) * pageSize
err := query.Offset(offset).
Limit(pageSize).
Order("created_at DESC").
Find(&notifications).Error
return notifications, total, err
}
// GetUnreadByReceiverID 获取用户的未读通知列表
func (r *SystemNotificationRepository) GetUnreadByReceiverID(receiverID string, limit int) ([]*model.SystemNotification, error) {
var notifications []*model.SystemNotification
err := r.db.Where("receiver_id = ? AND is_read = ?", receiverID, false).
Order("created_at DESC").
Limit(limit).
Find(&notifications).Error
return notifications, err
}
// GetUnreadCount 获取用户未读通知数量
func (r *SystemNotificationRepository) GetUnreadCount(receiverID string) (int64, error) {
var count int64
err := r.db.Model(&model.SystemNotification{}).
Where("receiver_id = ? AND is_read = ?", receiverID, false).
Count(&count).Error
return count, err
}
// MarkAsRead 标记单条通知为已读
func (r *SystemNotificationRepository) MarkAsRead(id int64, receiverID string) error {
now := model.SystemNotification{}.UpdatedAt
return r.db.Model(&model.SystemNotification{}).
Where("id = ? AND receiver_id = ?", id, receiverID).
Updates(map[string]interface{}{
"is_read": true,
"read_at": now,
}).Error
}
// MarkAllAsRead 标记用户所有通知为已读
func (r *SystemNotificationRepository) MarkAllAsRead(receiverID string) error {
now := model.SystemNotification{}.UpdatedAt
return r.db.Model(&model.SystemNotification{}).
Where("receiver_id = ? AND is_read = ?", receiverID, false).
Updates(map[string]interface{}{
"is_read": true,
"read_at": now,
}).Error
}
// Delete 删除通知(软删除)
func (r *SystemNotificationRepository) Delete(id int64, receiverID string) error {
return r.db.Where("id = ? AND receiver_id = ?", id, receiverID).
Delete(&model.SystemNotification{}).Error
}
// GetByType 获取用户指定类型的通知
func (r *SystemNotificationRepository) GetByType(receiverID string, notifyType model.SystemNotificationType, page, pageSize int) ([]*model.SystemNotification, int64, error) {
var notifications []*model.SystemNotification
var total int64
query := r.db.Model(&model.SystemNotification{}).
Where("receiver_id = ? AND type = ?", receiverID, notifyType)
query.Count(&total)
offset := (page - 1) * pageSize
err := query.Offset(offset).
Limit(pageSize).
Order("created_at DESC").
Find(&notifications).Error
return notifications, total, err
}
// GetByReceiverIDCursor 游标分页获取用户的通知列表
func (r *SystemNotificationRepository) GetByReceiverIDCursor(receiverID string, cursor string, pageSize int) ([]*model.SystemNotification, string, bool, error) {
query := r.db.Model(&model.SystemNotification{}).Where("receiver_id = ?", receiverID)
// 如果有游标,解析游标并添加条件
if cursor != "" {
// 游标格式createdAt_id
query = query.Where("created_at < ? OR (created_at = ? AND id < ?)", cursor, cursor, cursor)
}
// 多取一条用于判断是否还有下一页
var notifications []*model.SystemNotification
err := query.Order("created_at DESC, id DESC").
Limit(pageSize + 1).
Find(&notifications).Error
if err != nil {
return nil, "", false, err
}
hasMore := len(notifications) > pageSize
if hasMore {
notifications = notifications[:pageSize]
}
// 生成下一页游标
var nextCursor string
if hasMore && len(notifications) > 0 {
lastNotification := notifications[len(notifications)-1]
nextCursor = lastNotification.CreatedAt.Format("2006-01-02 15:04:05.999999999")
}
return notifications, nextCursor, hasMore, nil
}