
关于
构建实时客服聊天系统,包含用户端浮动组件和客服端管理面板。适用于实时聊天、客户支持、即时通讯或应用内支持需求
name: chat-widget description: 构建一个实时客服聊天系统,包含面向用户的浮动组件和面向客服人员的管理后台。当用户需要实时聊天、客户支持聊天、实时消息或应用内支持时使用。 risk: unknown source: community
实时客服聊天组件
构建一个实时客服聊天系统,包含面向用户的浮动组件和面向客服人员的管理后台。
何时使用此技能
当用户想要:
- 为应用添加实时聊天组件
- 构建客户支持聊天功能
- 创建用户与管理员之间的实时消息
- 添加应用内支持渠道
架构概览
┌─────────────────────────────────────────────────────────────────┐
│ FRONTEND │
├─────────────────────────────┬───────────────────────────────────┤
│ User Widget │ Admin Dashboard │
│ - Floating chat button │ - Chat list (active/archived) │
│ - Message panel │ - Conversation view │
│ - Unread badge │ - Archive/restore controls │
│ - Connection indicator │ - User info display │
└─────────────┬───────────────┴───────────────┬───────────────────┘
│ │
│ WebSocket + REST API │
▼ ▼
┌─────────────────────────────────────────────────────────────────┐
│ BACKEND │
├─────────────────────────────────────────────────────────────────┤
│ Channels │ Controllers │
│ - ChatChannel (per chat) │ - User: get/create chat │
│ - AdminChannel (global) │ - Admin: list, view, archive │
├─────────────────────────────┼───────────────────────────────────┤
│ Models │ Jobs │
│ - Chat (1 per user) │ - Email notification (delayed) │
│ - Message (many per chat) │ │
└─────────────────────────────────────────────────────────────────┘
实现指南
步骤 1:数据模型
创建两张表:support_chats 和 support_messages。
support_chats
id - primary key (UUID recommended)
user_id - foreign key to users (UNIQUE - one chat per user)
last_message_at - timestamp (for sorting chats by recency)
admin_viewed_at - timestamp (tracks when admin last viewed)
archived_at - timestamp (null = active, set = archived)
created_at
updated_at
support_messages
id - primary key (UUID recommended)
chat_id - foreign key to support_chats
content - text (required)
sender_type - enum: 'user' | 'admin'
read_at - timestamp (null = unread)
created_at
updated_at
关键索引:
support_chats.user_id(唯一)support_chats.last_message_at(用于排序)support_chats.archived_at(用于过滤)support_messages.chat_idsupport_messages.(chat_id, created_at)(复合索引,用于排序)
模型关系:
User has_one SupportChat
SupportChat belongs_to User
SupportChat has_many SupportMessages
SupportMessage belongs_to SupportChat
需要实现的模型方法:
Chat 模型:
function touch_last_message()
update last_message_at = now()
function unread_for_admin?()
return exists message where sender_type = 'user'
and created_at > admin_viewed_at
function mark_viewed_by_admin()
update admin_viewed_at = now()
function archive()
update archived_at = now()
function unarchive()
update archived_at = null
function archived?()
return archived_at != null
Message 模型:
after_create:
chat.touch_last_message()
if sender_type == 'user' and chat.archived?:
chat.unarchive() // Auto-reactivate on new user message
after_create_commit:
broadcast_to_chat_channel(message_data)
if sender_type == 'user':
broadcast_to_admin_notification_channel(message_data, chat_info)
if sender_type == 'admin':
schedule_email_notification(delay: 5.minutes)
步骤 2:API 端点
面向用户:
GET /support_chat - Get or create user's chat with messages
PATCH /support_chat/mark_read - Mark admin messages as read
面向管理员:
GET /admin/chats - List chats (query: archived=true/false)
GET /admin/chats/:id - Get chat with messages
POST /admin/chats/:id/archive - Archive chat
POST /admin/chats/:id/unarchive - Restore chat
控制器逻辑:
用户 GET /support_chat:
function show()
chat = current_user.support_chat || create_chat(user: current_user)
return {
id: chat.id,
messages: chat.messages.map(m => serialize_message(m))
}
管理员 GET /admin/chats:
function index()
chats = SupportChat
.where(archived_at: params.archived ? not_null : null)
.i
兼容工具
Claude CodeCursor
标签
后端开发
