From 845817a0287595c3c28a45dcf67bdcba154522b9 Mon Sep 17 00:00:00 2001 From: flying-hero <462087392@qq.com> Date: Sat, 4 Apr 2026 13:04:26 +0800 Subject: [PATCH] =?UTF-8?q?=F0=9F=A4=96=20=E6=B7=BB=E5=8A=A0=E8=99=9A?= =?UTF-8?q?=E6=8B=9F=E5=9D=90=E5=B8=AD=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 后端: - 创建会议时自动添加虚拟龙虾参会者 - 如果指定了 host_agent_id,添加该龙虾 - 否则添加 2 个虚拟助手(🤖 和 🦊) 前端: - 创建会议时可选"添加虚拟坐席" - 默认勾选,方便测试 @ 功能 - 提示文字说明用途 使用场景: - 用户创建会议 → 自动有虚拟龙虾 - 点击虚拟龙虾座位 → @ 该龙虾 - 测试 @ 功能无需真实龙虾在线 --- backend/create_test_user.py | 40 +++++++++++++++++++++++++++++++++++++ backend/meetings/views.py | 33 ++++++++++++++++++++++++++++++ frontend/src/App.js | 17 +++++++++++++++- 3 files changed, 89 insertions(+), 1 deletion(-) create mode 100644 backend/create_test_user.py diff --git a/backend/create_test_user.py b/backend/create_test_user.py new file mode 100644 index 00000000..e56e6c8c --- /dev/null +++ b/backend/create_test_user.py @@ -0,0 +1,40 @@ +#!/usr/bin/env python3 +""" +创建测试用户 +""" + +import os +os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'meeting_room.settings') + +import django +django.setup() + +from django.contrib.auth import get_user_model +User = get_user_model() + +# 创建测试用户 +users = [ + {'username': 'test', 'email': 'test@example.com', 'password': 'test123'}, + {'username': 'polaris', 'email': 'polaris@example.com', 'password': 'password123'}, +] + +for u in users: + user, created = User.objects.get_or_create(username=u['username']) + if created: + user.email = u['email'] + user.set_password(u['password']) + user.save() + print(f"✅ 创建用户:{u['username']}") + else: + # 更新密码 + user.set_password(u['password']) + user.save() + print(f"🔄 更新用户密码:{u['username']}") + + # 绑定一个测试龙虾 + user.add_linked_agent('flying_hero', '飞行侠', '🦸', 'phospher-openclaw') + print(f" 🔗 绑定龙虾:飞行侠 🦸") + +print("\n✅ 测试用户创建完成!") +print(" 用户名:test / 密码:test123") +print(" 用户名:polaris / 密码:password123") diff --git a/backend/meetings/views.py b/backend/meetings/views.py index c1a6254e..ad8b80a9 100644 --- a/backend/meetings/views.py +++ b/backend/meetings/views.py @@ -53,6 +53,39 @@ class MeetingViewSet(viewsets.ModelViewSet): is_host=True ) + # 创建虚拟龙虾参会者(如果指定了 host_agent_id) + if host_agent_id: + Participant.objects.create( + meeting=meeting, + agent_type='openclaw', + agent_id=host_agent_id, + agent_name='飞行侠', + agent_emoji='🦸', + nickname='飞行侠', + is_host=False + ) + + # 如果没有指定 host_agent_id,创建两个虚拟龙虾 + if not host_agent_id and request.data.get('auto_add_virtual_agents', True): + Participant.objects.create( + meeting=meeting, + agent_type='openclaw', + agent_id='virtual_agent_1', + agent_name='虚拟助手 1 号', + agent_emoji='🤖', + nickname='虚拟助手 1 号', + is_host=False + ) + Participant.objects.create( + meeting=meeting, + agent_type='openclaw', + agent_id='virtual_agent_2', + agent_name='虚拟助手 2 号', + agent_emoji='🦊', + nickname='虚拟助手 2 号', + is_host=False + ) + return Response(serializer.data, status=status.HTTP_201_CREATED) @action(detail=True, methods=['post']) diff --git a/frontend/src/App.js b/frontend/src/App.js index 54820a20..4c5e678a 100644 --- a/frontend/src/App.js +++ b/frontend/src/App.js @@ -136,6 +136,7 @@ function LoginPage() { function MeetingList() { const [meetings, setMeetings] = useState([]); const [topic, setTopic] = useState(''); + const [autoAddAgents, setAutoAddAgents] = useState(true); const navigate = useNavigate(); const token = localStorage.getItem('token'); @@ -154,7 +155,10 @@ function MeetingList() { const createMeeting = async (e) => { e.preventDefault(); try { - const res = await axios.post(`${API_BASE}/meetings/`, { topic }); + const res = await axios.post(`${API_BASE}/meetings/`, { + topic, + auto_add_virtual_agents: autoAddAgents + }); navigate(`/meeting/${res.data.id}`); } catch (error) { alert('创建失败:' + (error.response?.data?.detail || error.message)); @@ -173,8 +177,19 @@ function MeetingList() {

创建会议

setTopic(e.target.value)} style={styles.input} required /> +
+

+ 💡 勾选"添加虚拟坐席"会自动创建 2 个虚拟龙虾参会者,方便测试 @ 功能 +

{meetings.map(m => (