定位回复消息

This commit is contained in:
kuaifan 2022-06-17 15:25:13 +08:00
parent 3bd2e40a98
commit 88316fda1c
5 changed files with 106 additions and 42 deletions

View File

@ -178,6 +178,7 @@ class DialogController extends AbstractController
* @apiName msg__lists * @apiName msg__lists
* *
* @apiParam {Number} dialog_id 对话ID * @apiParam {Number} dialog_id 对话ID
* @apiParam {String} [position_id] 定位消息ID填写时page无效
* *
* @apiParam {Number} [page] 当前页,默认:1 * @apiParam {Number} [page] 当前页,默认:1
* @apiParam {Number} [pagesize] 每页显示数量,默认:50,最大:100 * @apiParam {Number} [pagesize] 每页显示数量,默认:50,最大:100
@ -191,10 +192,11 @@ class DialogController extends AbstractController
$user = User::auth(); $user = User::auth();
// //
$dialog_id = intval(Request::input('dialog_id')); $dialog_id = intval(Request::input('dialog_id'));
$position_id = intval(Request::input('position_id'));
// //
$dialog = WebSocketDialog::checkDialog($dialog_id); $dialog = WebSocketDialog::checkDialog($dialog_id);
// //
$list = WebSocketDialogMsg::select([ $builder = WebSocketDialogMsg::select([
'web_socket_dialog_msgs.*', 'web_socket_dialog_msgs.*',
'read.mention', 'read.mention',
'read.read_at', 'read.read_at',
@ -202,7 +204,15 @@ class DialogController extends AbstractController
$leftJoin $leftJoin
->on('read.userid', '=', DB::raw($user->userid)) ->on('read.userid', '=', DB::raw($user->userid))
->on('read.msg_id', '=', 'web_socket_dialog_msgs.id'); ->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)); })->where('web_socket_dialog_msgs.dialog_id', $dialog_id)->orderByDesc('web_socket_dialog_msgs.id');
//
$perPage = Base::getPaginate(100, 50);
if ($position_id > 0) {
$position_count = $builder->clone()->where('web_socket_dialog_msgs.id', '>=', $position_id)->count();
$list = $builder->paginate($perPage, [], 'page', ceil($position_count / $perPage));
} else {
$list = $builder->paginate($perPage);
}
// //
if ($dialog->type == 'group' && $dialog->group_type == 'task') { if ($dialog->type == 'group' && $dialog->group_type == 'task') {
$user->task_dialog_id = $dialog->id; $user->task_dialog_id = $dialog->id;

View File

@ -75,8 +75,8 @@ export default {
this.dispatch("on-longpress", e) this.dispatch("on-longpress", e)
}, },
onViewReply(replyId) { onViewReply(data) {
this.dispatch("on-view-reply", replyId) this.dispatch("on-view-reply", data)
}, },
onViewText(e) { onViewText(e) {

View File

@ -388,7 +388,10 @@ export default {
}, },
viewReply() { viewReply() {
this.$emit("on-view-reply", this.replyData.id) this.$emit("on-view-reply", {
msg_id: this.msgData.id,
reply_id: this.replyData.id
})
}, },
viewText(e) { viewText(e) {

View File

@ -79,9 +79,9 @@
:item-class-add="itemClassAdd" :item-class-add="itemClassAdd"
:extra-props="{dialogData, isMyDialog, operateVisible, operateItem}" :extra-props="{dialogData, isMyDialog, operateVisible, operateItem}"
:estimate-size="78" :estimate-size="78"
:keeps="80" :keeps="70"
@scroll="onScroll" @scroll="onScroll"
@totop="loadNextPage" @totop="onNextPage"
@on-longpress="onLongpress" @on-longpress="onLongpress"
@on-view-reply="onViewReply" @on-view-reply="onViewReply"
@ -89,7 +89,7 @@
@on-view-file="onViewFile" @on-view-file="onViewFile"
@on-emoji="onEmoji"> @on-emoji="onEmoji">
<template slot="header"> <template slot="header">
<div v-if="(allMsgs.length === 0 && dialogData.loading > 0) || dialogData.hasMorePages" class="dialog-item loading"><Loading/></div> <div v-if="(allMsgs.length === 0 && dialogData.loading > 0) || nextPage > 0" class="dialog-item loading"><Loading/></div>
<div v-else-if="allMsgs.length > 0" class="dialog-item loaded">{{$L('已加载全部消息')}}</div> <div v-else-if="allMsgs.length > 0" class="dialog-item loaded">{{$L('已加载全部消息')}}</div>
<div v-else class="dialog-item nothing">{{$L('暂无消息')}}</div> <div v-else class="dialog-item nothing">{{$L('暂无消息')}}</div>
</template> </template>
@ -326,6 +326,7 @@ export default {
recordState: '', recordState: '',
wrapperStart: 0, wrapperStart: 0,
scrollMoreLoad: false,
replyId: 0, replyId: 0,
replyActiveIndex: -1, replyActiveIndex: -1,
@ -386,6 +387,17 @@ export default {
return dialogMsgList; return dialogMsgList;
}, },
nextPage() {
if (this.allMsgs.length > 0) {
let topMsgPage = $A.runNum(this.allMsgs[0]._page);
let {lastPage} = this.dialogData;
if (topMsgPage < lastPage && lastPage > 1) {
return topMsgPage + 1
}
}
return 0
},
peopleNum() { peopleNum() {
return this.dialogData.type === 'group' ? $A.runNum(this.dialogData.people) : 0; return this.dialogData.type === 'group' ? $A.runNum(this.dialogData.people) : 0;
}, },
@ -798,8 +810,14 @@ export default {
this.$store.dispatch("openTask", this.dialogData.group_info.id); this.$store.dispatch("openTask", this.dialogData.group_info.id);
}, },
loadNextPage() { onNextPage() {
this.$store.dispatch('getDialogMoreMsgs', this.dialogId).then(result => { if (this.nextPage === 0) {
return
}
this.$store.dispatch('getDialogMoreMsgs', {
dialog_id: this.dialogId,
page: this.nextPage
}).then(result => {
const resData = result.data; const resData = result.data;
const ids = resData.data.map(item => item.id) const ids = resData.data.map(item => item.id)
this.$nextTick(() => { this.$nextTick(() => {
@ -887,7 +905,7 @@ export default {
} }
}, },
onScroll() { onScroll(evt, range) {
this.operateVisible = false; this.operateVisible = false;
this.__onScroll && clearTimeout(this.__onScroll); this.__onScroll && clearTimeout(this.__onScroll);
this.__onScroll = setTimeout(_ => { this.__onScroll = setTimeout(_ => {
@ -896,6 +914,25 @@ export default {
this.msgNew = 0; this.msgNew = 0;
} }
}, 100) }, 100)
//
if (!this.scrollMoreLoad) {
let tmpPage = 0;
for (let i = range.start; i <= range.end; i++) {
if (tmpPage - parseInt(this.allMsgs[i]._page) > 1) {
this.scrollMoreLoad = true
setTimeout(_ => {
this.$store.dispatch("getDialogMoreMsgs", {
dialog_id: this.dialogId,
page: tmpPage - 1
}).finally(_ => {
this.scrollMoreLoad = false
})
}, 100)
break;
}
tmpPage = parseInt(this.allMsgs[i]._page);
}
}
}, },
onBack() { onBack() {
@ -1021,19 +1058,45 @@ export default {
}); });
}, },
onViewReply(replyId) { onViewReply(data) {
if (this.operateVisible) { if (this.operateVisible) {
return return
} }
const index = this.allMsgs.findIndex(item => item.id === replyId) const toIndex = (index) => {
if (index > -1) { this.$refs.scroller?.scrollToIndex(index)
this.$refs.scroller?.scrollToIndex(index);
requestAnimationFrame(_ => { requestAnimationFrame(_ => {
this.replyActiveIndex = index; this.replyActiveIndex = index
setTimeout(_ => { setTimeout(_ => {
this.replyActiveIndex = -1; this.replyActiveIndex = -1
}, 800) }, 800)
}); })
}
const index = this.allMsgs.findIndex(item => item.id === data.reply_id)
if (index > -1) {
toIndex(index)
} else {
this.$store.dispatch("setLoad", {
key: `msg-${data.msg_id}`,
delay: 600
})
this.$store.dispatch("getDialogMoreMsgs", {
dialog_id: this.dialogId,
position_id: data.reply_id
}).then(_ => {
let i = 0;
let inter = setInterval(_ => {
i++
const index = this.allMsgs.findIndex(item => item.id === data.reply_id)
if (i > 10 || index > -1) {
clearInterval(inter)
if (index > -1) {
toIndex(index)
}
}
}, 100)
}).finally(_ => {
this.$store.dispatch("cancelLoad", `msg-${data.msg_id}`)
})
} }
}, },

View File

@ -2196,25 +2196,22 @@ export default {
return; return;
} }
dialog.loading = true; dialog.loading = true;
dialog.currentPage = 1;
dialog.hasMorePages = false;
// //
dispatch("call", { dispatch("call", {
url: 'dialog/msg/lists', url: 'dialog/msg/lists',
data: { data: {
dialog_id: dialog_id, dialog_id: dialog_id,
page: dialog.currentPage page: 1
}, },
}).then(result => { }).then(result => {
const resData = result.data; const resData = result.data;
dialog.currentPage = resData.current_page; dialog.lastPage = resData.last_page;
dialog.hasMorePages = !!resData.next_page_url;
dialog = Object.assign(dialog, resData.dialog) dialog = Object.assign(dialog, resData.dialog)
// //
const ids = resData.data.map(({id}) => id) const ids = resData.data.map(({id}) => id)
state.dialogMsgs = state.dialogMsgs.filter((item) => item.dialog_id != dialog_id || ids.includes(item.id)); state.dialogMsgs = state.dialogMsgs.filter((item) => item.dialog_id != dialog_id || ids.includes(item.id));
// //
dispatch("saveDialogMsg", resData.data); dispatch("saveDialogMsg", resData.data.map(item => Object.assign(item, {_page: resData.current_page})));
resolve() resolve()
}).catch(e => { }).catch(e => {
console.warn(e); console.warn(e);
@ -2227,46 +2224,37 @@ export default {
}, },
/** /**
* 获取更多(下一页)会话消息 * 获取更多会话消息指定页|定位页
* @param state * @param state
* @param dispatch * @param dispatch
* @param dialog_id * @param data {dialog_id, ?page, ?position_id}
*/ */
getDialogMoreMsgs({state, dispatch}, dialog_id) { getDialogMoreMsgs({state, dispatch}, data) {
return new Promise(function (resolve, reject) { return new Promise(function (resolve, reject) {
const dialog = state.cacheDialogs.find(({id}) => id == dialog_id); const dialog = state.cacheDialogs.find(({id}) => id == data.dialog_id);
if (!dialog) { if (!dialog) {
reject({msg: 'Parameter error'}); reject({msg: 'Parameter error'});
return; return;
} }
if (!dialog.hasMorePages) {
reject({msg: 'No more page'});
return;
}
if (dialog.loading) { if (dialog.loading) {
reject({msg: 'Loading'}); reject({msg: 'Loading'});
return; return;
} }
dialog.loading = true; dialog.loading = true;
dialog.currentPage++;
// //
dispatch("call", { dispatch("call", {
url: 'dialog/msg/lists', url: 'dialog/msg/lists',
data: { data,
dialog_id: dialog_id,
page: dialog.currentPage
},
}).then(result => { }).then(result => {
const resData = result.data; const resData = result.data;
dialog.loading = false; dialog.lastPage = resData.last_page;
dialog.currentPage = resData.current_page; dispatch("saveDialogMsg", resData.data.map(item => Object.assign(item, {_page: resData.current_page})));
dialog.hasMorePages = !!resData.next_page_url;
dispatch("saveDialogMsg", resData.data);
resolve(result) resolve(result)
}).catch(e => { }).catch(e => {
console.warn(e); console.warn(e);
dialog.loading = false;
reject(e) reject(e)
}).finally(_ => {
dialog.loading = false;
}); });
}); });
}, },