refactor(di): migrate from setter to constructor injection for logService
- Remove SetLogService methods from user, post, comment, and admin post services - Add logService as constructor parameter to all dependent services - Centralize call-related and message error definitions in app_errors.go - Add ConversationID field to WSEventResponse for improved message tracking - Simplify wire provider functions by removing manual setter calls
This commit is contained in:
@@ -27,9 +27,6 @@ type AdminPostService interface {
|
||||
SetPostPin(ctx context.Context, postID string, isPinned bool) (*dto.AdminPostDetailResponse, error)
|
||||
// SetPostFeature 加精/取消加精帖子
|
||||
SetPostFeature(ctx context.Context, postID string, isFeatured bool) (*dto.AdminPostDetailResponse, error)
|
||||
|
||||
// 日志服务设置
|
||||
SetLogService(logService *LogService)
|
||||
}
|
||||
|
||||
// adminPostServiceImpl 管理端帖子服务实现
|
||||
@@ -40,19 +37,14 @@ type adminPostServiceImpl struct {
|
||||
}
|
||||
|
||||
// NewAdminPostService 创建管理端帖子服务
|
||||
func NewAdminPostService(postRepo repository.PostRepository, cacheBackend cache.Cache) AdminPostService {
|
||||
func NewAdminPostService(postRepo repository.PostRepository, cacheBackend cache.Cache, logService *LogService) AdminPostService {
|
||||
return &adminPostServiceImpl{
|
||||
postRepo: postRepo,
|
||||
cache: cacheBackend,
|
||||
logService: nil,
|
||||
logService: logService,
|
||||
}
|
||||
}
|
||||
|
||||
// SetLogService 设置日志服务
|
||||
func (s *adminPostServiceImpl) SetLogService(logService *LogService) {
|
||||
s.logService = logService
|
||||
}
|
||||
|
||||
// GetPostList 获取帖子列表
|
||||
func (s *adminPostServiceImpl) GetPostList(ctx context.Context, page, pageSize int, keyword, status, authorID, startDate, endDate string) ([]dto.AdminPostListResponse, int64, error) {
|
||||
query := repository.AdminPostListQuery{
|
||||
|
||||
@@ -3,11 +3,11 @@ package service
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"carrot_bbs/internal/config"
|
||||
apperrors "carrot_bbs/internal/errors"
|
||||
"carrot_bbs/internal/model"
|
||||
"carrot_bbs/internal/pkg/ws"
|
||||
"carrot_bbs/internal/repository"
|
||||
@@ -16,16 +16,6 @@ import (
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
var (
|
||||
ErrCallNotFound = errors.New("call not found")
|
||||
ErrCallNotActive = errors.New("call is not active")
|
||||
ErrCallInProgress = errors.New("call already in progress between users")
|
||||
ErrNotParticipant = errors.New("user is not a participant of this call")
|
||||
ErrInvalidCallState = errors.New("invalid call state for this operation")
|
||||
ErrCalleeOffline = errors.New("callee is offline")
|
||||
ErrCallAlreadyAnswered = errors.New("call already answered on another device")
|
||||
)
|
||||
|
||||
// 通话相关常量
|
||||
const (
|
||||
CallLifetimeMs = 60000 // 通话邀请有效期 60秒 (参考 Matrix)
|
||||
@@ -82,7 +72,7 @@ func NewCallService(
|
||||
func (s *callService) Invite(ctx context.Context, callerID, calleeID, conversationID, mediaType string) (*model.CallSession, bool, error) {
|
||||
active, err := s.callRepo.GetActiveCallByConversationID(conversationID)
|
||||
if err == nil && active != nil {
|
||||
return nil, false, fmt.Errorf("%w: call %s", ErrCallInProgress, active.ID)
|
||||
return nil, false, apperrors.Wrap(fmt.Errorf("call %s", active.ID), apperrors.ErrCallInProgress)
|
||||
}
|
||||
|
||||
now := time.Now()
|
||||
@@ -152,12 +142,12 @@ func (s *callService) Invite(ctx context.Context, callerID, calleeID, conversati
|
||||
func (s *callService) Accept(ctx context.Context, callID, userID string) (*model.CallSession, error) {
|
||||
call, err := s.callRepo.GetCallByIDWithParticipants(callID)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("%w: %v", ErrCallNotFound, err)
|
||||
return nil, apperrors.Wrap(err, apperrors.ErrCallNotFound)
|
||||
}
|
||||
|
||||
// 检查用户是否是参与者
|
||||
if !isParticipant(call, userID) {
|
||||
return nil, ErrNotParticipant
|
||||
return nil, apperrors.ErrNotCallParticipant
|
||||
}
|
||||
|
||||
// === 修改:使用乐观锁更新状态 ===
|
||||
@@ -176,7 +166,7 @@ func (s *callService) Accept(ctx context.Context, callID, userID string) (*model
|
||||
}
|
||||
if result.RowsAffected == 0 {
|
||||
// 没有更新任何行,说明通话已被其他设备接听
|
||||
return nil, ErrCallAlreadyAnswered
|
||||
return nil, apperrors.ErrCallAlreadyAnswered
|
||||
}
|
||||
|
||||
// 更新参与者状态
|
||||
@@ -213,13 +203,13 @@ func (s *callService) Accept(ctx context.Context, callID, userID string) (*model
|
||||
func (s *callService) Reject(ctx context.Context, callID, userID string) error {
|
||||
call, err := s.callRepo.GetCallByIDWithParticipants(callID)
|
||||
if err != nil {
|
||||
return fmt.Errorf("%w: %v", ErrCallNotFound, err)
|
||||
return apperrors.Wrap(err, apperrors.ErrCallNotFound)
|
||||
}
|
||||
if call.Status != model.CallStatusCalling {
|
||||
return ErrInvalidCallState
|
||||
return apperrors.ErrInvalidCallState
|
||||
}
|
||||
if !isParticipant(call, userID) {
|
||||
return ErrNotParticipant
|
||||
return apperrors.ErrNotCallParticipant
|
||||
}
|
||||
|
||||
now := time.Now()
|
||||
@@ -249,13 +239,13 @@ func (s *callService) Reject(ctx context.Context, callID, userID string) error {
|
||||
func (s *callService) Busy(ctx context.Context, callID, userID string) error {
|
||||
call, err := s.callRepo.GetCallByIDWithParticipants(callID)
|
||||
if err != nil {
|
||||
return fmt.Errorf("%w: %v", ErrCallNotFound, err)
|
||||
return apperrors.Wrap(err, apperrors.ErrCallNotFound)
|
||||
}
|
||||
if call.Status != model.CallStatusCalling {
|
||||
return ErrInvalidCallState
|
||||
return apperrors.ErrInvalidCallState
|
||||
}
|
||||
if !isParticipant(call, userID) {
|
||||
return ErrNotParticipant
|
||||
return apperrors.ErrNotCallParticipant
|
||||
}
|
||||
|
||||
now := time.Now()
|
||||
@@ -276,14 +266,14 @@ func (s *callService) Busy(ctx context.Context, callID, userID string) error {
|
||||
func (s *callService) End(ctx context.Context, callID, userID string, reason string) (*model.CallSession, error) {
|
||||
call, err := s.callRepo.GetCallByIDWithParticipants(callID)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("%w: %v", ErrCallNotFound, err)
|
||||
return nil, apperrors.Wrap(err, apperrors.ErrCallNotFound)
|
||||
}
|
||||
if !call.IsActive() {
|
||||
return nil, ErrCallNotActive
|
||||
return nil, apperrors.ErrCallNotActive
|
||||
}
|
||||
// 允许系统结束通话时 userID 为空
|
||||
if userID != "" && !isParticipant(call, userID) {
|
||||
return nil, ErrNotParticipant
|
||||
return nil, apperrors.ErrNotCallParticipant
|
||||
}
|
||||
|
||||
now := time.Now()
|
||||
@@ -337,13 +327,13 @@ func (s *callService) End(ctx context.Context, callID, userID string, reason str
|
||||
func (s *callService) RelaySignal(ctx context.Context, callID, fromUserID string, signalType string, payload json.RawMessage) error {
|
||||
call, err := s.callRepo.GetCallByIDWithParticipants(callID)
|
||||
if err != nil {
|
||||
return fmt.Errorf("%w: %v", ErrCallNotFound, err)
|
||||
return apperrors.Wrap(err, apperrors.ErrCallNotFound)
|
||||
}
|
||||
if !call.IsActive() {
|
||||
return ErrCallNotActive
|
||||
return apperrors.ErrCallNotActive
|
||||
}
|
||||
if !isParticipant(call, fromUserID) {
|
||||
return ErrNotParticipant
|
||||
return apperrors.ErrNotCallParticipant
|
||||
}
|
||||
|
||||
participants, _ := s.callRepo.GetCallParticipants(callID)
|
||||
@@ -363,13 +353,13 @@ func (s *callService) RelaySignal(ctx context.Context, callID, fromUserID string
|
||||
func (s *callService) SetMuted(ctx context.Context, callID, userID string, muted bool) error {
|
||||
call, err := s.callRepo.GetCallByIDWithParticipants(callID)
|
||||
if err != nil {
|
||||
return fmt.Errorf("%w: %v", ErrCallNotFound, err)
|
||||
return apperrors.Wrap(err, apperrors.ErrCallNotFound)
|
||||
}
|
||||
if !call.IsActive() {
|
||||
return ErrCallNotActive
|
||||
return apperrors.ErrCallNotActive
|
||||
}
|
||||
if !isParticipant(call, userID) {
|
||||
return ErrNotParticipant
|
||||
return apperrors.ErrNotCallParticipant
|
||||
}
|
||||
|
||||
participants, _ := s.callRepo.GetCallParticipants(callID)
|
||||
|
||||
@@ -24,23 +24,18 @@ type CommentService struct {
|
||||
hookManager *hook.Manager
|
||||
}
|
||||
|
||||
func NewCommentService(commentRepo repository.CommentRepository, postRepo repository.PostRepository, systemMessageService SystemMessageService, postAIService *PostAIService, cacheBackend cache.Cache, hookManager *hook.Manager) *CommentService {
|
||||
func NewCommentService(commentRepo repository.CommentRepository, postRepo repository.PostRepository, systemMessageService SystemMessageService, postAIService *PostAIService, cacheBackend cache.Cache, hookManager *hook.Manager, logService *LogService) *CommentService {
|
||||
return &CommentService{
|
||||
commentRepo: commentRepo,
|
||||
postRepo: postRepo,
|
||||
systemMessageService: systemMessageService,
|
||||
cache: cacheBackend,
|
||||
postAIService: postAIService,
|
||||
logService: nil,
|
||||
logService: logService,
|
||||
hookManager: hookManager,
|
||||
}
|
||||
}
|
||||
|
||||
// SetLogService 设置日志服务
|
||||
func (s *CommentService) SetLogService(logService *LogService) {
|
||||
s.logService = logService
|
||||
}
|
||||
|
||||
// Create 创建评论
|
||||
func (s *CommentService) Create(ctx context.Context, postID, userID, content string, parentID *string, images string, imageURLs []string) (*model.Comment, error) {
|
||||
if s.postAIService != nil {
|
||||
|
||||
@@ -67,9 +67,7 @@ type PostService interface {
|
||||
// RecordShare 记录分享(仅已发布帖子计数 +1),返回最新 shares_count
|
||||
RecordShare(ctx context.Context, postID, userID string) (sharesCount int, err error)
|
||||
|
||||
// 日志服务设置
|
||||
SetLogService(logService *LogService)
|
||||
}
|
||||
}
|
||||
|
||||
// postServiceImpl 帖子服务实现
|
||||
type postServiceImpl struct {
|
||||
@@ -82,23 +80,18 @@ type postServiceImpl struct {
|
||||
hookManager *hook.Manager
|
||||
}
|
||||
|
||||
func NewPostService(postRepo repository.PostRepository, systemMessageService SystemMessageService, postAIService *PostAIService, cacheBackend cache.Cache, txManager repository.TransactionManager, hookManager *hook.Manager) PostService {
|
||||
func NewPostService(postRepo repository.PostRepository, systemMessageService SystemMessageService, postAIService *PostAIService, cacheBackend cache.Cache, txManager repository.TransactionManager, hookManager *hook.Manager, logService *LogService) PostService {
|
||||
return &postServiceImpl{
|
||||
postRepo: postRepo,
|
||||
systemMessageService: systemMessageService,
|
||||
cache: cacheBackend,
|
||||
postAIService: postAIService,
|
||||
txManager: txManager,
|
||||
logService: nil,
|
||||
logService: logService,
|
||||
hookManager: hookManager,
|
||||
}
|
||||
}
|
||||
|
||||
// SetLogService 设置日志服务
|
||||
func (s *postServiceImpl) SetLogService(logService *LogService) {
|
||||
s.logService = logService
|
||||
}
|
||||
|
||||
// PostListResult 帖子列表缓存结果
|
||||
type PostListResult struct {
|
||||
Posts []*model.Post
|
||||
|
||||
@@ -65,7 +65,7 @@ type pushServiceImpl struct {
|
||||
pushRepo repository.PushRecordRepository
|
||||
deviceRepo repository.DeviceTokenRepository
|
||||
messageRepo repository.MessageRepository
|
||||
wsHub *ws.Hub
|
||||
wsHub *ws.Hub
|
||||
|
||||
// 推送队列
|
||||
pushQueue chan *pushTask
|
||||
@@ -90,7 +90,7 @@ func NewPushService(
|
||||
pushRepo: pushRepo,
|
||||
deviceRepo: deviceRepo,
|
||||
messageRepo: messageRepo,
|
||||
wsHub: wsHub,
|
||||
wsHub: wsHub,
|
||||
pushQueue: make(chan *pushTask, PushQueueSize),
|
||||
stopChan: make(chan struct{}),
|
||||
}
|
||||
@@ -190,13 +190,14 @@ func (s *pushServiceImpl) pushViaWebSocket(ctx context.Context, userID string, m
|
||||
segments := message.Segments
|
||||
|
||||
event := &dto.WSEventResponse{
|
||||
ID: fmt.Sprintf("%s", message.ID),
|
||||
Time: message.CreatedAt.UnixMilli(),
|
||||
Type: "message",
|
||||
DetailType: detailType,
|
||||
Seq: fmt.Sprintf("%d", message.Seq),
|
||||
Segments: segments,
|
||||
SenderID: message.SenderID,
|
||||
ID: fmt.Sprintf("%s", message.ID),
|
||||
Time: message.CreatedAt.UnixMilli(),
|
||||
Type: "message",
|
||||
DetailType: detailType,
|
||||
ConversationID: message.ConversationID,
|
||||
Seq: fmt.Sprintf("%d", message.Seq),
|
||||
Segments: segments,
|
||||
SenderID: message.SenderID,
|
||||
}
|
||||
|
||||
s.wsHub.PublishToUser(userID, "chat_message", map[string]interface{}{
|
||||
|
||||
@@ -52,9 +52,6 @@ type UserService interface {
|
||||
UnblockUser(ctx context.Context, blockerID, blockedID string) error
|
||||
GetBlockedUsers(ctx context.Context, blockerID string, page, pageSize int) ([]*model.User, int64, error)
|
||||
IsBlocked(ctx context.Context, blockerID, blockedID string) (bool, error)
|
||||
|
||||
// 日志服务设置
|
||||
SetLogService(logService *LogService)
|
||||
}
|
||||
|
||||
// userServiceImpl 用户服务实现
|
||||
@@ -71,20 +68,16 @@ func NewUserService(
|
||||
systemMessageService SystemMessageService,
|
||||
emailService EmailService,
|
||||
cacheBackend cache.Cache,
|
||||
logService *LogService,
|
||||
) UserService {
|
||||
return &userServiceImpl{
|
||||
userRepo: userRepo,
|
||||
systemMessageService: systemMessageService,
|
||||
emailCodeService: NewEmailCodeService(emailService, cacheBackend),
|
||||
logService: nil,
|
||||
logService: logService,
|
||||
}
|
||||
}
|
||||
|
||||
// SetLogService 设置日志服务
|
||||
func (s *userServiceImpl) SetLogService(logService *LogService) {
|
||||
s.logService = logService
|
||||
}
|
||||
|
||||
// SendRegisterCode 发送注册验证码
|
||||
func (s *userServiceImpl) SendRegisterCode(ctx context.Context, email, clientIP string) error {
|
||||
user, err := s.userRepo.GetByEmail(email)
|
||||
|
||||
Reference in New Issue
Block a user