- 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.
192 lines
6.0 KiB
Go
192 lines
6.0 KiB
Go
package dto
|
|
|
|
import (
|
|
"time"
|
|
|
|
"carrot_bbs/internal/model"
|
|
)
|
|
|
|
// ==================== Call Request DTOs ====================
|
|
|
|
// StartCallRequest 发起通话请求
|
|
type StartCallRequest struct {
|
|
ConversationID string `json:"conversation_id" binding:"required"` // 会话ID
|
|
CallType model.CallType `json:"call_type" binding:"required"` // 通话类型: private, group
|
|
}
|
|
|
|
// AnswerCallRequest 接听通话请求
|
|
type AnswerCallRequest struct {
|
|
SDP string `json:"sdp" binding:"required"` // SDP Answer
|
|
}
|
|
|
|
// SendSDPRequest 发送SDP请求
|
|
type SendSDPRequest struct {
|
|
SDP string `json:"sdp" binding:"required"` // SDP Offer/Answer
|
|
Type string `json:"type" binding:"required"` // offer 或 answer
|
|
}
|
|
|
|
// SendICECandidateRequest 发送ICE候选请求
|
|
type SendICECandidateRequest struct {
|
|
Candidate string `json:"candidate" binding:"required"` // candidate 字符串
|
|
SDPMid string `json:"sdp_mid"` // SDP mid
|
|
SDPMLineIndex int16 `json:"sdp_mline_index"` // SDP m-line index
|
|
}
|
|
|
|
// ==================== Call Response DTOs ====================
|
|
|
|
// CallSessionResponse 通话会话响应
|
|
type CallSessionResponse struct {
|
|
ID string `json:"id"` // 通话ID
|
|
ConversationID string `json:"conversation_id"` // 会话ID
|
|
GroupID string `json:"group_id,omitempty"`
|
|
CallerID string `json:"caller_id"` // 发起者ID
|
|
CallType model.CallType `json:"call_type"` // 通话类型
|
|
Status model.CallStatus `json:"status"` // 通话状态
|
|
StartedAt *time.Time `json:"started_at,omitempty"`
|
|
EndedAt *time.Time `json:"ended_at,omitempty"`
|
|
Duration int64 `json:"duration"` // 通话时长(秒)
|
|
CreatedAt time.Time `json:"created_at"`
|
|
Participants []CallParticipantResponse `json:"participants"` // 参与者列表
|
|
Caller *UserResponse `json:"caller,omitempty"` // 发起者信息
|
|
}
|
|
|
|
// CallParticipantResponse 通话参与者响应
|
|
type CallParticipantResponse struct {
|
|
UserID string `json:"user_id"`
|
|
Status model.ParticipantStatus `json:"status"`
|
|
JoinedAt *time.Time `json:"joined_at,omitempty"`
|
|
LeftAt *time.Time `json:"left_at,omitempty"`
|
|
User *UserResponse `json:"user,omitempty"`
|
|
}
|
|
|
|
// ==================== Call SSE Event DTOs ====================
|
|
|
|
// CallInviteEvent 来电邀请事件
|
|
type CallInviteEvent struct {
|
|
CallID string `json:"call_id"`
|
|
ConversationID string `json:"conversation_id"`
|
|
GroupID string `json:"group_id,omitempty"`
|
|
CallerID string `json:"caller_id"`
|
|
CallType model.CallType `json:"call_type"`
|
|
Caller *UserResponse `json:"caller,omitempty"`
|
|
CreatedAt time.Time `json:"created_at"`
|
|
}
|
|
|
|
// CallAnswerEvent 接听响应事件
|
|
type CallAnswerEvent struct {
|
|
CallID string `json:"call_id"`
|
|
UserID string `json:"user_id"`
|
|
SDP string `json:"sdp"` // SDP Answer
|
|
}
|
|
|
|
// CallRejectEvent 拒绝通话事件
|
|
type CallRejectEvent struct {
|
|
CallID string `json:"call_id"`
|
|
UserID string `json:"user_id"`
|
|
}
|
|
|
|
// CallEndEvent 结束通话事件
|
|
type CallEndEvent struct {
|
|
CallID string `json:"call_id"`
|
|
UserID string `json:"user_id"`
|
|
Duration int64 `json:"duration"`
|
|
}
|
|
|
|
// CallICECandidateEvent ICE候选事件
|
|
type CallICECandidateEvent struct {
|
|
CallID string `json:"call_id"`
|
|
UserID string `json:"user_id"`
|
|
Candidate string `json:"candidate"`
|
|
SDPMid string `json:"sdp_mid"`
|
|
SDPMLineIndex int16 `json:"sdp_mline_index"`
|
|
}
|
|
|
|
// CallSDPOfferEvent SDP Offer事件
|
|
type CallSDPOfferEvent struct {
|
|
CallID string `json:"call_id"`
|
|
UserID string `json:"user_id"`
|
|
SDP string `json:"sdp"`
|
|
}
|
|
|
|
// CallSDPAnswerEvent SDP Answer事件
|
|
type CallSDPAnswerEvent struct {
|
|
CallID string `json:"call_id"`
|
|
UserID string `json:"user_id"`
|
|
SDP string `json:"sdp"`
|
|
}
|
|
|
|
// CallUserJoinedEvent 用户加入通话事件(群聊)
|
|
type CallUserJoinedEvent struct {
|
|
CallID string `json:"call_id"`
|
|
UserID string `json:"user_id"`
|
|
User *UserResponse `json:"user,omitempty"`
|
|
}
|
|
|
|
// CallUserLeftEvent 用户离开通话事件(群聊)
|
|
type CallUserLeftEvent struct {
|
|
CallID string `json:"call_id"`
|
|
UserID string `json:"user_id"`
|
|
}
|
|
|
|
// ==================== ICE Server Config ====================
|
|
|
|
// ICEServerConfig ICE服务器配置
|
|
type ICEServerConfig struct {
|
|
URLs []string `json:"urls"`
|
|
Username string `json:"username,omitempty"`
|
|
Credential string `json:"credential,omitempty"`
|
|
CredentialType string `json:"credential_type,omitempty"`
|
|
}
|
|
|
|
// CallConfigResponse 通话配置响应
|
|
type CallConfigResponse struct {
|
|
ICEServers []ICEServerConfig `json:"ice_servers"`
|
|
}
|
|
|
|
// ==================== Converter Functions ====================
|
|
|
|
// ConvertCallSessionToResponse 转换通话会话为响应格式
|
|
func ConvertCallSessionToResponse(call *model.CallSession, caller *model.User, participants []*model.User) *CallSessionResponse {
|
|
resp := &CallSessionResponse{
|
|
ID: call.ID,
|
|
ConversationID: call.ConversationID,
|
|
CallerID: call.CallerID,
|
|
CallType: call.CallType,
|
|
Status: call.Status,
|
|
StartedAt: call.StartedAt,
|
|
EndedAt: call.EndedAt,
|
|
Duration: call.Duration,
|
|
CreatedAt: call.CreatedAt,
|
|
}
|
|
|
|
if call.GroupID != nil {
|
|
resp.GroupID = *call.GroupID
|
|
}
|
|
|
|
if caller != nil {
|
|
resp.Caller = ConvertUserToResponse(caller)
|
|
}
|
|
|
|
// 转换参与者
|
|
resp.Participants = make([]CallParticipantResponse, 0, len(call.Participants))
|
|
userMap := make(map[string]*model.User)
|
|
for _, u := range participants {
|
|
userMap[u.ID] = u
|
|
}
|
|
|
|
for _, p := range call.Participants {
|
|
pr := CallParticipantResponse{
|
|
UserID: p.UserID,
|
|
Status: p.Status,
|
|
JoinedAt: p.JoinedAt,
|
|
LeftAt: p.LeftAt,
|
|
}
|
|
if u, ok := userMap[p.UserID]; ok {
|
|
pr.User = ConvertUserToResponse(u)
|
|
}
|
|
resp.Participants = append(resp.Participants, pr)
|
|
}
|
|
|
|
return resp
|
|
}
|