package adminnotification import ( "context" "hfb_sys/backend/internal/model" "gorm.io/gorm" ) type Repository struct { db *gorm.DB } func NewRepository(db *gorm.DB) *Repository { return &Repository{db: db} } func (r *Repository) List(ctx context.Context, query Query) (*PaginatedResult, error) { db := r.db.WithContext(ctx).Model(&model.AdminNotification{}). Where("admin_user_id = ?", query.AdminUserID) countDB := r.db.WithContext(ctx).Model(&model.AdminNotification{}). Where("admin_user_id = ?", query.AdminUserID) if query.OnlyUnread { db = db.Where("is_read = ?", false) countDB = countDB.Where("is_read = ?", false) } var total int64 if err := countDB.Count(&total).Error; err != nil { return nil, err } offset := (query.Page - 1) * query.PageSize var rows []model.AdminNotification if err := db.Order("id DESC").Offset(offset).Limit(query.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: query.Page, PageSize: query.PageSize}, nil } func (r *Repository) UnreadCount(ctx context.Context, adminUserID uint64) (int64, error) { var total int64 err := r.db.WithContext(ctx).Model(&model.AdminNotification{}). Where("admin_user_id = ? AND is_read = ?", adminUserID, false). Count(&total).Error return total, err } func (r *Repository) MarkRead(ctx context.Context, adminUserID uint64, id uint64) error { result := r.db.WithContext(ctx).Model(&model.AdminNotification{}). Where("id = ? AND admin_user_id = ?", id, adminUserID). Update("is_read", true) if result.Error != nil { return result.Error } if result.RowsAffected == 0 { var total int64 if err := r.db.WithContext(ctx).Model(&model.AdminNotification{}). Where("id = ? AND admin_user_id = ?", id, adminUserID). Count(&total).Error; err != nil { return err } if total == 0 { return ErrNotificationNotFound } } return nil } func (r *Repository) MarkAllRead(ctx context.Context, adminUserID uint64) (int64, error) { result := r.db.WithContext(ctx).Model(&model.AdminNotification{}). Where("admin_user_id = ? AND is_read = ?", adminUserID, false). Update("is_read", true) return result.RowsAffected, result.Error } // Entry 描述一条待写入的管理员通知。 type Entry struct { AdminUserID uint64 Type string Title string Content string } // Append 在事务中批量写入管理员通知。 // 典型用法:在业务事务内调用 adminnotification.Append(tx, entries...), // 确保通知与业务数据在同一事务中提交或回滚。 func Append(tx *gorm.DB, entries ...Entry) error { for _, entry := range entries { if entry.AdminUserID == 0 || entry.Title == "" { continue } row := model.AdminNotification{ AdminUserID: entry.AdminUserID, Type: entry.Type, Title: entry.Title, Content: entry.Content, } if row.Type == "" { row.Type = "system" } if err := tx.Create(&row).Error; err != nil { return err } } return nil } func toDTO(row model.AdminNotification) NotificationDTO { return NotificationDTO{ ID: row.ID, AdminUserID: row.AdminUserID, Type: row.Type, Title: row.Title, Content: row.Content, IsRead: row.IsRead, CreatedAt: row.CreatedAt, UpdatedAt: row.UpdatedAt, } }