573 lines
15 KiB
Vue
573 lines
15 KiB
Vue
<script setup>
|
||
import { ref } from 'vue'
|
||
import { onLoad } from '@dcloudio/uni-app'
|
||
import TUIChatEngine, {
|
||
TUIConversationService,
|
||
TUIFriendService,
|
||
TUIGroupService,
|
||
TUIUserService
|
||
} from '@tencentcloud/chat-uikit-engine-lite'
|
||
import { useUI } from '../../utils/use-ui'
|
||
import { navigateBack, navigateTo, reLaunch } from '@/utils/router'
|
||
import { TUIGlobal } from '@tencentcloud/universal-api'
|
||
import PopupBox from '../my-index/components/popup-box.vue'
|
||
import SwitchBar from '../../TUIKit/components/common/SwitchBar/index.vue'
|
||
import { TUIConstants, TUICore } from '@tencentcloud/tui-core-lite'
|
||
|
||
const { showLoading, hideLoading, showToast, showDialog } = useUI()
|
||
|
||
const loading = ref(true)
|
||
/** 验证信息输入 */
|
||
const verificationInfo = ref('')
|
||
/** 备注名 */
|
||
const remark = ref('')
|
||
/** 确认备注信息 */
|
||
const confirmRemark = ref('')
|
||
/** 用户 id */
|
||
const userId = ref('')
|
||
/** 好友信息 */
|
||
const friendInfo = ref({})
|
||
/** 详情页状态 */
|
||
const isDetail = ref(false)
|
||
/** 黑名单状态 */
|
||
const isBlack = ref(false)
|
||
/** 点击备注弹框 */
|
||
const showRemark = ref(false)
|
||
/** 好友详情进入状态:C2C 个人 GROUP 群组 */
|
||
const isDetailState = ref('')
|
||
/** 点击查看头像 */
|
||
const onViewAvatar = url => {
|
||
uni.previewImage({
|
||
urls: [url] // 图片路径数组(本地或网络)
|
||
})
|
||
}
|
||
|
||
/**
|
||
* 显示对应群信息
|
||
* @param res 群信息
|
||
* @param state 0 只能加入群 1 显示对应状态按钮
|
||
*/
|
||
const getGroupData = (res, state) => {
|
||
console.log(res, '==')
|
||
friendInfo.value = {
|
||
...res,
|
||
avatar: res.avatar,
|
||
nick: res.name,
|
||
cbType: 'group'
|
||
}
|
||
isDetail.value = !!res.selfInfo.role
|
||
loading.value = false
|
||
hideLoading()
|
||
}
|
||
|
||
/** 获取群信息 */
|
||
const getGroupInfo = () => {
|
||
loading.value = true
|
||
showLoading()
|
||
TUICore.callService({
|
||
serviceName: TUIConstants.TUISearch.SERVICE.NAME,
|
||
method: TUIConstants.TUISearch.SERVICE.METHOD.SEARCH_GROUP,
|
||
params: {
|
||
groupID: userId.value
|
||
}
|
||
})
|
||
.then(res => {
|
||
TUIGroupService.getGroupProfile({
|
||
groupID: res.data.group.groupID
|
||
})
|
||
.then(c => {
|
||
getGroupData(c.data.group, 1)
|
||
})
|
||
.catch(crr => {
|
||
getGroupData(res.data.group, 0)
|
||
})
|
||
})
|
||
.catch(err => {
|
||
console.log(err, '==')
|
||
loading.value = false
|
||
hideLoading()
|
||
})
|
||
}
|
||
|
||
/**
|
||
* 获取好友信息
|
||
* @param state 99 为自己
|
||
*/
|
||
const getFriendInfo = async state => {
|
||
loading.value = true
|
||
showLoading()
|
||
if (isDetail.value) {
|
||
TUIFriendService.getFriendProfile({
|
||
userIDList: [userId.value]
|
||
})
|
||
.then(res => {
|
||
const data = res.data.friendList[0]
|
||
friendInfo.value = { ...data.profile, cbType: 'C2C' }
|
||
confirmRemark.value = data.remark
|
||
remark.value = data.remark
|
||
console.log('好友信息==', friendInfo.value)
|
||
})
|
||
.finally(() => {
|
||
loading.value = false
|
||
hideLoading()
|
||
})
|
||
} else {
|
||
TUIUserService.getUserProfile({
|
||
userIDList: [userId.value]
|
||
})
|
||
.then(res => {
|
||
friendInfo.value = {
|
||
...res.data[0],
|
||
cbType: state == 99 ? 'me' : 'C2C'
|
||
}
|
||
console.log('获取好友信息成功', friendInfo.value)
|
||
})
|
||
.finally(() => {
|
||
loading.value = false
|
||
hideLoading()
|
||
})
|
||
}
|
||
}
|
||
|
||
const submit = async () => {
|
||
showLoading()
|
||
if (friendInfo.value?.cbType === 'group') {
|
||
TUIGroupService.joinGroup({
|
||
groupID: friendInfo.value.groupID,
|
||
applyMessage: verificationInfo.value
|
||
})
|
||
.then(imResponse => {
|
||
switch (imResponse?.data?.status) {
|
||
case TUIChatEngine.TYPES.JOIN_STATUS_WAIT_APPROVAL: // Wait for administrator approval
|
||
hideLoading()
|
||
showToast('等待管理员同意', 'success')
|
||
break
|
||
case TUIChatEngine.TYPES.JOIN_STATUS_SUCCESS: // Join group successfully
|
||
hideLoading()
|
||
showToast('加群成功', 'success')
|
||
break
|
||
case TUIChatEngine.TYPES.JOIN_STATUS_ALREADY_IN_GROUP: // Already in the group
|
||
hideLoading()
|
||
showToast('您已是群成员', 'success')
|
||
break
|
||
default:
|
||
break
|
||
}
|
||
})
|
||
.catch(error => {
|
||
console.warn('join group failed:', error)
|
||
hideLoading()
|
||
showToast('申请入群失败', 'error')
|
||
})
|
||
} else {
|
||
// 在这里可以添加提交验证信息的逻辑
|
||
let source = 'AddSource_Type_Web' // 来源渠道
|
||
// #ifdef H5
|
||
source = 'AddSource_Type_H5'
|
||
// #endif
|
||
|
||
// 判断是否为 App(5+ App)
|
||
// #ifdef APP-PLUS
|
||
source = 'AddSource_Type_App'
|
||
// #endif
|
||
|
||
try {
|
||
await TUIFriendService.addFriend({
|
||
to: userId.value,
|
||
source,
|
||
remark: remark.value || '',
|
||
wording: verificationInfo.value,
|
||
type: TUIChatEngine.TYPES.SNS_ADD_TYPE_BOTH
|
||
})
|
||
hideLoading()
|
||
await showToast('好友请求已发送', 'success')
|
||
navigateBack()
|
||
} catch (error) {
|
||
if (error.code === 30515) {
|
||
hideLoading()
|
||
const show = await showDialog(
|
||
'提示',
|
||
'该用户在黑名单中,不允许加好友'
|
||
)
|
||
if (show) {
|
||
navigateBack()
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
/** 加入黑名单 */
|
||
const switchChange = async () => {
|
||
const show = await showDialog(
|
||
'提示',
|
||
`确定要${isBlack.value ? '移除' : '添加'}黑名单吗?`
|
||
)
|
||
if (!show) {
|
||
return
|
||
}
|
||
showLoading()
|
||
if (isBlack.value) {
|
||
TUIUserService.removeFromBlacklist({
|
||
userIDList: [friendInfo.value.userID]
|
||
})
|
||
.then(async () => {
|
||
await showToast('移除黑名单成功', 'success')
|
||
isBlack.value = false
|
||
})
|
||
.finally(() => {
|
||
hideLoading()
|
||
})
|
||
} else {
|
||
TUIUserService.addToBlacklist({
|
||
userIDList: [friendInfo.value.userID]
|
||
})
|
||
.then(async () => {
|
||
await showToast('添加黑名单成功', 'success')
|
||
reLaunch('/TUIKit/components/TUIContact/index')
|
||
isBlack.value = true
|
||
})
|
||
.finally(() => {
|
||
hideLoading()
|
||
})
|
||
}
|
||
}
|
||
|
||
/** 备注确认修改 */
|
||
const onRemark = () => {
|
||
if (remark.value === confirmRemark.value) {
|
||
showToast('备注名相同,无法修改')
|
||
return
|
||
}
|
||
showLoading()
|
||
TUIFriendService.updateFriend({
|
||
userID: friendInfo.value.userID,
|
||
remark: remark.value
|
||
})
|
||
.then(async res => {
|
||
await showToast('修改备名成功', 'success')
|
||
remark.value = res.data.remark
|
||
confirmRemark.value = res.data.remark
|
||
})
|
||
.finally(() => {
|
||
hideLoading()
|
||
})
|
||
}
|
||
|
||
/** 删除好友/删除群 */
|
||
const onDeleteFriend = async () => {
|
||
const isMode = friendInfo.value?.cbType === 'group'
|
||
const show = await showDialog(
|
||
'提示',
|
||
`确定要${isMode ? '解除群聊' : '删除好友'}吗?`
|
||
)
|
||
if (!show) {
|
||
return
|
||
}
|
||
showLoading()
|
||
if (isMode) {
|
||
TUIGroupService.dismissGroup(friendInfo.value?.groupID)
|
||
.then(async () => {
|
||
await showToast('解除群聊成功', 'success')
|
||
reLaunch('/TUIKit/components/TUIContact/index')
|
||
})
|
||
.catch(async () => {
|
||
hideLoading()
|
||
await showToast('解除群聊失败', 'error')
|
||
})
|
||
} else {
|
||
TUIFriendService.deleteFriend({
|
||
userIDList: [friendInfo.value.userID],
|
||
type: TUIChatEngine.TYPES.SNS_DELETE_TYPE_BOTH
|
||
})
|
||
.then(async res => {
|
||
hideLoading()
|
||
const { successUserIDList } = res.data
|
||
if (successUserIDList[0].userID === friendInfo.value.userID) {
|
||
await showToast('删除好友成功', 'success')
|
||
reLaunch('/TUIKit/components/TUIContact/index')
|
||
} else {
|
||
await showToast('删除好友失败', 'error')
|
||
}
|
||
})
|
||
.catch(async () => {
|
||
hideLoading()
|
||
await showToast('删除好友失败', 'error')
|
||
})
|
||
}
|
||
}
|
||
|
||
/** 发送消息 */
|
||
const onSendMessage = () => {
|
||
if (isDetailState.value == 'C2C') {
|
||
navigateBack()
|
||
return
|
||
}
|
||
const data =
|
||
friendInfo.value?.cbType === 'group'
|
||
? `GROUP${friendInfo.value?.groupID}`
|
||
: `C2C${friendInfo.value.userID}`
|
||
TUIConversationService.switchConversation(data).then(() => {
|
||
TUIGlobal?.navigateTo({
|
||
url: `/TUIKit/components/TUIChat/index?type=${
|
||
isDetailState.value == 'GROUP' ? 'GROUP' : ''
|
||
}`
|
||
})
|
||
})
|
||
}
|
||
|
||
onLoad(e => {
|
||
isDetailState.value = e?.state || ''
|
||
userId.value = e?.id || ''
|
||
/** type: 不传为添加 1 为详情页 9 为群信息 99 为自己 */
|
||
if (e?.type == 9) {
|
||
uni.setNavigationBarTitle({
|
||
title: '群聊信息'
|
||
})
|
||
getGroupInfo()
|
||
} else {
|
||
isDetail.value = ['1'].includes(e?.type) || false
|
||
uni.setNavigationBarTitle({
|
||
title: isDetail.value ? '好友信息' : '发送好友申请'
|
||
})
|
||
getFriendInfo(e?.type)
|
||
}
|
||
})
|
||
</script>
|
||
|
||
<template>
|
||
<view v-if="!loading" class="details-box">
|
||
<!-- 顶部用户信息 -->
|
||
<view class="top-info">
|
||
<image
|
||
v-if="friendInfo?.avatar"
|
||
:src="friendInfo?.avatar"
|
||
mode="aspectFill"
|
||
class="avatar"
|
||
@tap="onViewAvatar(friendInfo?.avatar)"
|
||
></image>
|
||
<uni-icons v-else type="contact-filled" size="80"></uni-icons>
|
||
<view class="right-box">
|
||
<text>{{ friendInfo.nick || '未知名称' }}</text>
|
||
<text v-if="friendInfo?.cbType !== 'group'">
|
||
ID: {{ friendInfo.userID }}
|
||
</text>
|
||
<text v-if="friendInfo?.cbType !== 'group'">
|
||
个性签名: {{ friendInfo.selfSignature || '暂无个性签名' }}
|
||
</text>
|
||
<text v-else>
|
||
ID: {{ friendInfo.groupID || friendInfo.userID }}
|
||
</text>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 验证信息输入 -->
|
||
<view
|
||
v-if="!isDetail && friendInfo.cbType !== 'me'"
|
||
class="input-wrapper"
|
||
>
|
||
<text class="title">请填写验证信息</text>
|
||
<textarea
|
||
v-model="verificationInfo"
|
||
:maxlength="200"
|
||
placeholder="请输入验证信息"
|
||
class="input-text"
|
||
/>
|
||
</view>
|
||
|
||
<!-- 备注 -->
|
||
<view
|
||
v-if="!['group', 'me'].includes(friendInfo?.cbType) && !isDetail"
|
||
class="remark"
|
||
>
|
||
<text>备注名</text>
|
||
<input
|
||
v-model="remark"
|
||
:maxlength="80"
|
||
placeholder="请输入备注名"
|
||
placeholder-class="input-placeholder"
|
||
/>
|
||
</view>
|
||
|
||
<!-- 发送申请按钮 -->
|
||
<view
|
||
v-if="!isDetail && friendInfo.cbType !== 'me'"
|
||
class="send-btn"
|
||
@tap="submit"
|
||
>
|
||
<text>发送申请</text>
|
||
</view>
|
||
|
||
<!-- 去朋友圈 -->
|
||
<view
|
||
v-if="friendInfo?.cbType == 'me'"
|
||
class="remark"
|
||
@click="
|
||
navigateTo('/pages/discover/dynamic/dynamic', {
|
||
id: friendInfo.userID
|
||
})
|
||
"
|
||
>
|
||
<text>朋友圈</text>
|
||
<view style="display: flex; align-items: center">
|
||
<uni-icons type="right" color="#999999" size="36rpx"></uni-icons>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 修改好友信息======================== -->
|
||
<view
|
||
v-if="friendInfo?.cbType !== 'group' && isDetail"
|
||
class="remark"
|
||
@click="showRemark = true"
|
||
>
|
||
<text>备注名</text>
|
||
<view style="display: flex; align-items: center">
|
||
<text
|
||
style="margin-right: 10rpx; color: #999999; font-size: 28rpx"
|
||
>
|
||
{{ confirmRemark }}
|
||
</text>
|
||
<uni-icons type="right" color="#999999" size="36rpx"></uni-icons>
|
||
</view>
|
||
</view>
|
||
<view
|
||
v-if="friendInfo?.cbType !== 'group' && isDetail"
|
||
class="remark"
|
||
>
|
||
<text>加入黑名单</text>
|
||
<SwitchBar :value="isBlack" @click="switchChange" />
|
||
</view>
|
||
<view
|
||
v-if="friendInfo?.cbType !== 'group' && isDetail"
|
||
class="send-btn"
|
||
@tap="onDeleteFriend"
|
||
>
|
||
<text style="color: #eb1c26">删除好友</text>
|
||
</view>
|
||
|
||
<view
|
||
v-if="friendInfo?.selfInfo?.role == 'Owner' && isDetail"
|
||
class="send-btn"
|
||
@tap="onDeleteFriend"
|
||
>
|
||
<text style="color: #eb1c26">解除群聊</text>
|
||
</view>
|
||
|
||
<bottom-view v-if="isDetail">
|
||
<cb-button @click="onSendMessage">发送信息</cb-button>
|
||
</bottom-view>
|
||
<popup-box
|
||
v-model="showRemark"
|
||
v-model:name="remark"
|
||
title="备注信息"
|
||
@confirm="onRemark"
|
||
/>
|
||
</view>
|
||
</template>
|
||
|
||
<style scoped lang="scss">
|
||
// 背景色
|
||
page {
|
||
background: #f9f9f9;
|
||
}
|
||
|
||
.details-box {
|
||
padding: 26rpx 32rpx;
|
||
}
|
||
|
||
.send-btn {
|
||
border-radius: 16rpx;
|
||
margin-top: 20rpx;
|
||
background: #ffffff;
|
||
padding: 20rpx 32rpx;
|
||
text-align: center;
|
||
text {
|
||
font-size: 28rpx;
|
||
color: #00d993;
|
||
}
|
||
}
|
||
|
||
.remark {
|
||
border-radius: 16rpx;
|
||
margin-top: 20rpx;
|
||
background: #ffffff;
|
||
padding: 20rpx 32rpx;
|
||
display: flex;
|
||
justify-content: space-between;
|
||
align-items: center;
|
||
text {
|
||
font-size: 28rpx;
|
||
color: #333333;
|
||
}
|
||
input {
|
||
width: 80%;
|
||
text-align: right;
|
||
}
|
||
}
|
||
|
||
.input-wrapper {
|
||
margin-top: 20rpx;
|
||
background: #ffffff;
|
||
padding: 20rpx 32rpx;
|
||
border-radius: 16rpx;
|
||
display: flex;
|
||
flex-direction: column;
|
||
.title {
|
||
font-family:
|
||
PingFang SC,
|
||
PingFang SC;
|
||
font-weight: 500;
|
||
font-size: 28rpx;
|
||
color: #333333;
|
||
font-style: normal;
|
||
text-transform: none;
|
||
margin-bottom: 20rpx;
|
||
}
|
||
.input-text {
|
||
width: calc(100% - 40rpx);
|
||
// border: 2rpx solid #eeeeee;
|
||
color: #333333;
|
||
border-radius: 8rpx;
|
||
// padding: 20rpx;
|
||
}
|
||
}
|
||
|
||
.top-info {
|
||
background: #ffffff;
|
||
padding: 20rpx 32rpx;
|
||
border-radius: 16rpx;
|
||
display: flex;
|
||
align-items: center;
|
||
.avatar {
|
||
flex-shrink: 0;
|
||
width: 120rpx;
|
||
height: 120rpx;
|
||
border-radius: 60rpx;
|
||
}
|
||
.right-box {
|
||
height: 100%;
|
||
margin-left: 20rpx;
|
||
display: flex;
|
||
flex-direction: column;
|
||
justify-content: space-between;
|
||
text {
|
||
// 第一个
|
||
&:first-child {
|
||
font-size: 32rpx;
|
||
color: #333333;
|
||
}
|
||
font-size: 26rpx;
|
||
color: #999999;
|
||
&:last-child {
|
||
display: -webkit-box;
|
||
-webkit-box-orient: vertical;
|
||
-webkit-line-clamp: 1;
|
||
box-orient: vertical;
|
||
line-clamp: 1;
|
||
overflow: hidden;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
</style>
|