diff --git a/pages/chat/index.vue b/pages/chat/index.vue
index aaa29c3..68235d6 100644
--- a/pages/chat/index.vue
+++ b/pages/chat/index.vue
@@ -13,77 +13,86 @@
class="chat-scroll"
scroll-y
:scroll-into-view="scrollToView"
+ :scroll-top="scrollTop"
scroll-with-animation
+ :upper-threshold="20"
+ @scroll="handleScroll"
+ @scrolltoupper="handleScrollToUpper"
>
-
-
-
-
-
{{ vuex_msgUser.name }}
+
+
+
+
+
+
{{ vuex_msgUser.name }}
-
-
- {{ vuex_msgUser.collegeName }}
-
+
+
+ {{ vuex_msgUser.collegeName }}
+
-
-
-
{{ vuex_msgUser.collegeName }}
+
+
+ {{ vuex_msgUser.collegeName }}
+
-
-
-
-
- {{ formatShowTime(message.sendDate) }}
-
-
-
-
- {{ message.message }}
+
+
+ {{ formatShowTime(message.sendDate) }}
+
+
+
+
+
+ {{ message.message }}
+
+
+
+
+
+
+
+
+ {{ message.message }}
+
-
-
-
-
-
- {{ message.message }}
-
-
+
+
-
-
-
@@ -155,9 +164,15 @@ export default {
// 滚动位置
scrollToView: "",
+ scrollTop: 0,
+ currentScrollTop: 0,
+ currentScrollHeight: 0,
PageIndex: 1,
PageSize: 20,
+
+ isLoadingHistory: false,
+ noMoreHistory: false,
};
},
@@ -200,6 +215,7 @@ export default {
// 监听最后一条消息的ID变化,滚动到底部
lastMsgId(val) {
if (!val) return;
+ if (this.isLoadingHistory) return;
this.$nextTick(() => {
this.scrollToBottom();
});
@@ -267,20 +283,61 @@ export default {
// 加载对话消息
getMsgList() {
- this.$u.api
- .GetChatHistoryDataApi({
- "Item1.DialogueManagementId": this.vuex_msgUser.dialogueManagementId,
+ return this.$store.dispatch("fetchChatRecord", {
+ dialogueManagementId: this.vuex_msgUser.dialogueManagementId,
+ PageIndex: this.PageIndex,
+ PageSize: this.PageSize,
+ });
+ },
+
+ handleScroll(e) {
+ const detail = (e && e.detail) || {};
+ this.currentScrollTop = Number(detail.scrollTop) || 0;
+ this.currentScrollHeight = Number(detail.scrollHeight) || 0;
+ },
+
+ // 滚动到顶部,加载下一页历史消息
+ handleScrollToUpper() {
+ if (this.isLoadingHistory || this.noMoreHistory) return;
+
+ this.isLoadingHistory = true;
+ const beforeTop = this.currentScrollTop || 0;
+ const beforeHeight = this.currentScrollHeight || 0;
+ this.PageIndex += 1;
+ this.scrollToView = "";
+
+ this.$store
+ .dispatch("fetchChatRecordNextPage", {
+ dialogueManagementId: this.vuex_msgUser.dialogueManagementId,
PageIndex: this.PageIndex,
PageSize: this.PageSize,
})
- .then((res) => {
- const msgList = res.data.item1.reverse();
-
- this.$store.commit("push_MsgList", msgList);
- // // 滚动到底部
- // this.$nextTick(() => {
- // this.scrollToBottom();
- // });
+ .then((list) => {
+ if (!list || !list.length) {
+ this.noMoreHistory = true;
+ return;
+ }
+ this.$nextTick(() => {
+ const query = uni.createSelectorQuery().in(this);
+ query
+ .select(".chat-content")
+ .boundingClientRect((rect) => {
+ const afterHeight = Number(rect && rect.height) || 0;
+ const delta = afterHeight - beforeHeight;
+ if (delta > 0) {
+ this.scrollTop = beforeTop + delta;
+ }
+ })
+ .exec();
+ });
+ })
+ .catch(() => {
+ this.PageIndex = Math.max(1, this.PageIndex - 1);
+ })
+ .finally(() => {
+ setTimeout(() => {
+ this.isLoadingHistory = false;
+ }, 50);
});
},
diff --git a/store/index.js b/store/index.js
index 75f9025..5b85cc8 100644
--- a/store/index.js
+++ b/store/index.js
@@ -146,6 +146,21 @@ const store = new Vuex.Store({
push_MsgList(state, list) {
state.vuex_msgList = list || [];
},
+ // 追加历史消息到头部(分页加载)
+ prepend_MsgList(state, list) {
+ const prev = state.vuex_msgList || [];
+ const next = Array.isArray(list) ? list : [];
+ const merged = [...next, ...prev];
+
+ const seen = new Set();
+ state.vuex_msgList = merged.filter((item) => {
+ const id = item && item.id;
+ if (!id) return true;
+ if (seen.has(id)) return false;
+ seen.add(id);
+ return true;
+ });
+ },
// 推送一条新消息(去重)
push_Msg(state, msg) {
// 注:现在的消息没有id,无法去重,暂时用push_MsgList
@@ -232,18 +247,49 @@ const store = new Vuex.Store({
// 刷新列表,清零未读
dispatch("getUserlist");
},
- // 获取聊天记录(私聊)
+ // 获取聊天记录(私聊)——仅在进入聊天页时加载一次
async fetchChatRecord(
- { commit, state },
- { userId, friendId, PageIndex = 1, PageSize = 20 }
+ { commit },
+ { dialogueManagementId, PageIndex = 1, PageSize = 20 }
) {
- const params = { userId, friendId, PageIndex, PageSize };
+ return Vue.prototype.$u.api
+ .GetChatHistoryDataApi({
+ "Item1.DialogueManagementId": dialogueManagementId,
+ PageIndex,
+ PageSize,
+ })
+ .then((res) => {
+ const list =
+ (res && res.data && Array.isArray(res.data.item1)
+ ? res.data.item1
+ : []
+ ).slice().reverse();
+ commit("push_MsgList", list);
+ return list;
+ });
+ },
- Vue.prototype.$u.api.GetChatHistoryDataApi(params).then((res) => {
- const list = res && res.data ? res.data : [];
- // 将最新消息插入到消息列表尾部(或头部)
- list.forEach((msg) => commit("push_Msg", msg));
- });
+ // 获取下一页历史消息(滚动到顶部触发)
+ async fetchChatRecordNextPage(
+ { commit },
+ { dialogueManagementId, PageIndex = 1, PageSize = 20 }
+ ) {
+ return Vue.prototype.$u.api
+ .GetChatHistoryDataApi({
+ "Item1.DialogueManagementId": dialogueManagementId,
+ PageIndex,
+ PageSize,
+ })
+ .then((res) => {
+ const list =
+ (res && res.data && Array.isArray(res.data.item1)
+ ? res.data.item1
+ : []
+ ).slice().reverse();
+ if (!list.length) return [];
+ commit("prepend_MsgList", list);
+ return list;
+ });
},
// 设置消息置顶(服务端 + 本地)
async setTopMsgUser({ commit, dispatch }, user) {