mirror of
https://github.com/kuaifan/dootask.git
synced 2025-12-10 18:02:55 +00:00
perf: 优化消息标记已读/未读
This commit is contained in:
parent
30c149be31
commit
48b7f4924e
@ -41,7 +41,7 @@ class DialogController extends AbstractController
|
||||
{
|
||||
$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')
|
||||
->where('u.userid', $user->userid)
|
||||
->orderByDesc('u.top_at')
|
||||
@ -74,7 +74,7 @@ class DialogController extends AbstractController
|
||||
//
|
||||
$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')
|
||||
->where('web_socket_dialogs.id', $dialog_id)
|
||||
->where('u.userid', $user->userid)
|
||||
@ -524,19 +524,41 @@ class DialogController extends AbstractController
|
||||
if (!$dialogUser) {
|
||||
return Base::retError("会话不存在");
|
||||
}
|
||||
if ($type == 'read') {
|
||||
WebSocketDialogMsgRead::whereUserid($user->userid)
|
||||
->whereReadAt(null)
|
||||
->whereDialogId($dialogId)
|
||||
->update(
|
||||
[
|
||||
'read_at' => Carbon::now()
|
||||
]);
|
||||
$dialogUser->is_mark_unread = 0;
|
||||
$dialogUser->save();
|
||||
} elseif ($type == 'unread') {
|
||||
$dialogUser->is_mark_unread = 1;
|
||||
$dialogUser->save();
|
||||
switch ($type) {
|
||||
case 'read':
|
||||
WebSocketDialogMsgRead::whereUserid($user->userid)
|
||||
->whereReadAt(null)
|
||||
->whereDialogId($dialogId)
|
||||
->chunkById(100, function ($list) {
|
||||
/** @var WebSocketDialogMsgRead $item */
|
||||
$dialogMsg = [];
|
||||
foreach ($list as $item) {
|
||||
$item->read_at = Carbon::now();
|
||||
$item->save();
|
||||
if (isset($dialogMsg[$item->msg_id])) {
|
||||
$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");
|
||||
}
|
||||
|
||||
@ -105,9 +105,8 @@ class WebSocketDialog extends AbstractModel
|
||||
$last_msg = WebSocketDialogMsg::whereDialogId($dialog->id)->orderByDesc('id')->first();
|
||||
$dialog->last_msg = $last_msg;
|
||||
// 未读信息
|
||||
$unread = WebSocketDialogMsgRead::whereDialogId($dialog->id)->whereUserid($userid)->whereReadAt(null)->count();
|
||||
$isMarkUnread = WebSocketDialogUser::whereDialogId($dialog->id)->whereUserid($userid)->whereIsMarkUnread(1)->exists();
|
||||
$dialog->unread = $unread > 0 ? $unread : ($isMarkUnread ? 1 : 0);
|
||||
$dialog->unread = WebSocketDialogMsgRead::whereDialogId($dialog->id)->whereUserid($userid)->whereReadAt(null)->count();
|
||||
$dialog->is_mark_unread = $dialog->is_mark_unread ?? WebSocketDialogUser::whereDialogId($dialog->id)->whereUserid($userid)->value('is_mark_unread');
|
||||
// 对话人数
|
||||
$builder = WebSocketDialogUser::whereDialogId($dialog->id);
|
||||
$dialog->people = $builder->count();
|
||||
|
||||
@ -96,12 +96,12 @@ class WebSocketDialogMsg extends AbstractModel
|
||||
|
||||
/**
|
||||
* 获取占比
|
||||
* @param bool $increment 是否新增阅读数
|
||||
* @param bool|int $increment 是否新增阅读数
|
||||
* @return int
|
||||
*/
|
||||
public function generatePercentage($increment = false) {
|
||||
if ($increment) {
|
||||
$this->increment('read');
|
||||
$this->increment('read', is_bool($increment) ? 1 : $increment);
|
||||
}
|
||||
if ($this->read > $this->send || empty($this->send)) {
|
||||
return $this->appendattrs['percentage'] = 100;
|
||||
|
||||
@ -11,6 +11,7 @@ namespace App\Models;
|
||||
* @property int|null $userid 发送会员ID
|
||||
* @property int|null $after 在阅读之后才添加的记录
|
||||
* @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 newQuery()
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|WebSocketDialogMsgRead query()
|
||||
@ -29,4 +30,12 @@ class WebSocketDialogMsgRead extends AbstractModel
|
||||
parent::__construct($attributes);
|
||||
$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 {
|
||||
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() {
|
||||
let num = 0;
|
||||
this.cacheDialogs.some(({unread}) => {
|
||||
this.cacheDialogs.some(dialog => {
|
||||
let unread = $A.getDialogUnread(dialog);
|
||||
if (unread) {
|
||||
num += unread;
|
||||
}
|
||||
|
||||
@ -576,7 +576,7 @@ export default {
|
||||
msgUnread() {
|
||||
const {cacheDialogs, projectData} = this;
|
||||
const dialog = cacheDialogs.find(({id}) => id === projectData.dialog_id);
|
||||
return dialog ? dialog.unread : 0;
|
||||
return dialog ? $A.getDialogUnread(dialog) : 0;
|
||||
},
|
||||
|
||||
panelTask() {
|
||||
|
||||
@ -58,7 +58,7 @@
|
||||
</div>
|
||||
<div class="dialog-text no-dark-mode">{{formatLastMsg(dialog.last_msg)}}</div>
|
||||
</div>
|
||||
<Badge class="dialog-num" :count="dialog.unread"/>
|
||||
<Badge class="dialog-num" :count="$A.getDialogUnread(dialog)"/>
|
||||
</li>
|
||||
</ul>
|
||||
<ul v-else class="contacts">
|
||||
@ -85,7 +85,7 @@
|
||||
<DropdownItem @click.native="handleTopClick">
|
||||
{{ $L(topOperateItem.top_at ? '取消置顶' : '置顶该聊天') }}
|
||||
</DropdownItem>
|
||||
<DropdownItem @click.native="updateRead('read')" v-if="topOperateItem.unread > 0">
|
||||
<DropdownItem @click.native="updateRead('read')" v-if="$A.getDialogUnread(topOperateItem) > 0">
|
||||
{{ $L('标记已读') }}
|
||||
</DropdownItem>
|
||||
<DropdownItem @click.native="updateRead('unread')" v-else>
|
||||
@ -213,21 +213,22 @@ export default {
|
||||
return function (type) {
|
||||
let num = 0;
|
||||
this.cacheDialogs.some((dialog) => {
|
||||
if (dialog.unread) {
|
||||
let unread = $A.getDialogUnread(dialog);
|
||||
if (unread) {
|
||||
switch (type) {
|
||||
case 'project':
|
||||
case 'task':
|
||||
if (type == dialog.group_type) {
|
||||
num += dialog.unread;
|
||||
num += unread;
|
||||
}
|
||||
break;
|
||||
case 'user':
|
||||
if (type == dialog.type) {
|
||||
num += dialog.unread;
|
||||
num += unread;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
num += dialog.unread;
|
||||
num += unread;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -286,7 +287,7 @@ export default {
|
||||
onActive(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) {
|
||||
$A.scrollToView(this.$refs[`dialog_${dialog.id}`][0], {
|
||||
behavior: 'smooth',
|
||||
@ -322,7 +323,7 @@ export default {
|
||||
},
|
||||
|
||||
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
|
||||
}
|
||||
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);
|
||||
if (dialog && dialog.unread > 0) {
|
||||
dialog.unread--
|
||||
dialog.is_mark_unread = 0
|
||||
dispatch("saveDialog", dialog)
|
||||
}
|
||||
//
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user