mengstack-api/internal/modules/notification/application/service.go
MengStack Dev cb7ad4d35d feat(notification): M6 示例模块 + 单元测试
Complete 4-layer notification module as reference template:
domain → infrastructure → application → interfaces.
10 unit tests covering all service methods with mock repository.
2026-10-03 01:07:10 +08:00

83 lines
2.1 KiB
Go

package application
import (
"context"
"errors"
"mengstack/internal/modules/notification/domain"
"gorm.io/gorm"
)
type Service struct {
repo domain.NotificationRepository
}
func NewService(repo domain.NotificationRepository) *Service {
return &Service{repo: repo}
}
func (s *Service) Create(ctx context.Context, tenantID string, req *domain.CreateNotificationRequest) (*domain.NotificationDTO, error) {
n := &domain.Notification{
TenantID: tenantID,
UserID: req.UserID,
Title: req.Title,
Content: req.Content,
Type: req.Type,
}
if n.Type == "" {
n.Type = "info"
}
if err := s.repo.Create(ctx, n); err != nil {
return nil, err
}
dto := domain.ToNotificationDTO(n)
return &dto, nil
}
func (s *Service) Get(ctx context.Context, tenantID string, id uint) (*domain.NotificationDTO, error) {
n, err := s.repo.FindByID(ctx, tenantID, id)
if err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
return nil, nil
}
return nil, err
}
dto := domain.ToNotificationDTO(n)
return &dto, nil
}
func (s *Service) ListByUser(ctx context.Context, tenantID string, userID uint, page, pageSize int) ([]domain.NotificationDTO, int64, error) {
if page < 1 {
page = 1
}
if pageSize < 1 || pageSize > 100 {
pageSize = 20
}
notifications, total, err := s.repo.FindByUser(ctx, tenantID, userID, page, pageSize)
if err != nil {
return nil, 0, err
}
result := make([]domain.NotificationDTO, len(notifications))
for i, n := range notifications {
result[i] = domain.ToNotificationDTO(&n)
}
return result, total, nil
}
func (s *Service) MarkAsRead(ctx context.Context, tenantID string, id uint) error {
return s.repo.MarkAsRead(ctx, tenantID, id)
}
func (s *Service) MarkAllAsRead(ctx context.Context, tenantID string, userID uint) error {
return s.repo.MarkAllAsRead(ctx, tenantID, userID)
}
func (s *Service) CountUnread(ctx context.Context, tenantID string, userID uint) (int64, error) {
return s.repo.CountUnread(ctx, tenantID, userID)
}
func (s *Service) Delete(ctx context.Context, tenantID string, id uint) error {
return s.repo.Delete(ctx, tenantID, id)
}