diff --git a/internal/builders/conversation_builder.go b/internal/builders/conversation_builder.go
index 4c81f24..2fb377d 100644
--- a/internal/builders/conversation_builder.go
+++ b/internal/builders/conversation_builder.go
@@ -37,6 +37,7 @@ func BuildConversation(item *models.Conversation) response.ConversationResponse
AgentLastReadMessageID: readStateMessageID(agentReadState),
AgentLastReadSeqNo: readStateSeqNo(agentReadState),
AgentLastReadAt: readStateAt(agentReadState),
+ CustomerOnline: services.WsService.IsVisitorOnline(item.ExternalID),
ClosedAt: utils.FormatTimePtr(item.ClosedAt),
ClosedBy: item.ClosedBy,
CloseReason: item.CloseReason,
diff --git a/internal/pkg/dto/response/conversation_response.go b/internal/pkg/dto/response/conversation_response.go
index 720a491..c2e440f 100644
--- a/internal/pkg/dto/response/conversation_response.go
+++ b/internal/pkg/dto/response/conversation_response.go
@@ -41,6 +41,7 @@ type ConversationResponse struct {
AgentLastReadMessageID int64 `json:"agentLastReadMessageId"`
AgentLastReadSeqNo int64 `json:"agentLastReadSeqNo"`
AgentLastReadAt string `json:"agentLastReadAt,omitempty"`
+ CustomerOnline bool `json:"customerOnline"`
ClosedAt string `json:"closedAt,omitempty"`
ClosedBy int64 `json:"closedBy"`
ClosedByName string `json:"closedByName,omitempty"`
diff --git a/internal/services/ws_connection_manager.go b/internal/services/ws_connection_manager.go
index e308490..e2e3c70 100644
--- a/internal/services/ws_connection_manager.go
+++ b/internal/services/ws_connection_manager.go
@@ -104,6 +104,14 @@ func (m *WsConnectionManager) FindByTopics(topics []string) []*ClientSession {
return ret
}
+func (m *WsConnectionManager) HasTopic(topic string) bool {
+ m.mu.RLock()
+ defer m.mu.RUnlock()
+
+ sessions := m.topics[topic]
+ return len(sessions) > 0
+}
+
func (m *WsConnectionManager) subscribeLocked(session *ClientSession, topic string) {
if _, exists := session.Topics[topic]; exists {
return
diff --git a/internal/services/ws_service.go b/internal/services/ws_service.go
index c8dc56b..a418f32 100644
--- a/internal/services/ws_service.go
+++ b/internal/services/ws_service.go
@@ -386,6 +386,14 @@ func (s *wsService) PublishToTopics(topics []string, event RealtimeEvent) {
}
}
+func (s *wsService) IsVisitorOnline(visitorID string) bool {
+ visitorID = strings.TrimSpace(visitorID)
+ if visitorID == "" {
+ return false
+ }
+ return s.manager.HasTopic(s.visitorTopic(visitorID))
+}
+
func (s *wsService) routeConversationTopics(conversation *models.Conversation) []string {
if conversation == nil {
return nil
diff --git a/web/app/(console)/conversations/page.tsx b/web/app/(console)/conversations/page.tsx
index 7cc81c4..42c4324 100644
--- a/web/app/(console)/conversations/page.tsx
+++ b/web/app/(console)/conversations/page.tsx
@@ -270,9 +270,27 @@ export default function ConversationsPage() {
- {conversation.subject} -
++ {conversation.subject} +
+ + + {conversation.customerOnline ? "用户在线" : "用户离线"} + +{conversation.externalSource} / diff --git a/web/lib/api/agent.ts b/web/lib/api/agent.ts index 550f0de..cfe3536 100644 --- a/web/lib/api/agent.ts +++ b/web/lib/api/agent.ts @@ -58,6 +58,7 @@ export type AgentConversation = { agentLastReadMessageId: number agentLastReadSeqNo: number agentLastReadAt?: string + customerOnline: boolean closedAt?: string tags?: AgentConversationTag[] participants?: AgentConversationParticipant[]