飞行侠优化:点击座位 @Agent

功能:
- 点击座位自动填充 @消息
- 鼠标悬停放大效果
- 自动聚焦输入框

体验优化:
- 悬停视觉反馈
- 点击即可 @ 该参会者
- 无需手动输入 agent_id
This commit is contained in:
2026-04-04 11:53:20 +08:00
parent 5d963af156
commit 09f2bb9b6c

View File

@@ -108,6 +108,7 @@ function MeetingRoom() {
const [content, setContent] = useState(''); const [content, setContent] = useState('');
const [participants, setParticipants] = useState([]); const [participants, setParticipants] = useState([]);
const [meeting, setMeeting] = useState(null); const [meeting, setMeeting] = useState(null);
const [hoveredSeat, setHoveredSeat] = useState(null);
const token = localStorage.getItem('token'); const token = localStorage.getItem('token');
useEffect(() => { useEffect(() => {
@@ -152,17 +153,18 @@ function MeetingRoom() {
} }
}; };
const mentionAgent = async () => { const mentionAgent = async (targetAgentId, agentName) => {
const targetAgentId = prompt('@哪个 Agent输入 agent_id:'); const target = targetAgentId || prompt('@哪个 Agent输入 agent_id:');
if (!targetAgentId || !content.trim()) return; if (!target || !content.trim()) return;
const name = agentName || target;
try { try {
await axios.post(`${API_BASE}/meetings/${id}/mention_agent/`, { await axios.post(`${API_BASE}/meetings/${id}/mention_agent/`, {
target_agent_id: targetAgentId, content, target_agent_id: target, content,
sender_name: localStorage.getItem('user') ? JSON.parse(localStorage.getItem('user')).username : 'User' sender_name: localStorage.getItem('user') ? JSON.parse(localStorage.getItem('user')).username : 'User'
}); });
setContent(''); setContent('');
fetchMessages(); fetchMessages();
alert(`✅ 已 @${targetAgentId}`); alert(`✅ 已 @${name}`);
} catch (error) { } catch (error) {
alert('发送失败:' + (error.response?.data?.error || error.message)); alert('发送失败:' + (error.response?.data?.error || error.message));
} }
@@ -230,7 +232,19 @@ function MeetingRoom() {
<h2>🪑 座位图 <span style={styles.badge}>{participants.length}</span></h2> <h2>🪑 座位图 <span style={styles.badge}>{participants.length}</span></h2>
<div style={styles.seats}> <div style={styles.seats}>
{participants.map(p => ( {participants.map(p => (
<div key={p.id} style={styles.seat}> <div
key={p.id}
style={{...styles.seat, ...(hoveredSeat === p.id ? styles.seatHover : {})}}
onClick={() => {
if (p.agent_id) {
setContent(`@${p.nickname} `);
document.querySelector('input[placeholder="输入消息..."]')?.focus();
}
}}
onMouseEnter={() => setHoveredSeat(p.id)}
onMouseLeave={() => setHoveredSeat(null)}
title={p.agent_id ? '点击 @ 此人' : ''}
>
<div style={styles.seatEmoji}>{p.agent_emoji || '👤'}</div> <div style={styles.seatEmoji}>{p.agent_emoji || '👤'}</div>
<div style={styles.seatName}>{p.nickname}</div> <div style={styles.seatName}>{p.nickname}</div>
{p.is_host && <div style={styles.hostBadge}>👑</div>} {p.is_host && <div style={styles.hostBadge}>👑</div>}
@@ -300,7 +314,8 @@ const styles = {
badge: { background: '#667eea', color: 'white', padding: '4px 10px', borderRadius: '20px', fontSize: '12px', fontWeight: '600' }, badge: { background: '#667eea', color: 'white', padding: '4px 10px', borderRadius: '20px', fontSize: '12px', fontWeight: '600' },
btnGroup: { display: 'flex', marginTop: '10px' }, btnGroup: { display: 'flex', marginTop: '10px' },
seats: { display: 'flex', flexWrap: 'wrap', gap: '15px', justifyContent: 'center' }, seats: { display: 'flex', flexWrap: 'wrap', gap: '15px', justifyContent: 'center' },
seat: { background: 'linear-gradient(135deg, #667eea 0%, #764ba2 100%)', color: 'white', padding: '15px', borderRadius: '50%', width: '90px', height: '90px', display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center', textAlign: 'center' }, seat: { background: 'linear-gradient(135deg, #667eea 0%, #764ba2 100%)', color: 'white', padding: '15px', borderRadius: '50%', width: '90px', height: '90px', display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center', textAlign: 'center', cursor: 'pointer', transition: 'transform 0.2s', ':hover': { transform: 'scale(1.1)' } },
seatHover: { transform: 'scale(1.05)' },
seatEmoji: { fontSize: '28px', marginBottom: '5px' }, seatEmoji: { fontSize: '28px', marginBottom: '5px' },
seatName: { fontSize: '12px', fontWeight: '600' }, seatName: { fontSize: '12px', fontWeight: '600' },
hostBadge: { fontSize: '10px', opacity: '0.8' }, hostBadge: { fontSize: '10px', opacity: '0.8' },