定位回复消息

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

View File

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

View File

@ -388,7 +388,10 @@ export default {
},
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) {

View File

@ -79,9 +79,9 @@
:item-class-add="itemClassAdd"
:extra-props="{dialogData, isMyDialog, operateVisible, operateItem}"
:estimate-size="78"
:keeps="80"
:keeps="70"
@scroll="onScroll"
@totop="loadNextPage"
@totop="onNextPage"
@on-longpress="onLongpress"
@on-view-reply="onViewReply"
@ -89,7 +89,7 @@
@on-view-file="onViewFile"
@on-emoji="onEmoji">
<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 class="dialog-item nothing">{{$L('暂无消息')}}</div>
</template>
@ -326,6 +326,7 @@ export default {
recordState: '',
wrapperStart: 0,
scrollMoreLoad: false,
replyId: 0,
replyActiveIndex: -1,
@ -386,6 +387,17 @@ export default {
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() {
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);
},
loadNextPage() {
this.$store.dispatch('getDialogMoreMsgs', this.dialogId).then(result => {
onNextPage() {
if (this.nextPage === 0) {
return
}
this.$store.dispatch('getDialogMoreMsgs', {
dialog_id: this.dialogId,
page: this.nextPage
}).then(result => {
const resData = result.data;
const ids = resData.data.map(item => item.id)
this.$nextTick(() => {
@ -887,7 +905,7 @@ export default {
}
},
onScroll() {
onScroll(evt, range) {
this.operateVisible = false;
this.__onScroll && clearTimeout(this.__onScroll);
this.__onScroll = setTimeout(_ => {
@ -896,6 +914,25 @@ export default {
this.msgNew = 0;
}
}, 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() {
@ -1021,19 +1058,45 @@ export default {
});
},
onViewReply(replyId) {
onViewReply(data) {
if (this.operateVisible) {
return
}
const index = this.allMsgs.findIndex(item => item.id === replyId)
if (index > -1) {
this.$refs.scroller?.scrollToIndex(index);
const toIndex = (index) => {
this.$refs.scroller?.scrollToIndex(index)
requestAnimationFrame(_ => {
this.replyActiveIndex = index;
this.replyActiveIndex = index
setTimeout(_ => {
this.replyActiveIndex = -1;
this.replyActiveIndex = -1
}, 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;
}
dialog.loading = true;
dialog.currentPage = 1;
dialog.hasMorePages = false;
//
dispatch("call", {
url: 'dialog/msg/lists',
data: {
dialog_id: dialog_id,
page: dialog.currentPage
page: 1
},
}).then(result => {
const resData = result.data;
dialog.currentPage = resData.current_page;
dialog.hasMorePages = !!resData.next_page_url;
dialog.lastPage = resData.last_page;
dialog = Object.assign(dialog, resData.dialog)
//
const ids = resData.data.map(({id}) => 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()
}).catch(e => {
console.warn(e);
@ -2227,46 +2224,37 @@ export default {
},
/**
* 获取更多(下一页)会话消息
* 获取更多会话消息指定页|定位页
* @param state
* @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) {
const dialog = state.cacheDialogs.find(({id}) => id == dialog_id);
const dialog = state.cacheDialogs.find(({id}) => id == data.dialog_id);
if (!dialog) {
reject({msg: 'Parameter error'});
return;
}
if (!dialog.hasMorePages) {
reject({msg: 'No more page'});
return;
}
if (dialog.loading) {
reject({msg: 'Loading'});
return;
}
dialog.loading = true;
dialog.currentPage++;
//
dispatch("call", {
url: 'dialog/msg/lists',
data: {
dialog_id: dialog_id,
page: dialog.currentPage
},
data,
}).then(result => {
const resData = result.data;
dialog.loading = false;
dialog.currentPage = resData.current_page;
dialog.hasMorePages = !!resData.next_page_url;
dispatch("saveDialogMsg", resData.data);
dialog.lastPage = resData.last_page;
dispatch("saveDialogMsg", resData.data.map(item => Object.assign(item, {_page: resData.current_page})));
resolve(result)
}).catch(e => {
console.warn(e);
dialog.loading = false;
reject(e)
}).finally(_ => {
dialog.loading = false;
});
});
},