perf: 优化获取最近消息

This commit is contained in:
kuaifan 2024-01-15 22:28:42 +08:00 committed by Pang
parent 31efee2e97
commit b711605bdc
3 changed files with 78 additions and 67 deletions

View File

@ -553,10 +553,9 @@ class DialogController extends AbstractController
* @apiGroup dialog * @apiGroup dialog
* @apiName msg__latest * @apiName msg__latest
* *
* @apiParam {Number} [latest_id] 此消息ID之后的数据 * @apiParam {Array} [dialogs] 对话ID列表
* * - 格式:[{id:会话ID, latest_id:此消息ID之后的数据}, ...]
* @apiParam {Number} [page] 当前页,默认:1 * @apiParam {Number} [take] 每个会话获取多少条,默认:25,最大:50
* @apiParam {Number} [pagesize] 每页显示数量,默认:50,最大:100
* *
* @apiSuccess {Number} ret 返回状态码1正确、0错误 * @apiSuccess {Number} ret 返回状态码1正确、0错误
* @apiSuccess {String} msg 返回信息(错误描述) * @apiSuccess {String} msg 返回信息(错误描述)
@ -564,39 +563,51 @@ class DialogController extends AbstractController
*/ */
public function msg__latest() public function msg__latest()
{ {
if (!Base::judgeClientVersion('0.34.47')) {
return Base::retSuccess('success', ['data' => []]);
}
//
$user = User::auth(); $user = User::auth();
// //
$latest_id = intval(Request::input('latest_id')); $dialogs = Request::input('dialogs');
// if (empty($dialogs) || !is_array($dialogs)) {
\DB::statement("SET SQL_MODE=''"); return Base::retError('参数错误');
}
$builder = WebSocketDialogMsg::select([ $builder = WebSocketDialogMsg::select([
'web_socket_dialog_msgs.*', 'web_socket_dialog_msgs.*',
'read.mention', 'read.mention',
'read.read_at', 'read.read_at',
]) ])->leftJoin('web_socket_dialog_msg_reads as read', function ($leftJoin) use ($user) {
->join('web_socket_dialog_msg_reads as read', 'read.msg_id', '=', 'web_socket_dialog_msgs.id') $leftJoin
->where('read.userid', $user->userid) ->on('read.userid', '=', DB::raw($user->userid))
->orWhere('web_socket_dialog_msgs.userid', $user->userid); ->on('read.msg_id', '=', 'web_socket_dialog_msgs.id');
//
if ($latest_id > 0) {
$builder->where('read.msg_id', '>', $latest_id);
}
//
$data = $builder
->groupBy('id')
->orderByDesc('id')
->paginate(Base::getPaginate(100, 50));
if ($data->isEmpty()) {
return Base::retError('empty');
}
$data->transform(function (WebSocketDialogMsg $item) use ($user) {
if ($item->userid === $user->userid) {
$item->mention = 0;
$item->read_at = null;
}
return $item;
}); });
return Base::retSuccess('success', $data); $data = [];
$num = 0;
foreach ($dialogs as $item) {
$dialog_id = intval($item['id']);
$latest_id = intval($item['latest_id']);
if ($dialog_id <= 0) {
continue;
}
if ($num >= 5) {
break;
}
$num++;
WebSocketDialog::checkDialog($dialog_id);
//
$cloner = $builder->clone();
$cloner->where('web_socket_dialog_msgs.dialog_id', $dialog_id);
if ($latest_id > 0) {
$cloner->where('web_socket_dialog_msgs.id', '>', $latest_id);
}
$cloner->orderByDesc('web_socket_dialog_msgs.id');
$list = $cloner->take(Base::getPaginate(50, 25, 'take'))->get();
if ($list->isNotEmpty()) {
$data = array_merge($data, $list->toArray());
}
}
return Base::retSuccess('success', compact('data'));
} }
/** /**
@ -631,9 +642,7 @@ class DialogController extends AbstractController
->where('key', 'LIKE', "%{$key}%") ->where('key', 'LIKE', "%{$key}%")
->take(200) ->take(200)
->pluck('id'); ->pluck('id');
return Base::retSuccess('success', [ return Base::retSuccess('success', compact('data'));
'data' => $data
]);
} }
/** /**

View File

@ -2420,8 +2420,6 @@ export default {
state.loadDialogs--; state.loadDialogs--;
state.loadDialogAuto = false state.loadDialogAuto = false
}) })
//
dispatch("getDialogLatestMsgs").catch(() => {})
}) })
}, },
@ -2458,6 +2456,10 @@ export default {
dispatch("saveDialog", data.data); dispatch("saveDialog", data.data);
callData.save(data).then(ids => dispatch("forgetDialog", ids)) callData.save(data).then(ids => dispatch("forgetDialog", ids))
// //
if (data.current_page === 1) {
dispatch("getDialogLatestMsgs", data.data.map(({id}) => id))
}
//
if (data.next_page_url && data.current_page < 5) { if (data.next_page_url && data.current_page < 5) {
requestData.page++ requestData.page++
dispatch("getDialogs", requestData).then(resolve).catch(reject) dispatch("getDialogs", requestData).then(resolve).catch(reject)
@ -3023,48 +3025,44 @@ export default {
* 获取最新消息 * 获取最新消息
* @param state * @param state
* @param dispatch * @param dispatch
* @param requestData * @param dialogIds
* @returns {Promise<unknown>} * @returns {Promise<unknown>}
*/ */
getDialogLatestMsgs({state, dispatch}, requestData = {}) { getDialogLatestMsgs({state, dispatch}, dialogIds = []) {
return new Promise(function (resolve, reject) { return new Promise(function (resolve, reject) {
if (state.userId === 0) { if (state.userId === 0) {
reject({msg: 'Parameter error'}); reject({msg: 'Parameter error'});
return; return;
} }
if (!$A.isJson(requestData)) { if (!$A.isArray(dialogIds)) {
requestData = {} reject({msg: 'Parameter is not array'});
return
} }
if (typeof requestData.page === "undefined") { if (dialogIds.length === 0) {
requestData.page = 1 resolve()
} return
if (typeof requestData.pagesize === "undefined") {
requestData.pagesize = 20
}
if (typeof requestData.latest_id === "undefined") {
requestData.latest_id = state.loadDialogLatestId
} }
// //
const wait = dialogIds.slice(5)
const dialogs = dialogIds.slice(0, 5)
dispatch("call", { dispatch("call", {
method: 'post',
url: 'dialog/msg/latest', url: 'dialog/msg/latest',
data: requestData, data: {
dialogs: dialogs.map(id => {
return {
id,
latest_id: state.dialogMsgs.sort((a, b) => {
return b.id - a.id
}).find(({dialog_id}) => dialog_id == id)?.id || 0
}
}),
take: state.dialogMsgKeep
},
}).then(({data}) => { }).then(({data}) => {
const list = data.data dispatch("saveDialogMsg", data.data);
if (list.length === 0) { if (wait.length > 0) {
resolve() dispatch("getDialogLatestMsgs", wait).then(resolve).catch(reject)
return
}
//
const lastId = list[list.length - 1].id;
const lastNotExist = state.dialogMsgs.findIndex(({id}) => id == lastId) === -1
if (requestData.page === 1) {
state.loadDialogLatestId = list[0].id
}
dispatch("saveDialogMsg", list);
//
if (data.next_page_url && data.current_page < 5 && lastNotExist) {
requestData.page++
dispatch("getDialogLatestMsgs", requestData).then(resolve).catch(reject)
} else { } else {
resolve() resolve()
} }

View File

@ -725,7 +725,7 @@
&.an-emoji { &.an-emoji {
.content-text { .content-text {
> pre { > pre {
font-size: 72px; font-size: 72px !important;
line-height: 1; line-height: 1;
} }
} }
@ -734,7 +734,7 @@
&.two-emoji { &.two-emoji {
.content-text { .content-text {
> pre { > pre {
font-size: 52px; font-size: 52px !important;
line-height: 1; line-height: 1;
letter-spacing: 4px; letter-spacing: 4px;
} }
@ -744,7 +744,7 @@
&.three-emoji { &.three-emoji {
.content-text { .content-text {
> pre { > pre {
font-size: 32px; font-size: 32px !important;
line-height: 1; line-height: 1;
letter-spacing: 4px; letter-spacing: 4px;
} }
@ -761,6 +761,10 @@
max-width: 220px; max-width: 220px;
} }
.markdown-body {
line-height: 20px;
}
> pre { > pre {
display: block; display: block;
margin: 0; margin: 0;