feat: 优化已读消息标记逻辑,提升性能和可读性

This commit is contained in:
kuaifan 2025-10-17 00:41:38 +00:00
parent 123c74de46
commit e8235dd0a2
2 changed files with 43 additions and 15 deletions

View File

@ -2196,7 +2196,10 @@ class DialogController extends AbstractController
switch ($type) { switch ($type) {
case 'read': case 'read':
// 标记已读 // 标记已读
$builder = WebSocketDialogMsgRead::whereDialogId($dialog_id)->whereUserid($user->userid)->whereReadAt(null); $builder = WebSocketDialogMsgRead::whereDialogId($dialog_id)
->whereUserid($user->userid)
->whereReadAt(null)
->select(['id', 'msg_id']);
if ($after_msg_id > 0) { if ($after_msg_id > 0) {
$builder->where('msg_id', '>=', $after_msg_id); $builder->where('msg_id', '>=', $after_msg_id);
} }

View File

@ -3,6 +3,7 @@
namespace App\Models; namespace App\Models;
use Carbon\Carbon; use Carbon\Carbon;
use Illuminate\Support\Facades\DB;
/** /**
* App\Models\WebSocketDialogMsgRead * App\Models\WebSocketDialogMsgRead
@ -76,24 +77,48 @@ class WebSocketDialogMsgRead extends AbstractModel
*/ */
public static function onlyMarkRead($list) public static function onlyMarkRead($list)
{ {
$dialogMsg = []; if (empty($list)) {
return;
}
$collection = collect($list);
if ($collection->isEmpty()) {
return;
}
$now = Carbon::now();
$ids = [];
$msgCounts = [];
/** @var WebSocketDialogMsgRead $item */ /** @var WebSocketDialogMsgRead $item */
foreach ($list as $item) { foreach ($collection as $item) {
$item->read_at = Carbon::now(); $ids[] = $item->id;
$item->save(); if ($item->msg_id) {
if (isset($dialogMsg[$item->msg_id])) { $msgCounts[$item->msg_id] = ($msgCounts[$item->msg_id] ?? 0) + 1;
$dialogMsg[$item->msg_id]['readNum']++;
} else {
$dialogMsg[$item->msg_id] = [
'dialogMsg' => $item->webSocketDialogMsg,
'readNum' => 1
];
} }
} }
foreach ($dialogMsg as $item) {
if ($item['dialogMsg']) { if (!empty($ids)) {
$item['dialogMsg']->increment('read', $item['readNum']); DB::table((new self())->getTable())
->whereIn('id', $ids)
->whereNull('read_at')
->update(['read_at' => $now]);
} }
if (!empty($msgCounts)) {
$cases = [];
$bindings = [];
foreach ($msgCounts as $msgId => $num) {
$cases[] = 'WHEN ? THEN ?';
$bindings[] = $msgId;
$bindings[] = $num;
}
$msgIds = array_keys($msgCounts);
$bindings = array_merge($bindings, $msgIds);
$placeholders = implode(',', array_fill(0, count($msgIds), '?'));
$table = DB::getTablePrefix() . (new WebSocketDialogMsg())->getTable();
$sql = "UPDATE {$table} SET `read` = `read` + CASE `id` " . implode(' ', $cases) . " END WHERE `deleted_at` IS NULL AND `id` IN ({$placeholders})";
DB::update($sql, $bindings);
} }
} }
} }