Some checks failed
CI / Build & Test (push) Failing after 33s
- 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 编译错误
205 lines
6.3 KiB
Go
205 lines
6.3 KiB
Go
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"})
|
||
}
|