perf: 优化阅读消息

This commit is contained in:
kuaifan 2023-02-19 15:19:42 +08:00
parent 87d7be254a
commit aa5da2479c
8 changed files with 155 additions and 116 deletions

View File

@ -5,7 +5,6 @@ namespace App\Http\Controllers\Api;
use App\Models\AbstractModel; use App\Models\AbstractModel;
use App\Models\File; use App\Models\File;
use App\Models\FileContent; use App\Models\FileContent;
use App\Models\FileLink;
use App\Models\ProjectTask; use App\Models\ProjectTask;
use App\Models\ProjectTaskFile; use App\Models\ProjectTaskFile;
use App\Models\User; use App\Models\User;
@ -49,11 +48,11 @@ class DialogController extends AbstractController
{ {
$user = User::auth(); $user = User::auth();
// //
$builder = WebSocketDialog::select(['web_socket_dialogs.*', 'u.top_at', 'u.mark_unread', 'u.silence']) $builder = WebSocketDialog::select(['web_socket_dialogs.*', 'u.top_at', 'u.mark_unread', 'u.silence', 'u.updated_at as user_at'])
->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);
if (Request::exists('at_after')) { if (Request::exists('at_after')) {
$builder->where('web_socket_dialogs.last_at', '>', Carbon::parse(Request::input('at_after'))); $builder->where('u.updated_at', '>', Carbon::parse(Request::input('at_after')));
} }
$list = $builder $list = $builder
->orderByDesc('u.top_at') ->orderByDesc('u.top_at')
@ -102,7 +101,7 @@ class DialogController extends AbstractController
return Base::retError('请输入搜索关键词'); return Base::retError('请输入搜索关键词');
} }
// 搜索会话 // 搜索会话
$dialogs = WebSocketDialog::select(['web_socket_dialogs.*', 'u.top_at', 'u.mark_unread', 'u.silence']) $dialogs = WebSocketDialog::select(['web_socket_dialogs.*', 'u.top_at', 'u.mark_unread', 'u.silence', 'u.updated_at as user_at'])
->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.name', 'LIKE', "%{$key}%") ->where('web_socket_dialogs.name', 'LIKE', "%{$key}%")
->where('u.userid', $user->userid) ->where('u.userid', $user->userid)
@ -135,7 +134,7 @@ class DialogController extends AbstractController
} }
// 搜索消息会话 // 搜索消息会话
if (count($list) < 20) { if (count($list) < 20) {
$msgs = WebSocketDialog::select(['web_socket_dialogs.*', 'u.top_at', 'u.mark_unread', 'u.silence', 'm.id as search_msg_id']) $msgs = WebSocketDialog::select(['web_socket_dialogs.*', 'u.top_at', 'u.mark_unread', 'u.silence', 'u.updated_at as user_at', 'm.id as search_msg_id'])
->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')
->join('web_socket_dialog_msgs as m', 'web_socket_dialogs.id', '=', 'm.dialog_id') ->join('web_socket_dialog_msgs as m', 'web_socket_dialogs.id', '=', 'm.dialog_id')
->where('u.userid', $user->userid) ->where('u.userid', $user->userid)
@ -172,7 +171,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.*', 'u.top_at', 'u.mark_unread', 'u.silence']) $item = WebSocketDialog::select(['web_socket_dialogs.*', 'u.top_at', 'u.mark_unread', 'u.silence', 'u.updated_at as user_at'])
->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)
@ -523,7 +522,7 @@ class DialogController extends AbstractController
} }
/** /**
* @api {get} api/dialog/msg/read 11. 标记已读 * @api {get} api/dialog/msg/read 11. 已读聊天消息
* *
* @apiDescription 需要token身份 * @apiDescription 需要token身份
* @apiVersion 1.0.0 * @apiVersion 1.0.0
@ -543,45 +542,74 @@ class DialogController extends AbstractController
$id = Request::input('id'); $id = Request::input('id');
$ids = Base::explodeInt($id); $ids = Base::explodeInt($id);
// //
WebSocketDialogMsg::whereIn('id', $ids)->chunkById(20, function($list) use ($user) { $dialogIds = [];
WebSocketDialogMsg::whereIn('id', $ids)->chunkById(20, function($list) use ($user, &$dialogIds) {
/** @var WebSocketDialogMsg $item */ /** @var WebSocketDialogMsg $item */
foreach ($list as $item) { foreach ($list as $item) {
$item->readSuccess($user->userid); $item->readSuccess($user->userid);
$dialogIds[$item->dialog_id] = $item->dialog_id;
} }
}); });
return Base::retSuccess('success'); //
$data = [];
$dialogUsers = WebSocketDialogUser::with(['webSocketDialog'])->whereUserid($user->userid)->whereIn('dialog_id', array_values($dialogIds))->get();
foreach ($dialogUsers as $dialogUser) {
if (!$dialogUser->webSocketDialog) {
continue;
}
$dialogUser->updated_at = Carbon::now();
$dialogUser->save();
//
$dialogUser->webSocketDialog->generateUnread($user->userid);
$data[] = [
'id' => $dialogUser->webSocketDialog->id,
'unread' => $dialogUser->webSocketDialog->unread,
'mention' => $dialogUser->webSocketDialog->mention,
'position_msgs' => $dialogUser->webSocketDialog->position_msgs,
'user_at' => $dialogUser->updated_at,
];
}
return Base::retSuccess('success', $data);
} }
/** /**
* @api {get} api/dialog/msg/unread 12. 获取未读消息数量 * @api {get} api/dialog/msg/unread 12. 获取未读消息数
* *
* @apiDescription 需要token身份 * @apiDescription 需要token身份
* @apiVersion 1.0.0 * @apiVersion 1.0.0
* @apiGroup dialog * @apiGroup dialog
* @apiName msg__unread * @apiName msg__unread
* *
* @apiParam {Number} [dialog_id] 对话ID留空获取总未读消息数量 * @apiParam {Number} dialog_id 对话ID
* *
* @apiSuccess {Number} ret 返回状态码1正确、0错误 * @apiSuccess {Number} ret 返回状态码1正确、0错误
* @apiSuccess {String} msg 返回信息(错误描述) * @apiSuccess {String} msg 返回信息(错误描述)
* @apiSuccess {Object} data 返回数据 * @apiSuccess {Object} data 返回数据
* @apiSuccessExample {json} data: * @apiSuccessExample {json} data:
{ {
"unread": 43, // 未读消息数 "id": 43,
"last_umid": 308 // 最新的一条未读消息ID用于判断是否更新前端的未读数量 "unread": 308,
"mention": 11,
"position_msgs": [],
"user_at": "2020-12-12 00:00:00",
} }
*/ */
public function msg__unread() public function msg__unread()
{ {
$dialog_id = intval(Request::input('dialog_id')); $dialog_id = intval(Request::input('dialog_id'));
// //
$builder = WebSocketDialogMsgRead::whereUserid(User::userid())->whereReadAt(null); $dialogUser = WebSocketDialogUser::with(['webSocketDialog'])->whereDialogId($dialog_id)->whereUserid(User::userid())->first();
if ($dialog_id > 0) { if (empty($dialogUser?->webSocketDialog)) {
$builder->whereDialogId($dialog_id); return Base::retError('会话不存在');
} }
$dialogUser->webSocketDialog->generateUnread($dialogUser->userid);
//
return Base::retSuccess('success', [ return Base::retSuccess('success', [
'unread' => $builder->count(), 'id' => $dialogUser->webSocketDialog->id,
'last_umid' => intval($builder->orderByDesc('msg_id')->value('msg_id')), 'unread' => $dialogUser->webSocketDialog->unread,
'mention' => $dialogUser->webSocketDialog->mention,
'position_msgs' => $dialogUser->webSocketDialog->position_msgs,
'user_at' => $dialogUser->updated_at,
]); ]);
} }
@ -1044,41 +1072,48 @@ class DialogController extends AbstractController
public function msg__mark() public function msg__mark()
{ {
$user = User::auth(); $user = User::auth();
$dialogId = intval(Request::input('dialog_id')); //
$dialog_id = intval(Request::input('dialog_id'));
$type = Request::input('type'); $type = Request::input('type');
$afterMsgId = intval(Request::input('after_msg_id')); $after_msg_id = intval(Request::input('after_msg_id'));
$dialogUser = WebSocketDialogUser::whereUserid($user->userid)->whereDialogId($dialogId)->first(); //
if (!$dialogUser) { $dialogUser = WebSocketDialogUser::with(['webSocketDialog'])->whereDialogId($dialog_id)->whereUserid($user->userid)->first();
return Base::retError("会话不存在"); if (empty($dialogUser?->webSocketDialog)) {
return Base::retError('会话不存在');
} }
$data = [
'id' => $dialogId,
];
switch ($type) { switch ($type) {
case 'read': case 'read':
$data['mark_unread'] = 0; $builder = WebSocketDialogMsgRead::whereDialogId($dialog_id)->whereUserid($user->userid)->whereReadAt(null);
$data['unread'] = 0; if ($after_msg_id > 0) {
$data['mention'] = 0; $builder->where('msg_id', '>=', $after_msg_id);
$builder = WebSocketDialogMsgRead::whereUserid($user->userid)->whereReadAt(null)->whereDialogId($dialogId);
if ($afterMsgId > 0) {
$unBuilder = $builder->clone()->where('msg_id', '<', $afterMsgId);
$data['unread'] = $unBuilder->count();
$data['mention'] = $data['unread'] > 0 ? $unBuilder->whereMention(1)->count() : 0;
$builder->where('msg_id', '>=', $afterMsgId);
} }
$builder->chunkById(100, function ($list) { $builder->chunkById(100, function ($list) {
WebSocketDialogMsgRead::onlyMarkRead($list); WebSocketDialogMsgRead::onlyMarkRead($list);
}); });
$data['position_msgs'] = WebSocketDialog::find($dialogId)?->getPositionMsgs($user->userid) ?: []; //
$dialogUser->webSocketDialog->generateUnread($user->userid);
$data = [
'id' => $dialogUser->webSocketDialog->id,
'unread' => $dialogUser->webSocketDialog->unread,
'mention' => $dialogUser->webSocketDialog->mention,
'position_msgs' => $dialogUser->webSocketDialog->position_msgs,
'user_at' => Carbon::now()->toDateTimeString(),
'mark_unread' => 0,
];
break; break;
case 'unread': case 'unread':
$data['mark_unread'] = 1; $data = [
'id' => $dialogUser->webSocketDialog->id,
'user_at' => Carbon::now()->toDateTimeString(),
'mark_unread' => 1,
];
break; break;
default: default:
return Base::retError("参数错误"); return Base::retError("参数错误");
} }
$dialogUser->updated_at = $data['user_at'];
$dialogUser->mark_unread = $data['mark_unread']; $dialogUser->mark_unread = $data['mark_unread'];
$dialogUser->save(); $dialogUser->save();
return Base::retSuccess("success", $data); return Base::retSuccess("success", $data);

View File

@ -68,6 +68,10 @@ class WebSocketDialog extends AbstractModel
return $data[$key] ?? $default; return $data[$key] ?? $default;
}; };
// //
$this->pinyin = Base::cn2pinyin($this->name);
$this->top_at = $this->top_at ?? $dialogUserFun('top_at');
$this->user_at = $this->user_at ?? $dialogUserFun('updated_at');
//
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 = WebSocketDialogMsg::whereDialogId($this->id)->find($this->search_msg_id);
@ -76,31 +80,19 @@ class WebSocketDialog extends AbstractModel
// 最后消息 // 最后消息
$this->last_msg = WebSocketDialogMsg::whereDialogId($this->id)->orderByDesc('id')->first(); $this->last_msg = WebSocketDialogMsg::whereDialogId($this->id)->orderByDesc('id')->first();
// 未读信息 // 未读信息
$unBuilder = WebSocketDialogMsgRead::whereDialogId($this->id)->whereUserid($userid)->whereReadAt(null); $this->generateUnread($userid, $hasData);
$this->unread = $unBuilder->count(); // 未读标记
$this->mention = 0;
$this->last_umid = 0;
$this->position_msgs = [];
if ($this->unread > 0) {
$this->mention = $unBuilder->clone()->whereMention(1)->count();
$this->last_umid = intval($unBuilder->clone()->orderByDesc('msg_id')->value('msg_id'));
if ($hasData === true) {
$this->position_msgs = $this->getPositionMsgs($userid);
}
}
$this->mark_unread = $this->mark_unread ?? $dialogUserFun('mark_unread'); $this->mark_unread = $this->mark_unread ?? $dialogUserFun('mark_unread');
// 是否免打扰 // 是否免打扰
$this->silence = $this->silence ?? $dialogUserFun('silence'); $this->silence = $this->silence ?? $dialogUserFun('silence');
// 对话人数 // 对话人数
$builder = WebSocketDialogUser::whereDialogId($this->id); $this->people = WebSocketDialogUser::whereDialogId($this->id)->count();
$this->people = $builder->count();
// 有待办 // 有待办
$this->todo_num = WebSocketDialogMsgTodo::whereDialogId($this->id)->whereUserid($userid)->whereDoneAt(null)->count(); $this->todo_num = WebSocketDialogMsgTodo::whereDialogId($this->id)->whereUserid($userid)->whereDoneAt(null)->count();
} }
// 对方信息 // 对方信息
$this->dialog_user = null; $this->dialog_user = null;
$this->group_info = null; $this->group_info = null;
$this->top_at = $this->top_at ?? $dialogUserFun('top_at');
$this->bot = 0; $this->bot = 0;
switch ($this->type) { switch ($this->type) {
case "user": case "user":
@ -152,36 +144,45 @@ class WebSocketDialog extends AbstractModel
$this->has_file = $msgBuilder->clone()->whereMtype('file')->exists(); $this->has_file = $msgBuilder->clone()->whereMtype('file')->exists();
$this->has_link = $msgBuilder->clone()->whereLink(1)->exists(); $this->has_link = $msgBuilder->clone()->whereLink(1)->exists();
} }
$this->pinyin = Base::cn2pinyin($this->name);
return $this; return $this;
} }
/** /**
* 获取定位消息 * 生成未读数据
* @param $userid * @param $userid
* @return array[] * @param $positionData
* @return $this
*/ */
public function getPositionMsgs($userid) public function generateUnread($userid, $positionData = true)
{ {
$builder = WebSocketDialogMsgRead::whereDialogId($this->id)->whereUserid($userid)->whereReadAt(null); $builder = WebSocketDialogMsgRead::whereDialogId($this->id)->whereUserid($userid)->whereReadAt(null);
$array = []; $this->unread = $builder->count();
// @我的消息 $this->mention = 0;
$mention_id = intval($builder->clone()->whereMention(1)->orderByDesc('msg_id')->value('msg_id')); if ($this->unread > 0) {
if ($mention_id > 0) { $this->mention = $builder->clone()->whereMention(1)->count();
$array[] = [
'msg_id' => $mention_id,
'label' => Base::Lang('@我的消息'),
];
} }
// 最早一条未读消息 if ($positionData) {
$first_id = intval($builder->clone()->orderBy('msg_id')->value('msg_id')); $array = [];
if ($first_id > 0) { // @我的消息
$array[] = [ if ($this->mention > 0
'msg_id' => $first_id, && $mention_id = intval($builder->clone()->whereMention(1)->orderByDesc('msg_id')->value('msg_id'))) {
'label' => 'unread' $array[] = [
]; 'msg_id' => $mention_id,
'label' => Base::Lang('@我的消息'),
];
}
// 最早一条未读消息
if ($this->unread > 0
&& $first_id = intval($builder->clone()->orderBy('msg_id')->value('msg_id'))) {
$array[] = [
'msg_id' => $first_id,
'label' => '{UNREAD}'
];
}
//
$this->position_msgs = $array;
} }
return $array; return $this;
} }
/** /**

View File

@ -426,8 +426,9 @@ class WebSocketDialogMsg extends AbstractModel
WebSocketDialogMsgTodo::whereIn('msg_id', $ids)->delete(); WebSocketDialogMsgTodo::whereIn('msg_id', $ids)->delete();
self::whereIn('id', $ids)->delete(); self::whereIn('id', $ids)->delete();
// //
foreach ($dialogIds as $id) { $dialogDatas = WebSocketDialog::whereIn('id', $dialogIds)->get();
WebSocketDialog::find($id)?->updateMsgLastAt(); foreach ($dialogDatas as $dialogData) {
$dialogData->updateMsgLastAt();
} }
foreach ($replyIds as $id) { foreach ($replyIds as $id) {
self::whereId($id)->update(['reply_num' => self::whereReplyId($id)->count()]); self::whereId($id)->update(['reply_num' => self::whereReplyId($id)->count()]);
@ -453,9 +454,13 @@ class WebSocketDialogMsg extends AbstractModel
self::whereId($this->reply_id)->decrement('reply_num'); self::whereId($this->reply_id)->decrement('reply_num');
} }
// //
$dialog = $this->webSocketDialog; $dialogData = $this->webSocketDialog;
if ($dialog) { if ($dialogData) {
$userids = $dialog->dialogUser->pluck('userid')->toArray(); foreach ($dialogData->dialogUser as $dialogUser) {
$dialogUser->updated_at = Carbon::now();
$dialogUser->save();
}
$userids = $dialogData->dialogUser->pluck('userid')->toArray();
PushTask::push([ PushTask::push([
'userid' => $userids, 'userid' => $userids,
'msg' => [ 'msg' => [
@ -464,7 +469,7 @@ class WebSocketDialogMsg extends AbstractModel
'data' => [ 'data' => [
'id' => $this->id, 'id' => $this->id,
'dialog_id' => $this->dialog_id, 'dialog_id' => $this->dialog_id,
'last_msg' => $dialog->updateMsgLastAt(), 'last_msg' => $dialogData->updateMsgLastAt(),
'update_read' => $deleteRead ? 1 : 0 'update_read' => $deleteRead ? 1 : 0
], ],
] ]
@ -830,6 +835,7 @@ class WebSocketDialogMsg extends AbstractModel
$dialogMsg->send = 1; $dialogMsg->send = 1;
$dialogMsg->key = $dialogMsg->generateMsgKey(); $dialogMsg->key = $dialogMsg->generateMsgKey();
$dialogMsg->save(); $dialogMsg->save();
WebSocketDialogUser::whereDialogId($dialog->id)->update(['updated_at' => $dialog->updated_at]);
}); });
// //
$task = new WebSocketDialogMsgTask($dialogMsg->id); $task = new WebSocketDialogMsgTask($dialogMsg->id);

View File

@ -15,6 +15,7 @@ namespace App\Models;
* @property int|null $important 是否不可移出(项目、任务、部门人员) * @property int|null $important 是否不可移出(项目、任务、部门人员)
* @property \Illuminate\Support\Carbon|null $created_at * @property \Illuminate\Support\Carbon|null $created_at
* @property \Illuminate\Support\Carbon|null $updated_at * @property \Illuminate\Support\Carbon|null $updated_at
* @property-read \App\Models\WebSocketDialog|null $webSocketDialog
* @method static \Illuminate\Database\Eloquent\Builder|WebSocketDialogUser newModelQuery() * @method static \Illuminate\Database\Eloquent\Builder|WebSocketDialogUser newModelQuery()
* @method static \Illuminate\Database\Eloquent\Builder|WebSocketDialogUser newQuery() * @method static \Illuminate\Database\Eloquent\Builder|WebSocketDialogUser newQuery()
* @method static \Illuminate\Database\Eloquent\Builder|WebSocketDialogUser query() * @method static \Illuminate\Database\Eloquent\Builder|WebSocketDialogUser query()
@ -32,5 +33,11 @@ namespace App\Models;
*/ */
class WebSocketDialogUser extends AbstractModel class WebSocketDialogUser extends AbstractModel
{ {
/**
* @return \Illuminate\Database\Eloquent\Relations\HasOne
*/
public function webSocketDialog(): \Illuminate\Database\Eloquent\Relations\HasOne
{
return $this->hasOne(WebSocketDialog::class, 'id', 'dialog_id');
}
} }

