|
@@ -113,7 +113,7 @@
|
|
|
</div>
|
|
</div>
|
|
|
<div class="message-container" @click="handleMessageBoxClick">
|
|
<div class="message-container" @click="handleMessageBoxClick">
|
|
|
<el-scrollbar class="custom-scrollbar" style="height: 500px; width: 100%;" ref="manageRightRef">
|
|
<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-for="(m, msgIndex) in msgList" :key="msgRowKey(m, msgIndex)">
|
|
|
<el-row v-if="m.userId !== userId" style="margin-top: 5px" type="flex" align="top" >
|
|
<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="3" style="margin-left: 10px"><el-avatar :src="m.avatar"/></el-col>
|
|
|
<el-col :span="15">
|
|
<el-col :span="15">
|
|
@@ -127,7 +127,7 @@
|
|
|
<el-col>
|
|
<el-col>
|
|
|
<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="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 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-if="isUserSingleVisible(m)" 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 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="replyUser(m)">回复</a>
|
|
<a style="cursor: pointer;color: #ff0000;padding: 8px 8px 0 0;font-size: 12px;" @click.stop="replyUser(m)">回复</a>
|
|
|
<a style="cursor: pointer;color: #ff0000;padding: 8px 8px 0 0;font-size: 12px;" @click.stop="deleteMsg(m)">删除</a>
|
|
<a style="cursor: pointer;color: #ff0000;padding: 8px 8px 0 0;font-size: 12px;" @click.stop="deleteMsg(m)">删除</a>
|
|
@@ -293,6 +293,8 @@ export default {
|
|
|
videoUrl: '',
|
|
videoUrl: '',
|
|
|
},
|
|
},
|
|
|
msgList:[],
|
|
msgList:[],
|
|
|
|
|
+ // 按用户维度维护自见状态,避免消息行共享/重渲染导致按钮状态串台
|
|
|
|
|
+ userSingleVisibleMap: {},
|
|
|
currentTab: 'al',
|
|
currentTab: 'al',
|
|
|
searchKeyword: '',
|
|
searchKeyword: '',
|
|
|
globalVisible: false,
|
|
globalVisible: false,
|
|
@@ -517,17 +519,46 @@ export default {
|
|
|
// loadMsgList 中会自动滚动到底部,因为 isAutoScrollEnabled 已经是 true
|
|
// loadMsgList 中会自动滚动到底部,因为 isAutoScrollEnabled 已经是 true
|
|
|
this.loadMsgList();
|
|
this.loadMsgList();
|
|
|
},
|
|
},
|
|
|
|
|
+ msgRowKey(m, index) {
|
|
|
|
|
+ if (m && m.msgId != null && m.msgId !== '') {
|
|
|
|
|
+ return 'msg-' + m.msgId
|
|
|
|
|
+ }
|
|
|
|
|
+ return 'msg-tmp-' + (m && m.userId != null ? m.userId : 'x') + '-' + (m && m.createTime ? m.createTime : '') + '-' + index
|
|
|
|
|
+ },
|
|
|
|
|
+ isUserSingleVisible(m) {
|
|
|
|
|
+ if (!m || m.userId == null) {
|
|
|
|
|
+ return false
|
|
|
|
|
+ }
|
|
|
|
|
+ const uid = String(m.userId)
|
|
|
|
|
+ if (Object.prototype.hasOwnProperty.call(this.userSingleVisibleMap, uid)) {
|
|
|
|
|
+ return Number(this.userSingleVisibleMap[uid]) === 1
|
|
|
|
|
+ }
|
|
|
|
|
+ return Number(m.singleVisible) === 1
|
|
|
|
|
+ },
|
|
|
|
|
+ applyUserSingleVisible(userId, status) {
|
|
|
|
|
+ if (userId == null) {
|
|
|
|
|
+ return
|
|
|
|
|
+ }
|
|
|
|
|
+ const uid = String(userId)
|
|
|
|
|
+ const next = Number(status) === 1 ? 1 : 0
|
|
|
|
|
+ this.$set(this.userSingleVisibleMap, uid, next)
|
|
|
|
|
+ this.msgList.forEach(m1 => {
|
|
|
|
|
+ if (String(m1.userId) === uid) {
|
|
|
|
|
+ this.$set(m1, 'singleVisible', next)
|
|
|
|
|
+ }
|
|
|
|
|
+ })
|
|
|
|
|
+ },
|
|
|
singleVisible(m){
|
|
singleVisible(m){
|
|
|
- // 过滤当前所有消息 找到userId的相同的消息 更改他们的自可见状态
|
|
|
|
|
- m.singleVisible= m.singleVisible === 1 ? 0 : 1
|
|
|
|
|
- this.msgList.forEach(m1 => {m1.singleVisible = m1.userId === m.userId ? m.singleVisible : !m.singleVisible})
|
|
|
|
|
|
|
+ // 仅更新同一用户的消息自见状态,不影响其他用户
|
|
|
|
|
+ const status = this.isUserSingleVisible(m) ? 0 : 1
|
|
|
|
|
+ this.applyUserSingleVisible(m.userId, status)
|
|
|
// 消息自可见
|
|
// 消息自可见
|
|
|
let msg = {
|
|
let msg = {
|
|
|
liveId: this.liveId,
|
|
liveId: this.liveId,
|
|
|
userId: m.userId,
|
|
userId: m.userId,
|
|
|
userType: 0,
|
|
userType: 0,
|
|
|
cmd: 'singleVisible',
|
|
cmd: 'singleVisible',
|
|
|
- status:m.singleVisible
|
|
|
|
|
|
|
+ status
|
|
|
}
|
|
}
|
|
|
this.socket.send(JSON.stringify(msg))
|
|
this.socket.send(JSON.stringify(msg))
|
|
|
},
|
|
},
|
|
@@ -710,14 +741,15 @@ export default {
|
|
|
return;
|
|
return;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ // userId 使用专用 fs_user(400001),与后端入库账号一致
|
|
|
let msg = {
|
|
let msg = {
|
|
|
msg: this.newMsg,
|
|
msg: this.newMsg,
|
|
|
liveId: this.liveId,
|
|
liveId: this.liveId,
|
|
|
- userId: this.userId,
|
|
|
|
|
|
|
+ userId: 400001,
|
|
|
userType: 1,
|
|
userType: 1,
|
|
|
cmd: 'sendMsg',
|
|
cmd: 'sendMsg',
|
|
|
avatar: this.$store.state.user.user.avatar,
|
|
avatar: this.$store.state.user.user.avatar,
|
|
|
- nickName: this.$store.state.user.user.nickName,
|
|
|
|
|
|
|
+ nickName: this.$store.state.user.user.nickName || '直播管理员',
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
this.socket.send(JSON.stringify(msg))
|
|
this.socket.send(JSON.stringify(msg))
|
|
@@ -748,6 +780,14 @@ export default {
|
|
|
message.msgStatus = 0
|
|
message.msgStatus = 0
|
|
|
}
|
|
}
|
|
|
delete message.params
|
|
delete message.params
|
|
|
|
|
+ if (message.userId != null) {
|
|
|
|
|
+ const uid = String(message.userId)
|
|
|
|
|
+ if (Object.prototype.hasOwnProperty.call(this.userSingleVisibleMap, uid)) {
|
|
|
|
|
+ message.singleVisible = Number(this.userSingleVisibleMap[uid]) === 1 ? 1 : 0
|
|
|
|
|
+ } else {
|
|
|
|
|
+ this.$set(this.userSingleVisibleMap, uid, Number(message.singleVisible) === 1 ? 1 : 0)
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
if(this.msgList.length > 50){
|
|
if(this.msgList.length > 50){
|
|
|
this.msgList.shift()
|
|
this.msgList.shift()
|
|
|
}
|
|
}
|
|
@@ -807,6 +847,8 @@ export default {
|
|
|
this.silencedDisplayList = this.silencedDisplayList.filter(u => u.userId !== user.userId);
|
|
this.silencedDisplayList = this.silencedDisplayList.filter(u => u.userId !== user.userId);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ } else if (cmd === 'singleVisible') {
|
|
|
|
|
+ this.applyUserSingleVisible(data.userId, data.status)
|
|
|
} else if (cmd === 'live_start') {
|
|
} else if (cmd === 'live_start') {
|
|
|
|
|
|
|
|
} else if (cmd === 'live_end') {
|
|
} else if (cmd === 'live_end') {
|
|
@@ -1202,6 +1244,14 @@ export default {
|
|
|
row.msgStatus = 0
|
|
row.msgStatus = 0
|
|
|
}
|
|
}
|
|
|
this.msgList.push(row)
|
|
this.msgList.push(row)
|
|
|
|
|
+ if (row.userId != null) {
|
|
|
|
|
+ const uid = String(row.userId)
|
|
|
|
|
+ if (!Object.prototype.hasOwnProperty.call(this.userSingleVisibleMap, uid)) {
|
|
|
|
|
+ this.$set(this.userSingleVisibleMap, uid, Number(row.singleVisible) === 1 ? 1 : 0)
|
|
|
|
|
+ } else {
|
|
|
|
|
+ this.$set(row, 'singleVisible', Number(this.userSingleVisibleMap[uid]) === 1 ? 1 : 0)
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
})
|
|
})
|
|
|
|
|
|
|
@@ -1210,6 +1260,14 @@ export default {
|
|
|
this.alDisplayList.forEach(u => {
|
|
this.alDisplayList.forEach(u => {
|
|
|
this.msgList.filter(m => m.userId === u.userId).forEach(m => m.msgStatus = u.msgStatus)
|
|
this.msgList.filter(m => m.userId === u.userId).forEach(m => m.msgStatus = u.msgStatus)
|
|
|
})
|
|
})
|
|
|
|
|
+ Object.keys(this.userSingleVisibleMap).forEach(uid => {
|
|
|
|
|
+ const status = Number(this.userSingleVisibleMap[uid]) === 1 ? 1 : 0
|
|
|
|
|
+ this.msgList.forEach(m => {
|
|
|
|
|
+ if (String(m.userId) === uid) {
|
|
|
|
|
+ this.$set(m, 'singleVisible', status)
|
|
|
|
|
+ }
|
|
|
|
|
+ })
|
|
|
|
|
+ })
|
|
|
|
|
|
|
|
// 所有消息加载完成后,根据自动滚动状态决定是否滚动
|
|
// 所有消息加载完成后,根据自动滚动状态决定是否滚动
|
|
|
this.$nextTick(() => {
|
|
this.$nextTick(() => {
|