You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Laravel中如何实现/conversations路由展示收到的消息列表?

解决/conversations路由显示所有用户的问题

看起来你是把用户表的全量数据直接返回给页面了,这才导致所有用户都显示出来。咱们要做的是只筛选出和当前用户有过消息往来的用户,下面给你具体的解决思路和代码示例:

核心思路

消息系统里,用户的对话对象必然是和他有过消息收发的人——要么对方给他发过消息,要么他给对方发过消息。我们需要基于这个逻辑过滤用户列表,同时去重(避免同一个用户因为互发消息多次出现),还要排除当前用户自己。

具体实现(以Laravel为例,其他框架思路类似)

1. 确保模型关联正确

首先在User模型里定义和消息的关联关系,方便后续查询:

// app/Models/User.php
public function messagesSent()
{
    return $this->hasMany(Message::class, 'sender_id');
}

public function messagesReceived()
{
    return $this->hasMany(Message::class, 'receiver_id');
}

2. 修改控制器查询逻辑

把原来查询所有用户的代码,替换成过滤有对话记录的用户:

// 在你的ConversationsController的index方法里
$currentUser = auth()->user();

// 筛选出所有和当前用户有过消息的用户,去重并排除自己
$conversationUsers = User::whereHas('messagesSent', function ($query) use ($currentUser) {
    // 对方给当前用户发过消息
    $query->where('receiver_id', $currentUser->id);
})->orWhereHas('messagesReceived', function ($query) use ($currentUser) {
    // 当前用户给对方发过消息
    $query->where('sender_id', $currentUser->id);
})
->where('id', '!=', $currentUser->id) // 排除自己
->distinct() // 去重,避免重复显示同一个用户
->get();

return view('conversations.index', compact('conversationUsers'));

3. 优化体验:按最新消息排序

如果想让最新对话排在最前面,可以调整查询,加入最后一条消息的时间排序:

use Illuminate\Support\Facades\DB;

$conversationUsers = User::select('users.*', DB::raw('MAX(m.created_at) as last_message_at'))
    ->join('messages as m', function ($join) use ($currentUser) {
        $join->on('users.id', '=', 'm.sender_id')
             ->where('m.receiver_id', $currentUser->id)
             ->orOn('users.id', '=', 'm.receiver_id')
             ->where('m.sender_id', $currentUser->id);
    })
    ->where('users.id', '!=', $currentUser->id)
    ->groupBy('users.id')
    ->orderBy('last_message_at', 'desc')
    ->get();

原生SQL版本(如果不用ORM)

如果你的项目不用ORM,直接写SQL的话,查询语句可以这样写:

SELECT DISTINCT u.*, MAX(m.created_at) AS last_message_at
FROM users u
JOIN messages m 
  ON (u.id = m.sender_id AND m.receiver_id = ?) 
  OR (u.id = m.receiver_id AND m.sender_id = ?)
WHERE u.id != ?
GROUP BY u.id
ORDER BY last_message_at DESC;

把?替换成当前登录用户的ID即可。

这样修改后,/conversations路由就只会显示和当前用户有过消息往来的用户列表了,完全符合你的预期。

内容的提问来源于stack exchange,提问作者Douggy Budget

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 08:40:25