mirror of
https://github.com/kuaifan/dootask.git
synced 2025-12-12 11:19:56 +00:00
perf: 优化消息搜索速度
This commit is contained in:
parent
b976f294f9
commit
287b6b396d
@ -147,18 +147,26 @@ class DialogController extends AbstractController
|
|||||||
}
|
}
|
||||||
// 搜索消息会话
|
// 搜索消息会话
|
||||||
if (count($list) < 20) {
|
if (count($list) < 20) {
|
||||||
$msgs = WebSocketDialog::select(['web_socket_dialogs.*', 'u.top_at', 'u.last_at', 'u.mark_unread', 'u.silence', 'u.hide', 'u.color', 'u.updated_at as user_at', 'm.id as search_msg_id'])
|
$msgs = WebSocketDialogMsg::select(['web_socket_dialog_msgs.*'])
|
||||||
->join('web_socket_dialog_users as u', 'web_socket_dialogs.id', '=', 'u.dialog_id')
|
->join('web_socket_dialog_msg_reads as r', 'r.msg_id', '=', 'web_socket_dialog_msgs.id')
|
||||||
->join('web_socket_dialog_msgs as m', 'web_socket_dialogs.id', '=', 'm.dialog_id')
|
->where('r.userid', $user->userid)
|
||||||
->where('u.userid', $user->userid)
|
->where('r.live', 1)
|
||||||
->where('m.key', 'LIKE', "%{$key}%")
|
->where('web_socket_dialog_msgs.key', 'LIKE', "%{$key}%")
|
||||||
->orderByDesc('m.id')
|
->orderByDesc('r.msg_id')
|
||||||
->take(20 - count($list))
|
->take(20 - count($list))
|
||||||
->get();
|
->get();
|
||||||
$msgs->transform(function (WebSocketDialog $item) use ($user) {
|
foreach ($msgs as $msg) {
|
||||||
return $item->formatData($user->userid);
|
$item = WebSocketDialog::select(['web_socket_dialogs.*', 'u.top_at', 'u.last_at', 'u.mark_unread', 'u.silence', 'u.hide', 'u.color', 'u.updated_at as user_at'])
|
||||||
});
|
->join('web_socket_dialog_users as u', 'web_socket_dialogs.id', '=', 'u.dialog_id')
|
||||||
$list = array_merge($list, $msgs->toArray());
|
->where('web_socket_dialogs.id', $msg->dialog_id)
|
||||||
|
->first();
|
||||||
|
if (empty($item)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
$item->search_msg_id = $msg->id;
|
||||||
|
$item->last_msg = $msg;
|
||||||
|
$list[] = $item->formatData($user->userid);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
//
|
//
|
||||||
return Base::retSuccess('success', $list);
|
return Base::retSuccess('success', $list);
|
||||||
|
|||||||
@ -200,7 +200,7 @@ class WebSocketDialog extends AbstractModel
|
|||||||
//
|
//
|
||||||
if (isset($this->search_msg_id)) {
|
if (isset($this->search_msg_id)) {
|
||||||
// 最后消息 (搜索预览消息)
|
// 最后消息 (搜索预览消息)
|
||||||
$this->last_msg = WebSocketDialogMsg::whereDialogId($this->id)->find($this->search_msg_id);
|
$this->last_msg = $this->last_msg ?? WebSocketDialogMsg::whereDialogId($this->id)->find($this->search_msg_id);
|
||||||
$this->last_at = $this->last_msg ? Carbon::parse($this->last_msg->created_at)->toDateTimeString() : null;
|
$this->last_at = $this->last_msg ? Carbon::parse($this->last_msg->created_at)->toDateTimeString() : null;
|
||||||
} else {
|
} else {
|
||||||
// 未读信息
|
// 未读信息
|
||||||
@ -214,11 +214,11 @@ class WebSocketDialog extends AbstractModel
|
|||||||
// 是否免打扰
|
// 是否免打扰
|
||||||
$this->silence = $this->silence ?? $dialogUserFun('silence');
|
$this->silence = $this->silence ?? $dialogUserFun('silence');
|
||||||
// 对话人数
|
// 对话人数
|
||||||
$this->people = WebSocketDialogUser::whereDialogId($this->id)->count();
|
$this->people = $this->people ?? WebSocketDialogUser::whereDialogId($this->id)->count();
|
||||||
// 有待办
|
// 有待办
|
||||||
$this->todo_num = WebSocketDialogMsgTodo::whereDialogId($this->id)->whereUserid($userid)->whereDoneAt(null)->count();
|
$this->todo_num = $this->todo_num ?? WebSocketDialogMsgTodo::whereDialogId($this->id)->whereUserid($userid)->whereDoneAt(null)->count();
|
||||||
// 最后消息
|
// 最后消息
|
||||||
$this->last_msg = WebSocketDialogMsg::whereDialogId($this->id)->orderByDesc('id')->first();
|
$this->last_msg = $this->last_msg ?? WebSocketDialogMsg::whereDialogId($this->id)->orderByDesc('id')->first();
|
||||||
}
|
}
|
||||||
// 对方信息
|
// 对方信息
|
||||||
$this->pinyin = Base::cn2pinyin($this->name);
|
$this->pinyin = Base::cn2pinyin($this->name);
|
||||||
|
|||||||
@ -200,6 +200,7 @@ class WebSocketDialogMsg extends AbstractModel
|
|||||||
'msg_id' => $this->id,
|
'msg_id' => $this->id,
|
||||||
'userid' => $userid,
|
'userid' => $userid,
|
||||||
'after' => 1,
|
'after' => 1,
|
||||||
|
'live' => 1,
|
||||||
]);
|
]);
|
||||||
if ($msgRead->saveOrIgnore()) {
|
if ($msgRead->saveOrIgnore()) {
|
||||||
$this->send = WebSocketDialogMsgRead::whereMsgId($this->id)->count();
|
$this->send = WebSocketDialogMsgRead::whereMsgId($this->id)->count();
|
||||||
@ -638,16 +639,35 @@ class WebSocketDialogMsg extends AbstractModel
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 生成关键词
|
* 生成关键词并保存
|
||||||
* @return string
|
* @return void
|
||||||
*/
|
*/
|
||||||
public function generateMsgKey()
|
public function generateKeyAndSave(): void
|
||||||
{
|
{
|
||||||
return match ($this->type) {
|
$key = '';
|
||||||
'text' => str_replace(" ", " ", strip_tags($this->msg['text'])),
|
switch ($this->type) {
|
||||||
'meeting', 'file' => $this->msg['name'],
|
case 'text':
|
||||||
default => '',
|
case 'vote':
|
||||||
};
|
case 'word-chain':
|
||||||
|
$key = strip_tags($this->msg['text']);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'file':
|
||||||
|
$key = $this->msg['name'];
|
||||||
|
$key = preg_replace("/^(image|\d+)\.(png|jpg|jpeg|webp|gif)$/i", "", $key);
|
||||||
|
$key = preg_replace("/^LongText-(.*?)/i", "", $key);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'meeting':
|
||||||
|
$key = $this->msg['name'];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
$key = str_replace([""", "&", "<", ">"], "", $key);
|
||||||
|
$key = str_replace(["\r", "\n", "\t", " "], " ", $key);
|
||||||
|
$key = preg_replace("/^\/[A-Za-z]+/", " ", $key);
|
||||||
|
$key = preg_replace("/\s+/", " ", $key);
|
||||||
|
$this->key = trim($key);
|
||||||
|
$this->save();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -997,8 +1017,7 @@ class WebSocketDialogMsg extends AbstractModel
|
|||||||
'modify' => $modify,
|
'modify' => $modify,
|
||||||
];
|
];
|
||||||
$dialogMsg->updateInstance($updateData);
|
$dialogMsg->updateInstance($updateData);
|
||||||
$dialogMsg->key = $dialogMsg->generateMsgKey();
|
$dialogMsg->generateKeyAndSave();
|
||||||
$dialogMsg->save();
|
|
||||||
//
|
//
|
||||||
WebSocketDialogUser::whereDialogId($dialog->id)->whereUserid($sender)->whereHide(1)->change([
|
WebSocketDialogUser::whereDialogId($dialog->id)->whereUserid($sender)->whereHide(1)->change([
|
||||||
'hide' => 0, // 修改消息时,显示会话(仅自己)
|
'hide' => 0, // 修改消息时,显示会话(仅自己)
|
||||||
@ -1045,8 +1064,7 @@ class WebSocketDialogMsg extends AbstractModel
|
|||||||
]);
|
]);
|
||||||
AbstractModel::transaction(function () use ($dialogMsg) {
|
AbstractModel::transaction(function () use ($dialogMsg) {
|
||||||
$dialogMsg->send = 1;
|
$dialogMsg->send = 1;
|
||||||
$dialogMsg->key = $dialogMsg->generateMsgKey();
|
$dialogMsg->generateKeyAndSave();
|
||||||
$dialogMsg->save();
|
|
||||||
//
|
//
|
||||||
if ($dialogMsg->type === 'meeting') {
|
if ($dialogMsg->type === 'meeting') {
|
||||||
MeetingMsg::createInstance([
|
MeetingMsg::createInstance([
|
||||||
|
|||||||
@ -16,6 +16,7 @@ use Carbon\Carbon;
|
|||||||
* @property int|null $email 是否发了邮件
|
* @property int|null $email 是否发了邮件
|
||||||
* @property int|null $after 在阅读之后才添加的记录
|
* @property int|null $after 在阅读之后才添加的记录
|
||||||
* @property int|null $dot 红点标记
|
* @property int|null $dot 红点标记
|
||||||
|
* @property int|null $live 是否在会话里
|
||||||
* @property \Illuminate\Support\Carbon|null $read_at 阅读时间
|
* @property \Illuminate\Support\Carbon|null $read_at 阅读时间
|
||||||
* @property-read \App\Models\WebSocketDialogMsg|null $webSocketDialogMsg
|
* @property-read \App\Models\WebSocketDialogMsg|null $webSocketDialogMsg
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|AbstractModel cancelAppend()
|
* @method static \Illuminate\Database\Eloquent\Builder|AbstractModel cancelAppend()
|
||||||
@ -32,6 +33,7 @@ use Carbon\Carbon;
|
|||||||
* @method static \Illuminate\Database\Eloquent\Builder|WebSocketDialogMsgRead whereDot($value)
|
* @method static \Illuminate\Database\Eloquent\Builder|WebSocketDialogMsgRead whereDot($value)
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|WebSocketDialogMsgRead whereEmail($value)
|
* @method static \Illuminate\Database\Eloquent\Builder|WebSocketDialogMsgRead whereEmail($value)
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|WebSocketDialogMsgRead whereId($value)
|
* @method static \Illuminate\Database\Eloquent\Builder|WebSocketDialogMsgRead whereId($value)
|
||||||
|
* @method static \Illuminate\Database\Eloquent\Builder|WebSocketDialogMsgRead whereLive($value)
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|WebSocketDialogMsgRead whereMention($value)
|
* @method static \Illuminate\Database\Eloquent\Builder|WebSocketDialogMsgRead whereMention($value)
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|WebSocketDialogMsgRead whereMsgId($value)
|
* @method static \Illuminate\Database\Eloquent\Builder|WebSocketDialogMsgRead whereMsgId($value)
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|WebSocketDialogMsgRead whereReadAt($value)
|
* @method static \Illuminate\Database\Eloquent\Builder|WebSocketDialogMsgRead whereReadAt($value)
|
||||||
|
|||||||
@ -4,6 +4,7 @@ namespace App\Observers;
|
|||||||
|
|
||||||
use App\Models\Deleted;
|
use App\Models\Deleted;
|
||||||
use App\Models\WebSocketDialog;
|
use App\Models\WebSocketDialog;
|
||||||
|
use App\Models\WebSocketDialogMsgRead;
|
||||||
use App\Models\WebSocketDialogUser;
|
use App\Models\WebSocketDialogUser;
|
||||||
|
|
||||||
class WebSocketDialogObserver
|
class WebSocketDialogObserver
|
||||||
@ -39,6 +40,7 @@ class WebSocketDialogObserver
|
|||||||
public function deleted(WebSocketDialog $webSocketDialog)
|
public function deleted(WebSocketDialog $webSocketDialog)
|
||||||
{
|
{
|
||||||
Deleted::record('dialog', $webSocketDialog->id, $this->userids($webSocketDialog));
|
Deleted::record('dialog', $webSocketDialog->id, $this->userids($webSocketDialog));
|
||||||
|
WebSocketDialogMsgRead::whereDialogId($webSocketDialog->id)->update(['live' => 0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -49,7 +51,9 @@ class WebSocketDialogObserver
|
|||||||
*/
|
*/
|
||||||
public function restored(WebSocketDialog $webSocketDialog)
|
public function restored(WebSocketDialog $webSocketDialog)
|
||||||
{
|
{
|
||||||
Deleted::forget('dialog', $webSocketDialog->id, $this->userids($webSocketDialog));
|
$userids = $this->userids($webSocketDialog);
|
||||||
|
Deleted::forget('dialog', $webSocketDialog->id, $userids);
|
||||||
|
WebSocketDialogMsgRead::whereDialogId($webSocketDialog->id)->whereIn('userid', $userids)->update(['live' => 1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -3,6 +3,7 @@
|
|||||||
namespace App\Observers;
|
namespace App\Observers;
|
||||||
|
|
||||||
use App\Models\Deleted;
|
use App\Models\Deleted;
|
||||||
|
use App\Models\WebSocketDialogMsgRead;
|
||||||
use App\Models\WebSocketDialogUser;
|
use App\Models\WebSocketDialogUser;
|
||||||
use Carbon\Carbon;
|
use Carbon\Carbon;
|
||||||
|
|
||||||
@ -29,6 +30,7 @@ class WebSocketDialogUserObserver
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
Deleted::forget('dialog', $webSocketDialogUser->dialog_id, $webSocketDialogUser->userid);
|
Deleted::forget('dialog', $webSocketDialogUser->dialog_id, $webSocketDialogUser->userid);
|
||||||
|
WebSocketDialogMsgRead::whereDialogId($webSocketDialogUser->dialog_id)->whereUserid($webSocketDialogUser->userid)->update(['live' => 1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -51,6 +53,7 @@ class WebSocketDialogUserObserver
|
|||||||
public function deleted(WebSocketDialogUser $webSocketDialogUser)
|
public function deleted(WebSocketDialogUser $webSocketDialogUser)
|
||||||
{
|
{
|
||||||
Deleted::record('dialog', $webSocketDialogUser->dialog_id, $webSocketDialogUser->userid);
|
Deleted::record('dialog', $webSocketDialogUser->dialog_id, $webSocketDialogUser->userid);
|
||||||
|
WebSocketDialogMsgRead::whereDialogId($webSocketDialogUser->dialog_id)->whereUserid($webSocketDialogUser->userid)->update(['live' => 0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -128,6 +128,7 @@ class WebSocketDialogMsgTask extends AbstractTask
|
|||||||
'mention' => $mention,
|
'mention' => $mention,
|
||||||
'silence' => $silence,
|
'silence' => $silence,
|
||||||
'dot' => $dot,
|
'dot' => $dot,
|
||||||
|
'live' => 1,
|
||||||
])->saveOrIgnore();
|
])->saveOrIgnore();
|
||||||
$array[$userid] = [
|
$array[$userid] = [
|
||||||
'userid' => $userid,
|
'userid' => $userid,
|
||||||
|
|||||||
@ -26,11 +26,7 @@ class AddWebSocketDialogMsgsKey extends Migration
|
|||||||
\App\Models\WebSocketDialogMsg::chunkById(100, function ($lists) {
|
\App\Models\WebSocketDialogMsg::chunkById(100, function ($lists) {
|
||||||
/** @var \App\Models\WebSocketDialogMsg $item */
|
/** @var \App\Models\WebSocketDialogMsg $item */
|
||||||
foreach ($lists as $item) {
|
foreach ($lists as $item) {
|
||||||
$key = $item->generateMsgKey();
|
$item->generateKeyAndSave();
|
||||||
if ($key) {
|
|
||||||
$item->key = $key;
|
|
||||||
$item->save();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@ -0,0 +1,130 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use App\Models\WebSocketDialog;
|
||||||
|
use App\Models\WebSocketDialogMsg;
|
||||||
|
use App\Models\WebSocketDialogMsgRead;
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
|
||||||
|
class AddWebSocketDialogMsgReadsLive extends Migration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function up()
|
||||||
|
{
|
||||||
|
info("update web_socket_dialog_msg_reads live field");
|
||||||
|
$isAdd = false;
|
||||||
|
Schema::table('web_socket_dialog_msg_reads', function (Blueprint $table) use (&$isAdd) {
|
||||||
|
if (!Schema::hasColumn('web_socket_dialog_msg_reads', 'live')) {
|
||||||
|
$isAdd = true;
|
||||||
|
$table->integer('live')->nullable()->default(0)->index()->after('dot')->comment('是否在会话里');
|
||||||
|
$table->index(['userid', 'live', 'msg_id']);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
info("update web_socket_dialog_msgs deleted_at");
|
||||||
|
Schema::table('web_socket_dialog_msgs', function (Blueprint $table) {
|
||||||
|
$table->index('deleted_at');
|
||||||
|
});
|
||||||
|
if ($isAdd) {
|
||||||
|
// 关键词包含
|
||||||
|
$contains = [
|
||||||
|
'您可以通过发送以下命令来控制我',
|
||||||
|
'我的机器人。',
|
||||||
|
'机器人名称:',
|
||||||
|
'已加入的会话:',
|
||||||
|
'你可以通过执行以下命令来请求我:',
|
||||||
|
'假期类型:',
|
||||||
|
'评论了此审批',
|
||||||
|
'我是你的机器人助理',
|
||||||
|
'打卡时间: ',
|
||||||
|
'匿名消息使用说明',
|
||||||
|
'匿名消息将通过',
|
||||||
|
'导出任务统计已完成',
|
||||||
|
'我不是你的机器人',
|
||||||
|
'机器人名称由',
|
||||||
|
'您没有创建机器人',
|
||||||
|
'缺卡提醒:',
|
||||||
|
'打卡提醒:',
|
||||||
|
'文件下载打包已完成',
|
||||||
|
'您有一个新任务 #',
|
||||||
|
'您协助的任务 #',
|
||||||
|
'您负责的任务 #',
|
||||||
|
];
|
||||||
|
info("update web_socket_dialog_msgs key contains");
|
||||||
|
foreach ($contains as $key) {
|
||||||
|
WebSocketDialogMsg::whereType('text')->where('key', 'like', "%{$key}%")->update(['key' => '']);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 关键词开始以
|
||||||
|
$starts = [
|
||||||
|
'/hello',
|
||||||
|
'/help',
|
||||||
|
'/list',
|
||||||
|
'/info',
|
||||||
|
'/newbot',
|
||||||
|
'/setname',
|
||||||
|
'/deletebot',
|
||||||
|
'/token',
|
||||||
|
'/revoke',
|
||||||
|
'/webhook',
|
||||||
|
'/clearday',
|
||||||
|
'/dialog',
|
||||||
|
'/api',
|
||||||
|
];
|
||||||
|
info("update web_socket_dialog_msgs key starts");
|
||||||
|
foreach ($starts as $key) {
|
||||||
|
WebSocketDialogMsg::whereType('text')->where('key', 'like', "{$key}%")->update(['key' => '']);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 关键词等于
|
||||||
|
$equals = [
|
||||||
|
'我要打卡',
|
||||||
|
'IT资讯',
|
||||||
|
'36氪',
|
||||||
|
'60s读世界',
|
||||||
|
'开心笑话',
|
||||||
|
'心灵鸡汤',
|
||||||
|
'使用说明',
|
||||||
|
'隐私说明',
|
||||||
|
'帮助指令',
|
||||||
|
'API接口文档',
|
||||||
|
'我的机器人',
|
||||||
|
'清空上下文',
|
||||||
|
'操作频繁!',
|
||||||
|
'暂未开启签到功能。',
|
||||||
|
'暂未开放手动签到。',
|
||||||
|
'设置成功',
|
||||||
|
'机器人不存在。',
|
||||||
|
];
|
||||||
|
info("update web_socket_dialog_msgs key equals");
|
||||||
|
foreach ($equals as $key) {
|
||||||
|
WebSocketDialogMsg::whereType('text')->whereKey($key)->update(['key' => '']);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 更新是否在会话里面
|
||||||
|
info("update web_socket_dialog_msg_reads live value");
|
||||||
|
WebSocketDialog::chunk(100, function ($dialogs) {
|
||||||
|
/** @var WebSocketDialog $dialog */
|
||||||
|
foreach ($dialogs as $dialog) {
|
||||||
|
WebSocketDialogMsgRead::whereDialogId($dialog->id)->whereIn('userid', function ($query) use ($dialog) {
|
||||||
|
$query->select('userid')->from('web_socket_dialog_users')->whereDialogId($dialog->id);
|
||||||
|
})->update(['live' => 1]);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function down()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user