Merge branch 'main' of http://sl.vrgon.com:3000/JiXinHui/YingXingAI
This commit is contained in:
commit
e20570faa0
|
|
@ -13,77 +13,86 @@
|
||||||
class="chat-scroll"
|
class="chat-scroll"
|
||||||
scroll-y
|
scroll-y
|
||||||
:scroll-into-view="scrollToView"
|
:scroll-into-view="scrollToView"
|
||||||
|
:scroll-top="scrollTop"
|
||||||
scroll-with-animation
|
scroll-with-animation
|
||||||
|
:upper-threshold="20"
|
||||||
|
@scroll="handleScroll"
|
||||||
|
@scrolltoupper="handleScrollToUpper"
|
||||||
>
|
>
|
||||||
<!-- 教师信息 -->
|
<view class="chat-content">
|
||||||
<div class="teacher-info-card">
|
<!-- 教师信息 -->
|
||||||
<image class="teacher-avatar" :src="receiverHeadSculptureUrl"></image>
|
<div class="teacher-info-card">
|
||||||
<div class="teacher-info">
|
<image
|
||||||
<div class="teacher-name">{{ vuex_msgUser.name }}</div>
|
class="teacher-avatar"
|
||||||
|
:src="receiverHeadSculptureUrl"
|
||||||
|
></image>
|
||||||
|
<div class="teacher-info">
|
||||||
|
<div class="teacher-name">{{ vuex_msgUser.name }}</div>
|
||||||
|
|
||||||
<div class="teacher-school">
|
<div class="teacher-school">
|
||||||
<image
|
<image
|
||||||
class="school-icon"
|
class="school-icon"
|
||||||
src="/static/common/images/icon_college.png"
|
src="/static/common/images/icon_college.png"
|
||||||
></image>
|
></image>
|
||||||
<text class="school-text">{{ vuex_msgUser.collegeName }}</text>
|
<text class="school-text">{{ vuex_msgUser.collegeName }}</text>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="teacher-college">
|
<div class="teacher-college">
|
||||||
<image
|
<image
|
||||||
class="college-icon"
|
class="college-icon"
|
||||||
src="/static/common/images/icon_major.png"
|
src="/static/common/images/icon_major.png"
|
||||||
></image>
|
></image>
|
||||||
<text class="college-text">{{ vuex_msgUser.collegeName }}</text>
|
<text class="college-text">{{ vuex_msgUser.collegeName }}</text>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
|
|
||||||
<view
|
|
||||||
v-for="(message, index) in vuex_msgList"
|
|
||||||
:key="message.id"
|
|
||||||
:id="'msg-' + message.id"
|
|
||||||
>
|
|
||||||
<!-- 时间 -->
|
|
||||||
<view class="message-time" v-if="isShowTime(index)">
|
|
||||||
{{ formatShowTime(message.sendDate) }}
|
|
||||||
</view>
|
|
||||||
|
|
||||||
<!-- 0 发送消息 -->
|
|
||||||
<view
|
<view
|
||||||
class="message-right"
|
v-for="(message, index) in vuex_msgList"
|
||||||
v-if="message.senderId === vuex_user.Id"
|
:key="message.id"
|
||||||
:id="'msg-' + message.id"
|
:id="'msg-' + message.id"
|
||||||
>
|
>
|
||||||
<view class="message-content">
|
<!-- 时间 -->
|
||||||
<text>{{ message.message }}</text>
|
<view class="message-time" v-if="isShowTime(index)">
|
||||||
|
{{ formatShowTime(message.sendDate) }}
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 0 发送消息 -->
|
||||||
|
<view
|
||||||
|
class="message-right"
|
||||||
|
v-if="message.senderId === vuex_user.Id"
|
||||||
|
:id="'msg-' + message.id"
|
||||||
|
>
|
||||||
|
<view class="message-content">
|
||||||
|
<text>{{ message.message }}</text>
|
||||||
|
</view>
|
||||||
|
<image
|
||||||
|
class="user-avatar"
|
||||||
|
:src="headSculptureUrl"
|
||||||
|
mode="scaleToFill"
|
||||||
|
/>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 1 收到消息 -->
|
||||||
|
<view
|
||||||
|
class="message-left"
|
||||||
|
v-if="message.senderId !== vuex_user.Id"
|
||||||
|
:id="'msg-' + message.id"
|
||||||
|
>
|
||||||
|
<image
|
||||||
|
class="ai-avatar"
|
||||||
|
:src="receiverHeadSculptureUrl"
|
||||||
|
mode="scaleToFill"
|
||||||
|
/>
|
||||||
|
<view class="message-content">
|
||||||
|
<text>{{ message.message }}</text>
|
||||||
|
</view>
|
||||||
</view>
|
</view>
|
||||||
<image
|
|
||||||
class="user-avatar"
|
|
||||||
:src="headSculptureUrl"
|
|
||||||
mode="scaleToFill"
|
|
||||||
/>
|
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
<!-- 1 收到消息 -->
|
<!-- 底部间距 滚动锚点 -->
|
||||||
<view
|
<view id="bottom-anchor" class="bottom-anchor"></view>
|
||||||
class="message-left"
|
|
||||||
v-if="message.senderId !== vuex_user.Id"
|
|
||||||
:id="'msg-' + message.id"
|
|
||||||
>
|
|
||||||
<image
|
|
||||||
class="ai-avatar"
|
|
||||||
:src="receiverHeadSculptureUrl"
|
|
||||||
mode="scaleToFill"
|
|
||||||
/>
|
|
||||||
<view class="message-content">
|
|
||||||
<text>{{ message.message }}</text>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
<!-- 底部间距 滚动锚点 -->
|
|
||||||
<view id="bottom-anchor" class="bottom-anchor"></view>
|
|
||||||
</scroll-view>
|
</scroll-view>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
|
|
@ -155,9 +164,15 @@ export default {
|
||||||
|
|
||||||
// 滚动位置
|
// 滚动位置
|
||||||
scrollToView: "",
|
scrollToView: "",
|
||||||
|
scrollTop: 0,
|
||||||
|
currentScrollTop: 0,
|
||||||
|
currentScrollHeight: 0,
|
||||||
|
|
||||||
PageIndex: 1,
|
PageIndex: 1,
|
||||||
PageSize: 20,
|
PageSize: 20,
|
||||||
|
|
||||||
|
isLoadingHistory: false,
|
||||||
|
noMoreHistory: false,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
@ -200,6 +215,7 @@ export default {
|
||||||
// 监听最后一条消息的ID变化,滚动到底部
|
// 监听最后一条消息的ID变化,滚动到底部
|
||||||
lastMsgId(val) {
|
lastMsgId(val) {
|
||||||
if (!val) return;
|
if (!val) return;
|
||||||
|
if (this.isLoadingHistory) return;
|
||||||
this.$nextTick(() => {
|
this.$nextTick(() => {
|
||||||
this.scrollToBottom();
|
this.scrollToBottom();
|
||||||
});
|
});
|
||||||
|
|
@ -267,20 +283,61 @@ export default {
|
||||||
|
|
||||||
// 加载对话消息
|
// 加载对话消息
|
||||||
getMsgList() {
|
getMsgList() {
|
||||||
this.$u.api
|
return this.$store.dispatch("fetchChatRecord", {
|
||||||
.GetChatHistoryDataApi({
|
dialogueManagementId: this.vuex_msgUser.dialogueManagementId,
|
||||||
"Item1.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,
|
PageIndex: this.PageIndex,
|
||||||
PageSize: this.PageSize,
|
PageSize: this.PageSize,
|
||||||
})
|
})
|
||||||
.then((res) => {
|
.then((list) => {
|
||||||
const msgList = res.data.item1.reverse();
|
if (!list || !list.length) {
|
||||||
|
this.noMoreHistory = true;
|
||||||
this.$store.commit("push_MsgList", msgList);
|
return;
|
||||||
// // 滚动到底部
|
}
|
||||||
// this.$nextTick(() => {
|
this.$nextTick(() => {
|
||||||
// this.scrollToBottom();
|
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);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -146,6 +146,21 @@ const store = new Vuex.Store({
|
||||||
push_MsgList(state, list) {
|
push_MsgList(state, list) {
|
||||||
state.vuex_msgList = 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) {
|
push_Msg(state, msg) {
|
||||||
// 注:现在的消息没有id,无法去重,暂时用push_MsgList
|
// 注:现在的消息没有id,无法去重,暂时用push_MsgList
|
||||||
|
|
@ -232,18 +247,49 @@ const store = new Vuex.Store({
|
||||||
// 刷新列表,清零未读
|
// 刷新列表,清零未读
|
||||||
dispatch("getUserlist");
|
dispatch("getUserlist");
|
||||||
},
|
},
|
||||||
// 获取聊天记录(私聊)
|
// 获取聊天记录(私聊)——仅在进入聊天页时加载一次
|
||||||
async fetchChatRecord(
|
async fetchChatRecord(
|
||||||
{ commit, state },
|
{ commit },
|
||||||
{ userId, friendId, PageIndex = 1, PageSize = 20 }
|
{ 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 : [];
|
async fetchChatRecordNextPage(
|
||||||
// 将最新消息插入到消息列表尾部(或头部)
|
{ commit },
|
||||||
list.forEach((msg) => commit("push_Msg", msg));
|
{ 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) {
|
async setTopMsgUser({ commit, dispatch }, user) {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue