package handler import ( "strconv" "github.com/gin-gonic/gin" "with_you/internal/dto" "with_you/internal/pkg/cursor" "with_you/internal/pkg/response" "with_you/internal/service" ) // NotificationHandler 通知处理器 type NotificationHandler struct { notificationService *service.NotificationService } // NewNotificationHandler 创建通知处理器 func NewNotificationHandler(notificationService *service.NotificationService) *NotificationHandler { return &NotificationHandler{ notificationService: notificationService, } } // GetNotifications 获取通知列表 func (h *NotificationHandler) GetNotifications(c *gin.Context) { userID := c.GetString("user_id") if userID == "" { response.Unauthorized(c, "") return } page, _ := strconv.Atoi(c.DefaultQuery("page", "1")) pageSize, _ := strconv.Atoi(c.DefaultQuery("page_size", "20")) unreadOnly := c.Query("unread_only") == "true" notifications, total, err := h.notificationService.GetByUserID(c.Request.Context(), userID, page, pageSize, unreadOnly) if err != nil { response.InternalServerError(c, "failed to get notifications") return } response.Paginated(c, notifications, total, page, pageSize) } // MarkAsRead 标记为已读 func (h *NotificationHandler) MarkAsRead(c *gin.Context) { userID := c.GetString("user_id") if userID == "" { response.Unauthorized(c, "") return } id := c.Param("id") err := h.notificationService.MarkAsReadWithUserID(c.Request.Context(), id, userID) if err != nil { response.HandleError(c, err, "failed to mark as read") return } response.SuccessWithMessage(c, "marked as read", nil) } // MarkAllAsRead 标记所有为已读 func (h *NotificationHandler) MarkAllAsRead(c *gin.Context) { userID := c.GetString("user_id") if userID == "" { response.Unauthorized(c, "") return } err := h.notificationService.MarkAllAsRead(c.Request.Context(), userID) if err != nil { response.InternalServerError(c, "failed to mark all as read") return } response.SuccessWithMessage(c, "all marked as read", nil) } // GetUnreadCount 获取未读数量 func (h *NotificationHandler) GetUnreadCount(c *gin.Context) { userID := c.GetString("user_id") if userID == "" { response.Unauthorized(c, "") return } count, err := h.notificationService.GetUnreadCount(c.Request.Context(), userID) if err != nil { response.InternalServerError(c, "failed to get unread count") return } response.Success(c, gin.H{"count": count}) } // DeleteNotification 删除通知 func (h *NotificationHandler) DeleteNotification(c *gin.Context) { userID := c.GetString("user_id") if userID == "" { response.Unauthorized(c, "") return } id := c.Param("id") err := h.notificationService.DeleteNotification(c.Request.Context(), id, userID) if err != nil { response.HandleError(c, err, "failed to delete notification") return } response.Success(c, gin.H{"success": true}) } // ClearAllNotifications 清空所有通知 func (h *NotificationHandler) ClearAllNotifications(c *gin.Context) { userID := c.GetString("user_id") if userID == "" { response.Unauthorized(c, "") return } err := h.notificationService.ClearAllNotifications(c.Request.Context(), userID) if err != nil { response.InternalServerError(c, "failed to clear notifications") return } response.Success(c, gin.H{"success": true}) } // GetNotificationsByCursor 游标分页获取通知列表 func (h *NotificationHandler) GetNotificationsByCursor(c *gin.Context) { userID := c.GetString("user_id") if userID == "" { response.Unauthorized(c, "") return } // 解析游标分页请求 req := h.parseCursorRequest(c) unreadOnly := c.Query("unread_only") == "true" // 调用游标分页服务 result, err := h.notificationService.GetNotificationsByCursor(c.Request.Context(), userID, unreadOnly, req) if err != nil { response.InternalServerError(c, "failed to get notifications") return } // 转换为响应结构 notificationResponses := dto.ConvertNotificationsToResponse(result.Items) // 构建游标分页响应 cursorResp := &dto.NotificationCursorPageResponse{ Items: notificationResponses, NextCursor: result.NextCursor, PrevCursor: result.PrevCursor, HasMore: result.HasMore, } response.Success(c, cursorResp) } // parseCursorRequest 解析游标分页请求参数 func (h *NotificationHandler) parseCursorRequest(c *gin.Context) *cursor.PageRequest { cursorStr := c.Query("cursor") direction := cursor.Direction(c.DefaultQuery("direction", "forward")) pageSize, _ := strconv.Atoi(c.DefaultQuery("page_size", "20")) return cursor.NewPageRequest(cursorStr, direction, pageSize) }