You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

298 lines
7.9 KiB

<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',
chatIndex:null
}
},
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 || ''
this.chatIndex = options.chatIndex || ''
console.log('chatIndex...',this.chatIndex)
if (this.userId) {
this.loadFriend()
this.checkBlack()
}
},
methods: {
...mapActions('chatStore', ['removeChat','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}` })
},
findChatIdxByUser(){
let chat = {
type: 'PRIVATE',
targetId: this.userId,
showName: this.displayName,
headImage: this.userInfo.headImage || ''
}
return this.findChatIdx(chat)
},
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'
})
//聊天框 - 删除
if (this.isBlacked && this.chatIndex){
this.removeChat(Number(this.chatIndex)) // 调用 Vuex action
}
const privateChatIdx=this.findChatIdxByUser();
if (this.isBlacked && privateChatIdx>-1){
this.removeChat(Number(privateChatIdx))
}
} catch (err) {
uni.showToast({ title: '操作失败', icon: 'none' })
}
}
})
},
goBackChat() {
uni.reLaunch({
url: `/pages/chatbox/chat`
});
}
},
// 拦截返回
onBackPress(e) {
// 来源是左上角返回 / 安卓返回键
if(e.from === 'backbutton'){
if(this.isBlacked){
// 拉黑成功,自定义跳转chat
this.goBackChat()
return true // return true 阻止原生默认返回
}else{
// 未拉黑,放行,走原来的返回(回到chat-box)
return false
}
}
return false
}
}
</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>