Files
backend/internal/repository/call_repo.go
lafay d357998321
All checks were successful
Build Backend / build (push) Successful in 13m52s
Build Backend / build-docker (push) Successful in 1m8s
feat(call): enhance call handling with user connection events and active call management
- Updated CallService to handle user connection and disconnection events, allowing for automatic management of active calls based on user status.
- Introduced methods to retrieve active calls for users and send pending call invites when users reconnect.
- Modified the Invite method to return the callee's online status, improving user experience during call invitations.
- Enhanced WSHandler to support connection and disconnection event handlers, ensuring accurate call state management.
2026-03-28 04:34:49 +08:00

177 lines
5.3 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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)
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
})
}