功能:右侧「房间」面板显示所有房间在线人数,点击可切换房间

- ChatController 新增 roomsOnlineStatus() 接口
- GET /rooms/online-status 返回所有房间名称+Redis 实时在线人数
- 右侧面板房间列表动态渲染:当前房间高亮蓝色,有人数绿色徽标,空房间灰色
- 点击其他房间直接跳转,当前房间禁止点击并标注「当前」
- 切换到「房间」Tab 时自动触发拉取
This commit is contained in:
2026-03-03 14:46:22 +08:00
parent ad91c4420a
commit 4324633f82
4 changed files with 96 additions and 3 deletions
@@ -31,7 +31,7 @@
// 切换名单/房间/贴图/酷库 面板
['users', 'rooms', 'emoji', 'action'].forEach(t => {
document.getElementById('panel-' + t).style.display = t === tab ? 'block' : 'none';
document.getElementById('tab-' + t).classList.toggle('active', t === tab);
document.getElementById('tab-' + t)?.classList.toggle('active', t === tab);
});
// 贴图 Tab 懒加载
if (tab === 'emoji') {
@@ -40,6 +40,64 @@
img.removeAttribute('data-src');
});
}
// 房间 Tab:拉取在线人数列表
if (tab === 'rooms') {
loadRoomsOnlineStatus();
}
}
/**
* 拉取所有房间在线人数并渲染到右侧面板
*/
const _currentRoomId = {{ $room->id }};
function loadRoomsOnlineStatus() {
const container = document.getElementById('rooms-online-list');
if (!container) {
return;
}
fetch('{{ route('chat.rooms-online-status') }}')
.then(r => r.json())
.then(data => {
if (!data.rooms || !data.rooms.length) {
container.innerHTML =
'<div style="text-align:center;color:#bbb;padding:16px 0;font-size:11px;">暂无房间</div>';
return;
}
container.innerHTML = data.rooms.map(room => {
const isCurrent = room.id === _currentRoomId;
const closed = !room.door_open;
const bg = isCurrent ? '#ecf4ff' : '#fff';
const border = isCurrent ? '#aac5f0' : '#e0eaf5';
const nameColor = isCurrent ? '#336699' : (closed ? '#bbb' : '#444');
const badge = room.online > 0 ?
`<span style="background:#e8f5e9;color:#2e7d32;border-radius:8px;padding:0 5px;font-size:10px;font-weight:bold;">${room.online} 人</span>` :
`<span style="background:#f5f5f5;color:#bbb;border-radius:8px;padding:0 5px;font-size:10px;">空</span>`;
const currentTag = isCurrent ?
`<span style="font-size:9px;color:#336699;opacity:.7;margin-left:3px;">当前</span>` :
'';
const clickHandler = isCurrent ? '' : `onclick="location.href='/room/${room.id}'"`;
return `<div ${clickHandler}
style="display:flex;align-items:center;justify-content:space-between;
padding:5px 8px;margin:2px 3px;border-radius:5px;
border:1px solid ${border};background:${bg};
cursor:${isCurrent ? 'default' : 'pointer'};
transition:background .15s;"
onmouseover="if(${!isCurrent}) this.style.background='#ddeeff';"
onmouseout="this.style.background='${bg}';">
<span style="color:${nameColor};font-size:11px;font-weight:${isCurrent?'bold':'normal'};overflow:hidden;text-overflow:ellipsis;white-space:nowrap;max-width:90px;">
${room.name}${currentTag}
</span>
${badge}
</div>`;
}).join('');
})
.catch(() => {
container.innerHTML =
'<div style="text-align:center;color:#f00;padding:10px;font-size:11px;">加载失败</div>';
});
}
// ── 分屏切换 ──────────────────────────────────────