mirror of
https://github.com/kuaifan/dootask.git
synced 2025-12-11 18:42:54 +00:00
perf: 优化消息标记已读/未读
This commit is contained in:
parent
30c149be31
commit
48b7f4924e
@ -41,7 +41,7 @@ class DialogController extends AbstractController
|
|||||||
{
|
{
|
||||||
$user = User::auth();
|
$user = User::auth();
|
||||||
//
|
//
|
||||||
$list = WebSocketDialog::select(['web_socket_dialogs.*', 'u.top_at'])
|
$list = WebSocketDialog::select(['web_socket_dialogs.*', 'u.top_at', 'u.is_mark_unread'])
|
||||||
->join('web_socket_dialog_users as u', 'web_socket_dialogs.id', '=', 'u.dialog_id')
|
->join('web_socket_dialog_users as u', 'web_socket_dialogs.id', '=', 'u.dialog_id')
|
||||||
->where('u.userid', $user->userid)
|
->where('u.userid', $user->userid)
|
||||||
->orderByDesc('u.top_at')
|
->orderByDesc('u.top_at')
|
||||||
@ -74,7 +74,7 @@ class DialogController extends AbstractController
|
|||||||
//
|
//
|
||||||
$dialog_id = intval(Request::input('dialog_id'));
|
$dialog_id = intval(Request::input('dialog_id'));
|
||||||
//
|
//
|
||||||
$item = WebSocketDialog::select(['web_socket_dialogs.*'])
|
$item = WebSocketDialog::select(['web_socket_dialogs.*', 'u.top_at', 'u.is_mark_unread'])
|
||||||
->join('web_socket_dialog_users as u', 'web_socket_dialogs.id', '=', 'u.dialog_id')
|
->join('web_socket_dialog_users as u', 'web_socket_dialogs.id', '=', 'u.dialog_id')
|
||||||
->where('web_socket_dialogs.id', $dialog_id)
|
->where('web_socket_dialogs.id', $dialog_id)
|
||||||
->where('u.userid', $user->userid)
|
->where('u.userid', $user->userid)
|
||||||
@ -524,19 +524,41 @@ class DialogController extends AbstractController
|
|||||||
if (!$dialogUser) {
|
if (!$dialogUser) {
|
||||||
return Base::retError("会话不存在");
|
return Base::retError("会话不存在");
|
||||||
}
|
}
|
||||||
if ($type == 'read') {
|
switch ($type) {
|
||||||
WebSocketDialogMsgRead::whereUserid($user->userid)
|
case 'read':
|
||||||
->whereReadAt(null)
|
WebSocketDialogMsgRead::whereUserid($user->userid)
|
||||||
->whereDialogId($dialogId)
|
->whereReadAt(null)
|
||||||
->update(
|
->whereDialogId($dialogId)
|
||||||
[
|
->chunkById(100, function ($list) {
|
||||||
'read_at' => Carbon::now()
|
/** @var WebSocketDialogMsgRead $item */
|
||||||
]);
|
$dialogMsg = [];
|
||||||
$dialogUser->is_mark_unread = 0;
|
foreach ($list as $item) {
|
||||||
$dialogUser->save();
|
$item->read_at = Carbon::now();
|
||||||
} elseif ($type == 'unread') {
|
$item->save();
|
||||||
$dialogUser->is_mark_unread = 1;
|
if (isset($dialogMsg[$item->msg_id])) {
|
||||||
$dialogUser->save();
|
$dialogMsg[$item->msg_id]['re']++;
|
||||||
|
} else {
|
||||||
|
$dialogMsg[$item->msg_id] = [
|
||||||
|
'ob' => $item->webSocketDialogMsg,
|
||||||
|
're' => 1
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
foreach ($dialogMsg as $item) {
|
||||||
|
$item['ob']?->generatePercentage($item['re']);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
$dialogUser->is_mark_unread = 0;
|
||||||
|
$dialogUser->save();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'unread':
|
||||||
|
$dialogUser->is_mark_unread = 1;
|
||||||
|
$dialogUser->save();
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return Base::retError("参数错误");
|
||||||
}
|
}
|
||||||
return Base::retSuccess("success");
|
return Base::retSuccess("success");
|
||||||
}
|
}
|
||||||
|
|||||||
@ -105,9 +105,8 @@ class WebSocketDialog extends AbstractModel
|
|||||||
$last_msg = WebSocketDialogMsg::whereDialogId($dialog->id)->orderByDesc('id')->first();
|
$last_msg = WebSocketDialogMsg::whereDialogId($dialog->id)->orderByDesc('id')->first();
|
||||||
$dialog->last_msg = $last_msg;
|
$dialog->last_msg = $last_msg;
|
||||||
// 未读信息
|
// 未读信息
|
||||||
$unread = WebSocketDialogMsgRead::whereDialogId($dialog->id)->whereUserid($userid)->whereReadAt(null)->count();
|
$dialog->unread = WebSocketDialogMsgRead::whereDialogId($dialog->id)->whereUserid($userid)->whereReadAt(null)->count();
|
||||||
$isMarkUnread = WebSocketDialogUser::whereDialogId($dialog->id)->whereUserid($userid)->whereIsMarkUnread(1)->exists();
|
$dialog->is_mark_unread = $dialog->is_mark_unread ?? WebSocketDialogUser::whereDialogId($dialog->id)->whereUserid($userid)->value('is_mark_unread');
|
||||||
$dialog->unread = $unread > 0 ? $unread : ($isMarkUnread ? 1 : 0);
|
|
||||||
// 对话人数
|
// 对话人数
|
||||||
$builder = WebSocketDialogUser::whereDialogId($dialog->id);
|
$builder = WebSocketDialogUser::whereDialogId($dialog->id);
|
||||||
$dialog->people = $builder->count();
|
$dialog->people = $builder->count();
|
||||||
|
|||||||
@ -96,12 +96,12 @@ class WebSocketDialogMsg extends AbstractModel
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取占比
|
* 获取占比
|
||||||
* @param bool $increment 是否新增阅读数
|
* @param bool|int $increment 是否新增阅读数
|
||||||
* @return int
|
* @return int
|
||||||
*/
|
*/
|
||||||
public function generatePercentage($increment = false) {
|
public function generatePercentage($increment = false) {
|
||||||
if ($increment) {
|
if ($increment) {
|
||||||
$this->increment('read');
|
$this->increment('read', is_bool($increment) ? 1 : $increment);
|
||||||
}
|
}
|
||||||
if ($this->read > $this->send || empty($this->send)) {
|
if ($this->read > $this->send || empty($this->send)) {
|
||||||
return $this->appendattrs['percentage'] = 100;
|
return $this->appendattrs['percentage'] = 100;
|
||||||
|
|||||||
@ -11,6 +11,7 @@ namespace App\Models;
|
|||||||
* @property int|null $userid 发送会员ID
|
* @property int|null $userid 发送会员ID
|
||||||
* @property int|null $after 在阅读之后才添加的记录
|
* @property int|null $after 在阅读之后才添加的记录
|
||||||
* @property string|null $read_at 阅读时间
|
* @property string|null $read_at 阅读时间
|
||||||
|
* @property-read \App\Models\WebSocketDialogMsg|null $webSocketDialogMsg
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|WebSocketDialogMsgRead newModelQuery()
|
* @method static \Illuminate\Database\Eloquent\Builder|WebSocketDialogMsgRead newModelQuery()
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|WebSocketDialogMsgRead newQuery()
|
* @method static \Illuminate\Database\Eloquent\Builder|WebSocketDialogMsgRead newQuery()
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|WebSocketDialogMsgRead query()
|
* @method static \Illuminate\Database\Eloquent\Builder|WebSocketDialogMsgRead query()
|
||||||
@ -29,4 +30,12 @@ class WebSocketDialogMsgRead extends AbstractModel
|
|||||||
parent::__construct($attributes);
|
parent::__construct($attributes);
|
||||||
$this->timestamps = false;
|
$this->timestamps = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return \Illuminate\Database\Eloquent\Relations\HasOne
|
||||||
|
*/
|
||||||
|
public function webSocketDialogMsg(): \Illuminate\Database\Eloquent\Relations\HasOne
|
||||||
|
{
|
||||||
|
return $this->hasOne(WebSocketDialogMsg::class, 'id', 'msg_id');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
9
resources/assets/js/functions/web.js
vendored
9
resources/assets/js/functions/web.js
vendored
@ -376,6 +376,15 @@
|
|||||||
} else {
|
} else {
|
||||||
window.open(url)
|
window.open(url)
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 返回对话未读数量
|
||||||
|
* @param dialog
|
||||||
|
* @returns {*|number}
|
||||||
|
*/
|
||||||
|
getDialogUnread(dialog) {
|
||||||
|
return dialog ? (dialog.unread || dialog.is_mark_unread || 0) : 0
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@ -490,7 +490,8 @@ export default {
|
|||||||
|
|
||||||
msgAllUnread() {
|
msgAllUnread() {
|
||||||
let num = 0;
|
let num = 0;
|
||||||
this.cacheDialogs.some(({unread}) => {
|
this.cacheDialogs.some(dialog => {
|
||||||
|
let unread = $A.getDialogUnread(dialog);
|
||||||
if (unread) {
|
if (unread) {
|
||||||
num += unread;
|
num += unread;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -576,7 +576,7 @@ export default {
|
|||||||
msgUnread() {
|
msgUnread() {
|
||||||
const {cacheDialogs, projectData} = this;
|
const {cacheDialogs, projectData} = this;
|
||||||
const dialog = cacheDialogs.find(({id}) => id === projectData.dialog_id);
|
const dialog = cacheDialogs.find(({id}) => id === projectData.dialog_id);
|
||||||
return dialog ? dialog.unread : 0;
|
return dialog ? $A.getDialogUnread(dialog) : 0;
|
||||||
},
|
},
|
||||||
|
|
||||||
panelTask() {
|
panelTask() {
|
||||||
|
|||||||
@ -58,7 +58,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="dialog-text no-dark-mode">{{formatLastMsg(dialog.last_msg)}}</div>
|
<div class="dialog-text no-dark-mode">{{formatLastMsg(dialog.last_msg)}}</div>
|
||||||
</div>
|
</div>
|
||||||
<Badge class="dialog-num" :count="dialog.unread"/>
|
<Badge class="dialog-num" :count="$A.getDialogUnread(dialog)"/>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
<ul v-else class="contacts">
|
<ul v-else class="contacts">
|
||||||
@ -85,7 +85,7 @@
|
|||||||
<DropdownItem @click.native="handleTopClick">
|
<DropdownItem @click.native="handleTopClick">
|
||||||
{{ $L(topOperateItem.top_at ? '取消置顶' : '置顶该聊天') }}
|
{{ $L(topOperateItem.top_at ? '取消置顶' : '置顶该聊天') }}
|
||||||
</DropdownItem>
|
</DropdownItem>
|
||||||
<DropdownItem @click.native="updateRead('read')" v-if="topOperateItem.unread > 0">
|
<DropdownItem @click.native="updateRead('read')" v-if="$A.getDialogUnread(topOperateItem) > 0">
|
||||||
{{ $L('标记已读') }}
|
{{ $L('标记已读') }}
|
||||||
</DropdownItem>
|
</DropdownItem>
|
||||||
<DropdownItem @click.native="updateRead('unread')" v-else>
|
<DropdownItem @click.native="updateRead('unread')" v-else>
|
||||||
@ -213,21 +213,22 @@ export default {
|
|||||||
return function (type) {
|
return function (type) {
|
||||||
let num = 0;
|
let num = 0;
|
||||||
this.cacheDialogs.some((dialog) => {
|
this.cacheDialogs.some((dialog) => {
|
||||||
if (dialog.unread) {
|
let unread = $A.getDialogUnread(dialog);
|
||||||
|
if (unread) {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case 'project':
|
case 'project':
|
||||||
case 'task':
|
case 'task':
|
||||||
if (type == dialog.group_type) {
|
if (type == dialog.group_type) {
|
||||||
num += dialog.unread;
|
num += unread;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'user':
|
case 'user':
|
||||||
if (type == dialog.type) {
|
if (type == dialog.type) {
|
||||||
num += dialog.unread;
|
num += unread;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
num += dialog.unread;
|
num += unread;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -286,7 +287,7 @@ export default {
|
|||||||
onActive(type) {
|
onActive(type) {
|
||||||
if (this.dialogActive == type) {
|
if (this.dialogActive == type) {
|
||||||
// 再次点击滚动到未读条目
|
// 再次点击滚动到未读条目
|
||||||
const dialog = this.dialogList.find(({unread}) => unread > 0)
|
const dialog = this.dialogList.find(dialog => $A.getDialogUnread(dialog) > 0)
|
||||||
if (dialog) {
|
if (dialog) {
|
||||||
$A.scrollToView(this.$refs[`dialog_${dialog.id}`][0], {
|
$A.scrollToView(this.$refs[`dialog_${dialog.id}`][0], {
|
||||||
behavior: 'smooth',
|
behavior: 'smooth',
|
||||||
@ -322,7 +323,7 @@ export default {
|
|||||||
},
|
},
|
||||||
|
|
||||||
filterDialog(dialog) {
|
filterDialog(dialog) {
|
||||||
if (dialog.unread > 0 || dialog.id == this.dialogId || dialog.top_at) {
|
if ($A.getDialogUnread(dialog) > 0 || dialog.id == this.dialogId || dialog.top_at) {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
if (dialog.name === undefined) {
|
if (dialog.name === undefined) {
|
||||||
|
|||||||
1
resources/assets/js/store/actions.js
vendored
1
resources/assets/js/store/actions.js
vendored
@ -2085,6 +2085,7 @@ export default {
|
|||||||
let dialog = state.cacheDialogs.find(({id}) => id == data.dialog_id);
|
let dialog = state.cacheDialogs.find(({id}) => id == data.dialog_id);
|
||||||
if (dialog && dialog.unread > 0) {
|
if (dialog && dialog.unread > 0) {
|
||||||
dialog.unread--
|
dialog.unread--
|
||||||
|
dialog.is_mark_unread = 0
|
||||||
dispatch("saveDialog", dialog)
|
dispatch("saveDialog", dialog)
|
||||||
}
|
}
|
||||||
//
|
//
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user