love_php/app/Services/ChatSessionService.php
2026-04-02 09:20:51 +08:00

171 lines
6.7 KiB
PHP

<?php
namespace App\Services;
use App\Contracts\UserContract;
use App\Models\App\MsgHistory;
use App\Models\App\Team;
use App\Models\App\UserTeam;
use App\Models\ChatMessage;
use App\Models\User;
use Illuminate\Support\Facades\DB;
class ChatSessionService
{
protected $commonUtils;
public function __construct()
{
$this->commonUtils = new CommonUtilsService();
}
/**
* 小程序会话数据
*/
public function session()
{
$user = auth()->user();
$user_id = request()->input('user_id');
if (!$user_id) {
$user_id = $user->id;
}
\DB::enableQueryLog(); // 启用查询日志
$group_chat = (new Team())
->setTable('t')
->from('teams as t')
->join("user_team as ut", "t.id", "=", "ut.team_id")
->leftJoin("msg_histories as last_msg", function ($join) {
$join->on('t.id', '=', 'last_msg.team_id')
->whereRaw('ufutx_last_msg.id IN (select MAX(last_msg2.id) from ufutx_msg_histories as last_msg2 group by last_msg2.team_id)');
})
->select('ut.id', 'ut.user_id', 'ut.team_id as join_to_id')
->selectRaw("'group_chat' as chat_type")
->selectRaw("ufutx_last_msg.id as last_id")
->selectRaw("UNIX_TIMESTAMP(if(ufutx_last_msg.created_at,ufutx_last_msg.created_at,ufutx_t.created_at)) as last_time")
->selectRaw('ufutx_ut.is_top')
->where('ut.user_id', $user_id);
$u1 = DB::table('chat_messages')->where('user_id', '<>', $user_id)->where('other_user_id', $user_id)
->select('id', 'user_id as receiver', 'content', 'created_at');
$u2 = DB::table('chat_messages')->where('user_id', '=', $user_id)->where('other_user_id', '<>', $user_id)
->select('id', 'other_user_id as receiver', 'content', 'created_at');
$query = $u1->union($u2)->orderBy('id', 'desc');
$sql = $query->toSql();
$linkmen = DB::table(DB::raw("($sql) as ufutx_m"))
->mergeBindings($query)
->join('message_linkmen as l', 'm.receiver', 'l.other_user_id')
->join('users as u', 'l.other_user_id', 'u.id')
->whereNull('l.deleted_at')
->where('l.user_id', $user_id)
->select('l.id', 'l.user_id', 'm.receiver as join_to_id')
->selectRaw("'linkmen' as chat_type")
->selectRaw("ufutx_m.id as last_id")
->selectRaw("UNIX_TIMESTAMP(ufutx_m.created_at) as last_time")
->selectRaw("'0' as is_top")
->groupBy(['join_to_id'])
->orderBy('last_time', 'desc');
$union_all_query = $linkmen->unionAll($group_chat);
$data = DB::table(DB::raw("({$union_all_query->toSql()}) as sub"))
->mergeBindings($union_all_query)
->orderBy('is_top', 'desc')
->orderBy('last_time', 'desc')
->paginate();
$queries = \DB::getQueryLog(); // 获取查询日志
// \Log::info("查看sql语句");
// \Log::info($queries);
foreach ($data as &$item) {
switch ($item->chat_type) {
case 'linkmen':
$item = $this->handleLinkmen($item, $user);
break;
case 'group_chat':
$item = $this->handleGroupChat($item, $user);
break;
}
}
return $data;
}
private function handleLinkmen($item, $user)
{
$item->other_user_id = $item->join_to_id;
$item->new_count = ChatMessage::where('status', 0)->where('other_user_id', $user->id)
->where('user_id', $item->other_user_id)->count() ?: 0;
$item->type = $user->type;
$item->other_user = User::selectRaw('id,nickname,photo,app_avatar,circle_avatar,type,hidden_profile,sex,is_photo_audited')->find($item->other_user_id);
$item->last_message = ChatMessage::select('user_id', 'other_user_id', 'content', 'content_type', 'created_at', 'is_recall')->find($item->last_id);
if (!$item->last_message) {
return $item;
}
if ($item->last_message) {
$last_time = $this->commonUtils->getLastTime(strtotime($item->last_message->created_at->toDateTimeString()));
$last_time = (explode(' ', $last_time))[0];
$item->last_message->last_time = $last_time;
switch ($item->last_message->content_type) {
case 'AUDIO':
$content = "[语音]";
break;
case 'VIDEO':
$content = "[视频]";
break;
case 'PICTURE':
$content = "[图片]";
break;
default:
$content = $item->last_message->content;
}
if ($item->last_message->is_recall) {
$text = $item->last_message->user_id == $user->id ? '我' : '对方';
$content = "[{$text}撤回了一条消息]";
}
$item->last_message->content = $content;
}
return $item;
}
private function handleGroupChat($item, $user)
{
$item->team_id = $item->join_to_id;
$item->team = Team::select('id', 'tid', 'tname', 'icon')->find($item->team_id);
$item->last_message = MsgHistory::with('otherUser:id,nickname,photo,app_avatar,circle_avatar,type,hidden_profile')
->whereHas('otherUser')
->select('user_id', 'team_id', 'body', 'created_at', 'type', 'is_recall')
->find($item->last_id) ?: null;
if (!$item->last_message) {
return $item;
}
//群昵称
$group_chat_nick = UserTeam::where('user_id', $item->last_message->otherUser->id)->where('team_id', $item->team_id)->value('nick');
if (!empty($group_chat_nick)) {
$item->last_message->otherUser->nickname = $group_chat_nick;
}
$last_time = $this->commonUtils->getLastTime(strtotime($item->last_message->created_at->toDateTimeString()));
$last_time = (explode(' ', $last_time))[0];
$item->last_message->last_time = $last_time;
$body = json_decode(json_encode($item->last_message->body), true);
switch ($item->last_message->type) {
case 1:
$body['msg'] = '[图片]';
break;
case 2:
$body['msg'] = '[语音]';
break;
case 3:
$body['msg'] = '[视频]';
break;
}
if ($item->last_message->is_recall) {
$body['msg'] = '[撤回了一条消息]';
}
$item->last_message->body = json_encode($body);
return $item;
}
}