View File

@ -280,7 +280,7 @@ class BotReceiveMsgTask extends AbstractTask
$nameKey = $isManager ? $array[2] : $array[1]; $nameKey = $isManager ? $array[2] : $array[1];
$data = $this->botManagerOne($botId, $msg->userid); $data = $this->botManagerOne($botId, $msg->userid);
if ($data) { if ($data) {
$list = WebSocketDialog::select(['web_socket_dialogs.*', 'u.top_at', 'u.mark_unread', 'u.silence']) $list = WebSocketDialog::select(['web_socket_dialogs.*', 'u.top_at', 'u.mark_unread', 'u.silence', 'u.updated_at as user_at'])
->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.name', 'LIKE', "%{$nameKey}%") ->where('web_socket_dialogs.name', 'LIKE', "%{$nameKey}%")
->where('u.userid', $data->userid) ->where('u.userid', $data->userid)

View File

@ -778,14 +778,14 @@ export default {
positionMsg() { positionMsg() {
const {unread, position_msgs} = this.dialogData const {unread, position_msgs} = this.dialogData
if (unread === 0 || this.allMsgs.length === 0 ||position_msgs.length === 0) { if (!position_msgs || position_msgs.length === 0 || unread === 0 || this.allMsgs.length === 0) {
return null return null
} }
const item = position_msgs.sort((a, b) => { const item = position_msgs.sort((a, b) => {
return b.msg_id - a.msg_id return b.msg_id - a.msg_id
})[0] })[0]
if (this.allMsgs.findIndex(({id}) => id == item.msg_id) === -1) { if (this.allMsgs.findIndex(({id}) => id == item.msg_id) === -1) {
if (item.label === 'unread') { if (item.label === '{UNREAD}') {
return Object.assign(item, { return Object.assign(item, {
'label': this.$L(`未读消息${unread}`) 'label': this.$L(`未读消息${unread}`)
}) })

View File

@ -2066,11 +2066,11 @@ export default {
} else if ($A.isJson(data)) { } else if ($A.isJson(data)) {
const index = state.cacheDialogs.findIndex(({id}) => id == data.id); const index = state.cacheDialogs.findIndex(({id}) => id == data.id);
if (index > -1) { if (index > -1) {
const original = state.cacheDialogs[index]; const original = state.cacheDialogs[index]
if (typeof data.unread === "number" && data.unread > original.unread && data.last_umid <= original.last_umid) { if ($A.Time(data.user_at) < $A.Time(original.user_at)) {
// 增加未读数时新数据的最后一条未读消息id <= 原数据,则不更新未读数 typeof data.unread !== "undefined" && delete data.unread
data.unread = original.unread; typeof data.mention !== "undefined" && delete data.mention
data.mention = original.mention; typeof data.position_msgs !== "undefined" && delete data.position_msgs
} }
state.cacheDialogs.splice(index, 1, Object.assign({}, original, data)); state.cacheDialogs.splice(index, 1, Object.assign({}, original, data));
} else { } else {
@ -2148,9 +2148,9 @@ export default {
callData.page = 1 callData.page = 1
if (state.cacheDialogs.length > 0) { if (state.cacheDialogs.length > 0) {
const tmpList = state.cacheDialogs.sort((a, b) => { const tmpList = state.cacheDialogs.sort((a, b) => {
return $A.Date(b.last_at) - $A.Date(a.last_at); return $A.Date(b.user_at) - $A.Date(a.user_at);
}) })
callData.at_after = tmpList[0].last_at; callData.at_after = tmpList[0].user_at;
} }
} }
// //
@ -2598,32 +2598,23 @@ export default {
if (data.read_at) return; if (data.read_at) return;
data.read_at = $A.formatDate(); data.read_at = $A.formatDate();
// //
const dialog = state.cacheDialogs.find(({id}) => id == data.dialog_id); state.wsReadWaitData[data.id] = data.id;
if (dialog && dialog.unread > 0) {
const newData = {
id: data.dialog_id,
mark_unread: 0,
}
newData.unread = dialog.unread - 1;
if (data.mention) {
newData.mention = dialog.mention - 1;
}
dispatch("saveDialog", newData)
}
//
state.wsReadWaitList.push(data.id);
clearTimeout(state.wsReadTimeout); clearTimeout(state.wsReadTimeout);
state.wsReadTimeout = setTimeout(() => { state.wsReadTimeout = setTimeout(_ => {
const id = $A.cloneJSON(state.wsReadWaitList); const ids = Object.values(state.wsReadWaitData);
state.wsReadWaitList = []; state.wsReadWaitData = {};
// //
dispatch("call", { dispatch("call", {
url: 'dialog/msg/read', url: 'dialog/msg/read',
data: { data: {
id: id.join(",") id: ids.join(",")
} }
}).then(({data}) => {
dispatch("saveDialog", data)
}).catch(_ => { }).catch(_ => {
state.wsReadWaitList.push(...id) ids.some(id => {
state.wsReadWaitData[id] = id;
})
}); });
}, 50); }, 50);
}, },
@ -2825,10 +2816,8 @@ export default {
dispatch("call", { dispatch("call", {
url: 'dialog/msg/unread', url: 'dialog/msg/unread',
data: {dialog_id} data: {dialog_id}
}).then(result => { }).then(({data}) => {
newData.unread = result.data.unread dispatch("saveDialog", Object.assign(newData, data))
newData.last_umid = result.data.last_umid
dispatch("saveDialog", newData)
}).catch(() => {}); }).catch(() => {});
} else { } else {
dispatch("saveDialog", newData) dispatch("saveDialog", newData)
@ -2852,11 +2841,12 @@ export default {
if (dialog) { if (dialog) {
const newData = { const newData = {
id: dialog_id, id: dialog_id,
last_umid: data.id, unread: dialog.unread + 1,
mention: dialog.mention,
user_at: data.created_at,
} }
newData.unread = dialog.unread + 1;
if (data.mention) { if (data.mention) {
newData.mention = dialog.mention + 1; newData.mention++;
} }
dispatch("saveDialog", newData) dispatch("saveDialog", newData)
} }

View File

@ -63,7 +63,7 @@ export default {
wsOpenNum: 0, wsOpenNum: 0,
wsListener: {}, wsListener: {},
wsReadTimeout: null, wsReadTimeout: null,
wsReadWaitList: [], wsReadWaitData: {},
// 会员信息 // 会员信息
userInfo: {}, userInfo: {},