Files
backend/internal/repository/system_notification_repo.go

150 lines
4.7 KiB
Go
Raw Normal View History

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
}