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(¬ification, "id = ?", id).Error if err != nil { return nil, err } return ¬ification, 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(¬ifications).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(¬ifications).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(¬ifications).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(¬ifications).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 }