Files
backend/internal/service/notification_service/notification_service.go
T
2026-07-15 22:42:31 +08:00

128 lines
3.9 KiB
Go

package notification_service
import (
"strings"
"github.com/XingfenD/yoresee_doc/internal/dto"
"github.com/XingfenD/yoresee_doc/internal/model"
"github.com/XingfenD/yoresee_doc/internal/repository"
"github.com/XingfenD/yoresee_doc/internal/repository/notification_repo"
"github.com/XingfenD/yoresee_doc/internal/repository/user_repo"
"github.com/XingfenD/yoresee_doc/internal/status"
"github.com/XingfenD/yoresee_doc/internal/utils"
"github.com/sirupsen/logrus"
)
type NotificationService struct {
notificationRepo *notification_repo.NotificationRepository
userRepo *user_repo.UserRepository
}
func NewNotificationService(repos *repository.Repositories) *NotificationService {
return &NotificationService{
notificationRepo: repos.Notification,
userRepo: repos.User,
}
}
func (s *NotificationService) CreateNotifications(req *dto.CreateNotificationRequest) error {
if req == nil || len(req.ReceiverExternalIDs) == 0 {
return status.StatusParamError
}
if strings.TrimSpace(req.Type) == "" {
return status.StatusParamError
}
users, err := s.userRepo.ListByExternal(req.ReceiverExternalIDs).Exec()
if err != nil {
return status.StatusReadDBError
}
if len(users) == 0 {
return status.StatusUserNotFound
}
userIDMap := make(map[string]int64, len(users))
for _, user := range users {
userIDMap[user.ExternalID] = user.ID
}
items := make([]model.Notification, 0, len(req.ReceiverExternalIDs))
for _, externalID := range req.ReceiverExternalIDs {
id, ok := userIDMap[externalID]
if !ok {
return status.StatusUserNotFound
}
items = append(items, model.Notification{
ExternalID: utils.GenerateExternalID(utils.ExternalIDContextNotification),
ReceiverID: id,
Type: req.Type,
Status: "unread",
Title: req.Title,
Content: req.Content,
Payload: req.PayloadJSON,
})
}
if err := s.notificationRepo.CreateBatch(items).Exec(); err != nil {
return status.StatusWriteDBError
}
return nil
}
func (s *NotificationService) ListNotifications(req *dto.ListNotificationsRequest) ([]model.Notification, int64, error) {
if req == nil || strings.TrimSpace(req.UserExternalID) == "" {
return nil, 0, status.StatusParamError
}
userID, err := s.userRepo.GetIDByExternalID(req.UserExternalID).Exec()
if err != nil {
return nil, 0, status.StatusUserNotFound
}
list, total, err := s.notificationRepo.List(userID).
WithStatus(req.Status).
WithPagination(req.Pagination.Page, req.Pagination.PageSize).
ExecWithTotal()
if err != nil {
logrus.Errorf("[Service layer: NotificationService] list notifications failed, user_external_id=%s, err=%+v", req.UserExternalID, err)
return nil, 0, status.GenErrWithCustomMsg(status.StatusReadDBError, "list notifications failed")
}
for i := range list {
if strings.TrimSpace(list[i].ExternalID) == "" {
externalID := utils.GenerateExternalID(utils.ExternalIDContextNotification)
list[i].ExternalID = externalID
_ = s.notificationRepo.UpdateExternalID(list[i].ID, externalID).Exec()
}
}
return list, total, nil
}
func (s *NotificationService) MarkRead(req *dto.MarkNotificationsReadRequest) error {
if req == nil || strings.TrimSpace(req.UserExternalID) == "" {
return status.StatusParamError
}
userID, err := s.userRepo.GetIDByExternalID(req.UserExternalID).Exec()
if err != nil {
return status.StatusUserNotFound
}
if err := s.notificationRepo.MarkRead(userID, req.ExternalIDs).Exec(); err != nil {
return status.StatusWriteDBError
}
return nil
}
func (s *NotificationService) MarkAllRead(userExternalID string) error {
if strings.TrimSpace(userExternalID) == "" {
return status.StatusParamError
}
userID, err := s.userRepo.GetIDByExternalID(userExternalID).Exec()
if err != nil {
return status.StatusUserNotFound
}
if err := s.notificationRepo.MarkAllRead(userID).Exec(); err != nil {
return status.StatusWriteDBError
}
return nil
}
var NotificationSvc *NotificationService