refactor: update repository interfaces and improve dependency injection
- Refactored repository structures to use interfaces instead of concrete types, enhancing flexibility and testability. - Updated various repository methods to accept interfaces, allowing for better dependency management. - Modified wire generation to accommodate new repository interfaces, ensuring proper service injection throughout the application. - Enhanced handler methods to utilize DTOs for filtering and data handling, improving code clarity and maintainability.
This commit is contained in:
@@ -25,12 +25,12 @@ type AdminCommentService interface {
|
||||
|
||||
// adminCommentServiceImpl 管理端评论服务实现
|
||||
type adminCommentServiceImpl struct {
|
||||
commentRepo *repository.CommentRepository
|
||||
postRepo *repository.PostRepository
|
||||
commentRepo repository.CommentRepository
|
||||
postRepo repository.PostRepository
|
||||
}
|
||||
|
||||
// NewAdminCommentService 创建管理端评论服务
|
||||
func NewAdminCommentService(commentRepo *repository.CommentRepository, postRepo *repository.PostRepository) AdminCommentService {
|
||||
func NewAdminCommentService(commentRepo repository.CommentRepository, postRepo repository.PostRepository) AdminCommentService {
|
||||
return &adminCommentServiceImpl{
|
||||
commentRepo: commentRepo,
|
||||
postRepo: postRepo,
|
||||
|
||||
@@ -28,21 +28,21 @@ type AdminDashboardService interface {
|
||||
// adminDashboardServiceImpl 管理端仪表盘服务实现
|
||||
type adminDashboardServiceImpl struct {
|
||||
db *gorm.DB
|
||||
userRepo *repository.UserRepository
|
||||
postRepo *repository.PostRepository
|
||||
commentRepo *repository.CommentRepository
|
||||
userRepo repository.UserRepository
|
||||
postRepo repository.PostRepository
|
||||
commentRepo repository.CommentRepository
|
||||
groupRepo repository.GroupRepository
|
||||
activityRepo *repository.UserActivityRepository
|
||||
activityRepo repository.UserActivityRepository
|
||||
}
|
||||
|
||||
// NewAdminDashboardService 创建管理端仪表盘服务
|
||||
func NewAdminDashboardService(
|
||||
db *gorm.DB,
|
||||
userRepo *repository.UserRepository,
|
||||
postRepo *repository.PostRepository,
|
||||
commentRepo *repository.CommentRepository,
|
||||
userRepo repository.UserRepository,
|
||||
postRepo repository.PostRepository,
|
||||
commentRepo repository.CommentRepository,
|
||||
groupRepo repository.GroupRepository,
|
||||
activityRepo *repository.UserActivityRepository,
|
||||
activityRepo repository.UserActivityRepository,
|
||||
) AdminDashboardService {
|
||||
return &adminDashboardServiceImpl{
|
||||
db: db,
|
||||
|
||||
@@ -30,13 +30,13 @@ type AdminGroupService interface {
|
||||
// adminGroupServiceImpl 管理端群组服务实现
|
||||
type adminGroupServiceImpl struct {
|
||||
groupRepo repository.GroupRepository
|
||||
userRepo *repository.UserRepository
|
||||
userRepo repository.UserRepository
|
||||
}
|
||||
|
||||
// NewAdminGroupService 创建管理端群组服务
|
||||
func NewAdminGroupService(
|
||||
groupRepo repository.GroupRepository,
|
||||
userRepo *repository.UserRepository,
|
||||
userRepo repository.UserRepository,
|
||||
) AdminGroupService {
|
||||
return &adminGroupServiceImpl{
|
||||
groupRepo: groupRepo,
|
||||
|
||||
@@ -34,13 +34,13 @@ type AdminPostService interface {
|
||||
|
||||
// adminPostServiceImpl 管理端帖子服务实现
|
||||
type adminPostServiceImpl struct {
|
||||
postRepo *repository.PostRepository
|
||||
postRepo repository.PostRepository
|
||||
cache cache.Cache
|
||||
logService *LogService
|
||||
}
|
||||
|
||||
// NewAdminPostService 创建管理端帖子服务
|
||||
func NewAdminPostService(postRepo *repository.PostRepository, cacheBackend cache.Cache) AdminPostService {
|
||||
func NewAdminPostService(postRepo repository.PostRepository, cacheBackend cache.Cache) AdminPostService {
|
||||
return &adminPostServiceImpl{
|
||||
postRepo: postRepo,
|
||||
cache: cacheBackend,
|
||||
|
||||
@@ -20,11 +20,11 @@ type AdminUserService interface {
|
||||
|
||||
// adminUserServiceImpl 管理端用户服务实现
|
||||
type adminUserServiceImpl struct {
|
||||
userRepo *repository.UserRepository
|
||||
userRepo repository.UserRepository
|
||||
}
|
||||
|
||||
// NewAdminUserService 创建管理端用户服务
|
||||
func NewAdminUserService(userRepo *repository.UserRepository) AdminUserService {
|
||||
func NewAdminUserService(userRepo repository.UserRepository) AdminUserService {
|
||||
return &adminUserServiceImpl{
|
||||
userRepo: userRepo,
|
||||
}
|
||||
|
||||
@@ -11,7 +11,6 @@ import (
|
||||
"carrot_bbs/internal/repository"
|
||||
|
||||
"go.uber.org/zap"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
// AsyncLogConfig 异步日志配置
|
||||
@@ -31,7 +30,6 @@ type AsyncLogManager struct {
|
||||
dataChangeChan chan *model.DataChangeLog
|
||||
|
||||
cfg *AsyncLogConfig
|
||||
db *gorm.DB
|
||||
wg sync.WaitGroup
|
||||
ctx context.Context
|
||||
cancel context.CancelFunc
|
||||
@@ -42,10 +40,9 @@ type AsyncLogManager struct {
|
||||
|
||||
// NewAsyncLogManager 创建异步日志管理器
|
||||
func NewAsyncLogManager(
|
||||
db *gorm.DB,
|
||||
operationRepo *repository.OperationLogRepository,
|
||||
loginRepo *repository.LoginLogRepository,
|
||||
dataChangeRepo *repository.DataChangeLogRepository,
|
||||
operationRepo repository.OperationLogRepository,
|
||||
loginRepo repository.LoginLogRepository,
|
||||
dataChangeRepo repository.DataChangeLogRepository,
|
||||
logger *zap.Logger,
|
||||
cfg *AsyncLogConfig,
|
||||
) *AsyncLogManager {
|
||||
@@ -56,7 +53,6 @@ func NewAsyncLogManager(
|
||||
loginChan: make(chan *model.LoginLog, cfg.BufferSize),
|
||||
dataChangeChan: make(chan *model.DataChangeLog, cfg.BufferSize),
|
||||
cfg: cfg,
|
||||
db: db,
|
||||
ctx: ctx,
|
||||
cancel: cancel,
|
||||
logger: logger,
|
||||
@@ -90,9 +86,9 @@ func NewAsyncLogManager(
|
||||
// worker 处理协程
|
||||
func (m *AsyncLogManager) worker(
|
||||
id int,
|
||||
operationRepo *repository.OperationLogRepository,
|
||||
loginRepo *repository.LoginLogRepository,
|
||||
dataChangeRepo *repository.DataChangeLogRepository,
|
||||
operationRepo repository.OperationLogRepository,
|
||||
loginRepo repository.LoginLogRepository,
|
||||
dataChangeRepo repository.DataChangeLogRepository,
|
||||
) {
|
||||
opBatch := make([]*model.OperationLog, 0, m.cfg.BatchSize)
|
||||
loginBatch := make([]*model.LoginLog, 0, m.cfg.BatchSize)
|
||||
@@ -164,9 +160,9 @@ func (m *AsyncLogManager) flushBatches(
|
||||
ops []*model.OperationLog,
|
||||
logins []*model.LoginLog,
|
||||
changes []*model.DataChangeLog,
|
||||
operationRepo *repository.OperationLogRepository,
|
||||
loginRepo *repository.LoginLogRepository,
|
||||
dataChangeRepo *repository.DataChangeLogRepository,
|
||||
operationRepo repository.OperationLogRepository,
|
||||
loginRepo repository.LoginLogRepository,
|
||||
dataChangeRepo repository.DataChangeLogRepository,
|
||||
) {
|
||||
if len(ops) == 0 && len(logins) == 0 && len(changes) == 0 {
|
||||
return
|
||||
@@ -194,17 +190,17 @@ func (m *AsyncLogManager) flushBatches(
|
||||
}
|
||||
|
||||
// flushOperationLogs 刷新操作日志
|
||||
func (m *AsyncLogManager) flushOperationLogs(logs []*model.OperationLog, repo *repository.OperationLogRepository) error {
|
||||
func (m *AsyncLogManager) flushOperationLogs(logs []*model.OperationLog, repo repository.OperationLogRepository) error {
|
||||
return repo.BatchCreateOperationLogs(context.Background(), logs)
|
||||
}
|
||||
|
||||
// flushLoginLogs 刷新登录日志
|
||||
func (m *AsyncLogManager) flushLoginLogs(logs []*model.LoginLog, repo *repository.LoginLogRepository) error {
|
||||
func (m *AsyncLogManager) flushLoginLogs(logs []*model.LoginLog, repo repository.LoginLogRepository) error {
|
||||
return repo.BatchCreateLoginLogs(context.Background(), logs)
|
||||
}
|
||||
|
||||
// flushDataChangeLogs 刷新数据变更日志
|
||||
func (m *AsyncLogManager) flushDataChangeLogs(logs []*model.DataChangeLog, repo *repository.DataChangeLogRepository) error {
|
||||
func (m *AsyncLogManager) flushDataChangeLogs(logs []*model.DataChangeLog, repo repository.DataChangeLogRepository) error {
|
||||
return repo.BatchCreateDataChangeLogs(context.Background(), logs)
|
||||
}
|
||||
|
||||
|
||||
@@ -21,11 +21,11 @@ type ChannelService interface {
|
||||
}
|
||||
|
||||
type channelServiceImpl struct {
|
||||
channelRepo *repository.ChannelRepository
|
||||
channelRepo repository.ChannelRepository
|
||||
cache cache.Cache
|
||||
}
|
||||
|
||||
func NewChannelService(channelRepo *repository.ChannelRepository, c cache.Cache) ChannelService {
|
||||
func NewChannelService(channelRepo repository.ChannelRepository, c cache.Cache) ChannelService {
|
||||
return &channelServiceImpl{channelRepo: channelRepo, cache: c}
|
||||
}
|
||||
|
||||
|
||||
@@ -56,9 +56,8 @@ type ChatService interface {
|
||||
|
||||
// chatServiceImpl 聊天服务实现
|
||||
type chatServiceImpl struct {
|
||||
db *gorm.DB
|
||||
repo *repository.MessageRepository
|
||||
userRepo *repository.UserRepository
|
||||
repo repository.MessageRepository
|
||||
userRepo repository.UserRepository
|
||||
sensitive SensitiveService
|
||||
sseHub *sse.Hub
|
||||
|
||||
@@ -69,9 +68,8 @@ type chatServiceImpl struct {
|
||||
|
||||
// NewChatService 创建聊天服务
|
||||
func NewChatService(
|
||||
db *gorm.DB,
|
||||
repo *repository.MessageRepository,
|
||||
userRepo *repository.UserRepository,
|
||||
repo repository.MessageRepository,
|
||||
userRepo repository.UserRepository,
|
||||
sensitive SensitiveService,
|
||||
sseHub *sse.Hub,
|
||||
cacheBackend cache.Cache,
|
||||
@@ -90,7 +88,6 @@ func NewChatService(
|
||||
)
|
||||
|
||||
return &chatServiceImpl{
|
||||
db: db,
|
||||
repo: repo,
|
||||
userRepo: userRepo,
|
||||
sensitive: sensitive,
|
||||
@@ -538,13 +535,9 @@ func (s *chatServiceImpl) GetAllUnreadCount(ctx context.Context, userID string)
|
||||
// RecallMessage 撤回消息(2分钟内)
|
||||
func (s *chatServiceImpl) RecallMessage(ctx context.Context, messageID string, userID string) error {
|
||||
// 获取消息
|
||||
var message model.Message
|
||||
err := s.db.First(&message, "id = ?", messageID).Error
|
||||
message, err := s.repo.GetMessageByID(messageID)
|
||||
if err != nil {
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
return errors.New("message not found")
|
||||
}
|
||||
return fmt.Errorf("failed to get message: %w", err)
|
||||
return errors.New("message not found")
|
||||
}
|
||||
|
||||
// 验证是否是消息发送者
|
||||
@@ -563,10 +556,7 @@ func (s *chatServiceImpl) RecallMessage(ctx context.Context, messageID string, u
|
||||
}
|
||||
|
||||
// 更新消息状态为已撤回,并清空原始消息内容,仅保留撤回占位
|
||||
err = s.db.Model(&message).Updates(map[string]interface{}{
|
||||
"status": model.MessageStatusRecalled,
|
||||
"segments": model.MessageSegments{},
|
||||
}).Error
|
||||
err = s.repo.RecallMessage(messageID, userID)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to recall message: %w", err)
|
||||
}
|
||||
@@ -604,22 +594,15 @@ func (s *chatServiceImpl) RecallMessage(ctx context.Context, messageID string, u
|
||||
// DeleteMessage 删除消息(仅对自己可见)
|
||||
func (s *chatServiceImpl) DeleteMessage(ctx context.Context, messageID string, userID string) error {
|
||||
// 获取消息
|
||||
var message model.Message
|
||||
err := s.db.First(&message, "id = ?", messageID).Error
|
||||
message, err := s.repo.GetMessageByID(messageID)
|
||||
if err != nil {
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
return errors.New("message not found")
|
||||
}
|
||||
return fmt.Errorf("failed to get message: %w", err)
|
||||
return errors.New("message not found")
|
||||
}
|
||||
|
||||
// 验证用户是否是会话参与者
|
||||
_, err = s.getParticipant(ctx, message.ConversationID, userID)
|
||||
if err != nil {
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
return errors.New("no permission to delete this message")
|
||||
}
|
||||
return fmt.Errorf("failed to get participant: %w", err)
|
||||
return errors.New("no permission to delete this message")
|
||||
}
|
||||
|
||||
// 对于删除消息,我们使用软删除,但需要确保只对当前用户隐藏
|
||||
@@ -629,7 +612,7 @@ func (s *chatServiceImpl) DeleteMessage(ctx context.Context, messageID string, u
|
||||
}
|
||||
|
||||
// 更新消息状态为已删除
|
||||
err = s.db.Model(&message).Update("status", model.MessageStatusDeleted).Error
|
||||
err = s.repo.UpdateMessageStatus(message.ID, model.MessageStatusDeleted)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to delete message: %w", err)
|
||||
}
|
||||
|
||||
@@ -15,8 +15,8 @@ import (
|
||||
)
|
||||
|
||||
type CommentService struct {
|
||||
commentRepo *repository.CommentRepository
|
||||
postRepo *repository.PostRepository
|
||||
commentRepo repository.CommentRepository
|
||||
postRepo repository.PostRepository
|
||||
systemMessageService SystemMessageService
|
||||
cache cache.Cache
|
||||
postAIService *PostAIService
|
||||
@@ -24,7 +24,7 @@ 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) *CommentService {
|
||||
return &CommentService{
|
||||
commentRepo: commentRepo,
|
||||
postRepo: postRepo,
|
||||
|
||||
@@ -106,25 +106,23 @@ type GroupMembersResult struct {
|
||||
|
||||
// groupService 群组服务实现
|
||||
type groupService struct {
|
||||
db *gorm.DB
|
||||
groupRepo repository.GroupRepository
|
||||
userRepo *repository.UserRepository
|
||||
messageRepo *repository.MessageRepository
|
||||
userRepo repository.UserRepository
|
||||
messageRepo repository.MessageRepository
|
||||
requestRepo repository.GroupJoinRequestRepository
|
||||
notifyRepo *repository.SystemNotificationRepository
|
||||
notifyRepo repository.SystemNotificationRepository
|
||||
sseHub *sse.Hub
|
||||
cache cache.Cache
|
||||
}
|
||||
|
||||
// NewGroupService 创建群组服务
|
||||
func NewGroupService(db *gorm.DB, groupRepo repository.GroupRepository, userRepo *repository.UserRepository, messageRepo *repository.MessageRepository, sseHub *sse.Hub, cacheBackend cache.Cache) GroupService {
|
||||
func NewGroupService(groupRepo repository.GroupRepository, userRepo repository.UserRepository, messageRepo repository.MessageRepository, requestRepo repository.GroupJoinRequestRepository, notifyRepo repository.SystemNotificationRepository, sseHub *sse.Hub, cacheBackend cache.Cache) GroupService {
|
||||
return &groupService{
|
||||
db: db,
|
||||
groupRepo: groupRepo,
|
||||
userRepo: userRepo,
|
||||
messageRepo: messageRepo,
|
||||
requestRepo: repository.NewGroupJoinRequestRepository(db),
|
||||
notifyRepo: repository.NewSystemNotificationRepository(db),
|
||||
requestRepo: requestRepo,
|
||||
notifyRepo: notifyRepo,
|
||||
sseHub: sseHub,
|
||||
cache: cacheBackend,
|
||||
}
|
||||
@@ -263,43 +261,17 @@ func (s *groupService) CreateGroup(ownerID string, name string, description stri
|
||||
GroupID: &group.ID,
|
||||
}
|
||||
|
||||
// 在事务中创建会话和参与者
|
||||
err = s.db.Transaction(func(tx *gorm.DB) error {
|
||||
// 创建会话
|
||||
if err := tx.Create(conversation).Error; err != nil {
|
||||
return err
|
||||
// 收集所有参与者
|
||||
participants := make([]string, 0, len(memberIDs)+1)
|
||||
participants = append(participants, ownerID)
|
||||
for _, memberID := range memberIDs {
|
||||
if memberID != ownerID {
|
||||
participants = append(participants, memberID)
|
||||
}
|
||||
}
|
||||
|
||||
// 添加群主为会话参与者
|
||||
ownerParticipant := model.ConversationParticipant{
|
||||
ConversationID: conversation.ID,
|
||||
UserID: ownerID,
|
||||
LastReadSeq: 0,
|
||||
}
|
||||
if err := tx.Create(&ownerParticipant).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// 添加被邀请的成员为会话参与者
|
||||
for _, memberID := range memberIDs {
|
||||
if memberID == ownerID {
|
||||
continue
|
||||
}
|
||||
participant := model.ConversationParticipant{
|
||||
ConversationID: conversation.ID,
|
||||
UserID: memberID,
|
||||
LastReadSeq: 0,
|
||||
}
|
||||
if err := tx.Create(&participant).Error; err != nil {
|
||||
// 单个参与者添加失败继续处理其他成员
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
// 使用仓储创建会话和参与者
|
||||
if err := s.messageRepo.CreateConversationWithParticipants(conversation, participants); err != nil {
|
||||
// 记录错误但不影响群组创建成功
|
||||
}
|
||||
|
||||
@@ -418,30 +390,8 @@ func (s *groupService) TransferOwner(userID string, groupID string, newOwnerID s
|
||||
return ErrNotGroupMember
|
||||
}
|
||||
|
||||
// 在事务中更新
|
||||
return s.db.Transaction(func(tx *gorm.DB) error {
|
||||
// 更新群组的群主
|
||||
group.OwnerID = newOwnerID
|
||||
if err := tx.Save(group).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// 更新原群主为管理员
|
||||
if err := tx.Model(&model.GroupMember{}).
|
||||
Where("group_id = ? AND user_id = ?", groupID, userID).
|
||||
Update("role", model.GroupRoleAdmin).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// 更新新群主为群主
|
||||
if err := tx.Model(&model.GroupMember{}).
|
||||
Where("group_id = ? AND user_id = ?", groupID, newOwnerID).
|
||||
Update("role", model.GroupRoleOwner).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
// 使用仓储的 TransferOwner 方法(在事务中更新)
|
||||
return s.groupRepo.TransferOwner(groupID, userID, newOwnerID)
|
||||
}
|
||||
|
||||
// GetUserGroups 获取用户加入的群组列表
|
||||
@@ -593,9 +543,7 @@ func (s *groupService) collectGroupReviewerIDs(groupID string, ownerID string, s
|
||||
if ownerID != "" && ownerID != skipUserID {
|
||||
reviewerSet[ownerID] = struct{}{}
|
||||
}
|
||||
|
||||
var reviewers []model.GroupMember
|
||||
if err := s.db.Where("group_id = ? AND role IN ?", groupID, []string{model.GroupRoleOwner, model.GroupRoleAdmin}).Find(&reviewers).Error; err == nil {
|
||||
if reviewers, err := s.groupRepo.GetAdmins(groupID); err == nil {
|
||||
for _, reviewer := range reviewers {
|
||||
if reviewer.UserID == "" || reviewer.UserID == skipUserID {
|
||||
continue
|
||||
|
||||
@@ -19,7 +19,7 @@ import (
|
||||
// HotRankWorker 定时在候选池上重算热门分,写入 Redis ZSET(仅 TopN)及 top_ids(Redis+本地缓存)
|
||||
type HotRankWorker struct {
|
||||
cfg *config.Config
|
||||
postRepo *repository.PostRepository
|
||||
postRepo repository.PostRepository
|
||||
c cache.Cache
|
||||
mu sync.Mutex
|
||||
stopOnce sync.Once
|
||||
@@ -28,7 +28,7 @@ type HotRankWorker struct {
|
||||
}
|
||||
|
||||
// NewHotRankWorker 创建热门榜重算 worker(cache 需为 Redis 实现才有意义)
|
||||
func NewHotRankWorker(cfg *config.Config, postRepo *repository.PostRepository, c cache.Cache) *HotRankWorker {
|
||||
func NewHotRankWorker(cfg *config.Config, postRepo repository.PostRepository, c cache.Cache) *HotRankWorker {
|
||||
return &HotRankWorker{
|
||||
cfg: cfg,
|
||||
postRepo: postRepo,
|
||||
|
||||
@@ -30,9 +30,9 @@ type LogCleanupService interface {
|
||||
|
||||
// logCleanupServiceImpl 日志清理服务实现
|
||||
type logCleanupServiceImpl struct {
|
||||
operationRepo *repository.OperationLogRepository
|
||||
loginRepo *repository.LoginLogRepository
|
||||
dataChangeRepo *repository.DataChangeLogRepository
|
||||
operationRepo repository.OperationLogRepository
|
||||
loginRepo repository.LoginLogRepository
|
||||
dataChangeRepo repository.DataChangeLogRepository
|
||||
cfg *LogCleanupConfig
|
||||
logger *zap.Logger
|
||||
ctx context.Context
|
||||
@@ -41,9 +41,9 @@ type logCleanupServiceImpl struct {
|
||||
|
||||
// NewLogCleanupService 创建日志清理服务
|
||||
func NewLogCleanupService(
|
||||
operationRepo *repository.OperationLogRepository,
|
||||
loginRepo *repository.LoginLogRepository,
|
||||
dataChangeRepo *repository.DataChangeLogRepository,
|
||||
operationRepo repository.OperationLogRepository,
|
||||
loginRepo repository.LoginLogRepository,
|
||||
dataChangeRepo repository.DataChangeLogRepository,
|
||||
cfg *LogCleanupConfig,
|
||||
logger *zap.Logger,
|
||||
) LogCleanupService {
|
||||
|
||||
@@ -4,6 +4,7 @@ import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"carrot_bbs/internal/dto"
|
||||
"carrot_bbs/internal/model"
|
||||
"carrot_bbs/internal/repository"
|
||||
)
|
||||
@@ -11,7 +12,7 @@ import (
|
||||
// OperationLogService 操作日志服务接口
|
||||
type OperationLogService interface {
|
||||
RecordOperation(log *model.OperationLog)
|
||||
GetOperationLogs(ctx context.Context, filters repository.LogFilter, page, pageSize int) ([]*model.OperationLog, int64, error)
|
||||
GetOperationLogs(ctx context.Context, filters dto.LogFilter, page, pageSize int) ([]*model.OperationLog, int64, error)
|
||||
GetOperationLogsByUser(ctx context.Context, userID string, page, pageSize int) ([]*model.OperationLog, int64, error)
|
||||
GetOperationLogsByTimeRange(ctx context.Context, startTime, endTime string, page, pageSize int) ([]*model.OperationLog, int64, error)
|
||||
GetStatistics(ctx context.Context, startTime, endTime string) (*repository.OperationLogStatistics, error)
|
||||
@@ -20,13 +21,13 @@ type OperationLogService interface {
|
||||
// operationLogServiceImpl 操作日志服务实现
|
||||
type operationLogServiceImpl struct {
|
||||
asyncManager *AsyncLogManager
|
||||
repo *repository.OperationLogRepository
|
||||
repo repository.OperationLogRepository
|
||||
}
|
||||
|
||||
// NewOperationLogService 创建操作日志服务
|
||||
func NewOperationLogService(
|
||||
asyncManager *AsyncLogManager,
|
||||
repo *repository.OperationLogRepository,
|
||||
repo repository.OperationLogRepository,
|
||||
) OperationLogService {
|
||||
return &operationLogServiceImpl{
|
||||
asyncManager: asyncManager,
|
||||
@@ -40,7 +41,7 @@ func (s *operationLogServiceImpl) RecordOperation(log *model.OperationLog) {
|
||||
}
|
||||
|
||||
// GetOperationLogs 获取操作日志列表
|
||||
func (s *operationLogServiceImpl) GetOperationLogs(ctx context.Context, filters repository.LogFilter, page, pageSize int) ([]*model.OperationLog, int64, error) {
|
||||
func (s *operationLogServiceImpl) GetOperationLogs(ctx context.Context, filters dto.LogFilter, page, pageSize int) ([]*model.OperationLog, int64, error) {
|
||||
return s.repo.GetOperationLogs(ctx, filters, page, pageSize)
|
||||
}
|
||||
|
||||
@@ -62,7 +63,7 @@ func (s *operationLogServiceImpl) GetStatistics(ctx context.Context, startTime,
|
||||
// LoginLogService 登录日志服务接口
|
||||
type LoginLogService interface {
|
||||
RecordLogin(log *model.LoginLog)
|
||||
GetLoginLogs(ctx context.Context, filters repository.LoginFilter, page, pageSize int) ([]*model.LoginLog, int64, error)
|
||||
GetLoginLogs(ctx context.Context, filters dto.LoginFilter, page, pageSize int) ([]*model.LoginLog, int64, error)
|
||||
GetLoginLogsByUser(ctx context.Context, userID string, page, pageSize int) ([]*model.LoginLog, int64, error)
|
||||
GetFailedLoginsByIP(ctx context.Context, ip string, timeWindow string) (int64, error)
|
||||
GetRecentSuccessLogins(ctx context.Context, userID string, limit int) ([]*model.LoginLog, error)
|
||||
@@ -72,13 +73,13 @@ type LoginLogService interface {
|
||||
// loginLogServiceImpl 登录日志服务实现
|
||||
type loginLogServiceImpl struct {
|
||||
asyncManager *AsyncLogManager
|
||||
repo *repository.LoginLogRepository
|
||||
repo repository.LoginLogRepository
|
||||
}
|
||||
|
||||
// NewLoginLogService 创建登录日志服务
|
||||
func NewLoginLogService(
|
||||
asyncManager *AsyncLogManager,
|
||||
repo *repository.LoginLogRepository,
|
||||
repo repository.LoginLogRepository,
|
||||
) LoginLogService {
|
||||
return &loginLogServiceImpl{
|
||||
asyncManager: asyncManager,
|
||||
@@ -92,7 +93,7 @@ func (s *loginLogServiceImpl) RecordLogin(log *model.LoginLog) {
|
||||
}
|
||||
|
||||
// GetLoginLogs 获取登录日志列表
|
||||
func (s *loginLogServiceImpl) GetLoginLogs(ctx context.Context, filters repository.LoginFilter, page, pageSize int) ([]*model.LoginLog, int64, error) {
|
||||
func (s *loginLogServiceImpl) GetLoginLogs(ctx context.Context, filters dto.LoginFilter, page, pageSize int) ([]*model.LoginLog, int64, error) {
|
||||
return s.repo.GetLoginLogs(ctx, filters, page, pageSize)
|
||||
}
|
||||
|
||||
@@ -123,7 +124,7 @@ func (s *loginLogServiceImpl) GetStatistics(ctx context.Context, startTime, endT
|
||||
// DataChangeLogService 数据变更日志服务接口
|
||||
type DataChangeLogService interface {
|
||||
RecordDataChange(log *model.DataChangeLog)
|
||||
GetDataChangeLogs(ctx context.Context, filters repository.DataChangeFilter, page, pageSize int) ([]*model.DataChangeLog, int64, error)
|
||||
GetDataChangeLogs(ctx context.Context, filters dto.DataChangeFilter, page, pageSize int) ([]*model.DataChangeLog, int64, error)
|
||||
GetDataChangeLogsByUser(ctx context.Context, userID string, page, pageSize int) ([]*model.DataChangeLog, int64, error)
|
||||
GetDataChangeLogsByOperator(ctx context.Context, operatorID string, page, pageSize int) ([]*model.DataChangeLog, int64, error)
|
||||
GetStatistics(ctx context.Context, startTime, endTime string) (*repository.DataChangeLogStatistics, error)
|
||||
@@ -132,13 +133,13 @@ type DataChangeLogService interface {
|
||||
// dataChangeLogServiceImpl 数据变更日志服务实现
|
||||
type dataChangeLogServiceImpl struct {
|
||||
asyncManager *AsyncLogManager
|
||||
repo *repository.DataChangeLogRepository
|
||||
repo repository.DataChangeLogRepository
|
||||
}
|
||||
|
||||
// NewDataChangeLogService 创建数据变更日志服务
|
||||
func NewDataChangeLogService(
|
||||
asyncManager *AsyncLogManager,
|
||||
repo *repository.DataChangeLogRepository,
|
||||
repo repository.DataChangeLogRepository,
|
||||
) DataChangeLogService {
|
||||
return &dataChangeLogServiceImpl{
|
||||
asyncManager: asyncManager,
|
||||
@@ -152,7 +153,7 @@ func (s *dataChangeLogServiceImpl) RecordDataChange(log *model.DataChangeLog) {
|
||||
}
|
||||
|
||||
// GetDataChangeLogs 获取数据变更日志列表
|
||||
func (s *dataChangeLogServiceImpl) GetDataChangeLogs(ctx context.Context, filters repository.DataChangeFilter, page, pageSize int) ([]*model.DataChangeLog, int64, error) {
|
||||
func (s *dataChangeLogServiceImpl) GetDataChangeLogs(ctx context.Context, filters dto.DataChangeFilter, page, pageSize int) ([]*model.DataChangeLog, int64, error) {
|
||||
return s.repo.GetDataChangeLogs(ctx, filters, page, pageSize)
|
||||
}
|
||||
|
||||
|
||||
@@ -2,6 +2,8 @@ package service
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"carrot_bbs/internal/dto"
|
||||
"carrot_bbs/internal/model"
|
||||
"carrot_bbs/internal/repository"
|
||||
)
|
||||
@@ -21,7 +23,7 @@ type MaterialService interface {
|
||||
DeleteSubject(id string) error
|
||||
|
||||
// 资料相关
|
||||
ListMaterials(params repository.MaterialFileQueryParams) ([]*model.MaterialFile, int64, error)
|
||||
ListMaterials(params dto.MaterialFileQueryParams) ([]*model.MaterialFile, int64, error)
|
||||
GetMaterialByID(id string) (*model.MaterialFile, error)
|
||||
GetMaterialByIDWithSubject(id string) (*model.MaterialFile, error)
|
||||
GetMaterialsBySubject(subjectID string, page, pageSize int) ([]*model.MaterialFile, int64, error)
|
||||
@@ -36,14 +38,14 @@ type MaterialService interface {
|
||||
|
||||
// materialServiceImpl 学习资料服务实现
|
||||
type materialServiceImpl struct {
|
||||
subjectRepo *repository.MaterialSubjectRepository
|
||||
fileRepo *repository.MaterialFileRepository
|
||||
subjectRepo repository.MaterialSubjectRepository
|
||||
fileRepo repository.MaterialFileRepository
|
||||
}
|
||||
|
||||
// NewMaterialService 创建学习资料服务
|
||||
func NewMaterialService(
|
||||
subjectRepo *repository.MaterialSubjectRepository,
|
||||
fileRepo *repository.MaterialFileRepository,
|
||||
subjectRepo repository.MaterialSubjectRepository,
|
||||
fileRepo repository.MaterialFileRepository,
|
||||
) MaterialService {
|
||||
return &materialServiceImpl{
|
||||
subjectRepo: subjectRepo,
|
||||
@@ -127,7 +129,7 @@ func (s *materialServiceImpl) DeleteSubject(id string) error {
|
||||
// 资料相关方法
|
||||
// =====================================================
|
||||
|
||||
func (s *materialServiceImpl) ListMaterials(params repository.MaterialFileQueryParams) ([]*model.MaterialFile, int64, error) {
|
||||
func (s *materialServiceImpl) ListMaterials(params dto.MaterialFileQueryParams) ([]*model.MaterialFile, int64, error) {
|
||||
return s.fileRepo.List(params)
|
||||
}
|
||||
|
||||
|
||||
@@ -10,7 +10,6 @@ import (
|
||||
"carrot_bbs/internal/repository"
|
||||
|
||||
"go.uber.org/zap"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
// 缓存TTL常量
|
||||
@@ -25,10 +24,8 @@ const (
|
||||
|
||||
// MessageService 消息服务
|
||||
type MessageService struct {
|
||||
db *gorm.DB
|
||||
|
||||
// 基础仓储
|
||||
messageRepo *repository.MessageRepository
|
||||
messageRepo repository.MessageRepository
|
||||
|
||||
// 缓存相关字段
|
||||
conversationCache *cache.ConversationCache
|
||||
@@ -40,7 +37,7 @@ type MessageService struct {
|
||||
}
|
||||
|
||||
// NewMessageService 创建消息服务
|
||||
func NewMessageService(db *gorm.DB, messageRepo *repository.MessageRepository, cacheBackend cache.Cache, uploadService *UploadService) *MessageService {
|
||||
func NewMessageService(messageRepo repository.MessageRepository, cacheBackend cache.Cache, uploadService *UploadService) *MessageService {
|
||||
// 创建适配器
|
||||
convRepoAdapter := cache.NewConversationRepositoryAdapter(messageRepo)
|
||||
msgRepoAdapter := cache.NewMessageRepositoryAdapter(messageRepo)
|
||||
@@ -54,7 +51,6 @@ func NewMessageService(db *gorm.DB, messageRepo *repository.MessageRepository, c
|
||||
)
|
||||
|
||||
return &MessageService{
|
||||
db: db,
|
||||
messageRepo: messageRepo,
|
||||
conversationCache: conversationCache,
|
||||
baseCache: cacheBackend,
|
||||
@@ -161,7 +157,7 @@ func (s *MessageService) GetConversations(ctx context.Context, userID string, pa
|
||||
|
||||
// 生成缓存键
|
||||
cacheKey := cache.ConversationListKey(userID, page, pageSize)
|
||||
result, err := cache.GetOrLoadTyped[*ConversationListResult](
|
||||
result, err := cache.GetOrLoadTyped(
|
||||
s.baseCache,
|
||||
cacheKey,
|
||||
conversationTTL,
|
||||
@@ -252,7 +248,7 @@ func (s *MessageService) GetUnreadCount(ctx context.Context, conversationID stri
|
||||
// 生成缓存键
|
||||
cacheKey := cache.UnreadDetailKey(userID, conversationID)
|
||||
|
||||
return cache.GetOrLoadTyped[int64](
|
||||
return cache.GetOrLoadTyped(
|
||||
s.baseCache,
|
||||
cacheKey,
|
||||
unreadTTL,
|
||||
|
||||
@@ -20,12 +20,12 @@ const (
|
||||
|
||||
// NotificationService 通知服务
|
||||
type NotificationService struct {
|
||||
notificationRepo *repository.NotificationRepository
|
||||
notificationRepo repository.NotificationRepository
|
||||
cache cache.Cache
|
||||
}
|
||||
|
||||
// NewNotificationService 创建通知服务
|
||||
func NewNotificationService(notificationRepo *repository.NotificationRepository, cacheBackend cache.Cache) *NotificationService {
|
||||
func NewNotificationService(notificationRepo repository.NotificationRepository, cacheBackend cache.Cache) *NotificationService {
|
||||
return &NotificationService{
|
||||
notificationRepo: notificationRepo,
|
||||
cache: cacheBackend,
|
||||
|
||||
@@ -73,7 +73,7 @@ type PostService interface {
|
||||
|
||||
// postServiceImpl 帖子服务实现
|
||||
type postServiceImpl struct {
|
||||
postRepo *repository.PostRepository
|
||||
postRepo repository.PostRepository
|
||||
systemMessageService SystemMessageService
|
||||
cache cache.Cache
|
||||
postAIService *PostAIService
|
||||
@@ -82,7 +82,7 @@ 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) PostService {
|
||||
return &postServiceImpl{
|
||||
postRepo: postRepo,
|
||||
systemMessageService: systemMessageService,
|
||||
|
||||
@@ -62,9 +62,9 @@ type PushService interface {
|
||||
|
||||
// pushServiceImpl 推送服务实现
|
||||
type pushServiceImpl struct {
|
||||
pushRepo *repository.PushRecordRepository
|
||||
deviceRepo *repository.DeviceTokenRepository
|
||||
messageRepo *repository.MessageRepository
|
||||
pushRepo repository.PushRecordRepository
|
||||
deviceRepo repository.DeviceTokenRepository
|
||||
messageRepo repository.MessageRepository
|
||||
sseHub *sse.Hub
|
||||
|
||||
// 推送队列
|
||||
@@ -81,9 +81,9 @@ type pushTask struct {
|
||||
|
||||
// NewPushService 创建推送服务
|
||||
func NewPushService(
|
||||
pushRepo *repository.PushRecordRepository,
|
||||
deviceRepo *repository.DeviceTokenRepository,
|
||||
messageRepo *repository.MessageRepository,
|
||||
pushRepo repository.PushRecordRepository,
|
||||
deviceRepo repository.DeviceTokenRepository,
|
||||
messageRepo repository.MessageRepository,
|
||||
sseHub *sse.Hub,
|
||||
) PushService {
|
||||
return &pushServiceImpl{
|
||||
|
||||
@@ -26,22 +26,30 @@ type SystemMessageService interface {
|
||||
// 发送系统公告
|
||||
SendSystemAnnouncement(ctx context.Context, userIDs []string, title string, content string) error
|
||||
SendBroadcastAnnouncement(ctx context.Context, title string, content string) error
|
||||
|
||||
// 查询通知(供 Handler 层的 REST API 使用)
|
||||
GetNotifications(receiverID string, page, pageSize int) ([]*model.SystemNotification, int64, error)
|
||||
GetNotificationsByCursor(receiverID string, cursorStr string, pageSize int) ([]*model.SystemNotification, string, bool, error)
|
||||
GetUnreadCount(receiverID string) (int64, error)
|
||||
MarkAsRead(notificationID int64, receiverID string) error
|
||||
MarkAllAsRead(receiverID string) error
|
||||
DeleteNotification(notificationID int64, receiverID string) error
|
||||
}
|
||||
|
||||
type systemMessageServiceImpl struct {
|
||||
notifyRepo *repository.SystemNotificationRepository
|
||||
notifyRepo repository.SystemNotificationRepository
|
||||
pushService PushService
|
||||
userRepo *repository.UserRepository
|
||||
postRepo *repository.PostRepository
|
||||
userRepo repository.UserRepository
|
||||
postRepo repository.PostRepository
|
||||
cache cache.Cache
|
||||
}
|
||||
|
||||
// NewSystemMessageService 创建系统消息服务
|
||||
func NewSystemMessageService(
|
||||
notifyRepo *repository.SystemNotificationRepository,
|
||||
notifyRepo repository.SystemNotificationRepository,
|
||||
pushService PushService,
|
||||
userRepo *repository.UserRepository,
|
||||
postRepo *repository.PostRepository,
|
||||
userRepo repository.UserRepository,
|
||||
postRepo repository.PostRepository,
|
||||
cacheBackend cache.Cache,
|
||||
) SystemMessageService {
|
||||
return &systemMessageServiceImpl{
|
||||
@@ -402,6 +410,51 @@ func (s *systemMessageServiceImpl) createNotification(ctx context.Context, userI
|
||||
return notification, nil
|
||||
}
|
||||
|
||||
// GetNotifications 获取通知列表(供 Handler 调用)
|
||||
func (s *systemMessageServiceImpl) GetNotifications(receiverID string, page, pageSize int) ([]*model.SystemNotification, int64, error) {
|
||||
return s.notifyRepo.GetByReceiverID(receiverID, page, pageSize)
|
||||
}
|
||||
|
||||
// GetNotificationsByCursor 游标分页获取通知列表(供 Handler 调用)
|
||||
func (s *systemMessageServiceImpl) GetNotificationsByCursor(receiverID string, cursorStr string, pageSize int) ([]*model.SystemNotification, string, bool, error) {
|
||||
return s.notifyRepo.GetByReceiverIDCursorLegacy(receiverID, cursorStr, pageSize)
|
||||
}
|
||||
|
||||
// GetUnreadCount 获取未读数量(供 Handler 调用)
|
||||
func (s *systemMessageServiceImpl) GetUnreadCount(receiverID string) (int64, error) {
|
||||
return s.notifyRepo.GetUnreadCount(receiverID)
|
||||
}
|
||||
|
||||
// MarkAsRead 标记单条为已读(供 Handler 调用)
|
||||
func (s *systemMessageServiceImpl) MarkAsRead(notificationID int64, receiverID string) error {
|
||||
err := s.notifyRepo.MarkAsRead(notificationID, receiverID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
cache.InvalidateUnreadSystem(s.cache, receiverID)
|
||||
return nil
|
||||
}
|
||||
|
||||
// MarkAllAsRead 标记全部为已读(供 Handler 调用)
|
||||
func (s *systemMessageServiceImpl) MarkAllAsRead(receiverID string) error {
|
||||
err := s.notifyRepo.MarkAllAsRead(receiverID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
cache.InvalidateUnreadSystem(s.cache, receiverID)
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeleteNotification 删除通知(供 Handler 调用)
|
||||
func (s *systemMessageServiceImpl) DeleteNotification(notificationID int64, receiverID string) error {
|
||||
err := s.notifyRepo.Delete(notificationID, receiverID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
cache.InvalidateUnreadSystem(s.cache, receiverID)
|
||||
return nil
|
||||
}
|
||||
|
||||
// getActorInfo 获取操作者信息
|
||||
func (s *systemMessageServiceImpl) getActorInfo(ctx context.Context, operatorID string) (string, string, error) {
|
||||
// 从用户仓储获取用户信息
|
||||
|
||||
@@ -35,11 +35,11 @@ type UserActivityService interface {
|
||||
|
||||
// userActivityService 实现
|
||||
type userActivityService struct {
|
||||
repo *repository.UserActivityRepository
|
||||
repo repository.UserActivityRepository
|
||||
}
|
||||
|
||||
// NewUserActivityService 创建用户活跃统计服务
|
||||
func NewUserActivityService(repo *repository.UserActivityRepository) UserActivityService {
|
||||
func NewUserActivityService(repo repository.UserActivityRepository) UserActivityService {
|
||||
return &userActivityService{repo: repo}
|
||||
}
|
||||
|
||||
|
||||
@@ -59,7 +59,7 @@ type UserService interface {
|
||||
|
||||
// userServiceImpl 用户服务实现
|
||||
type userServiceImpl struct {
|
||||
userRepo *repository.UserRepository
|
||||
userRepo repository.UserRepository
|
||||
systemMessageService SystemMessageService
|
||||
emailCodeService EmailCodeService
|
||||
logService *LogService
|
||||
@@ -67,7 +67,7 @@ type userServiceImpl struct {
|
||||
|
||||
// NewUserService 创建用户服务
|
||||
func NewUserService(
|
||||
userRepo *repository.UserRepository,
|
||||
userRepo repository.UserRepository,
|
||||
systemMessageService SystemMessageService,
|
||||
emailService EmailService,
|
||||
cacheBackend cache.Cache,
|
||||
|
||||
@@ -16,8 +16,8 @@ import (
|
||||
|
||||
// VoteService 投票服务
|
||||
type VoteService struct {
|
||||
voteRepo *repository.VoteRepository
|
||||
postRepo *repository.PostRepository
|
||||
voteRepo repository.VoteRepository
|
||||
postRepo repository.PostRepository
|
||||
cache cache.Cache
|
||||
postAIService *PostAIService
|
||||
systemMessageService SystemMessageService
|
||||
@@ -25,8 +25,8 @@ type VoteService struct {
|
||||
|
||||
// NewVoteService 创建投票服务
|
||||
func NewVoteService(
|
||||
voteRepo *repository.VoteRepository,
|
||||
postRepo *repository.PostRepository,
|
||||
voteRepo repository.VoteRepository,
|
||||
postRepo repository.PostRepository,
|
||||
cache cache.Cache,
|
||||
postAIService *PostAIService,
|
||||
systemMessageService SystemMessageService,
|
||||
|
||||
Reference in New Issue
Block a user