package repository import ( "context" "with_you/internal/model" "gorm.io/gorm" ) // CallRepository 通话仓库接口 type CallRepository interface { // 通话会话操作 CreateCall(call *model.CallSession) error GetCallByID(id string) (*model.CallSession, error) GetCallByIDWithParticipants(id string) (*model.CallSession, error) UpdateCall(call *model.CallSession) error GetActiveCallByConversationID(conversationID string) (*model.CallSession, error) GetActiveCallsByUserID(userID string) ([]model.CallSession, error) // 获取用户参与的活跃通话 // 通话参与者操作 CreateCallParticipant(participant *model.CallParticipant) error GetCallParticipant(callID, userID string) (*model.CallParticipant, error) GetCallParticipants(callID string) ([]model.CallParticipant, error) UpdateCallParticipant(participant *model.CallParticipant) error // 通话历史 GetCallHistory(userID string, page, pageSize int) ([]model.CallSession, int64, error) // 事务操作 CreateCallWithParticipants(ctx context.Context, call *model.CallSession, participants []*model.CallParticipant) error } // callRepository 通话仓库实现 type callRepository struct { db *gorm.DB } // NewCallRepository 创建通话仓库 func NewCallRepository(db *gorm.DB) CallRepository { return &callRepository{db: db} } // CreateCall 创建通话会话 func (r *callRepository) CreateCall(call *model.CallSession) error { return r.db.Create(call).Error } // GetCallByID 根据ID获取通话会话 func (r *callRepository) GetCallByID(id string) (*model.CallSession, error) { var call model.CallSession err := r.db.First(&call, "id = ?", id).Error if err != nil { return nil, err } return &call, nil } // GetCallByIDWithParticipants 根据ID获取通话会话(包含参与者) func (r *callRepository) GetCallByIDWithParticipants(id string) (*model.CallSession, error) { var call model.CallSession err := r.db.Preload("Participants").First(&call, "id = ?", id).Error if err != nil { return nil, err } return &call, nil } // UpdateCall 更新通话会话 func (r *callRepository) UpdateCall(call *model.CallSession) error { return r.db.Save(call).Error } // GetActiveCallByConversationID 获取会话中的活跃通话 func (r *callRepository) GetActiveCallByConversationID(conversationID string) (*model.CallSession, error) { var call model.CallSession err := r.db.Where("conversation_id = ? AND status IN ?", conversationID, []model.CallStatus{ model.CallStatusCalling, model.CallStatusConnected, }).First(&call).Error if err != nil { return nil, err } return &call, nil } // GetActiveCallsByUserID 获取用户参与的所有活跃通话 func (r *callRepository) GetActiveCallsByUserID(userID string) ([]model.CallSession, error) { var calls []model.CallSession // 子查询获取用户参与的通话ID subQuery := r.db.Model(&model.CallParticipant{}). Select("DISTINCT call_id"). Where("user_id = ?", userID) err := r.db.Where("id IN (?) AND status IN ?", subQuery, []model.CallStatus{ model.CallStatusCalling, model.CallStatusConnected, }).Preload("Participants").Find(&calls).Error if err != nil { return nil, err } return calls, nil } // CreateCallParticipant 创建通话参与者 func (r *callRepository) CreateCallParticipant(participant *model.CallParticipant) error { return r.db.Create(participant).Error } // GetCallParticipant 获取通话参与者 func (r *callRepository) GetCallParticipant(callID, userID string) (*model.CallParticipant, error) { var participant model.CallParticipant err := r.db.Where("call_id = ? AND user_id = ?", callID, userID).First(&participant).Error if err != nil { return nil, err } return &participant, nil } // GetCallParticipants 获取通话参与者列表 func (r *callRepository) GetCallParticipants(callID string) ([]model.CallParticipant, error) { var participants []model.CallParticipant err := r.db.Where("call_id = ?", callID).Find(&participants).Error if err != nil { return nil, err } return participants, nil } // UpdateCallParticipant 更新通话参与者 func (r *callRepository) UpdateCallParticipant(participant *model.CallParticipant) error { return r.db.Save(participant).Error } // GetCallHistory 获取用户通话历史 func (r *callRepository) GetCallHistory(userID string, page, pageSize int) ([]model.CallSession, int64, error) { var calls []model.CallSession var total int64 // 子查询获取用户参与的通话ID subQuery := r.db.Model(&model.CallParticipant{}). Select("DISTINCT call_id"). Where("user_id = ?", userID) query := r.db.Model(&model.CallSession{}). Where("id IN (?)", subQuery). Order("created_at DESC") if err := query.Count(&total).Error; err != nil { return nil, 0, err } offset := (page - 1) * pageSize if err := query.Preload("Participants").Offset(offset).Limit(pageSize).Find(&calls).Error; err != nil { return nil, 0, err } return calls, total, nil } // CreateCallWithParticipants 创建通话会话和参与者(事务) func (r *callRepository) CreateCallWithParticipants(ctx context.Context, call *model.CallSession, participants []*model.CallParticipant) error { return r.db.WithContext(ctx).Transaction(func(tx *gorm.DB) error { if err := tx.Create(call).Error; err != nil { return err } for _, p := range participants { p.CallID = call.ID if err := tx.Create(p).Error; err != nil { return err } } return nil }) }