feat(chat): 优化聊天页面消息处理和滚动逻辑
This commit is contained in:
parent
a9edb58d6f
commit
4737ca0feb
33
App.vue
33
App.vue
|
|
@ -177,7 +177,7 @@ export default {
|
||||||
// 收到任何消息都重置心跳
|
// 收到任何消息都重置心跳
|
||||||
this.reset();
|
this.reset();
|
||||||
|
|
||||||
console.log("[WebSocket] 收到消息:", e);
|
// console.log("[WebSocket] 收到消息:", e);
|
||||||
|
|
||||||
// 心跳消息不处理
|
// 心跳消息不处理
|
||||||
// if (typeof e.data === "string" && e.data.indexOf("heartCheck") >= 0) {
|
// if (typeof e.data === "string" && e.data.indexOf("heartCheck") >= 0) {
|
||||||
|
|
@ -195,7 +195,7 @@ export default {
|
||||||
|
|
||||||
const type = msgData.Type;
|
const type = msgData.Type;
|
||||||
|
|
||||||
console.log("收到消息类型:", type);
|
console.log("收到消息:", type, msgData);
|
||||||
// 收到服务端心跳响应不处理
|
// 收到服务端心跳响应不处理
|
||||||
if (type === "pong") return;
|
if (type === "pong") return;
|
||||||
|
|
||||||
|
|
@ -220,21 +220,22 @@ export default {
|
||||||
this.$u.vuex("vuex_tabbar", tab);
|
this.$u.vuex("vuex_tabbar", tab);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 维护消息提示队列(与原逻辑兼容,使用通用 key)
|
// 收到私聊消息
|
||||||
let msgList = this.vuex_msgList || "";
|
if (type === "PrivateChatMessage") {
|
||||||
if (type === "ChatMessageDto") {
|
|
||||||
const data = msgData.Data || {};
|
const data = msgData.Data || {};
|
||||||
const msgUserId = data.ChatType === 1 ? data?.ToId : data?.UserId;
|
const processData = {
|
||||||
const key = `chat_${msgUserId || "unknown"}`;
|
dialogueManagementId: data.DialogueManagementId,
|
||||||
if (msgList.indexOf(key) < 0) {
|
senderId: data.SenderId,
|
||||||
msgList += key + ",";
|
receiverId: data.ReceiverId,
|
||||||
this.$u.vuex("vuex_msgList", msgList);
|
sendDate: data.SendDate,
|
||||||
}
|
message: data.Message,
|
||||||
} else {
|
};
|
||||||
if (msgList.indexOf("WebSocketMessage") < 0) {
|
this.$store.commit("push_Msg", {
|
||||||
msgList += "WebSocketMessage,";
|
...processData,
|
||||||
this.$u.vuex("vuex_msgList", msgList);
|
messageType: 0,
|
||||||
}
|
filePath: "",
|
||||||
|
id: Math.random().toString(36).substring(2),
|
||||||
|
});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
// 连接关闭
|
// 连接关闭
|
||||||
|
|
|
||||||
|
|
@ -81,6 +81,9 @@
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
|
<!-- 底部间距 滚动锚点 -->
|
||||||
|
<view id="bottom-anchor" class="bottom-anchor"></view>
|
||||||
</scroll-view>
|
</scroll-view>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
|
|
@ -127,25 +130,6 @@ export default {
|
||||||
|
|
||||||
// 消息列表
|
// 消息列表
|
||||||
messageList: [
|
messageList: [
|
||||||
{
|
|
||||||
id: "9cac8661-bf09-4b63-ab15-1a0a36b921e0",
|
|
||||||
message: "你知道今年的录取分数线吗",
|
|
||||||
sendDate: "2025-07-10T15:11:32.886075",
|
|
||||||
isSend: true,
|
|
||||||
isRead: false,
|
|
||||||
interactMode: 0,
|
|
||||||
messageType: 0,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: "02306fc3-c821-4a23-ad66-0bd77d154105",
|
|
||||||
message:
|
|
||||||
"目前,2025年的录取分数线还没有正式公布,因为学校需要等招生工作结束后才会公布最终的录取分数线。不过,你可以参考2023-2024年的录取分数线作为大致的参考。\n\n如果你想知道具体专业的录取分数线,可以告诉我你所在省份和科类(历史类或物理类),我可以根据往年数据给你一些参考建议。如果需要更准确的信息,建议关注江西新能源科技职业学院的官网(www.jxnee.edu.cn)或者直接联系招生办(电话:0790-6764666/6765666)。",
|
|
||||||
sendDate: "2025-07-10T15:11:32.88644",
|
|
||||||
isSend: true,
|
|
||||||
isRead: false,
|
|
||||||
interactMode: 1,
|
|
||||||
messageType: 0,
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
id: "9cac8661-bf09-4b63-ab15-1a0a36b91110",
|
id: "9cac8661-bf09-4b63-ab15-1a0a36b91110",
|
||||||
message: "你知道今年的录取分数线吗",
|
message: "你知道今年的录取分数线吗",
|
||||||
|
|
@ -185,14 +169,16 @@ export default {
|
||||||
|
|
||||||
// 加载历史消息
|
// 加载历史消息
|
||||||
this.getMsgList();
|
this.getMsgList();
|
||||||
|
|
||||||
// 滚动到底部
|
|
||||||
this.$nextTick(() => {
|
|
||||||
this.scrollToBottom();
|
|
||||||
});
|
|
||||||
},
|
},
|
||||||
|
|
||||||
computed: {
|
computed: {
|
||||||
|
// 最后一条消息的ID
|
||||||
|
lastMsgId() {
|
||||||
|
const list = this.vuex_msgList || [];
|
||||||
|
if (!list.length) return "";
|
||||||
|
return list[list.length - 1]?.id || "";
|
||||||
|
},
|
||||||
|
|
||||||
receiverHeadSculptureUrl() {
|
receiverHeadSculptureUrl() {
|
||||||
if (this.vuex_msgUser.headSculptureUrl) {
|
if (this.vuex_msgUser.headSculptureUrl) {
|
||||||
return this.baseUrl + "/" + this.vuex_msgUser.headSculptureUrl;
|
return this.baseUrl + "/" + this.vuex_msgUser.headSculptureUrl;
|
||||||
|
|
@ -206,7 +192,17 @@ export default {
|
||||||
return this.baseUrl + "/" + this.vuex_user.HeadSculptureUrl;
|
return this.baseUrl + "/" + this.vuex_user.HeadSculptureUrl;
|
||||||
}
|
}
|
||||||
|
|
||||||
return "/static/common/images/avatar.png";
|
return "/static/common/images/avatar_default2.png";
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
watch: {
|
||||||
|
// 监听最后一条消息的ID变化,滚动到底部
|
||||||
|
lastMsgId(val) {
|
||||||
|
if (!val) return;
|
||||||
|
this.$nextTick(() => {
|
||||||
|
this.scrollToBottom();
|
||||||
|
});
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
@ -216,18 +212,6 @@ export default {
|
||||||
uni.navigateBack();
|
uni.navigateBack();
|
||||||
},
|
},
|
||||||
|
|
||||||
// this.vuex_msgUser = {
|
|
||||||
// dialogueManagementId: "08de36ed-8bc0-4b79-86e7-0128010ccc4b",
|
|
||||||
// receiverId: "08de33d5-b517-4801-8474-4a4ad5642691",
|
|
||||||
// receiverName: "华忠林",
|
|
||||||
// receiverHeadSculptureUrl: "tx.jpg",
|
|
||||||
// title: "",
|
|
||||||
// startTime: "2025-12-09T14:38:21.295504",
|
|
||||||
// lastMessageTime: "0001-01-01T00:00:00",
|
|
||||||
// isOverhead: false,
|
|
||||||
// unReadCount: 0,
|
|
||||||
// };
|
|
||||||
|
|
||||||
// 点击发送
|
// 点击发送
|
||||||
handleSend() {
|
handleSend() {
|
||||||
if (!this.messageValue) {
|
if (!this.messageValue) {
|
||||||
|
|
@ -270,10 +254,10 @@ export default {
|
||||||
this.$store.commit("push_Msg", msgUserData);
|
this.$store.commit("push_Msg", msgUserData);
|
||||||
// 清空输入框
|
// 清空输入框
|
||||||
this.messageValue = "";
|
this.messageValue = "";
|
||||||
// 滚动到底部
|
// // 滚动到底部
|
||||||
this.$nextTick(() => {
|
// this.$nextTick(() => {
|
||||||
this.scrollToBottom();
|
// this.scrollToBottom();
|
||||||
});
|
// });
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.catch((error) => {
|
.catch((error) => {
|
||||||
|
|
@ -281,22 +265,6 @@ export default {
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
// 接收消息
|
|
||||||
receiveMessage(content) {
|
|
||||||
const message = {
|
|
||||||
id: Date.now(),
|
|
||||||
content: content,
|
|
||||||
isSelf: false,
|
|
||||||
timestamp: this.formatTime(new Date()),
|
|
||||||
};
|
|
||||||
|
|
||||||
this.messageList.push(message);
|
|
||||||
|
|
||||||
this.$nextTick(() => {
|
|
||||||
this.scrollToBottom();
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
// 加载对话消息
|
// 加载对话消息
|
||||||
getMsgList() {
|
getMsgList() {
|
||||||
this.$u.api
|
this.$u.api
|
||||||
|
|
@ -309,15 +277,29 @@ export default {
|
||||||
const msgList = res.data.item1.reverse();
|
const msgList = res.data.item1.reverse();
|
||||||
|
|
||||||
this.$store.commit("push_MsgList", msgList);
|
this.$store.commit("push_MsgList", msgList);
|
||||||
|
// // 滚动到底部
|
||||||
|
// this.$nextTick(() => {
|
||||||
|
// this.scrollToBottom();
|
||||||
|
// });
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
// 滚动到底部
|
// 滚动到底部
|
||||||
scrollToBottom() {
|
scrollToBottom() {
|
||||||
if (this.vuex_msgList.length > 0) {
|
// if (this.vuex_msglist.length > 0) {
|
||||||
const lastMsg = this.vuex_msgList[this.vuex_msgList.length - 1];
|
// const lastMsg = this.vuex_msglist[this.vuex_msglist.length - 1];
|
||||||
this.scrollToView = "msg-" + lastMsg.id;
|
// this.scrollToView = "msg-" + lastMsg.id;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// 滚动到底部锚点
|
||||||
|
if (this.scrollToView === "bottom-anchor") {
|
||||||
|
this.scrollToView = "";
|
||||||
|
this.$nextTick(() => {
|
||||||
|
this.scrollToView = "bottom-anchor";
|
||||||
|
});
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
this.scrollToView = "bottom-anchor";
|
||||||
},
|
},
|
||||||
|
|
||||||
// 格式化时间
|
// 格式化时间
|
||||||
|
|
@ -424,7 +406,7 @@ export default {
|
||||||
|
|
||||||
.teacher-info-card {
|
.teacher-info-card {
|
||||||
background-color: #ffffff;
|
background-color: #ffffff;
|
||||||
padding: 30rpx;
|
padding: 32rpx;
|
||||||
border-radius: 16rpx;
|
border-radius: 16rpx;
|
||||||
margin: 30rpx 0;
|
margin: 30rpx 0;
|
||||||
box-shadow: 0 2rpx 10rpx rgba(0, 0, 0, 0.1);
|
box-shadow: 0 2rpx 10rpx rgba(0, 0, 0, 0.1);
|
||||||
|
|
@ -437,21 +419,21 @@ export default {
|
||||||
width: 120rpx;
|
width: 120rpx;
|
||||||
height: 120rpx;
|
height: 120rpx;
|
||||||
border-radius: 10rpx;
|
border-radius: 10rpx;
|
||||||
margin-right: 30rpx;
|
margin-right: 36rpx;
|
||||||
object-fit: cover;
|
object-fit: cover;
|
||||||
}
|
}
|
||||||
|
|
||||||
.teacher-info {
|
.teacher-info {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
justify-content: space-between;
|
justify-content: space-evenly;
|
||||||
gap: 8rpx;
|
gap: 16rpx;
|
||||||
flex: 1;
|
flex: 1;
|
||||||
|
|
||||||
.teacher-name {
|
.teacher-name {
|
||||||
font-family: PingFang SC;
|
font-family: PingFang SC;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
font-size: 32rpx;
|
font-size: 36rpx;
|
||||||
color: #333333;
|
color: #333333;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -538,6 +520,11 @@ export default {
|
||||||
text-align: left;
|
text-align: left;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.bottom-anchor {
|
||||||
|
height: 48rpx;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -102,15 +102,15 @@ export default {
|
||||||
|
|
||||||
// 打开聊天页面
|
// 打开聊天页面
|
||||||
openChat(item) {
|
openChat(item) {
|
||||||
// console.log('打开聊天:', item);
|
console.log('打开聊天:', item);
|
||||||
// uni.navigateTo({
|
// uni.navigateTo({
|
||||||
// url: `/pages/chat/chat-detail?userId=${item.userId}&name=${item.name}`
|
// url: `/pages/chat/chat-detail?userId=${item.userId}&name=${item.name}`
|
||||||
// });
|
// });
|
||||||
const dialogueManagementId = item.dialogueManagementId
|
// const id = item.id
|
||||||
const receiverId = item.receiverId
|
// const receiverId = item.receiverId
|
||||||
this.$store.dispatch("selectTeacherChatItem", {
|
this.$store.dispatch("selectTeacherChatItem", {
|
||||||
dialogueManagementId,
|
id: item.id,
|
||||||
receiverId,
|
receiverId: item.userId,
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -32,7 +32,8 @@
|
||||||
<view class="teacher-detail">
|
<view class="teacher-detail">
|
||||||
<view class="teacher-name">
|
<view class="teacher-name">
|
||||||
<text>{{ teacher.name }}</text>
|
<text>{{ teacher.name }}</text>
|
||||||
<view v-if="teacher.presence" class="online-status">
|
<!-- presence 0在线 1离线 -->
|
||||||
|
<view v-if="teacher.presence == 0" class="online-status">
|
||||||
<view class="online-dot"></view>
|
<view class="online-dot"></view>
|
||||||
<text>在线</text>
|
<text>在线</text>
|
||||||
</view>
|
</view>
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue