|
|
@@ -111,8 +111,9 @@
|
|
|
全局用户自见
|
|
|
</label>
|
|
|
</div>
|
|
|
- <el-scrollbar class="custom-scrollbar" style="height: 500px; width: 100%;" ref="manageRightRef">
|
|
|
- <el-row v-for="m in msgList" :key="m.msgId">
|
|
|
+ <div class="message-container" @click="handleMessageBoxClick">
|
|
|
+ <el-scrollbar class="custom-scrollbar" style="height: 500px; width: 100%;" ref="manageRightRef">
|
|
|
+ <el-row v-for="m in msgList" :key="m.msgId">
|
|
|
<el-row v-if="m.userId !== userId" style="margin-top: 5px" type="flex" align="top" >
|
|
|
<el-col :span="3" style="margin-left: 10px"><el-avatar :src="m.avatar"/></el-col>
|
|
|
<el-col :span="15">
|
|
|
@@ -124,11 +125,11 @@
|
|
|
</div>
|
|
|
</el-col>
|
|
|
<el-col>
|
|
|
- <a style="cursor: pointer;color: #ff0000;padding: 8px 8px 0 0;font-size: 12px;" @click="changeUserState(m)">{{ m.msgStatus === 1 ? '解禁' : '禁言' }}</a>
|
|
|
- <a style="cursor: pointer;color: #ff0000;padding: 8px 8px 0 0;font-size: 12px;" @click="blockUser(m)">拉黑</a>
|
|
|
- <a v-if="m.singleVisible === 1" style="cursor: pointer;color: #ff0000;padding: 8px 8px 0 0;font-size: 12px;" @click="singleVisible(m)">解除用户自见</a>
|
|
|
- <a v-else style="cursor: pointer;color: #ff0000;padding: 8px 8px 0 0;font-size: 12px;" @click="singleVisible(m)">用户自见</a>
|
|
|
- <a style="cursor: pointer;color: #ff0000;padding: 8px 8px 0 0;font-size: 12px;" @click="deleteMsg(m)">删除</a>
|
|
|
+ <a style="cursor: pointer;color: #ff0000;padding: 8px 8px 0 0;font-size: 12px;" @click.stop="changeUserState(m)">{{ m.msgStatus === 1 ? '解禁' : '禁言' }}</a>
|
|
|
+ <a style="cursor: pointer;color: #ff0000;padding: 8px 8px 0 0;font-size: 12px;" @click.stop="blockUser(m)">拉黑</a>
|
|
|
+ <a v-if="m.singleVisible === 1" style="cursor: pointer;color: #ff0000;padding: 8px 8px 0 0;font-size: 12px;" @click.stop="singleVisible(m)">解除用户自见</a>
|
|
|
+ <a v-else style="cursor: pointer;color: #ff0000;padding: 8px 8px 0 0;font-size: 12px;" @click.stop="singleVisible(m)">用户自见</a>
|
|
|
+ <a style="cursor: pointer;color: #ff0000;padding: 8px 8px 0 0;font-size: 12px;" @click.stop="deleteMsg(m)">删除</a>
|
|
|
</el-col>
|
|
|
</el-row>
|
|
|
</el-col>
|
|
|
@@ -145,7 +146,18 @@
|
|
|
</el-row>
|
|
|
<!-- 底部留白 -->
|
|
|
<div style="height: 20px;"></div>
|
|
|
- </el-scrollbar>
|
|
|
+ </el-scrollbar>
|
|
|
+ <!-- 加载最新消息按钮 -->
|
|
|
+ <el-button
|
|
|
+ v-if="showLoadLatestBtn"
|
|
|
+ class="load-latest-btn"
|
|
|
+ type="primary"
|
|
|
+ size="small"
|
|
|
+ @click.stop="loadLatestMessages"
|
|
|
+ icon="el-icon-refresh">
|
|
|
+ 加载最新消息
|
|
|
+ </el-button>
|
|
|
+ </div>
|
|
|
<!-- <div class="message-list">-->
|
|
|
<!-- <div class="message-item" v-for="msg in msgList" :key="msg.id">-->
|
|
|
<!-- <div class="message-avatar">-->
|
|
|
@@ -390,6 +402,15 @@ export default {
|
|
|
topMsgForm: {
|
|
|
msg: '',
|
|
|
duration: 5
|
|
|
+ },
|
|
|
+ // 消息滚动控制
|
|
|
+ isAutoScrollEnabled: true, // 是否启用自动滚动
|
|
|
+ autoScrollTimer: null, // 自动滚动定时器
|
|
|
+ showLoadLatestBtn: false, // 是否显示加载最新消息按钮
|
|
|
+ msgParams: {
|
|
|
+ pageNum: 1,
|
|
|
+ pageSize: 30,
|
|
|
+ liveId: null
|
|
|
}
|
|
|
};
|
|
|
},
|
|
|
@@ -431,6 +452,65 @@ export default {
|
|
|
this.initScrollListeners();
|
|
|
},
|
|
|
methods: {
|
|
|
+ // 点击消息框
|
|
|
+ handleMessageBoxClick() {
|
|
|
+ // 点击消息框时,停止自动滚动
|
|
|
+ this.isAutoScrollEnabled = false;
|
|
|
+ // 停止自动滚动定时器
|
|
|
+ if (this.autoScrollTimer) {
|
|
|
+ clearTimeout(this.autoScrollTimer);
|
|
|
+ this.autoScrollTimer = null;
|
|
|
+ }
|
|
|
+ // 检查是否在底部,如果不在底部则显示加载最新消息按钮
|
|
|
+ this.$nextTick(() => {
|
|
|
+ if (this.$refs.manageRightRef && this.$refs.manageRightRef.wrap) {
|
|
|
+ const wrap = this.$refs.manageRightRef.wrap;
|
|
|
+ const scrollHeight = wrap.scrollHeight;
|
|
|
+ const clientHeight = wrap.clientHeight;
|
|
|
+ const currentScrollTop = wrap.scrollTop;
|
|
|
+ const maxScrollTop = scrollHeight - clientHeight;
|
|
|
+
|
|
|
+ if (currentScrollTop < maxScrollTop - 50) {
|
|
|
+ this.showLoadLatestBtn = true;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ });
|
|
|
+ },
|
|
|
+ // 滚动到底部
|
|
|
+ scrollToBottom(forceScroll = false) {
|
|
|
+ // 如果自动滚动被禁用且不是强制滚动,则不执行
|
|
|
+ console.log("scrollToBottom")
|
|
|
+ console.log(!this.isAutoScrollEnabled && !forceScroll)
|
|
|
+ console.log(this.$refs.manageRightRef && this.$refs.manageRightRef.wrap)
|
|
|
+ console.log(forceScroll || this.isAutoScrollEnabled)
|
|
|
+ if (!this.isAutoScrollEnabled && !forceScroll) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (this.$refs.manageRightRef && this.$refs.manageRightRef.wrap) {
|
|
|
+ this.$nextTick(() => {
|
|
|
+ const wrap = this.$refs.manageRightRef.wrap;
|
|
|
+ if (!wrap) return;
|
|
|
+
|
|
|
+
|
|
|
+ // 强制滚动或启用自动滚动时,直接滚动到底部并隐藏按钮
|
|
|
+ if (forceScroll || this.isAutoScrollEnabled) {
|
|
|
+ this.showLoadLatestBtn = false;
|
|
|
+ this.$refs.manageRightRef.wrap.scrollTop = this.$refs.manageRightRef.wrap.scrollHeight - this.$refs.manageRightRef.wrap.clientHeight
|
|
|
+ }
|
|
|
+ });
|
|
|
+ }
|
|
|
+ },
|
|
|
+ // 加载最新消息
|
|
|
+ loadLatestMessages() {
|
|
|
+ this.showLoadLatestBtn = false;
|
|
|
+ // 恢复自动滚动
|
|
|
+ this.isAutoScrollEnabled = true;
|
|
|
+ // 重新请求最新消息
|
|
|
+ this.resetMsgParams();
|
|
|
+ // loadMsgList 中会自动滚动到底部,因为 isAutoScrollEnabled 已经是 true
|
|
|
+ this.loadMsgList();
|
|
|
+ },
|
|
|
singleVisible(m){
|
|
|
// 过滤当前所有消息 找到userId的相同的消息 更改他们的自可见状态
|
|
|
m.singleVisible= m.singleVisible === 1 ? 0 : 1
|
|
|
@@ -637,12 +717,19 @@ export default {
|
|
|
this.msgList.shift()
|
|
|
}
|
|
|
this.msgList.push(message)
|
|
|
- // 移动到底部
|
|
|
- this.$nextTick(() => {
|
|
|
- setTimeout(() => {
|
|
|
- this.$refs.manageRightRef.wrap.scrollTop = this.$refs.manageRightRef.wrap.scrollHeight - this.$refs.manageRightRef.wrap.clientHeight
|
|
|
- }, 200)
|
|
|
- })
|
|
|
+ // 如果启用自动滚动,自动滚动到底部
|
|
|
+ console.log("handleWsMessage")
|
|
|
+ console.log(this.isAutoScrollEnabled)
|
|
|
+ if (this.isAutoScrollEnabled) {
|
|
|
+ this.$nextTick(() => {
|
|
|
+ this.autoScrollTimer = setTimeout(() => {
|
|
|
+ this.scrollToBottom();
|
|
|
+ }, 200);
|
|
|
+ });
|
|
|
+ } else {
|
|
|
+ // 自动滚动被禁用时,显示加载最新消息按钮
|
|
|
+ this.showLoadLatestBtn = true;
|
|
|
+ }
|
|
|
} else if (cmd === 'entry' || cmd === 'out') {
|
|
|
const user = data;
|
|
|
const online = cmd === 'entry' ? 0 : 1; // 0=在线,1=离线
|
|
|
@@ -1076,22 +1163,13 @@ export default {
|
|
|
let totalPage = (total % this.msgParams.pageSize == 0) ? Math.floor(total / this.msgParams.pageSize) : Math.floor(total / this.msgParams.pageSize + 1);
|
|
|
rows.forEach(row => {
|
|
|
if (!this.msgList.some(m => m.msgId === row.msgId)) {
|
|
|
-
|
|
|
let user = this.alDisplayList.find(u => u.userId === row.userId)
|
|
|
if (user) {
|
|
|
row.msgStatus = user.msgStatus
|
|
|
} else {
|
|
|
row.msgStatus = 0
|
|
|
}
|
|
|
-
|
|
|
this.msgList.push(row)
|
|
|
-
|
|
|
- // 移动到底部
|
|
|
- this.$nextTick(() => {
|
|
|
- setTimeout(() => {
|
|
|
- this.$refs.manageRightRef.wrap.scrollTop = this.$refs.manageRightRef.wrap.scrollHeight - this.$refs.manageRightRef.wrap.clientHeight
|
|
|
- }, 200)
|
|
|
- })
|
|
|
}
|
|
|
})
|
|
|
|
|
|
@@ -1100,6 +1178,31 @@ export default {
|
|
|
this.alDisplayList.forEach(u => {
|
|
|
this.msgList.filter(m => m.userId === u.userId).forEach(m => m.msgStatus = u.msgStatus)
|
|
|
})
|
|
|
+
|
|
|
+ // 所有消息加载完成后,根据自动滚动状态决定是否滚动
|
|
|
+ this.$nextTick(() => {
|
|
|
+ setTimeout(() => {
|
|
|
+ if (this.isAutoScrollEnabled) {
|
|
|
+ // 如果启用自动滚动,强制滚动到底部并隐藏按钮
|
|
|
+ this.scrollToBottom(true);
|
|
|
+ } else {
|
|
|
+ // 如果禁用自动滚动,检查是否在底部,决定是否显示按钮
|
|
|
+ if (this.$refs.manageRightRef && this.$refs.manageRightRef.wrap) {
|
|
|
+ const wrap = this.$refs.manageRightRef.wrap;
|
|
|
+ const scrollHeight = wrap.scrollHeight;
|
|
|
+ const clientHeight = wrap.clientHeight;
|
|
|
+ const currentScrollTop = wrap.scrollTop;
|
|
|
+ const maxScrollTop = scrollHeight - clientHeight;
|
|
|
+
|
|
|
+ if (currentScrollTop < maxScrollTop - 50) {
|
|
|
+ // this.showLoadLatestBtn = true;
|
|
|
+ } else {
|
|
|
+ this.showLoadLatestBtn = false;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }, 300);
|
|
|
+ });
|
|
|
}
|
|
|
})
|
|
|
|
|
|
@@ -1200,6 +1303,7 @@ export default {
|
|
|
pageSize: 30,
|
|
|
liveId: this.liveId
|
|
|
};
|
|
|
+ // 重置时不改变按钮状态,由后续的滚动逻辑决定
|
|
|
this.taskParams = {
|
|
|
currentPage: 1,
|
|
|
pageSize: 20,
|
|
|
@@ -1320,6 +1424,9 @@ export default {
|
|
|
if (this.autoMsgTimer != null) {
|
|
|
clearInterval(this.autoMsgTimer);
|
|
|
}
|
|
|
+ if (this.autoScrollTimer) {
|
|
|
+ clearTimeout(this.autoScrollTimer);
|
|
|
+ }
|
|
|
},
|
|
|
// 使用 deactivated 和 activated 钩子替代 beforeDestroy 和 destroyed
|
|
|
deactivated() {
|
|
|
@@ -1623,4 +1730,14 @@ export default {
|
|
|
text-align: center;
|
|
|
border-radius: 4px;
|
|
|
}
|
|
|
+.message-container {
|
|
|
+ position: relative;
|
|
|
+}
|
|
|
+.load-latest-btn {
|
|
|
+ position: absolute;
|
|
|
+ bottom: 20px;
|
|
|
+ right: 20px;
|
|
|
+ z-index: 10;
|
|
|
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
|
|
|
+}
|
|
|
</style>
|