164 lines
4.4 KiB
Go
164 lines
4.4 KiB
Go
package services
|
|
|
|
import (
|
|
"fmt"
|
|
"time"
|
|
|
|
"github.com/Nanqipro/YunQue-Tech-Projects/ai_english_learning/serve/internal/models"
|
|
"gorm.io/gorm"
|
|
)
|
|
|
|
// NotificationService 通知服务
|
|
type NotificationService struct {
|
|
db *gorm.DB
|
|
}
|
|
|
|
// NewNotificationService 创建通知服务实例
|
|
func NewNotificationService(db *gorm.DB) *NotificationService {
|
|
return &NotificationService{db: db}
|
|
}
|
|
|
|
// GetUserNotifications 获取用户通知列表
|
|
func (s *NotificationService) GetUserNotifications(userID int64, page, limit int, onlyUnread bool) ([]models.Notification, int64, error) {
|
|
var notifications []models.Notification
|
|
var total int64
|
|
|
|
query := s.db.Model(&models.Notification{}).Where("user_id = ?", userID)
|
|
|
|
// 只查询未读通知
|
|
if onlyUnread {
|
|
query = query.Where("is_read = ?", false)
|
|
}
|
|
|
|
// 获取总数
|
|
if err := query.Count(&total).Error; err != nil {
|
|
return nil, 0, fmt.Errorf("统计通知数量失败: %w", err)
|
|
}
|
|
|
|
// 分页查询
|
|
offset := (page - 1) * limit
|
|
if err := query.Order("priority DESC, created_at DESC").
|
|
Offset(offset).
|
|
Limit(limit).
|
|
Find(¬ifications).Error; err != nil {
|
|
return nil, 0, fmt.Errorf("查询通知列表失败: %w", err)
|
|
}
|
|
|
|
return notifications, total, nil
|
|
}
|
|
|
|
// GetUnreadCount 获取未读通知数量
|
|
func (s *NotificationService) GetUnreadCount(userID int64) (int64, error) {
|
|
var count int64
|
|
if err := s.db.Model(&models.Notification{}).
|
|
Where("user_id = ? AND is_read = ?", userID, false).
|
|
Count(&count).Error; err != nil {
|
|
return 0, fmt.Errorf("统计未读通知失败: %w", err)
|
|
}
|
|
return count, nil
|
|
}
|
|
|
|
// MarkAsRead 标记通知为已读
|
|
func (s *NotificationService) MarkAsRead(userID, notificationID int64) error {
|
|
now := time.Now()
|
|
result := s.db.Model(&models.Notification{}).
|
|
Where("id = ? AND user_id = ?", notificationID, userID).
|
|
Updates(map[string]interface{}{
|
|
"is_read": true,
|
|
"read_at": now,
|
|
})
|
|
|
|
if result.Error != nil {
|
|
return fmt.Errorf("标记通知已读失败: %w", result.Error)
|
|
}
|
|
|
|
if result.RowsAffected == 0 {
|
|
return fmt.Errorf("通知不存在或无权限")
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// MarkAllAsRead 标记所有通知为已读
|
|
func (s *NotificationService) MarkAllAsRead(userID int64) error {
|
|
now := time.Now()
|
|
result := s.db.Model(&models.Notification{}).
|
|
Where("user_id = ? AND is_read = ?", userID, false).
|
|
Updates(map[string]interface{}{
|
|
"is_read": true,
|
|
"read_at": now,
|
|
})
|
|
|
|
if result.Error != nil {
|
|
return fmt.Errorf("标记所有通知已读失败: %w", result.Error)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// DeleteNotification 删除通知
|
|
func (s *NotificationService) DeleteNotification(userID, notificationID int64) error {
|
|
result := s.db.Where("id = ? AND user_id = ?", notificationID, userID).
|
|
Delete(&models.Notification{})
|
|
|
|
if result.Error != nil {
|
|
return fmt.Errorf("删除通知失败: %w", result.Error)
|
|
}
|
|
|
|
if result.RowsAffected == 0 {
|
|
return fmt.Errorf("通知不存在或无权限")
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// CreateNotification 创建通知(内部使用)
|
|
func (s *NotificationService) CreateNotification(notification *models.Notification) error {
|
|
if err := s.db.Create(notification).Error; err != nil {
|
|
return fmt.Errorf("创建通知失败: %w", err)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// SendSystemNotification 发送系统通知
|
|
func (s *NotificationService) SendSystemNotification(userID int64, title, content string, link *string, priority int) error {
|
|
notification := &models.Notification{
|
|
UserID: userID,
|
|
Type: models.NotificationTypeSystem,
|
|
Title: title,
|
|
Content: content,
|
|
Link: link,
|
|
Priority: priority,
|
|
IsRead: false,
|
|
}
|
|
return s.CreateNotification(notification)
|
|
}
|
|
|
|
// SendLearningReminder 发送学习提醒
|
|
func (s *NotificationService) SendLearningReminder(userID int64, title, content string, link *string) error {
|
|
notification := &models.Notification{
|
|
UserID: userID,
|
|
Type: models.NotificationTypeLearning,
|
|
Title: title,
|
|
Content: content,
|
|
Link: link,
|
|
Priority: models.NotificationPriorityNormal,
|
|
IsRead: false,
|
|
}
|
|
return s.CreateNotification(notification)
|
|
}
|
|
|
|
// SendAchievementNotification 发送成就通知
|
|
func (s *NotificationService) SendAchievementNotification(userID int64, title, content string, link *string) error {
|
|
notification := &models.Notification{
|
|
UserID: userID,
|
|
Type: models.NotificationTypeAchievement,
|
|
Title: title,
|
|
Content: content,
|
|
Link: link,
|
|
Priority: models.NotificationPriorityImportant,
|
|
IsRead: false,
|
|
}
|
|
return s.CreateNotification(notification)
|
|
}
|