feat(call): integrate call handling and WebSocket support
- Added CallHandler and related services for managing call sessions and participants. - Enhanced WSHandler to support call signaling, including invite, answer, reject, and end functionalities. - Updated router to include call-related routes for history and ICE server retrieval. - Introduced WebRTC configuration in the application settings for call management. - Refactored wire generation to include CallService and CallRepository for improved dependency injection.
This commit is contained in:
156
internal/repository/call_repo.go
Normal file
156
internal/repository/call_repo.go
Normal file
@@ -0,0 +1,156 @@
|
||||
package repository
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"carrot_bbs/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)
|
||||
|
||||
// 通话参与者操作
|
||||
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
|
||||
}
|
||||
|
||||
// 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
|
||||
})
|
||||
}
|
||||
Reference in New Issue
Block a user