Files
uniapp-im-shop/pages/adduser/details.vue

573 lines
15 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<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
// 判断是否为 App5+ 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>