Files
server/app/http/controllers/admin/notification_controller.go
2026-01-16 15:49:34 +08:00

178 lines
5.0 KiB
Go

package admin
import (
"github.com/goravel/framework/contracts/http"
"github.com/spf13/cast"
apperrors "goravel/app/errors"
"goravel/app/http/helpers"
"goravel/app/http/response"
"goravel/app/models"
"goravel/app/services"
"goravel/app/utils/logger"
)
type NotificationController struct {
service services.NotificationService
}
func NewNotificationController() *NotificationController {
return &NotificationController{
service: services.NewNotificationServiceImpl(),
}
}
func (r *NotificationController) Index(ctx http.Context) http.Response {
admin := r.currentAdmin(ctx)
if admin == nil {
return response.Error(ctx, http.StatusUnauthorized, apperrors.ErrNotLoggedIn.Code)
}
page := helpers.GetIntQuery(ctx, "page", 1)
pageSize := helpers.GetIntQuery(ctx, "page_size", 10)
notifType := ctx.Request().Query("type", "")
isRead := ctx.Request().Query("is_read", "")
notifications, total, err := r.service.List(admin.ID, page, pageSize, notifType, isRead)
if err != nil {
logger.ErrorfHTTP(ctx, "list notifications error: %v", err)
return response.Error(ctx, http.StatusInternalServerError, apperrors.ErrQueryFailed.Code)
}
count, err := r.service.UnreadCount(admin.ID)
if err != nil {
logger.ErrorfHTTP(ctx, "unread count error: %v", err)
}
return response.Success(ctx, http.Json{
"notifications": notifications,
"unread_count": count,
"pagination": http.Json{
"page": page,
"page_size": pageSize,
"total": total,
"total_page": (total + int64(pageSize) - 1) / int64(pageSize),
},
})
}
func (r *NotificationController) UnreadCount(ctx http.Context) http.Response {
admin := r.currentAdmin(ctx)
if admin == nil {
return response.Error(ctx, http.StatusUnauthorized, apperrors.ErrNotLoggedIn.Code)
}
count, err := r.service.UnreadCount(admin.ID)
if err != nil {
return response.Error(ctx, http.StatusInternalServerError, apperrors.ErrQueryFailed.Code)
}
return response.Success(ctx, http.Json{
"count": count,
})
}
func (r *NotificationController) Recent(ctx http.Context) http.Response {
admin := r.currentAdmin(ctx)
if admin == nil {
return response.Error(ctx, http.StatusUnauthorized, apperrors.ErrNotLoggedIn.Code)
}
limit := helpers.GetIntQuery(ctx, "limit", 5)
notifications, err := r.service.ListRecent(admin.ID, limit)
if err != nil {
return response.Error(ctx, http.StatusInternalServerError, apperrors.ErrQueryFailed.Code)
}
count, _ := r.service.UnreadCount(admin.ID)
return response.Success(ctx, http.Json{
"notifications": notifications,
"unread_count": count,
})
}
func (r *NotificationController) MarkRead(ctx http.Context) http.Response {
admin := r.currentAdmin(ctx)
if admin == nil {
return response.Error(ctx, http.StatusUnauthorized, apperrors.ErrNotLoggedIn.Code)
}
id := helpers.GetUintRoute(ctx, "id")
if id == 0 {
return response.Error(ctx, http.StatusBadRequest, apperrors.ErrParamsRequired.Code)
}
if err := r.service.MarkRead(admin.ID, id); err != nil {
// 使用业务错误类型,直接提取错误码
if businessErr, ok := apperrors.GetBusinessError(err); ok {
return response.Error(ctx, http.StatusNotFound, businessErr.Code)
}
return response.Error(ctx, http.StatusInternalServerError, apperrors.ErrUpdateFailed.Code)
}
return response.Success(ctx, http.Json{
"id": id,
})
}
func (r *NotificationController) MarkAllRead(ctx http.Context) http.Response {
admin := r.currentAdmin(ctx)
if admin == nil {
return response.Error(ctx, http.StatusUnauthorized, apperrors.ErrNotLoggedIn.Code)
}
if err := r.service.MarkAllRead(admin.ID); err != nil {
return response.Error(ctx, http.StatusInternalServerError, apperrors.ErrUpdateFailed.Code)
}
return response.Success(ctx)
}
func (r *NotificationController) Store(ctx http.Context) http.Response {
admin := r.currentAdmin(ctx)
if admin == nil {
return response.Error(ctx, http.StatusUnauthorized, apperrors.ErrNotLoggedIn.Code)
}
title := ctx.Request().Input("title")
content := ctx.Request().Input("content")
notificationType := ctx.Request().Input("type", "announcement")
if title == "" || content == "" {
return response.Error(ctx, http.StatusBadRequest, apperrors.ErrParamsRequired.Code)
}
var receiverID *uint
receiverVal := ctx.Request().Input("receiver_id")
if receiverVal != "" {
id := cast.ToUint(receiverVal)
if id > 0 {
receiverID = &id
}
}
senderID := admin.ID
notification, err := r.service.Create(title, content, notificationType, &senderID, receiverID)
if err != nil {
return response.Error(ctx, http.StatusInternalServerError, apperrors.ErrCreateFailed.Code)
}
if notification == nil {
return response.Success(ctx)
}
return response.Success(ctx, http.Json{
"notification": notification,
})
}
func (r *NotificationController) currentAdmin(ctx http.Context) *models.Admin {
if adminValue := ctx.Value("admin"); adminValue != nil {
if admin, ok := adminValue.(models.Admin); ok {
return &admin
}
if adminPtr, ok := adminValue.(*models.Admin); ok {
return adminPtr
}
}
return nil
}