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:
@@ -39,18 +39,6 @@ func InitializeApp() (*App, error) {
|
|||||||
systemMessageService := wire.ProvideSystemMessageService(systemNotificationRepository, pushService, userRepository, postRepository, cache)
|
systemMessageService := wire.ProvideSystemMessageService(systemNotificationRepository, pushService, userRepository, postRepository, cache)
|
||||||
emailClient := wire.ProvideEmailClient(config)
|
emailClient := wire.ProvideEmailClient(config)
|
||||||
emailService := wire.ProvideEmailService(emailClient)
|
emailService := wire.ProvideEmailService(emailClient)
|
||||||
userService := wire.ProvideUserService(userRepository, systemMessageService, emailService, cache)
|
|
||||||
userActivityRepository := wire.ProvideUserActivityRepository(db, cache)
|
|
||||||
userActivityService := wire.ProvideUserActivityService(userActivityRepository)
|
|
||||||
openaiClient := wire.ProvideOpenAIClient(config)
|
|
||||||
postAIService := wire.ProvidePostAIService(openaiClient)
|
|
||||||
transactionManager := wire.ProvideTransactionManager(db)
|
|
||||||
manager := wire.ProvideHookManager()
|
|
||||||
commentRepository := repository.NewCommentRepository(db)
|
|
||||||
moderationHooks := wire.ProvideModerationHooks(manager, postAIService, postRepository, commentRepository, config)
|
|
||||||
builtinHooks := wire.ProvideBuiltinHooks(manager)
|
|
||||||
postService := wire.ProvidePostService(postRepository, systemMessageService, postAIService, cache, transactionManager, manager, moderationHooks, builtinHooks)
|
|
||||||
commentService := wire.ProvideCommentService(commentRepository, postRepository, systemMessageService, postAIService, cache, manager)
|
|
||||||
operationLogRepository := repository.NewOperationLogRepository(db)
|
operationLogRepository := repository.NewOperationLogRepository(db)
|
||||||
loginLogRepository := repository.NewLoginLogRepository(db)
|
loginLogRepository := repository.NewLoginLogRepository(db)
|
||||||
dataChangeLogRepository := repository.NewDataChangeLogRepository(db)
|
dataChangeLogRepository := repository.NewDataChangeLogRepository(db)
|
||||||
@@ -60,10 +48,22 @@ func InitializeApp() (*App, error) {
|
|||||||
loginLogService := wire.ProvideLoginLogService(asyncLogManager, loginLogRepository)
|
loginLogService := wire.ProvideLoginLogService(asyncLogManager, loginLogRepository)
|
||||||
dataChangeLogService := wire.ProvideDataChangeLogService(asyncLogManager, dataChangeLogRepository)
|
dataChangeLogService := wire.ProvideDataChangeLogService(asyncLogManager, dataChangeLogRepository)
|
||||||
logService := wire.ProvideLogService(operationLogService, loginLogService, dataChangeLogService)
|
logService := wire.ProvideLogService(operationLogService, loginLogService, dataChangeLogService)
|
||||||
userHandler := wire.ProvideUserHandler(userService, userActivityService, postService, commentService, logService)
|
userService := wire.ProvideUserService(userRepository, systemMessageService, emailService, cache, logService)
|
||||||
|
userActivityRepository := wire.ProvideUserActivityRepository(db, cache)
|
||||||
|
userActivityService := wire.ProvideUserActivityService(userActivityRepository)
|
||||||
|
userHandler := handler.NewUserHandler(userService, userActivityService, logService)
|
||||||
|
openaiClient := wire.ProvideOpenAIClient(config)
|
||||||
|
postAIService := wire.ProvidePostAIService(openaiClient)
|
||||||
|
transactionManager := wire.ProvideTransactionManager(db)
|
||||||
|
manager := wire.ProvideHookManager()
|
||||||
|
commentRepository := repository.NewCommentRepository(db)
|
||||||
|
moderationHooks := wire.ProvideModerationHooks(manager, postAIService, postRepository, commentRepository, config)
|
||||||
|
builtinHooks := wire.ProvideBuiltinHooks(manager)
|
||||||
|
postService := wire.ProvidePostService(postRepository, systemMessageService, postAIService, cache, transactionManager, manager, moderationHooks, builtinHooks, logService)
|
||||||
channelRepository := repository.NewChannelRepository(db)
|
channelRepository := repository.NewChannelRepository(db)
|
||||||
channelService := wire.ProvideChannelService(channelRepository, cache)
|
channelService := wire.ProvideChannelService(channelRepository, cache)
|
||||||
postHandler := wire.ProvidePostHandler(postService, userService, channelService, logService)
|
postHandler := handler.NewPostHandler(postService, userService, channelService)
|
||||||
|
commentService := wire.ProvideCommentService(commentRepository, postRepository, systemMessageService, postAIService, cache, manager, logService)
|
||||||
commentHandler := handler.NewCommentHandler(commentService)
|
commentHandler := handler.NewCommentHandler(commentService)
|
||||||
s3Client, err := wire.ProvideS3Client(config)
|
s3Client, err := wire.ProvideS3Client(config)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -104,7 +104,7 @@ func InitializeApp() (*App, error) {
|
|||||||
roleHandler := handler.NewRoleHandler(roleService)
|
roleHandler := handler.NewRoleHandler(roleService)
|
||||||
adminUserService := wire.ProvideAdminUserService(userRepository)
|
adminUserService := wire.ProvideAdminUserService(userRepository)
|
||||||
adminUserHandler := handler.NewAdminUserHandler(adminUserService)
|
adminUserHandler := handler.NewAdminUserHandler(adminUserService)
|
||||||
adminPostService := wire.ProvideAdminPostService(postRepository, cache)
|
adminPostService := wire.ProvideAdminPostService(postRepository, cache, logService)
|
||||||
adminPostHandler := handler.NewAdminPostHandler(adminPostService)
|
adminPostHandler := handler.NewAdminPostHandler(adminPostService)
|
||||||
adminCommentService := wire.ProvideAdminCommentService(commentRepository, postRepository)
|
adminCommentService := wire.ProvideAdminCommentService(commentRepository, postRepository)
|
||||||
adminCommentHandler := handler.NewAdminCommentHandler(adminCommentService)
|
adminCommentHandler := handler.NewAdminCommentHandler(adminCommentService)
|
||||||
@@ -117,10 +117,10 @@ func InitializeApp() (*App, error) {
|
|||||||
qrCodeHandler := handler.NewQRCodeHandler(qrCodeLoginService)
|
qrCodeHandler := handler.NewQRCodeHandler(qrCodeLoginService)
|
||||||
materialSubjectRepository := repository.NewMaterialSubjectRepository(db)
|
materialSubjectRepository := repository.NewMaterialSubjectRepository(db)
|
||||||
materialFileRepository := repository.NewMaterialFileRepository(db)
|
materialFileRepository := repository.NewMaterialFileRepository(db)
|
||||||
callRepository := repository.NewCallRepository(db)
|
|
||||||
materialService := wire.ProvideMaterialService(materialSubjectRepository, materialFileRepository)
|
materialService := wire.ProvideMaterialService(materialSubjectRepository, materialFileRepository)
|
||||||
callService := wire.ProvideCallService(callRepository, hub, config, db)
|
|
||||||
materialHandler := handler.NewMaterialHandler(materialService)
|
materialHandler := handler.NewMaterialHandler(materialService)
|
||||||
|
callRepository := repository.NewCallRepository(db)
|
||||||
|
callService := wire.ProvideCallService(callRepository, hub, config, db)
|
||||||
callHandler := handler.NewCallHandler(callService)
|
callHandler := handler.NewCallHandler(callService)
|
||||||
wsHandler := wire.ProvideWSHandler(hub, chatService, groupService, jwtService, callService)
|
wsHandler := wire.ProvideWSHandler(hub, chatService, groupService, jwtService, callService)
|
||||||
router := ProvideRouter(userHandler, postHandler, commentHandler, messageHandler, notificationHandler, uploadHandler, jwtService, pushHandler, systemMessageHandler, groupHandler, stickerHandler, voteHandler, channelHandler, scheduleHandler, roleHandler, adminUserHandler, adminPostHandler, adminCommentHandler, adminGroupHandler, adminDashboardHandler, adminLogHandler, qrCodeHandler, materialHandler, callHandler, logService, userActivityService, casbinService, wsHandler)
|
router := ProvideRouter(userHandler, postHandler, commentHandler, messageHandler, notificationHandler, uploadHandler, jwtService, pushHandler, systemMessageHandler, groupHandler, stickerHandler, voteHandler, channelHandler, scheduleHandler, roleHandler, adminUserHandler, adminPostHandler, adminCommentHandler, adminGroupHandler, adminDashboardHandler, adminLogHandler, qrCodeHandler, materialHandler, callHandler, logService, userActivityService, casbinService, wsHandler)
|
||||||
|
|||||||
2
go.sum
2
go.sum
@@ -115,6 +115,8 @@ github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX
|
|||||||
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||||
github.com/google/pprof v0.0.0-20250317173921-a4b03ec1a45e h1:ijClszYn+mADRFY17kjQEVQ1XRhq2/JR1M3sGqeJoxs=
|
github.com/google/pprof v0.0.0-20250317173921-a4b03ec1a45e h1:ijClszYn+mADRFY17kjQEVQ1XRhq2/JR1M3sGqeJoxs=
|
||||||
github.com/google/pprof v0.0.0-20250317173921-a4b03ec1a45e/go.mod h1:boTsfXsheKC2y+lKOCMpSfarhxDeIzfZG1jqGcPl3cA=
|
github.com/google/pprof v0.0.0-20250317173921-a4b03ec1a45e/go.mod h1:boTsfXsheKC2y+lKOCMpSfarhxDeIzfZG1jqGcPl3cA=
|
||||||
|
github.com/google/subcommands v1.2.0 h1:vWQspBTo2nEqTUFita5/KeEWlUL8kQObDFbub/EN9oE=
|
||||||
|
github.com/google/subcommands v1.2.0/go.mod h1:ZjhPrFU+Olkh9WazFPsl27BQ4UPiG37m3yTrtFlrHVk=
|
||||||
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||||
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
|
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
|
||||||
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||||
|
|||||||
@@ -139,54 +139,54 @@ type PostImageResponse struct {
|
|||||||
|
|
||||||
// PostResponse 帖子响应(列表用)
|
// PostResponse 帖子响应(列表用)
|
||||||
type PostResponse struct {
|
type PostResponse struct {
|
||||||
ID string `json:"id"`
|
ID string `json:"id"`
|
||||||
UserID string `json:"user_id"`
|
UserID string `json:"user_id"`
|
||||||
ChannelID *string `json:"channel_id,omitempty"`
|
ChannelID *string `json:"channel_id,omitempty"`
|
||||||
Title string `json:"title"`
|
Title string `json:"title"`
|
||||||
Content string `json:"content"`
|
Content string `json:"content"`
|
||||||
Images []PostImageResponse `json:"images"`
|
Images []PostImageResponse `json:"images"`
|
||||||
Status string `json:"status,omitempty"`
|
Status string `json:"status,omitempty"`
|
||||||
LikesCount int `json:"likes_count"`
|
LikesCount int `json:"likes_count"`
|
||||||
CommentsCount int `json:"comments_count"`
|
CommentsCount int `json:"comments_count"`
|
||||||
FavoritesCount int `json:"favorites_count"`
|
FavoritesCount int `json:"favorites_count"`
|
||||||
SharesCount int `json:"shares_count"`
|
SharesCount int `json:"shares_count"`
|
||||||
ViewsCount int `json:"views_count"`
|
ViewsCount int `json:"views_count"`
|
||||||
IsPinned bool `json:"is_pinned"`
|
IsPinned bool `json:"is_pinned"`
|
||||||
IsLocked bool `json:"is_locked"`
|
IsLocked bool `json:"is_locked"`
|
||||||
IsVote bool `json:"is_vote"`
|
IsVote bool `json:"is_vote"`
|
||||||
CreatedAt string `json:"created_at"`
|
CreatedAt string `json:"created_at"`
|
||||||
UpdatedAt string `json:"updated_at"`
|
UpdatedAt string `json:"updated_at"`
|
||||||
ContentEditedAt string `json:"content_edited_at,omitempty"`
|
ContentEditedAt string `json:"content_edited_at,omitempty"`
|
||||||
Author *UserResponse `json:"author"`
|
Author *UserResponse `json:"author"`
|
||||||
IsLiked bool `json:"is_liked"`
|
IsLiked bool `json:"is_liked"`
|
||||||
IsFavorited bool `json:"is_favorited"`
|
IsFavorited bool `json:"is_favorited"`
|
||||||
Channel *PostChannelBrief `json:"channel,omitempty"`
|
Channel *PostChannelBrief `json:"channel,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// PostDetailResponse 帖子详情响应
|
// PostDetailResponse 帖子详情响应
|
||||||
type PostDetailResponse struct {
|
type PostDetailResponse struct {
|
||||||
ID string `json:"id"`
|
ID string `json:"id"`
|
||||||
UserID string `json:"user_id"`
|
UserID string `json:"user_id"`
|
||||||
ChannelID *string `json:"channel_id,omitempty"`
|
ChannelID *string `json:"channel_id,omitempty"`
|
||||||
Title string `json:"title"`
|
Title string `json:"title"`
|
||||||
Content string `json:"content"`
|
Content string `json:"content"`
|
||||||
Images []PostImageResponse `json:"images"`
|
Images []PostImageResponse `json:"images"`
|
||||||
Status string `json:"status"`
|
Status string `json:"status"`
|
||||||
LikesCount int `json:"likes_count"`
|
LikesCount int `json:"likes_count"`
|
||||||
CommentsCount int `json:"comments_count"`
|
CommentsCount int `json:"comments_count"`
|
||||||
FavoritesCount int `json:"favorites_count"`
|
FavoritesCount int `json:"favorites_count"`
|
||||||
SharesCount int `json:"shares_count"`
|
SharesCount int `json:"shares_count"`
|
||||||
ViewsCount int `json:"views_count"`
|
ViewsCount int `json:"views_count"`
|
||||||
IsPinned bool `json:"is_pinned"`
|
IsPinned bool `json:"is_pinned"`
|
||||||
IsLocked bool `json:"is_locked"`
|
IsLocked bool `json:"is_locked"`
|
||||||
IsVote bool `json:"is_vote"`
|
IsVote bool `json:"is_vote"`
|
||||||
CreatedAt string `json:"created_at"`
|
CreatedAt string `json:"created_at"`
|
||||||
UpdatedAt string `json:"updated_at"`
|
UpdatedAt string `json:"updated_at"`
|
||||||
ContentEditedAt string `json:"content_edited_at,omitempty"`
|
ContentEditedAt string `json:"content_edited_at,omitempty"`
|
||||||
Author *UserResponse `json:"author"`
|
Author *UserResponse `json:"author"`
|
||||||
IsLiked bool `json:"is_liked"`
|
IsLiked bool `json:"is_liked"`
|
||||||
IsFavorited bool `json:"is_favorited"`
|
IsFavorited bool `json:"is_favorited"`
|
||||||
Channel *PostChannelBrief `json:"channel,omitempty"`
|
Channel *PostChannelBrief `json:"channel,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// ==================== Comment DTOs ====================
|
// ==================== Comment DTOs ====================
|
||||||
@@ -687,13 +687,14 @@ type GroupAnnouncementListResponse struct {
|
|||||||
// WSEventResponse WebSocket事件响应结构体
|
// WSEventResponse WebSocket事件响应结构体
|
||||||
// 用于后端推送消息给前端的标准格式
|
// 用于后端推送消息给前端的标准格式
|
||||||
type WSEventResponse struct {
|
type WSEventResponse struct {
|
||||||
ID string `json:"id"` // 事件唯一ID (UUID)
|
ID string `json:"id"` // 事件唯一ID (UUID)
|
||||||
Time int64 `json:"time"` // 时间戳 (毫秒)
|
Time int64 `json:"time"` // 时间戳 (毫秒)
|
||||||
Type string `json:"type"` // 事件类型 (message, notification, system等)
|
Type string `json:"type"` // 事件类型 (message, notification, system等)
|
||||||
DetailType string `json:"detail_type"` // 详细类型 (private, group, like, comment等)
|
DetailType string `json:"detail_type"` // 详细类型 (private, group, like, comment等)
|
||||||
Seq string `json:"seq"` // 消息序列号
|
ConversationID string `json:"conversation_id"` // 会话ID
|
||||||
Segments model.MessageSegments `json:"segments"` // 消息段数组
|
Seq string `json:"seq"` // 消息序列号
|
||||||
SenderID string `json:"sender_id"` // 发送者用户ID
|
Segments model.MessageSegments `json:"segments"` // 消息段数组
|
||||||
|
SenderID string `json:"sender_id"` // 发送者用户ID
|
||||||
}
|
}
|
||||||
|
|
||||||
// ==================== WebSocket Request DTOs ====================
|
// ==================== WebSocket Request DTOs ====================
|
||||||
@@ -914,22 +915,22 @@ type WSResponse struct {
|
|||||||
|
|
||||||
// AdminPostListResponse 管理端帖子列表响应
|
// AdminPostListResponse 管理端帖子列表响应
|
||||||
type AdminPostListResponse struct {
|
type AdminPostListResponse struct {
|
||||||
ID string `json:"id"`
|
ID string `json:"id"`
|
||||||
UserID string `json:"user_id"`
|
UserID string `json:"user_id"`
|
||||||
Title string `json:"title"`
|
Title string `json:"title"`
|
||||||
Content string `json:"content"`
|
Content string `json:"content"`
|
||||||
Images []PostImageResponse `json:"images"`
|
Images []PostImageResponse `json:"images"`
|
||||||
Status string `json:"status"`
|
Status string `json:"status"`
|
||||||
LikesCount int `json:"likes_count,omitzero"`
|
LikesCount int `json:"likes_count,omitzero"`
|
||||||
CommentsCount int `json:"comments_count,omitzero"`
|
CommentsCount int `json:"comments_count,omitzero"`
|
||||||
FavoritesCount int `json:"favorites_count,omitzero"`
|
FavoritesCount int `json:"favorites_count,omitzero"`
|
||||||
ViewsCount int `json:"views_count,omitzero"`
|
ViewsCount int `json:"views_count,omitzero"`
|
||||||
IsPinned bool `json:"is_pinned"`
|
IsPinned bool `json:"is_pinned"`
|
||||||
IsFeatured bool `json:"is_featured"`
|
IsFeatured bool `json:"is_featured"`
|
||||||
IsLocked bool `json:"is_locked"`
|
IsLocked bool `json:"is_locked"`
|
||||||
RejectReason string `json:"reject_reason,omitempty"`
|
RejectReason string `json:"reject_reason,omitempty"`
|
||||||
ReviewedAt string `json:"reviewed_at,omitempty"`
|
ReviewedAt string `json:"reviewed_at,omitempty"`
|
||||||
ReviewedBy string `json:"reviewed_by,omitempty"`
|
ReviewedBy string `json:"reviewed_by,omitempty"`
|
||||||
CreatedAt string `json:"created_at"`
|
CreatedAt string `json:"created_at"`
|
||||||
UpdatedAt string `json:"updated_at"`
|
UpdatedAt string `json:"updated_at"`
|
||||||
ContentEditedAt string `json:"content_edited_at,omitempty"`
|
ContentEditedAt string `json:"content_edited_at,omitempty"`
|
||||||
@@ -938,24 +939,24 @@ type AdminPostListResponse struct {
|
|||||||
|
|
||||||
// AdminPostDetailResponse 管理端帖子详情响应
|
// AdminPostDetailResponse 管理端帖子详情响应
|
||||||
type AdminPostDetailResponse struct {
|
type AdminPostDetailResponse struct {
|
||||||
ID string `json:"id"`
|
ID string `json:"id"`
|
||||||
UserID string `json:"user_id"`
|
UserID string `json:"user_id"`
|
||||||
ChannelID *string `json:"channel_id,omitempty"`
|
ChannelID *string `json:"channel_id,omitempty"`
|
||||||
Title string `json:"title"`
|
Title string `json:"title"`
|
||||||
Content string `json:"content"`
|
Content string `json:"content"`
|
||||||
Images []PostImageResponse `json:"images"`
|
Images []PostImageResponse `json:"images"`
|
||||||
Status string `json:"status"`
|
Status string `json:"status"`
|
||||||
LikesCount int `json:"likes_count,omitzero"`
|
LikesCount int `json:"likes_count,omitzero"`
|
||||||
CommentsCount int `json:"comments_count,omitzero"`
|
CommentsCount int `json:"comments_count,omitzero"`
|
||||||
FavoritesCount int `json:"favorites_count,omitzero"`
|
FavoritesCount int `json:"favorites_count,omitzero"`
|
||||||
SharesCount int `json:"shares_count,omitzero"`
|
SharesCount int `json:"shares_count,omitzero"`
|
||||||
ViewsCount int `json:"views_count,omitzero"`
|
ViewsCount int `json:"views_count,omitzero"`
|
||||||
IsPinned bool `json:"is_pinned"`
|
IsPinned bool `json:"is_pinned"`
|
||||||
IsFeatured bool `json:"is_featured"`
|
IsFeatured bool `json:"is_featured"`
|
||||||
IsLocked bool `json:"is_locked"`
|
IsLocked bool `json:"is_locked"`
|
||||||
IsVote bool `json:"is_vote"`
|
IsVote bool `json:"is_vote"`
|
||||||
RejectReason string `json:"reject_reason,omitempty"`
|
RejectReason string `json:"reject_reason,omitempty"`
|
||||||
ReviewedAt string `json:"reviewed_at,omitempty"`
|
ReviewedAt string `json:"reviewed_at,omitempty"`
|
||||||
ReviewedBy string `json:"reviewed_by,omitempty"`
|
ReviewedBy string `json:"reviewed_by,omitempty"`
|
||||||
CreatedAt string `json:"created_at"`
|
CreatedAt string `json:"created_at"`
|
||||||
UpdatedAt string `json:"updated_at"`
|
UpdatedAt string `json:"updated_at"`
|
||||||
|
|||||||
@@ -99,6 +99,34 @@ var (
|
|||||||
ErrCannotModifyOwnRole = &AppError{Code: "CANNOT_MODIFY_OWN_ROLE", Message: "不能修改自己的角色"}
|
ErrCannotModifyOwnRole = &AppError{Code: "CANNOT_MODIFY_OWN_ROLE", Message: "不能修改自己的角色"}
|
||||||
ErrCannotModifySuperAdmin = &AppError{Code: "CANNOT_MODIFY_SUPER_ADMIN", Message: "不能修改超级管理员角色"}
|
ErrCannotModifySuperAdmin = &AppError{Code: "CANNOT_MODIFY_SUPER_ADMIN", Message: "不能修改超级管理员角色"}
|
||||||
ErrCasbinInternal = &AppError{Code: "CASBIN_INTERNAL_ERROR", Message: "权限系统内部错误"}
|
ErrCasbinInternal = &AppError{Code: "CASBIN_INTERNAL_ERROR", Message: "权限系统内部错误"}
|
||||||
|
|
||||||
|
// 通话相关错误
|
||||||
|
ErrCallNotFound = &AppError{Code: "CALL_NOT_FOUND", Message: "通话不存在"}
|
||||||
|
ErrCallNotActive = &AppError{Code: "CALL_NOT_ACTIVE", Message: "通话未激活"}
|
||||||
|
ErrCallInProgress = &AppError{Code: "CALL_IN_PROGRESS", Message: "用户之间已有通话"}
|
||||||
|
ErrNotCallParticipant = &AppError{Code: "NOT_CALL_PARTICIPANT", Message: "不是通话参与者"}
|
||||||
|
ErrInvalidCallState = &AppError{Code: "INVALID_CALL_STATE", Message: "通话状态无效"}
|
||||||
|
ErrCalleeOffline = &AppError{Code: "CALLEE_OFFLINE", Message: "对方不在线"}
|
||||||
|
ErrCallAlreadyAnswered = &AppError{Code: "CALL_ALREADY_ANSWERED", Message: "通话已在其他设备应答"}
|
||||||
|
|
||||||
|
// 消息相关错误
|
||||||
|
ErrConversationNotFound = &AppError{Code: "CONVERSATION_NOT_FOUND", Message: "会话不存在或无权限"}
|
||||||
|
ErrNotConversationMember = &AppError{Code: "NOT_CONVERSATION_MEMBER", Message: "不是会话参与者"}
|
||||||
|
ErrMessageNotFound = &AppError{Code: "MESSAGE_NOT_FOUND", Message: "消息不存在"}
|
||||||
|
ErrMessageAlreadyRecalled = &AppError{Code: "MESSAGE_ALREADY_RECALLED", Message: "消息已撤回"}
|
||||||
|
ErrMessageRecallTimeout = &AppError{Code: "MESSAGE_RECALL_TIMEOUT", Message: "消息撤回超时(2分钟)"}
|
||||||
|
ErrCannotSendMessage = &AppError{Code: "CANNOT_SEND_MESSAGE", Message: "无法发送消息"}
|
||||||
|
ErrCannotSendImage = &AppError{Code: "CANNOT_SEND_IMAGE", Message: "对方未关注你,暂不支持发送图片"}
|
||||||
|
ErrMessageLimitReached = &AppError{Code: "MESSAGE_LIMIT_REACHED", Message: "对方未关注你前,仅允许发送一条消息"}
|
||||||
|
ErrQRCodeSessionExpired = &AppError{Code: "QRCODE_SESSION_EXPIRED", Message: "二维码已过期"}
|
||||||
|
ErrQRCodeAlreadyScanned = &AppError{Code: "QRCODE_ALREADY_SCANNED", Message: "二维码已被扫描"}
|
||||||
|
ErrQRCodeInvalidStatus = &AppError{Code: "QRCODE_INVALID_STATUS", Message: "二维码状态无效"}
|
||||||
|
ErrPushNotImplemented = &AppError{Code: "PUSH_NOT_IMPLEMENTED", Message: "推送服务未实现"}
|
||||||
|
ErrPushQueueFull = &AppError{Code: "PUSH_QUEUE_FULL", Message: "推送队列已满"}
|
||||||
|
ErrUserOffline = &AppError{Code: "USER_OFFLINE", Message: "用户不在线"}
|
||||||
|
|
||||||
|
// 学习资料相关错误
|
||||||
|
ErrSubjectHasMaterials = &AppError{Code: "SUBJECT_HAS_MATERIALS", Message: "学科下存在资料,无法删除"}
|
||||||
)
|
)
|
||||||
|
|
||||||
// Wrap 包装错误
|
// Wrap 包装错误
|
||||||
|
|||||||
@@ -363,13 +363,14 @@ func (h *MessageHandler) HandleSendMessage(c *gin.Context) {
|
|||||||
|
|
||||||
// 构建 WSEventResponse 格式响应
|
// 构建 WSEventResponse 格式响应
|
||||||
wsResponse := dto.WSEventResponse{
|
wsResponse := dto.WSEventResponse{
|
||||||
ID: msg.ID,
|
ID: msg.ID,
|
||||||
Time: msg.CreatedAt.UnixMilli(),
|
Time: msg.CreatedAt.UnixMilli(),
|
||||||
Type: "message",
|
Type: "message",
|
||||||
DetailType: params.DetailType,
|
DetailType: params.DetailType,
|
||||||
Seq: strconv.FormatInt(msg.Seq, 10),
|
ConversationID: conversationID,
|
||||||
Segments: params.Segments,
|
Seq: strconv.FormatInt(msg.Seq, 10),
|
||||||
SenderID: userID,
|
Segments: params.Segments,
|
||||||
|
SenderID: userID,
|
||||||
}
|
}
|
||||||
|
|
||||||
response.Success(c, wsResponse)
|
response.Success(c, wsResponse)
|
||||||
|
|||||||
@@ -39,10 +39,11 @@ type UserHandler struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// NewUserHandler 创建用户处理器
|
// NewUserHandler 创建用户处理器
|
||||||
func NewUserHandler(userService service.UserService, activityService service.UserActivityService) *UserHandler {
|
func NewUserHandler(userService service.UserService, activityService service.UserActivityService, logService *service.LogService) *UserHandler {
|
||||||
return &UserHandler{
|
return &UserHandler{
|
||||||
userService: userService,
|
userService: userService,
|
||||||
activityService: activityService,
|
activityService: activityService,
|
||||||
|
logService: logService,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -56,11 +57,6 @@ func (h *UserHandler) SetActivityService(activityService service.UserActivitySer
|
|||||||
h.activityService = activityService
|
h.activityService = activityService
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetLogService 设置日志服务
|
|
||||||
func (h *UserHandler) SetLogService(logService *service.LogService) {
|
|
||||||
h.logService = logService
|
|
||||||
}
|
|
||||||
|
|
||||||
// generateTokenID 生成Token ID
|
// generateTokenID 生成Token ID
|
||||||
func generateTokenID(token string) string {
|
func generateTokenID(token string) string {
|
||||||
h := sha256.New()
|
h := sha256.New()
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ import (
|
|||||||
"go.uber.org/zap"
|
"go.uber.org/zap"
|
||||||
|
|
||||||
"carrot_bbs/internal/dto"
|
"carrot_bbs/internal/dto"
|
||||||
|
apperrors "carrot_bbs/internal/errors"
|
||||||
"carrot_bbs/internal/model"
|
"carrot_bbs/internal/model"
|
||||||
"carrot_bbs/internal/pkg/response"
|
"carrot_bbs/internal/pkg/response"
|
||||||
"carrot_bbs/internal/pkg/ws"
|
"carrot_bbs/internal/pkg/ws"
|
||||||
@@ -338,13 +339,14 @@ func (h *WSHandler) handleChat(ctx context.Context, client *ws.Client, payload j
|
|||||||
}
|
}
|
||||||
|
|
||||||
resp := dto.WSEventResponse{
|
resp := dto.WSEventResponse{
|
||||||
ID: message.ID,
|
ID: message.ID,
|
||||||
Time: message.CreatedAt.UnixMilli(),
|
Time: message.CreatedAt.UnixMilli(),
|
||||||
Type: "message",
|
Type: "message",
|
||||||
DetailType: detailType,
|
DetailType: detailType,
|
||||||
Seq: strconv.FormatInt(message.Seq, 10),
|
ConversationID: req.ConversationID,
|
||||||
Segments: req.Segments,
|
Seq: strconv.FormatInt(message.Seq, 10),
|
||||||
SenderID: client.UserID,
|
Segments: req.Segments,
|
||||||
|
SenderID: client.UserID,
|
||||||
}
|
}
|
||||||
|
|
||||||
msg := ws.ResponseMessage{
|
msg := ws.ResponseMessage{
|
||||||
@@ -474,7 +476,7 @@ func (h *WSHandler) handleCallInvite(ctx context.Context, client *ws.Client, pay
|
|||||||
zap.String("callee_id", req.CalleeID),
|
zap.String("callee_id", req.CalleeID),
|
||||||
zap.Error(err),
|
zap.Error(err),
|
||||||
)
|
)
|
||||||
if errors.Is(err, service.ErrCallInProgress) {
|
if errors.Is(err, apperrors.ErrCallInProgress) {
|
||||||
h.wsHub.SendError(client, "call_in_progress", err.Error())
|
h.wsHub.SendError(client, "call_in_progress", err.Error())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -514,7 +516,7 @@ func (h *WSHandler) handleCallAnswer(ctx context.Context, client *ws.Client, pay
|
|||||||
call, err := h.callService.Accept(ctx, req.CallID, client.UserID)
|
call, err := h.callService.Accept(ctx, req.CallID, client.UserID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// === 区分已接听错误 ===
|
// === 区分已接听错误 ===
|
||||||
if errors.Is(err, service.ErrCallAlreadyAnswered) {
|
if errors.Is(err, apperrors.ErrCallAlreadyAnswered) {
|
||||||
h.wsHub.SendError(client, "call_already_answered", "通话已被其他设备接听")
|
h.wsHub.SendError(client, "call_already_answered", "通话已被其他设备接听")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,9 +27,6 @@ type AdminPostService interface {
|
|||||||
SetPostPin(ctx context.Context, postID string, isPinned bool) (*dto.AdminPostDetailResponse, error)
|
SetPostPin(ctx context.Context, postID string, isPinned bool) (*dto.AdminPostDetailResponse, error)
|
||||||
// SetPostFeature 加精/取消加精帖子
|
// SetPostFeature 加精/取消加精帖子
|
||||||
SetPostFeature(ctx context.Context, postID string, isFeatured bool) (*dto.AdminPostDetailResponse, error)
|
SetPostFeature(ctx context.Context, postID string, isFeatured bool) (*dto.AdminPostDetailResponse, error)
|
||||||
|
|
||||||
// 日志服务设置
|
|
||||||
SetLogService(logService *LogService)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// adminPostServiceImpl 管理端帖子服务实现
|
// adminPostServiceImpl 管理端帖子服务实现
|
||||||
@@ -40,19 +37,14 @@ type adminPostServiceImpl struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// NewAdminPostService 创建管理端帖子服务
|
// NewAdminPostService 创建管理端帖子服务
|
||||||
func NewAdminPostService(postRepo repository.PostRepository, cacheBackend cache.Cache) AdminPostService {
|
func NewAdminPostService(postRepo repository.PostRepository, cacheBackend cache.Cache, logService *LogService) AdminPostService {
|
||||||
return &adminPostServiceImpl{
|
return &adminPostServiceImpl{
|
||||||
postRepo: postRepo,
|
postRepo: postRepo,
|
||||||
cache: cacheBackend,
|
cache: cacheBackend,
|
||||||
logService: nil,
|
logService: logService,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetLogService 设置日志服务
|
|
||||||
func (s *adminPostServiceImpl) SetLogService(logService *LogService) {
|
|
||||||
s.logService = logService
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetPostList 获取帖子列表
|
// GetPostList 获取帖子列表
|
||||||
func (s *adminPostServiceImpl) GetPostList(ctx context.Context, page, pageSize int, keyword, status, authorID, startDate, endDate string) ([]dto.AdminPostListResponse, int64, error) {
|
func (s *adminPostServiceImpl) GetPostList(ctx context.Context, page, pageSize int, keyword, status, authorID, startDate, endDate string) ([]dto.AdminPostListResponse, int64, error) {
|
||||||
query := repository.AdminPostListQuery{
|
query := repository.AdminPostListQuery{
|
||||||
|
|||||||
@@ -3,11 +3,11 @@ package service
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"errors"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"carrot_bbs/internal/config"
|
"carrot_bbs/internal/config"
|
||||||
|
apperrors "carrot_bbs/internal/errors"
|
||||||
"carrot_bbs/internal/model"
|
"carrot_bbs/internal/model"
|
||||||
"carrot_bbs/internal/pkg/ws"
|
"carrot_bbs/internal/pkg/ws"
|
||||||
"carrot_bbs/internal/repository"
|
"carrot_bbs/internal/repository"
|
||||||
@@ -16,16 +16,6 @@ import (
|
|||||||
"gorm.io/gorm"
|
"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 (
|
const (
|
||||||
CallLifetimeMs = 60000 // 通话邀请有效期 60秒 (参考 Matrix)
|
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) {
|
func (s *callService) Invite(ctx context.Context, callerID, calleeID, conversationID, mediaType string) (*model.CallSession, bool, error) {
|
||||||
active, err := s.callRepo.GetActiveCallByConversationID(conversationID)
|
active, err := s.callRepo.GetActiveCallByConversationID(conversationID)
|
||||||
if err == nil && active != nil {
|
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()
|
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) {
|
func (s *callService) Accept(ctx context.Context, callID, userID string) (*model.CallSession, error) {
|
||||||
call, err := s.callRepo.GetCallByIDWithParticipants(callID)
|
call, err := s.callRepo.GetCallByIDWithParticipants(callID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("%w: %v", ErrCallNotFound, err)
|
return nil, apperrors.Wrap(err, apperrors.ErrCallNotFound)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 检查用户是否是参与者
|
// 检查用户是否是参与者
|
||||||
if !isParticipant(call, userID) {
|
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 {
|
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 {
|
func (s *callService) Reject(ctx context.Context, callID, userID string) error {
|
||||||
call, err := s.callRepo.GetCallByIDWithParticipants(callID)
|
call, err := s.callRepo.GetCallByIDWithParticipants(callID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("%w: %v", ErrCallNotFound, err)
|
return apperrors.Wrap(err, apperrors.ErrCallNotFound)
|
||||||
}
|
}
|
||||||
if call.Status != model.CallStatusCalling {
|
if call.Status != model.CallStatusCalling {
|
||||||
return ErrInvalidCallState
|
return apperrors.ErrInvalidCallState
|
||||||
}
|
}
|
||||||
if !isParticipant(call, userID) {
|
if !isParticipant(call, userID) {
|
||||||
return ErrNotParticipant
|
return apperrors.ErrNotCallParticipant
|
||||||
}
|
}
|
||||||
|
|
||||||
now := time.Now()
|
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 {
|
func (s *callService) Busy(ctx context.Context, callID, userID string) error {
|
||||||
call, err := s.callRepo.GetCallByIDWithParticipants(callID)
|
call, err := s.callRepo.GetCallByIDWithParticipants(callID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("%w: %v", ErrCallNotFound, err)
|
return apperrors.Wrap(err, apperrors.ErrCallNotFound)
|
||||||
}
|
}
|
||||||
if call.Status != model.CallStatusCalling {
|
if call.Status != model.CallStatusCalling {
|
||||||
return ErrInvalidCallState
|
return apperrors.ErrInvalidCallState
|
||||||
}
|
}
|
||||||
if !isParticipant(call, userID) {
|
if !isParticipant(call, userID) {
|
||||||
return ErrNotParticipant
|
return apperrors.ErrNotCallParticipant
|
||||||
}
|
}
|
||||||
|
|
||||||
now := time.Now()
|
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) {
|
func (s *callService) End(ctx context.Context, callID, userID string, reason string) (*model.CallSession, error) {
|
||||||
call, err := s.callRepo.GetCallByIDWithParticipants(callID)
|
call, err := s.callRepo.GetCallByIDWithParticipants(callID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("%w: %v", ErrCallNotFound, err)
|
return nil, apperrors.Wrap(err, apperrors.ErrCallNotFound)
|
||||||
}
|
}
|
||||||
if !call.IsActive() {
|
if !call.IsActive() {
|
||||||
return nil, ErrCallNotActive
|
return nil, apperrors.ErrCallNotActive
|
||||||
}
|
}
|
||||||
// 允许系统结束通话时 userID 为空
|
// 允许系统结束通话时 userID 为空
|
||||||
if userID != "" && !isParticipant(call, userID) {
|
if userID != "" && !isParticipant(call, userID) {
|
||||||
return nil, ErrNotParticipant
|
return nil, apperrors.ErrNotCallParticipant
|
||||||
}
|
}
|
||||||
|
|
||||||
now := time.Now()
|
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 {
|
func (s *callService) RelaySignal(ctx context.Context, callID, fromUserID string, signalType string, payload json.RawMessage) error {
|
||||||
call, err := s.callRepo.GetCallByIDWithParticipants(callID)
|
call, err := s.callRepo.GetCallByIDWithParticipants(callID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("%w: %v", ErrCallNotFound, err)
|
return apperrors.Wrap(err, apperrors.ErrCallNotFound)
|
||||||
}
|
}
|
||||||
if !call.IsActive() {
|
if !call.IsActive() {
|
||||||
return ErrCallNotActive
|
return apperrors.ErrCallNotActive
|
||||||
}
|
}
|
||||||
if !isParticipant(call, fromUserID) {
|
if !isParticipant(call, fromUserID) {
|
||||||
return ErrNotParticipant
|
return apperrors.ErrNotCallParticipant
|
||||||
}
|
}
|
||||||
|
|
||||||
participants, _ := s.callRepo.GetCallParticipants(callID)
|
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 {
|
func (s *callService) SetMuted(ctx context.Context, callID, userID string, muted bool) error {
|
||||||
call, err := s.callRepo.GetCallByIDWithParticipants(callID)
|
call, err := s.callRepo.GetCallByIDWithParticipants(callID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("%w: %v", ErrCallNotFound, err)
|
return apperrors.Wrap(err, apperrors.ErrCallNotFound)
|
||||||
}
|
}
|
||||||
if !call.IsActive() {
|
if !call.IsActive() {
|
||||||
return ErrCallNotActive
|
return apperrors.ErrCallNotActive
|
||||||
}
|
}
|
||||||
if !isParticipant(call, userID) {
|
if !isParticipant(call, userID) {
|
||||||
return ErrNotParticipant
|
return apperrors.ErrNotCallParticipant
|
||||||
}
|
}
|
||||||
|
|
||||||
participants, _ := s.callRepo.GetCallParticipants(callID)
|
participants, _ := s.callRepo.GetCallParticipants(callID)
|
||||||
|
|||||||
@@ -24,23 +24,18 @@ type CommentService struct {
|
|||||||
hookManager *hook.Manager
|
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{
|
return &CommentService{
|
||||||
commentRepo: commentRepo,
|
commentRepo: commentRepo,
|
||||||
postRepo: postRepo,
|
postRepo: postRepo,
|
||||||
systemMessageService: systemMessageService,
|
systemMessageService: systemMessageService,
|
||||||
cache: cacheBackend,
|
cache: cacheBackend,
|
||||||
postAIService: postAIService,
|
postAIService: postAIService,
|
||||||
logService: nil,
|
logService: logService,
|
||||||
hookManager: hookManager,
|
hookManager: hookManager,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetLogService 设置日志服务
|
|
||||||
func (s *CommentService) SetLogService(logService *LogService) {
|
|
||||||
s.logService = logService
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create 创建评论
|
// Create 创建评论
|
||||||
func (s *CommentService) Create(ctx context.Context, postID, userID, content string, parentID *string, images string, imageURLs []string) (*model.Comment, error) {
|
func (s *CommentService) Create(ctx context.Context, postID, userID, content string, parentID *string, images string, imageURLs []string) (*model.Comment, error) {
|
||||||
if s.postAIService != nil {
|
if s.postAIService != nil {
|
||||||
|
|||||||
@@ -67,9 +67,7 @@ type PostService interface {
|
|||||||
// RecordShare 记录分享(仅已发布帖子计数 +1),返回最新 shares_count
|
// RecordShare 记录分享(仅已发布帖子计数 +1),返回最新 shares_count
|
||||||
RecordShare(ctx context.Context, postID, userID string) (sharesCount int, err error)
|
RecordShare(ctx context.Context, postID, userID string) (sharesCount int, err error)
|
||||||
|
|
||||||
// 日志服务设置
|
}
|
||||||
SetLogService(logService *LogService)
|
|
||||||
}
|
|
||||||
|
|
||||||
// postServiceImpl 帖子服务实现
|
// postServiceImpl 帖子服务实现
|
||||||
type postServiceImpl struct {
|
type postServiceImpl struct {
|
||||||
@@ -82,23 +80,18 @@ type postServiceImpl struct {
|
|||||||
hookManager *hook.Manager
|
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{
|
return &postServiceImpl{
|
||||||
postRepo: postRepo,
|
postRepo: postRepo,
|
||||||
systemMessageService: systemMessageService,
|
systemMessageService: systemMessageService,
|
||||||
cache: cacheBackend,
|
cache: cacheBackend,
|
||||||
postAIService: postAIService,
|
postAIService: postAIService,
|
||||||
txManager: txManager,
|
txManager: txManager,
|
||||||
logService: nil,
|
logService: logService,
|
||||||
hookManager: hookManager,
|
hookManager: hookManager,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetLogService 设置日志服务
|
|
||||||
func (s *postServiceImpl) SetLogService(logService *LogService) {
|
|
||||||
s.logService = logService
|
|
||||||
}
|
|
||||||
|
|
||||||
// PostListResult 帖子列表缓存结果
|
// PostListResult 帖子列表缓存结果
|
||||||
type PostListResult struct {
|
type PostListResult struct {
|
||||||
Posts []*model.Post
|
Posts []*model.Post
|
||||||
|
|||||||
@@ -65,7 +65,7 @@ type pushServiceImpl struct {
|
|||||||
pushRepo repository.PushRecordRepository
|
pushRepo repository.PushRecordRepository
|
||||||
deviceRepo repository.DeviceTokenRepository
|
deviceRepo repository.DeviceTokenRepository
|
||||||
messageRepo repository.MessageRepository
|
messageRepo repository.MessageRepository
|
||||||
wsHub *ws.Hub
|
wsHub *ws.Hub
|
||||||
|
|
||||||
// 推送队列
|
// 推送队列
|
||||||
pushQueue chan *pushTask
|
pushQueue chan *pushTask
|
||||||
@@ -90,7 +90,7 @@ func NewPushService(
|
|||||||
pushRepo: pushRepo,
|
pushRepo: pushRepo,
|
||||||
deviceRepo: deviceRepo,
|
deviceRepo: deviceRepo,
|
||||||
messageRepo: messageRepo,
|
messageRepo: messageRepo,
|
||||||
wsHub: wsHub,
|
wsHub: wsHub,
|
||||||
pushQueue: make(chan *pushTask, PushQueueSize),
|
pushQueue: make(chan *pushTask, PushQueueSize),
|
||||||
stopChan: make(chan struct{}),
|
stopChan: make(chan struct{}),
|
||||||
}
|
}
|
||||||
@@ -190,13 +190,14 @@ func (s *pushServiceImpl) pushViaWebSocket(ctx context.Context, userID string, m
|
|||||||
segments := message.Segments
|
segments := message.Segments
|
||||||
|
|
||||||
event := &dto.WSEventResponse{
|
event := &dto.WSEventResponse{
|
||||||
ID: fmt.Sprintf("%s", message.ID),
|
ID: fmt.Sprintf("%s", message.ID),
|
||||||
Time: message.CreatedAt.UnixMilli(),
|
Time: message.CreatedAt.UnixMilli(),
|
||||||
Type: "message",
|
Type: "message",
|
||||||
DetailType: detailType,
|
DetailType: detailType,
|
||||||
Seq: fmt.Sprintf("%d", message.Seq),
|
ConversationID: message.ConversationID,
|
||||||
Segments: segments,
|
Seq: fmt.Sprintf("%d", message.Seq),
|
||||||
SenderID: message.SenderID,
|
Segments: segments,
|
||||||
|
SenderID: message.SenderID,
|
||||||
}
|
}
|
||||||
|
|
||||||
s.wsHub.PublishToUser(userID, "chat_message", map[string]interface{}{
|
s.wsHub.PublishToUser(userID, "chat_message", map[string]interface{}{
|
||||||
|
|||||||
@@ -52,9 +52,6 @@ type UserService interface {
|
|||||||
UnblockUser(ctx context.Context, blockerID, blockedID string) error
|
UnblockUser(ctx context.Context, blockerID, blockedID string) error
|
||||||
GetBlockedUsers(ctx context.Context, blockerID string, page, pageSize int) ([]*model.User, int64, error)
|
GetBlockedUsers(ctx context.Context, blockerID string, page, pageSize int) ([]*model.User, int64, error)
|
||||||
IsBlocked(ctx context.Context, blockerID, blockedID string) (bool, error)
|
IsBlocked(ctx context.Context, blockerID, blockedID string) (bool, error)
|
||||||
|
|
||||||
// 日志服务设置
|
|
||||||
SetLogService(logService *LogService)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// userServiceImpl 用户服务实现
|
// userServiceImpl 用户服务实现
|
||||||
@@ -71,20 +68,16 @@ func NewUserService(
|
|||||||
systemMessageService SystemMessageService,
|
systemMessageService SystemMessageService,
|
||||||
emailService EmailService,
|
emailService EmailService,
|
||||||
cacheBackend cache.Cache,
|
cacheBackend cache.Cache,
|
||||||
|
logService *LogService,
|
||||||
) UserService {
|
) UserService {
|
||||||
return &userServiceImpl{
|
return &userServiceImpl{
|
||||||
userRepo: userRepo,
|
userRepo: userRepo,
|
||||||
systemMessageService: systemMessageService,
|
systemMessageService: systemMessageService,
|
||||||
emailCodeService: NewEmailCodeService(emailService, cacheBackend),
|
emailCodeService: NewEmailCodeService(emailService, cacheBackend),
|
||||||
logService: nil,
|
logService: logService,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetLogService 设置日志服务
|
|
||||||
func (s *userServiceImpl) SetLogService(logService *LogService) {
|
|
||||||
s.logService = logService
|
|
||||||
}
|
|
||||||
|
|
||||||
// SendRegisterCode 发送注册验证码
|
// SendRegisterCode 发送注册验证码
|
||||||
func (s *userServiceImpl) SendRegisterCode(ctx context.Context, email, clientIP string) error {
|
func (s *userServiceImpl) SendRegisterCode(ctx context.Context, email, clientIP string) error {
|
||||||
user, err := s.userRepo.GetByEmail(email)
|
user, err := s.userRepo.GetByEmail(email)
|
||||||
|
|||||||
@@ -30,8 +30,8 @@ var HandlerSet = wire.NewSet(
|
|||||||
handler.NewCallHandler,
|
handler.NewCallHandler,
|
||||||
|
|
||||||
// 需要特殊处理的 Handler
|
// 需要特殊处理的 Handler
|
||||||
ProvideUserHandler,
|
handler.NewUserHandler,
|
||||||
ProvidePostHandler,
|
handler.NewPostHandler,
|
||||||
ProvideMessageHandler,
|
ProvideMessageHandler,
|
||||||
ProvideSystemMessageHandler,
|
ProvideSystemMessageHandler,
|
||||||
ProvideGroupHandler,
|
ProvideGroupHandler,
|
||||||
@@ -39,54 +39,6 @@ var HandlerSet = wire.NewSet(
|
|||||||
ProvideWSHandler,
|
ProvideWSHandler,
|
||||||
)
|
)
|
||||||
|
|
||||||
// ProvideUserHandler 提供用户处理器
|
|
||||||
func ProvideUserHandler(
|
|
||||||
userService service.UserService,
|
|
||||||
activityService service.UserActivityService,
|
|
||||||
postService service.PostService,
|
|
||||||
commentService *service.CommentService,
|
|
||||||
logService *service.LogService,
|
|
||||||
) *handler.UserHandler {
|
|
||||||
h := handler.NewUserHandler(userService, activityService)
|
|
||||||
h.SetLogService(logService)
|
|
||||||
|
|
||||||
// 同时设置到其他服务
|
|
||||||
if ps, ok := postService.(interface{ SetLogService(*service.LogService) }); ok {
|
|
||||||
ps.SetLogService(logService)
|
|
||||||
}
|
|
||||||
if commentService != nil {
|
|
||||||
commentService.SetLogService(logService)
|
|
||||||
}
|
|
||||||
|
|
||||||
return h
|
|
||||||
}
|
|
||||||
|
|
||||||
// ProvidePostHandler 提供帖子处理器
|
|
||||||
func ProvidePostHandler(
|
|
||||||
postService service.PostService,
|
|
||||||
userService service.UserService,
|
|
||||||
channelService service.ChannelService,
|
|
||||||
logService *service.LogService,
|
|
||||||
) *handler.PostHandler {
|
|
||||||
h := handler.NewPostHandler(postService, userService, channelService)
|
|
||||||
if ps, ok := postService.(interface{ SetLogService(*service.LogService) }); ok {
|
|
||||||
ps.SetLogService(logService)
|
|
||||||
}
|
|
||||||
return h
|
|
||||||
}
|
|
||||||
|
|
||||||
// ProvideAdminPostHandler 提供管理端帖子处理器
|
|
||||||
func ProvideAdminPostHandler(
|
|
||||||
postService service.AdminPostService,
|
|
||||||
logService *service.LogService,
|
|
||||||
) *handler.AdminPostHandler {
|
|
||||||
h := handler.NewAdminPostHandler(postService)
|
|
||||||
if ps, ok := postService.(interface{ SetLogService(*service.LogService) }); ok {
|
|
||||||
ps.SetLogService(logService)
|
|
||||||
}
|
|
||||||
return h
|
|
||||||
}
|
|
||||||
|
|
||||||
// ProvideMessageHandler 提供消息处理器
|
// ProvideMessageHandler 提供消息处理器
|
||||||
func ProvideMessageHandler(
|
func ProvideMessageHandler(
|
||||||
chatService service.ChatService,
|
chatService service.ChatService,
|
||||||
|
|||||||
@@ -115,8 +115,9 @@ func ProvidePostService(
|
|||||||
hookManager *hook.Manager,
|
hookManager *hook.Manager,
|
||||||
_ *hook.ModerationHooks,
|
_ *hook.ModerationHooks,
|
||||||
_ *hook.BuiltinHooks,
|
_ *hook.BuiltinHooks,
|
||||||
|
logService *service.LogService,
|
||||||
) service.PostService {
|
) service.PostService {
|
||||||
return service.NewPostService(postRepo, systemMessageService, postAIService, cacheBackend, txManager, hookManager)
|
return service.NewPostService(postRepo, systemMessageService, postAIService, cacheBackend, txManager, hookManager, logService)
|
||||||
}
|
}
|
||||||
|
|
||||||
func ProvideCommentService(
|
func ProvideCommentService(
|
||||||
@@ -126,8 +127,9 @@ func ProvideCommentService(
|
|||||||
postAIService *service.PostAIService,
|
postAIService *service.PostAIService,
|
||||||
cacheBackend cache.Cache,
|
cacheBackend cache.Cache,
|
||||||
hookManager *hook.Manager,
|
hookManager *hook.Manager,
|
||||||
|
logService *service.LogService,
|
||||||
) *service.CommentService {
|
) *service.CommentService {
|
||||||
return service.NewCommentService(commentRepo, postRepo, systemMessageService, postAIService, cacheBackend, hookManager)
|
return service.NewCommentService(commentRepo, postRepo, systemMessageService, postAIService, cacheBackend, hookManager, logService)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ProvideMessageService 提供消息服务
|
// ProvideMessageService 提供消息服务
|
||||||
@@ -153,8 +155,9 @@ func ProvideUserService(
|
|||||||
systemMessageService service.SystemMessageService,
|
systemMessageService service.SystemMessageService,
|
||||||
emailService service.EmailService,
|
emailService service.EmailService,
|
||||||
cacheBackend cache.Cache,
|
cacheBackend cache.Cache,
|
||||||
|
logService *service.LogService,
|
||||||
) service.UserService {
|
) service.UserService {
|
||||||
return service.NewUserService(userRepo, systemMessageService, emailService, cacheBackend)
|
return service.NewUserService(userRepo, systemMessageService, emailService, cacheBackend, logService)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ProvideStickerService 提供表情服务
|
// ProvideStickerService 提供表情服务
|
||||||
@@ -247,8 +250,8 @@ func ProvideAdminUserService(userRepo repository.UserRepository) service.AdminUs
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ProvideAdminPostService 提供管理端帖子服务
|
// ProvideAdminPostService 提供管理端帖子服务
|
||||||
func ProvideAdminPostService(postRepo repository.PostRepository, cacheBackend cache.Cache) service.AdminPostService {
|
func ProvideAdminPostService(postRepo repository.PostRepository, cacheBackend cache.Cache, logService *service.LogService) service.AdminPostService {
|
||||||
return service.NewAdminPostService(postRepo, cacheBackend)
|
return service.NewAdminPostService(postRepo, cacheBackend, logService)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ProvideAdminCommentService 提供管理端评论服务
|
// ProvideAdminCommentService 提供管理端评论服务
|
||||||
|
|||||||
Reference in New Issue
Block a user