Files

120 lines
2.9 KiB
Go

package notification
import (
"context"
"time"
"hfb_sys/backend/internal/model"
"gorm.io/gorm"
)
type Repository struct {
db *gorm.DB
}
type Entry struct {
UserID uint64
Type string
Title string
Content string
BizType string
BizID *uint64
}
func NewRepository(db *gorm.DB) *Repository {
return &Repository{db: db}
}
func (r *Repository) List(ctx context.Context, userID uint64, page, pageSize int) (*PaginatedResult, error) {
var total int64
if err := r.db.WithContext(ctx).Model(&model.Notification{}).Where("user_id = ?", userID).Count(&total).Error; err != nil {
return nil, err
}
offset := (page - 1) * pageSize
var rows []model.Notification
if err := r.db.WithContext(ctx).Where("user_id = ?", userID).Order("id DESC").Offset(offset).Limit(pageSize).Find(&rows).Error; err != nil {
return nil, err
}
items := make([]NotificationDTO, 0, len(rows))
for _, row := range rows {
items = append(items, toDTO(row))
}
return &PaginatedResult{Items: items, Total: total, Page: page, PageSize: pageSize}, nil
}
func (r *Repository) MarkRead(ctx context.Context, userID uint64, id uint64) error {
now := time.Now()
result := r.db.WithContext(ctx).Model(&model.Notification{}).
Where("id = ? AND user_id = ?", id, userID).
Update("read_at", now)
if result.Error != nil {
return result.Error
}
if result.RowsAffected == 0 {
var total int64
if err := r.db.WithContext(ctx).Model(&model.Notification{}).
Where("id = ? AND user_id = ?", id, userID).
Count(&total).Error; err != nil {
return err
}
if total == 0 {
return ErrNotificationNotFound
}
}
return nil
}
func (r *Repository) UnreadCount(ctx context.Context, userID uint64) (int64, error) {
var total int64
err := r.db.WithContext(ctx).Model(&model.Notification{}).
Where("user_id = ? AND read_at IS NULL", userID).
Count(&total).Error
return total, err
}
func (r *Repository) MarkAllRead(ctx context.Context, userID uint64) (int64, error) {
now := time.Now()
result := r.db.WithContext(ctx).Model(&model.Notification{}).
Where("user_id = ? AND read_at IS NULL", userID).
Update("read_at", now)
return result.RowsAffected, result.Error
}
func Append(tx *gorm.DB, entries ...Entry) error {
for _, entry := range entries {
if entry.UserID == 0 || entry.Title == "" {
continue
}
row := model.Notification{
UserID: entry.UserID,
Type: entry.Type,
Title: entry.Title,
Content: entry.Content,
BizType: entry.BizType,
BizID: entry.BizID,
}
if row.Type == "" {
row.Type = "system"
}
if err := tx.Create(&row).Error; err != nil {
return err
}
}
return nil
}
func toDTO(row model.Notification) NotificationDTO {
return NotificationDTO{
ID: row.ID,
UserID: row.UserID,
Type: row.Type,
Title: row.Title,
Content: row.Content,
BizType: row.BizType,
BizID: row.BizID,
ReadAt: row.ReadAt,
CreatedAt: row.CreatedAt,
}
}