package interfaces import ( "net/http" "strconv" "mengstack/internal/kernel/response" "mengstack/internal/modules/notification/application" "mengstack/internal/modules/notification/domain" "github.com/gin-gonic/gin" ) type Handler struct { svc *application.Service } func NewHandler(svc *application.Service) *Handler { return &Handler{svc: svc} } // Create godoc // @Summary 创建通知 // @Description 向指定用户发送通知 // @Tags Notification // @Accept json // @Produce json // @Param request body domain.CreateNotificationRequest true "通知内容" // @Success 200 {object} response.Response{data=domain.NotificationDTO} // @Failure 400 {object} response.Response // @Security Bearer // @Security TenantID // @Router /api/v1/notifications [post] func (h *Handler) Create(c *gin.Context) { var req domain.CreateNotificationRequest if err := c.ShouldBindJSON(&req); err != nil { response.Fail(c, response.NewBadRequest("invalid request: "+err.Error())) return } tenantID := c.GetString("tenant_id") n, err := h.svc.Create(c.Request.Context(), tenantID, &req) if err != nil { response.HandleError(c, err) return } response.Success(c, n) } // Get godoc // @Summary 获取通知详情 // @Description 根据 ID 获取指定通知的详细信息 // @Tags Notification // @Produce json // @Param id path int true "通知 ID" // @Success 200 {object} response.Response{data=domain.NotificationDTO} // @Failure 400 {object} response.Response // @Failure 404 {object} response.Response // @Security Bearer // @Security TenantID // @Router /api/v1/notifications/{id} [get] func (h *Handler) Get(c *gin.Context) { id, err := strconv.ParseUint(c.Param("id"), 10, 64) if err != nil { response.Fail(c, response.NewBadRequest("invalid id")) return } tenantID := c.GetString("tenant_id") n, err := h.svc.Get(c.Request.Context(), tenantID, uint(id)) if err != nil { response.HandleError(c, err) return } if n == nil { response.Fail(c, response.NewBadRequest("notification not found")) return } response.Success(c, n) } // ListByUser godoc // @Summary 获取用户通知列表 // @Description 分页获取指定用户的通知列表 // @Tags Notification // @Produce json // @Param userId path int true "用户 ID" // @Param page query int false "页码(默认 1)" // @Param page_size query int false "每页条数(默认 20)" // @Success 200 {object} response.Response // @Failure 400 {object} response.Response // @Failure 500 {object} response.Response // @Security Bearer // @Security TenantID // @Router /api/v1/notifications/user/{userId} [get] func (h *Handler) ListByUser(c *gin.Context) { userID, err := strconv.ParseUint(c.Param("userId"), 10, 64) if err != nil { response.Fail(c, response.NewBadRequest("invalid user_id")) return } page, _ := strconv.Atoi(c.DefaultQuery("page", "1")) pageSize, _ := strconv.Atoi(c.DefaultQuery("page_size", "20")) tenantID := c.GetString("tenant_id") notifications, total, err := h.svc.ListByUser(c.Request.Context(), tenantID, uint(userID), page, pageSize) if err != nil { response.HandleError(c, err) return } response.Success(c, gin.H{ "items": notifications, "total": total, "page": page, }) } // MarkAsRead godoc // @Summary 标记通知已读 // @Description 将指定通知标记为已读 // @Tags Notification // @Param id path int true "通知 ID" // @Success 200 {object} response.Response // @Failure 400 {object} response.Response // @Failure 404 {object} response.Response // @Security Bearer // @Security TenantID // @Router /api/v1/notifications/{id}/read [put] func (h *Handler) MarkAsRead(c *gin.Context) { id, err := strconv.ParseUint(c.Param("id"), 10, 64) if err != nil { response.Fail(c, response.NewBadRequest("invalid id")) return } tenantID := c.GetString("tenant_id") if err := h.svc.MarkAsRead(c.Request.Context(), tenantID, uint(id)); err != nil { response.HandleError(c, err) return } response.Success(c, nil) } // MarkAllAsRead godoc // @Summary 全部标记已读 // @Description 将当前用户的所有通知标记为已读 // @Tags Notification // @Produce json // @Success 200 {object} response.Response // @Failure 500 {object} response.Response // @Security Bearer // @Security TenantID // @Router /api/v1/notifications/read-all [put] func (h *Handler) MarkAllAsRead(c *gin.Context) { userID := c.GetUint("user_id") tenantID := c.GetString("tenant_id") if err := h.svc.MarkAllAsRead(c.Request.Context(), tenantID, userID); err != nil { response.HandleError(c, err) return } response.Success(c, nil) } // CountUnread godoc // @Summary 获取未读通知数 // @Description 获取当前用户的未读通知数量 // @Tags Notification // @Produce json // @Success 200 {object} response.Response // @Failure 500 {object} response.Response // @Security Bearer // @Security TenantID // @Router /api/v1/notifications/unread-count [get] func (h *Handler) CountUnread(c *gin.Context) { userID := c.GetUint("user_id") tenantID := c.GetString("tenant_id") count, err := h.svc.CountUnread(c.Request.Context(), tenantID, userID) if err != nil { response.HandleError(c, err) return } response.Success(c, gin.H{"count": count}) } // Delete godoc // @Summary 删除通知 // @Description 删除指定通知 // @Tags Notification // @Param id path int true "通知 ID" // @Success 200 {object} response.Response // @Failure 400 {object} response.Response // @Failure 404 {object} response.Response // @Security Bearer // @Security TenantID // @Router /api/v1/notifications/{id} [delete] func (h *Handler) Delete(c *gin.Context) { id, err := strconv.ParseUint(c.Param("id"), 10, 64) if err != nil { response.Fail(c, response.NewBadRequest("invalid id")) return } tenantID := c.GetString("tenant_id") if err := h.svc.Delete(c.Request.Context(), tenantID, uint(id)); err != nil { response.HandleError(c, err) return } c.JSON(http.StatusOK, gin.H{"code": 0, "message": "deleted"}) }