聊天增加拉黑功能

main
15004070936 2 weeks ago
parent c874217268
commit f6d2870863

@ -59,7 +59,8 @@ const MESSAGE_STATUS = {
SENDED: 1,
RECALL: 2,
READED: 3,
BLOCKED:4
BLOCKED:4,
ISBLACK:5,
}
export {

@ -8,7 +8,7 @@
</view>
<view class="message-normal" v-else-if="isNormal" :class="{ 'message-mine': msgInfo.selfSend }">
<head-image class="avatar" @longpress.prevent="$emit('longPressHead')" :id="msgInfo.sendId" :url="headImage"
:name="showName" size="small"></head-image>
:name="showName" size="small" :selfSend="msgInfo.selfSend" ></head-image>
<view class="content">
<view v-if="msgInfo.groupId && !msgInfo.selfSend" class="top">
<text>{{ showName }}</text>
@ -80,10 +80,16 @@
<!-- </view>-->
<!-- </long-press-menu>-->
<view class="message-status" v-if="!isAction">
<text class="chat-unread" v-if="msgInfo.selfSend && !msgInfo.groupId
&& msgInfo.status == $enums.MESSAGE_STATUS.ISBLACK">消息已被对方拒收。</text>
<text v-else>
<text class="chat-readed" v-if="msgInfo.selfSend && !msgInfo.groupId
&& msgInfo.status == $enums.MESSAGE_STATUS.READED">已读</text>
<text class="chat-unread" v-if="msgInfo.selfSend && !msgInfo.groupId
&& msgInfo.status != $enums.MESSAGE_STATUS.READED">未读</text>
</text>
</view>
<view class="chat-receipt" v-if="msgInfo.receipt && msgInfo.groupId" @click="onShowReadedBox">
<text v-if="msgInfo.receiptOk" class="tool-icon iconfont icon-ok"></text>

@ -1,5 +1,5 @@
<template>
<view class="head-image" @click="showUserInfo($event)" :title="name">
<view class="head-image" @click="showUserInfo($event)" :title="name" >
<image class="avatar-image" v-if="url" :src="url" :style="avatarImageStyle" lazy-load="true"
mode="aspectFill" />
<view class="avatar-text" v-if="!url" :style="avatarTextStyle">
@ -38,12 +38,16 @@ export default {
type: Boolean,
default: false
},
selfSend: {
type: Boolean,
default: false
},
},
methods: {
showUserInfo(e) {
if (this.id && this.id > 0) {
if (!this.selfSend && this.id && this.id > 0) {
uni.navigateTo({
url: "/pages/common/user-info?id=" + this.id
url: "/pages/chatbox/im-user-info?id=" + this.id
})
}
}

@ -188,6 +188,16 @@
}
}
},
{
"path" : "pages/chatbox/im-user-info",
"style" :
{
"navigationBarTitleText": "",
"enablePullDownRefresh": false,
"navigationBarBackgroundColor": "#00a89b",
"navigationBarTextStyle": "white"
}
},
{
"path": "pages/chatbox/report",
"style": {

@ -267,6 +267,7 @@ export default {
},
methods: {
// ==================== 投诉选择模式 ====================
/**
* 获取可选的消息列表(排除系统提示消息)
@ -628,7 +629,6 @@ export default {
}
// 构造临时消息(模拟文件对象)
const data = { originUrl: filePath, thumbUrl: filePath };
const msgInfo = {
id: 0,
tmpId: this.generateId(),
@ -639,7 +639,7 @@ export default {
type: this.$enums.MESSAGE_TYPE.IMAGE,
readedCount: 0,
loadStatus: 'loading',
status: this.$enums.MESSAGE_STATUS.UNSEND,
// status: this.$enums.MESSAGE_STATUS.UNSEND,
receipt: this.isReceipt
};
@ -665,6 +665,7 @@ export default {
// 发送消息请求
this.sendMessageRequest(msgInfo).then(m => {
msgInfo.loadStatus = 'ok';
msgInfo.status=m.status
msgInfo.id = m.id;
// 再次插入更新消息
this.insertMessage({ msgInfo, chatInfo: this.chat });
@ -703,7 +704,7 @@ export default {
selfSend: true,
type: this.$enums.MESSAGE_TYPE.VIDEO,
loadStatus: 'loading',
status: this.$enums.MESSAGE_STATUS.UNSEND,
// status: this.$enums.MESSAGE_STATUS.UNSEND,
receipt: this.isReceipt
};
this.fillTargetId(msgInfo, this.chat.targetId);
@ -724,6 +725,7 @@ export default {
this.sendMessageRequest(msgInfo).then(m => {
msgInfo.loadStatus = 'ok';
msgInfo.id = m.id;
msgInfo.status=m.status
this.insertMessage({ msgInfo, chatInfo: this.chat });
this.isReceipt = true;
});
@ -761,7 +763,7 @@ export default {
receipt: this.isReceipt
};
this.fillTargetId(msgInfo, this.chat.targetId);
this.insertMessage({ msgInfo, chatInfo: this.chat });
// this.insertMessage({ msgInfo, chatInfo: this.chat });
this.moveChatToTop();
this.scrollToBottom();
@ -779,6 +781,8 @@ export default {
this.sendMessageRequest(msgInfo).then(m => {
msgInfo.loadStatus = 'ok';
msgInfo.id = m.id;
msgInfo.status=m.status
console.log("msgInfo1",msgInfo)
this.insertMessage({ msgInfo, chatInfo: this.chat });
this.isReceipt = true;
});
@ -1061,7 +1065,6 @@ export default {
}, 100);
},
onScrollToTop() {
console.log("lalal...........")
if (this.showMinIdx > 0) {
// #ifndef H5
this.scrollToMsgIdx(this.showMinIdx);
@ -1160,6 +1163,7 @@ export default {
return str.replace(/[<>&"]/g, c => ({ '<': '&lt;', '>': '&gt;', '&': '&amp;', '"': '&quot;' }[c]));
},
sendMessageRequest(msgInfo) {
return new Promise((resolve, reject) => {
this.reqQueue.push({ msgInfo, resolve, reject });
this.processReqQueue();

@ -0,0 +1,256 @@
<template>
<view class="page">
<view class="body">
<!-- 头像 + 名称 -->
<view class="user-card">
<image class="avatar" :src="userInfo.headImage || defaultAvatar" mode="aspectFill"></image>
<view class="nickname">{{ displayName }}</view>
<view class="uid">ID:{{ userInfo.id || userInfo.userId || '-' }}</view>
</view>
<!-- 黑名单开关行 仿微信 -->
<!-- <view class="black-row">-->
<!-- <text class="black-label">加入黑名单</text>-->
<!-- <switch-->
<!-- :checked="isBlacked"-->
<!-- active-color="#00a89b"-->
<!-- @change="onBlackSwitchChange"-->
<!-- />-->
<!-- </view>-->
<view class="black-row">
<text class="black-label">加入黑名单</text>
<view class="custom-switch" :class="{ on: isBlacked }" @tap="handleSwitchTap">
<view class="switch-dot"></view>
</view>
</view>
<!-- 发消息按钮 -->
<view class="actions">
<button class="btn-chat" @tap="onSendMessage">发消息</button>
</view>
</view>
</view>
</template>
<script>
import { mapActions, mapGetters } from 'vuex'
export default {
data() {
return {
userId: '',
userInfo: {},
isBlacked: false,
defaultAvatar: '/static/image/kff.png'
}
},
computed: {
...mapGetters('chatStore', ['findChatIdx']),
displayName() {
if (!this.userInfo) return ''
return this.userInfo.remarkNickName || this.userInfo.nickName || this.userInfo.showNickName || '未命名'
}
},
onLoad(options) {
this.userId = options.id || ''
if (this.userId) {
this.loadFriend()
this.checkBlack()
}
},
methods: {
...mapActions('chatStore', ['openChat']),
async loadFriend() {
try {
const { data: res } = await uni.$http.get('/api/friend/find/' + this.userId)
if (res.data) {
this.userInfo = res.data
}
} catch (e) {
console.error('加载好友信息失败', e)
}
},
async checkBlack() {
try {
const { data: res } = await uni.$http.post(`/api/blacklist/check?targetUid=${this.userId}`)
if (res && res.data) {
console.log('查询黑名单状态', res.data)
this.isBlacked = !!res.data.meBlackTarget
}
} catch (e) {
console.error('查询黑名单状态失败', e)
}
},
/**
* switch点击,不直接改状态,弹出确认弹窗
*/
onBlackSwitchChange(e) {
// e.detail.value 是用户想要切换到的目标状态
const targetStatus = e.detail.value
const title = targetStatus ? '加入黑名单' : '取消黑名单'
const content = targetStatus
? '加入黑名单后,对方将无法给你发送消息,确定?'
: '确定将该用户移出黑名单?'
uni.showModal({
title,
content,
success: async (res) => {
if (!res.confirm) {
// 用户点取消,不做任何操作,switch会自动回弹回旧状态,无需手动赋值
return
}
try {
const url = targetStatus ? '/api/blacklist/add?targetUid=' : '/api/blacklist/cancel?targetUid='
await uni.$http.post(`${url}${this.userId}`)
// 接口成功才更新本地状态
this.isBlacked = targetStatus
uni.showToast({
title: this.isBlacked ? '已加入黑名单' : '已取消黑名单',
icon: 'none'
})
} catch (err) {
uni.showToast({ title: '操作失败', icon: 'none' })
}
}
})
},
onSendMessage() {
// if (this.isBlacked) {
// uni.showToast({ title: '你已将对方加入黑名单', icon: 'none' })
// return
// }
let chat = {
type: 'PRIVATE',
targetId: this.userId,
showName: this.displayName,
headImage: this.userInfo.headImage || ''
}
this.openChat(chat)
let chatIdx = this.findChatIdx(chat)
uni.navigateTo({ url: `/pages/chatbox/chat-box?chatIdx=${chatIdx}` })
},
handleSwitchTap() {
// 用户想要切换到的目标状态
const targetStatus = !this.isBlacked
const title = targetStatus ? '加入黑名单' : '取消黑名单'
const content = targetStatus
? '加入黑名单后,对方将无法给你发送消息,确定?'
: '确定将该用户移出黑名单?'
uni.showModal({
title,
content,
success: async (res) => {
if (!res.confirm) {
// 用户点取消,不做任何变更
return
}
try {
const url = targetStatus ? '/api/blacklist/add?targetUid=' : '/api/blacklist/cancel?targetUid='
await uni.$http.post(`${url}${this.userId}`)
this.isBlacked = targetStatus
uni.showToast({
title: this.isBlacked ? '已加入黑名单' : '已取消黑名单',
icon: 'none'
})
} catch (err) {
uni.showToast({ title: '操作失败', icon: 'none' })
}
}
})
},
}
}
</script>
<style lang="scss" scoped>
.page {
min-height: 100vh;
background-color: #f4f4f4;
}
.body {
padding: 24rpx 0;
}
.user-card {
background: #fff;
padding: 60rpx 0 40rpx;
display: flex;
flex-direction: column;
align-items: center;
.avatar {
width: 160rpx;
height: 160rpx;
border-radius: 50%;
background: #eee;
}
.nickname {
margin-top: 24rpx;
font-size: 36rpx;
font-weight: 600;
color: #222;
}
.uid {
margin-top: 10rpx;
font-size: 24rpx;
color: #999;
}
}
/* 黑名单开关行 */
.black-row {
margin-top: 24rpx;
background-color: #ffffff;
display: flex;
align-items: center;
justify-content: space-between;
padding: 30rpx 40rpx;
.black-label {
font-size: 32rpx;
color: #333;
}
}
.custom-switch {
width: 88rpx;
height: 52rpx;
border-radius: 26rpx;
background-color: #e5e5e5;
position: relative;
transition: background-color 0.24s ease;
.switch-dot {
position: absolute;
top: 3rpx;
left: 3rpx;
width: 46rpx;
height: 46rpx;
border-radius: 50%;
background-color: #ffffff;
box-shadow: 0 2rpx 6rpx rgba(0, 0, 0, 0.18);
transition: left 0.24s ease;
}
&.on {
background-color: #00a89b;
.switch-dot {
left: 39rpx;
}
}
}
.actions {
margin-top: 40rpx;
padding: 0 40rpx;
.btn-chat {
width: 100%;
height: 88rpx;
line-height: 88rpx;
background: #00a89b;
color: #fff;
font-size: 32rpx;
border-radius: 12rpx;
&::after { border: none; }
&:active { opacity: 0.85; }
}
}
</style>
Loading…
Cancel
Save