mengstack-api/internal/modules/notification/interfaces/handler.go
MengStack Dev 9148d2f6da
Some checks failed
CI / Build & Test (push) Failing after 33s
feat: Swagger 全量注解 + M8 质量加固
- 37 个端点全部添加 godoc Swagger 注解(RBAC 11 / Org 5 / Audit 1 / Settings 7 / Notification 7)
- 重新生成 docs/(swagger.json/yaml/docs.go)
- M8 质量横切:IP 限流、安全头、Body 限制、结构化日志增强、优雅关闭
- 新增 Dockerfile 多阶段构建 + .dockerignore
- 新增 testutil 测试工具包
- 修复 testutil.go 编译错误
2026-10-03 01:57:39 +08:00

205 lines
6.3 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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"})
}