package app import ( "math" "strconv" "github.com/go-playground/validator/v10" "github.com/gofiber/fiber/v2" "go.uber.org/zap" notificationapp "github.com/break/junhong_cmp_fiber/internal/application/notification" "github.com/break/junhong_cmp_fiber/internal/middleware" "github.com/break/junhong_cmp_fiber/internal/model/dto" notificationquery "github.com/break/junhong_cmp_fiber/internal/query/notification" "github.com/break/junhong_cmp_fiber/pkg/errors" "github.com/break/junhong_cmp_fiber/pkg/logger" "github.com/break/junhong_cmp_fiber/pkg/response" ) // ClientNotificationHandler 提供当前个人客户的简化站内通知接口。 type ClientNotificationHandler struct { query *notificationquery.Query readService *notificationapp.ReadService validate *validator.Validate } // NewClientNotificationHandler 创建个人客户站内通知 Handler。 func NewClientNotificationHandler(query *notificationquery.Query, readService *notificationapp.ReadService, validate *validator.Validate) *ClientNotificationHandler { return &ClientNotificationHandler{query: query, readService: readService, validate: validate} } // UnreadCount 查询当前个人客户的业务通知未读数。 // GET /api/c/v1/notifications/unread-count func (h *ClientNotificationHandler) UnreadCount(c *fiber.Ctx) error { customerID, ok := middleware.GetCustomerID(c) if !ok || customerID == 0 { return errors.New(errors.CodeUnauthorized) } result, err := h.query.PersonalUnreadCount(c.UserContext(), customerID) if err != nil { return err } return response.Success(c, result) } // List 查询当前个人客户的未过期业务通知列表。 // GET /api/c/v1/notifications func (h *ClientNotificationHandler) List(c *fiber.Ctx) error { var request dto.PersonalNotificationListRequest if err := c.QueryParser(&request); err != nil { logPersonalNotificationListValidationFailure(c, request, err) return errors.New(errors.CodeInvalidParam) } if h.validate != nil { if err := h.validate.Struct(request); err != nil { logPersonalNotificationListValidationFailure(c, request, err) return errors.New(errors.CodeInvalidParam) } } customerID, ok := middleware.GetCustomerID(c) if !ok || customerID == 0 { return errors.New(errors.CodeUnauthorized) } result, err := h.query.PersonalList(c.UserContext(), customerID, request) if err != nil { return err } return response.SuccessWithPagination(c, result.Items, result.Total, result.Page, result.Size) } // MarkAllRead 将当前个人客户可见的全部通知幂等标记为已读。 // PUT /api/c/v1/notifications/read-all func (h *ClientNotificationHandler) MarkAllRead(c *fiber.Ctx) error { customerID, ok := middleware.GetCustomerID(c) if !ok || customerID == 0 { return errors.New(errors.CodeUnauthorized) } result, err := h.readService.MarkAllPersonalRead(c.UserContext(), customerID) if err != nil { return err } return response.Success(c, result) } // MarkRead 将当前个人客户的一条通知幂等标记为已读。 // PUT /api/c/v1/notifications/:id/read func (h *ClientNotificationHandler) MarkRead(c *fiber.Ctx) error { notificationID, err := strconv.ParseUint(c.Params("id"), 10, 64) if err != nil || notificationID == 0 || notificationID > math.MaxInt64 { return errors.New(errors.CodeInvalidParam) } customerID, ok := middleware.GetCustomerID(c) if !ok || customerID == 0 { return errors.New(errors.CodeUnauthorized) } if err := h.readService.MarkPersonalRead(c.UserContext(), customerID, uint(notificationID)); err != nil { return err } return response.Success(c, dto.NotificationReadResponse{Success: true}) } func logPersonalNotificationListValidationFailure(c *fiber.Ctx, request dto.PersonalNotificationListRequest, err error) { logger.GetAppLogger().Warn("个人客户站内通知列表参数验证失败", zap.String("method", c.Method()), zap.String("path", c.Path()), zap.Int("page", request.Page), zap.Int("page_size", request.PageSize), zap.Error(err), ) }