mirror of
https://github.com/kuaifan/dootask.git
synced 2026-03-03 16:02:08 +00:00
perf: 优化@提醒
This commit is contained in:
parent
d5ac6fc0c7
commit
8893254664
@ -12,6 +12,7 @@ use App\Models\WebSocketDialogMsgRead;
|
||||
use App\Models\WebSocketDialogUser;
|
||||
use App\Module\Base;
|
||||
use Carbon\Carbon;
|
||||
use DB;
|
||||
use Request;
|
||||
use Response;
|
||||
|
||||
@ -145,11 +146,15 @@ class DialogController extends AbstractController
|
||||
//
|
||||
$dialog = WebSocketDialog::checkDialog($dialog_id);
|
||||
//
|
||||
$list = WebSocketDialogMsg::whereDialogId($dialog_id)->orderByDesc('id')->paginate(Base::getPaginate(100, 50));
|
||||
$list->transform(function (WebSocketDialogMsg $item) use ($user) {
|
||||
$item->is_read = $item->userid === $user->userid || WebSocketDialogMsgRead::whereMsgId($item->id)->whereUserid($user->userid)->value('read_at');
|
||||
return $item;
|
||||
});
|
||||
$list = WebSocketDialogMsg::select([
|
||||
'web_socket_dialog_msgs.*',
|
||||
'read.mention',
|
||||
'read.read_at',
|
||||
])->leftJoin('web_socket_dialog_msg_reads as read', function ($leftJoin) use ($user) {
|
||||
$leftJoin
|
||||
->on('read.userid', '=', DB::raw($user->userid))
|
||||
->on('read.msg_id', '=', 'web_socket_dialog_msgs.id');
|
||||
})->where('web_socket_dialog_msgs.dialog_id', $dialog_id)->orderByDesc('web_socket_dialog_msgs.id')->paginate(Base::getPaginate(100, 50));
|
||||
//
|
||||
if ($dialog->type == 'group' && $dialog->group_type == 'task') {
|
||||
$user->task_dialog_id = $dialog->id;
|
||||
|
||||
@ -62,7 +62,9 @@ class WebSocketDialog extends AbstractModel
|
||||
$last_msg = WebSocketDialogMsg::whereDialogId($this->id)->orderByDesc('id')->first();
|
||||
$this->last_msg = $last_msg;
|
||||
// 未读信息
|
||||
$this->unread = WebSocketDialogMsgRead::whereDialogId($this->id)->whereUserid($userid)->whereReadAt(null)->count();
|
||||
$unreadBuilder = WebSocketDialogMsgRead::whereDialogId($this->id)->whereUserid($userid)->whereReadAt(null);
|
||||
$this->unread = $unreadBuilder->count();
|
||||
$this->mention = $unreadBuilder->whereMention(1)->count();
|
||||
$this->mark_unread = $this->mark_unread ?? WebSocketDialogUser::whereDialogId($this->id)->whereUserid($userid)->value('mark_unread');
|
||||
// 对话人数
|
||||
$builder = WebSocketDialogUser::whereDialogId($this->id);
|
||||
|
||||
@ -11,6 +11,7 @@ use Carbon\Carbon;
|
||||
* @property int|null $dialog_id 对话ID
|
||||
* @property int|null $msg_id 消息ID
|
||||
* @property int|null $userid 发送会员ID
|
||||
* @property int|null $mention 是否提及(被@)
|
||||
* @property int|null $after 在阅读之后才添加的记录
|
||||
* @property string|null $read_at 阅读时间
|
||||
* @property-read \App\Models\WebSocketDialogMsg|null $webSocketDialogMsg
|
||||
@ -20,6 +21,7 @@ use Carbon\Carbon;
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|WebSocketDialogMsgRead whereAfter($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|WebSocketDialogMsgRead whereDialogId($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|WebSocketDialogMsgRead whereId($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 whereReadAt($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|WebSocketDialogMsgRead whereUserid($value)
|
||||
|
||||
@ -48,30 +48,38 @@ class WebSocketDialogMsgTask extends AbstractTask
|
||||
}
|
||||
|
||||
// 推送目标①:群成员
|
||||
$array = [];
|
||||
$userids = $dialog->dialogUser->pluck('userid')->toArray();
|
||||
foreach ($userids AS $userid) {
|
||||
if ($userid == $msg->userid) {
|
||||
continue;
|
||||
}
|
||||
$mention = preg_match("/<span class=\"mention user\" data-id=\"[0|{$userid}]\">/", $msg->type === 'text' ? $msg->msg['text'] : '');
|
||||
WebSocketDialogMsgRead::createInstance([
|
||||
'dialog_id' => $msg->dialog_id,
|
||||
'msg_id' => $msg->id,
|
||||
'userid' => $userid,
|
||||
'mention' => $mention,
|
||||
])->saveOrIgnore();
|
||||
$array[$userid] = $mention;
|
||||
}
|
||||
// 更新已发送数量
|
||||
$msg->send = WebSocketDialogMsgRead::whereMsgId($msg->id)->count();
|
||||
$msg->save();
|
||||
// 开始推送消息
|
||||
PushTask::push([
|
||||
'userid' => $userids,
|
||||
'ignoreFd' => $this->ignoreFd,
|
||||
'msg' => [
|
||||
'type' => 'dialog',
|
||||
'mode' => 'add',
|
||||
'data' => $msg->toArray(),
|
||||
]
|
||||
]);
|
||||
foreach ($array as $userid => $mention) {
|
||||
PushTask::push([
|
||||
'userid' => $userid,
|
||||
'ignoreFd' => $this->ignoreFd,
|
||||
'msg' => [
|
||||
'type' => 'dialog',
|
||||
'mode' => 'add',
|
||||
'data' => array_merge($msg->toArray(), [
|
||||
'mention' => $mention,
|
||||
]),
|
||||
]
|
||||
]);
|
||||
}
|
||||
|
||||
// 推送目标②:正在打开这个任务会话的会员
|
||||
if ($dialog->type == 'group' && $dialog->group_type == 'task') {
|
||||
|
||||
@ -0,0 +1,34 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
class AddWebSocketDialogMsgReadsMention extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::table('web_socket_dialog_msg_reads', function (Blueprint $table) {
|
||||
if (!Schema::hasColumn('web_socket_dialog_msg_reads', 'mention')) {
|
||||
$table->boolean('mention')->default(0)->after('userid')->nullable()->comment('是否提及(被@)');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::table('web_socket_dialog_msg_reads', function (Blueprint $table) {
|
||||
$table->dropColumn("mention");
|
||||
});
|
||||
}
|
||||
}
|
||||
9
resources/assets/js/functions/web.js
vendored
9
resources/assets/js/functions/web.js
vendored
@ -367,6 +367,15 @@
|
||||
getDialogUnread(dialog) {
|
||||
return dialog ? (dialog.unread || dialog.mark_unread || 0) : 0
|
||||
},
|
||||
|
||||
/**
|
||||
* 返回对话@提及未读数量
|
||||
* @param dialog
|
||||
* @returns {*|number}
|
||||
*/
|
||||
getDialogMention(dialog) {
|
||||
return dialog ? (dialog.mention || 0) : 0
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
|
||||
@ -147,7 +147,7 @@
|
||||
<li @click="toggleRoute('messenger')" :class="classNameRoute('messenger')">
|
||||
<i class="taskfont"></i>
|
||||
<div class="menu-title">{{$L('消息')}}</div>
|
||||
<Badge class="menu-badge" :count="msgAllUnread"/>
|
||||
<Badge class="menu-badge" :text="msgUnreadMention"/>
|
||||
</li>
|
||||
<li @click="toggleRoute('file')" :class="classNameRoute('file')">
|
||||
<i class="taskfont"></i>
|
||||
@ -497,13 +497,26 @@ export default {
|
||||
|
||||
...mapGetters(['taskData', 'dashboardTask']),
|
||||
|
||||
msgUnreadMention() {
|
||||
let num = 0;
|
||||
let mention = 0;
|
||||
this.cacheDialogs.some(dialog => {
|
||||
num += $A.getDialogUnread(dialog);
|
||||
mention += $A.getDialogMention(dialog);
|
||||
})
|
||||
if (num <= 0) {
|
||||
return '';
|
||||
}
|
||||
if (mention > 0) {
|
||||
return `${num}·@${mention}`
|
||||
}
|
||||
return String(num);
|
||||
},
|
||||
|
||||
msgAllUnread() {
|
||||
let num = 0;
|
||||
this.cacheDialogs.some(dialog => {
|
||||
let unread = $A.getDialogUnread(dialog);
|
||||
if (unread) {
|
||||
num += unread;
|
||||
}
|
||||
num += $A.getDialogUnread(dialog);
|
||||
})
|
||||
return num;
|
||||
},
|
||||
@ -886,6 +899,8 @@ export default {
|
||||
switch (type) {
|
||||
case 'text':
|
||||
body = msg.text;
|
||||
body = body.replace(/<img src=".*?"\/>/g, `[${this.$L('图片')}]`)
|
||||
body = body.replace(/<[^>]+>/g,"")
|
||||
break;
|
||||
case 'file':
|
||||
body = '[' + this.$L(msg.type == 'img' ? '图片信息' : '文件信息') + ']'
|
||||
|
||||
@ -141,6 +141,7 @@ export default {
|
||||
allowedChars: /^\S*$/,
|
||||
mentionDenotationChars: ["@", "#"],
|
||||
defaultMenuOrientation: this.defaultMenuOrientation,
|
||||
isolateCharacter: true,
|
||||
renderItem: (data) => {
|
||||
if (data.disabled === true) {
|
||||
return `<div class="mention-item-disabled">${data.value}</div>`;
|
||||
|
||||
@ -50,6 +50,7 @@
|
||||
<Icon v-else class="icon-avatar" type="md-person" />
|
||||
<div class="dialog-box">
|
||||
<div class="dialog-title">
|
||||
<div v-if="$A.getDialogMention(dialog) > 0" class="mention">[@{{$A.getDialogMention(dialog)}}]</div>
|
||||
<template v-for="tag in $A.dialogTags(dialog)" v-if="tag.color != 'success'">
|
||||
<Tag :color="tag.color" :fade="false">{{$L(tag.text)}}</Tag>
|
||||
</template>
|
||||
|
||||
12
resources/assets/js/store/actions.js
vendored
12
resources/assets/js/store/actions.js
vendored
@ -2122,13 +2122,16 @@ export default {
|
||||
*/
|
||||
dialogMsgRead({state, dispatch}, data) {
|
||||
if (data.userid == state.userId) return;
|
||||
if (data.is_read === true) return;
|
||||
data.is_read = true;
|
||||
if (data.read_at) return;
|
||||
data.read_at = $A.formatDate();
|
||||
//
|
||||
let dialog = state.cacheDialogs.find(({id}) => id == data.dialog_id);
|
||||
if (dialog && dialog.unread > 0) {
|
||||
dialog.unread--
|
||||
dialog.mark_unread = 0
|
||||
dialog.unread--
|
||||
if (data.mention) {
|
||||
dialog.mention--
|
||||
}
|
||||
dispatch("saveDialog", dialog)
|
||||
}
|
||||
//
|
||||
@ -2268,6 +2271,9 @@ export default {
|
||||
if (dialog && state.cacheUnreads[data.id] === undefined) {
|
||||
state.cacheUnreads[data.id] = true;
|
||||
dialog.unread++;
|
||||
if (data.mention) {
|
||||
dialog.mention++;
|
||||
}
|
||||
dispatch("saveDialog", dialog)
|
||||
}
|
||||
}
|
||||
|
||||
@ -48,6 +48,38 @@
|
||||
min-width: 220px;
|
||||
max-width: 350px;
|
||||
max-height: 360px;
|
||||
overflow-y: overlay;
|
||||
|
||||
&::-webkit-scrollbar {
|
||||
width: 10px;
|
||||
height: 10px;
|
||||
}
|
||||
|
||||
&::-webkit-scrollbar-thumb {
|
||||
border-radius: 10px;
|
||||
background: rgba(0, 0, 0, 0);
|
||||
}
|
||||
|
||||
&::-webkit-scrollbar-thumb:active {
|
||||
border-radius: 10px;
|
||||
background: rgba(0, 0, 0, .5);
|
||||
}
|
||||
|
||||
&:hover::-webkit-scrollbar-thumb {
|
||||
border: 2px solid transparent;
|
||||
background: rgba(0, 0, 0, .2);
|
||||
background-clip: content-box;
|
||||
}
|
||||
|
||||
&:hover::-webkit-scrollbar-thumb:hover {
|
||||
border-top-width: 0;
|
||||
border-bottom-width: 0;
|
||||
}
|
||||
|
||||
&::-webkit-scrollbar-track {
|
||||
border-radius: 10px;
|
||||
background: rgba(0, 0, 0, 0);
|
||||
}
|
||||
|
||||
.ql-mention-list {
|
||||
> li {
|
||||
|
||||
11
resources/assets/sass/pages/page-messenger.scss
vendored
11
resources/assets/sass/pages/page-messenger.scss
vendored
@ -126,6 +126,16 @@
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
line-height: 24px;
|
||||
.mention {
|
||||
color: #ff0000;
|
||||
background-color: transparent;
|
||||
font-weight: 600;
|
||||
flex-shrink: 0;
|
||||
margin-right: 4px;
|
||||
padding: 0;
|
||||
height: auto;
|
||||
width: auto;
|
||||
}
|
||||
.ivu-tag {
|
||||
margin: 0 4px 0 0;
|
||||
padding: 0 5px;
|
||||
@ -170,6 +180,7 @@
|
||||
align-items: center;
|
||||
.common-avatar,
|
||||
.last-self {
|
||||
flex-shrink: 0;
|
||||
padding-right: 4px;
|
||||
margin-right: 4px;
|
||||
position: relative;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user