2026-03-27 01:54:34 +08:00
|
|
|
|
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)
|
2026-03-28 04:34:49 +08:00
|
|
|
|
GetActiveCallsByUserID(userID string) ([]model.CallSession, error) // 获取用户参与的活跃通话
|
2026-03-27 01:54:34 +08:00
|
|
|
|
|
|
|
|
|
|
// 通话参与者操作
|
|
|
|
|
|
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
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-03-28 04:34:49 +08:00
|
|
|
|
// 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
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-03-27 01:54:34 +08:00
|
|
|
|
// 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
|
|
|
|
|
|
})
|
|
|
|
|
|
}
|