first commit
This commit is contained in:
778
pages/ContactPages/ContactPages.vue
Normal file
778
pages/ContactPages/ContactPages.vue
Normal file
@@ -0,0 +1,778 @@
|
||||
<template>
|
||||
<view class="status-bar"></view>
|
||||
<!-- 添加好友弹窗 -->
|
||||
<view class="popup-overlay" v-if="currentAddFriend">
|
||||
<view class="popup-card">
|
||||
<view class="close-popup-card" @click="closeAddFriendCard">
|
||||
<view class="iconfont icon-quxiao"></view>
|
||||
</view>
|
||||
<view class="popup-title">{{isAgreeBeFriend ? '通过好友申请' : '申请添加朋友'}}</view>
|
||||
<view class="friend-card">
|
||||
<view class="friend-card-left">
|
||||
<view class="friend-avatar">{{currentAddFriend.avatar}}</view>
|
||||
</view>
|
||||
<view class="friend-card-middle">
|
||||
<view class="friend-name">{{currentAddFriend.username}}</view>
|
||||
<view class="friend-label">{{currentAddFriend.sessionId}}</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="nickname-wrapper">
|
||||
<view>好友备注</view>
|
||||
<input class="input-nickname" placeholder="请输入好友名称" />
|
||||
</view>
|
||||
<view class="text-btn confirm-btn">{{isAgreeBeFriend ? '确认通过' : '发送申请'}}</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="tabbar-page page-container">
|
||||
<swiper class="content-swiper" :current="currentTab" :duration="300" @change="onSwiperChange">
|
||||
|
||||
<swiper-item class="content-swiper-item">
|
||||
<view class="tabpage-containner">
|
||||
<view class="tabpage-header">
|
||||
<view class="iconfont icon-fanhui" @click="handleBack"></view>
|
||||
<view class="tabpage-title">通讯录</view>
|
||||
</view>
|
||||
<view class="tabpage-body">
|
||||
<scroll-view class="group-member" direction="vertical" scroll-y="true">
|
||||
<view class="friend-list">
|
||||
<view class="friend-card" @click="changeChatType(0)">
|
||||
<view class="friend-card-left">
|
||||
<view class="friend-avatar" style=" background-color: #38bdf8;">
|
||||
<view class="iconfont icon-Robot" style="font-size: 80rpx; color: #fff;">
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="friend-card-middle">
|
||||
<view class="friend-name">{{FriendAI.name}}</view>
|
||||
<view class="friend-label"></view>
|
||||
</view>
|
||||
<view class="friend-card-right">
|
||||
<uni-icons type="right"></uni-icons>
|
||||
</view>
|
||||
</view>
|
||||
<view class="friend-card" v-for="friend in FriendInfoList" :key="friend.sessionId" @click="changeChatType(friend.type,friend.sessionId)">
|
||||
<view class="friend-card-left">
|
||||
<!-- <view class="friend-avatar">{{friend.avatar}}</view> -->
|
||||
<!-- 显示头像图片 -->
|
||||
<image v-if="friend.avatar" :src="friend.avatar" class="friend-avatar"
|
||||
mode="aspectFill"></image>
|
||||
<!-- 如果没有头像,显示默认头像 -->
|
||||
<view v-else class="friend-avatar">
|
||||
<uni-icons type="person-filled" size="100rpx" color="#ffffff"></uni-icons>
|
||||
</view>
|
||||
</view>
|
||||
<view class="friend-card-middle">
|
||||
<view class="friend-name">{{friend.friendNickName}}</view>
|
||||
<view class="friend-label">{{friend.sessionId}}</view>
|
||||
</view>
|
||||
<view class="friend-card-right">
|
||||
<uni-icons type="right"></uni-icons>
|
||||
</view>
|
||||
</view>
|
||||
<view>群聊</view>
|
||||
<view class="solid-line"></view>
|
||||
<view class="friend-card" v-for="group in GroupList" :key="group.id" @click="changeChatType(group.type,group.id)">
|
||||
<view class="friend-card-left">
|
||||
<!-- 群聊只有默认头像 -->
|
||||
<view class="friend-avatar" style="background-color: #ffaaff;">
|
||||
<view class="iconfont icon-qunliao" style="font-size: 80rpx; color: #fff;">
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="friend-card-middle">
|
||||
<view class="friend-name">{{group.name}}</view>
|
||||
<view class="friend-label">{{group.createTime}}</view>
|
||||
</view>
|
||||
<view class="friend-card-right">
|
||||
<uni-icons type="right"></uni-icons>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</scroll-view>
|
||||
</view>
|
||||
</view>
|
||||
</swiper-item>
|
||||
|
||||
|
||||
<swiper-item class="content-swiper-item">
|
||||
<view class="tabpage-containner">
|
||||
<view class="tabpage-header">
|
||||
<view class="iconfont icon-fanhui" @click="handleBack"></view>
|
||||
<view class="tabpage-title">新建群聊</view>
|
||||
</view>
|
||||
<view class="tabpage-body">
|
||||
<view class="group-info">
|
||||
<view class="group-name">
|
||||
<view>群名称</view>
|
||||
<input class="input" placeholder="请输入群名称" v-model="createGroupName" />
|
||||
</view>
|
||||
<view class="group-member-wrapper">
|
||||
<view class="member-title">群成员</view>
|
||||
<view class="group-ismember-list">
|
||||
<view class="group-ismember-info" v-for="(item,index) in selectGroupMember"
|
||||
:key="index">
|
||||
<view class="group-ismember-name">{{item.friendNickName}}</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="create-group-btn" @click="createGroup">创建群聊</view>
|
||||
</view>
|
||||
<view class="solid-line"></view>
|
||||
<scroll-view class="group-member" direction="vertical" scroll-y="true">
|
||||
<view class="friend-list">
|
||||
<view class="friend-card" v-for="friend in FriendInfoList" :key="friend.receiver">
|
||||
<view class="friend-card-left">
|
||||
<image v-if="friend.avatar" :src="friend.avatar" class="friend-avatar"
|
||||
mode="aspectFill"></image>
|
||||
<!-- 如果没有头像,显示默认头像 -->
|
||||
<view v-else class="friend-avatar">
|
||||
<uni-icons type="person-filled" size="100rpx" color="#ffffff"></uni-icons>
|
||||
</view>
|
||||
</view>
|
||||
<view class="friend-card-middle">
|
||||
<view class="friend-name">{{friend.friendNickName}}</view>
|
||||
<view class="friend-label">{{friend.email}}</view>
|
||||
</view>
|
||||
<view class="friend-card-right" @click="handlCreateEmember(friend.receiver)">
|
||||
<view class="friend-checkbox">
|
||||
<uni-icons type="checkmarkempty"
|
||||
v-if="selectGroupMember?.find(item => item.id === friend.receiver)"></uni-icons>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</scroll-view>
|
||||
</view>
|
||||
</view>
|
||||
</swiper-item>
|
||||
|
||||
<swiper-item class="content-swiper-item">
|
||||
<view class="tabpage-containner">
|
||||
<view class="tabpage-header">
|
||||
<view class="iconfont icon-fanhui" @click="handleBack"></view>
|
||||
<view class="tabpage-title">添加好友</view>
|
||||
</view>
|
||||
<view class="tabpage-body">
|
||||
<view class="search-warpper">
|
||||
<input class="search-file-input" :class="{active:isSearchFriend}"
|
||||
@focus="handleFriendSearchFocus" @blur="handleFriendSearchFocus"
|
||||
v-model="searchFriendName" />
|
||||
<view class="iconfont icon-sousuo" @click="searchFriend"></view>
|
||||
</view>
|
||||
<view v-if="!searchFriendName" class="search-tip">请输入用户名或邮箱进行搜索</view>
|
||||
<view v-else-if="searchResultList.length" class="search-result">
|
||||
<scroll-view class="group-member" direction="vertical" scroll-y="true">
|
||||
<view class="friend-list">
|
||||
<view class="friend-card" v-for="friend in searchResultList" :key="friend.id">
|
||||
<view class="friend-card-left">
|
||||
<view class="friend-avatar">{{friend.avatar}}</view>
|
||||
</view>
|
||||
<view class="friend-card-middle">
|
||||
<view class="friend-name">{{friend.nickname}}</view>
|
||||
<view class="friend-label">{{friend.email}}</view>
|
||||
</view>
|
||||
<view class="friend-card-right" @click="addNewFriend(friend.id)">
|
||||
<view class="add-btn text-btn">添加</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</scroll-view>
|
||||
</view>
|
||||
<view v-else class="no-result">未找到相关用户,请尝试其他关键词</view>
|
||||
</view>
|
||||
</view>
|
||||
</swiper-item>
|
||||
|
||||
<swiper-item class="content-swiper-item">
|
||||
<view class="tabpage-containner">
|
||||
<view class="tabpage-header">
|
||||
<view class="iconfont icon-fanhui" @click="handleBack"></view>
|
||||
<view class="tabpage-title">视频会议</view>
|
||||
</view>
|
||||
<view class="tabpage-body">
|
||||
<view class="join-meeting-wrapper">
|
||||
<view>加入会议</view>
|
||||
<input class="input-meeting" placeholder="请输入会议号" />
|
||||
<view class="meeting-btn text-btn">加入会议</view>
|
||||
</view>
|
||||
<view class="solid-line"></view>
|
||||
<view class="create-meeting-wrapper">
|
||||
<view>创建会议</view>
|
||||
<view class="meeting-field">
|
||||
<view class="meeting-label">会议主题</view>
|
||||
<input class="input-meeting" placeholder="例如:XXX" />
|
||||
</view>
|
||||
<view class="meeting-field">
|
||||
<view class="meeting-label">会议密码</view>
|
||||
<input class="input-meeting" placeholder="留空则无密码" />
|
||||
</view>
|
||||
<view class="meeting-field">
|
||||
<view class="meeting-label">邀请好友</view>
|
||||
<view class="friend-card">
|
||||
<view class="friend-card-left">
|
||||
<view class="friend-avatar">avatar</view>
|
||||
</view>
|
||||
<view class="friend-card-middle">
|
||||
<view class="friend-name">friend.nickname</view>
|
||||
<view class="friend-label">friend.email</view>
|
||||
</view>
|
||||
<view class="friend-card-right" @click="addNewFriend(friend.id)">
|
||||
<view class="add-btn text-btn">添加</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="meeting-toggles">
|
||||
<view class="meeting-toggles-item">
|
||||
<view class="meeting-toggles-icon icon-btn">
|
||||
<uni-icons type="mic-filled"></uni-icons>开启麦克风入会
|
||||
</view>
|
||||
<view class="meeting-toggles-switch" @click="togglesVoice">
|
||||
<view class="switch-box" :class="{active : isVoice}">
|
||||
<view class="switch-track"></view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="meeting-toggles-item">
|
||||
<view class="meeting-toggles-icon icon-btn">
|
||||
<uni-icons type="eye-filled"></uni-icons>开启摄像头入会
|
||||
</view>
|
||||
<view class="meeting-toggles-switch" @click="togglesCamera">
|
||||
<view class="switch-box" :class="{active : isCamera}">
|
||||
<view class="switch-track"></view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="meeting-btn text-btn">加入会议</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</swiper-item>
|
||||
|
||||
<swiper-item class="content-swiper-item">
|
||||
<view class="tabpage-containner">
|
||||
<view class="tabpage-header">
|
||||
<view class="iconfont icon-fanhui" @click="handleBack"></view>
|
||||
<view class="tabpage-title">好友申请</view>
|
||||
</view>
|
||||
<view class="tabpage-body">
|
||||
<scroll-view class="group-member" direction="vertical" scroll-y="true">
|
||||
<view class="friend-list">
|
||||
<view class="friend-card" v-for="friend in mockFriendDB" :key="friend.id">
|
||||
<view class="friend-card-left">
|
||||
<view class="friend-avatar">{{friend.avatar}}</view>
|
||||
</view>
|
||||
<view class="friend-card-middle">
|
||||
<view class="friend-name">{{friend.nickname}}</view>
|
||||
<view class="friend-label">{{friend.email}}</view>
|
||||
</view>
|
||||
<view class="friend-card-right">
|
||||
<view class="friend-option">
|
||||
<view class="refuse-btn text-btn" @click="refuseBeFriend(friend)">拒绝</view>
|
||||
<view class="agree-btn text-btn" @click="agreeBeFriend(friend)">同意</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
</view>
|
||||
</scroll-view>
|
||||
</view>
|
||||
</view>
|
||||
</swiper-item>
|
||||
|
||||
|
||||
</swiper>
|
||||
<view class="bottom-tabbar">
|
||||
<view v-for="(tab, index) in tabList" :key="tab.name" @click="switchTab(index)" class="tab-item">
|
||||
<view class="tab-icon">{{tab.icon}}</view>
|
||||
<view class="tab-label">{{tab.label}}</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import {
|
||||
onMounted,
|
||||
reactive,
|
||||
ref,
|
||||
watch
|
||||
} from 'vue';
|
||||
|
||||
import {
|
||||
getToken
|
||||
} from '@/utils/user-info.js'
|
||||
import {
|
||||
getChatFriend,
|
||||
getGroup
|
||||
} from '@/utils/friend-api.js'
|
||||
import {
|
||||
getUserInfo,
|
||||
getUserAvatar,
|
||||
searchUsers
|
||||
} from '@/utils/cloud-api.js'
|
||||
import {
|
||||
useFriendSocketStore
|
||||
} from '@/stores/friend-socket.js'
|
||||
|
||||
const friendSocketStore = useFriendSocketStore()
|
||||
// 连接实时通讯socket
|
||||
const handleFriendConnect = () => {
|
||||
if (friendSocketStore.isConnected) return
|
||||
if (!userToken.value || !UserId.value) {
|
||||
console.warn('Token或UserId未准备好');
|
||||
return
|
||||
}
|
||||
friendSocketStore.connect({
|
||||
token: userToken.value,
|
||||
UserId: UserId.value
|
||||
})
|
||||
}
|
||||
|
||||
// 返回聊天界面
|
||||
const handleBack = () => {
|
||||
uni.navigateBack({
|
||||
delta: 1,
|
||||
fail() {
|
||||
uni.reLaunch({
|
||||
url: '/pages/Chat/Chat'
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 选择群聊或对话时,修改聊天类型并返回聊天页面
|
||||
const changeChatType = (type,sessionId='') =>{
|
||||
uni.setStorageSync('chatType', type)
|
||||
if(sessionId){
|
||||
uni.setStorageSync('currentSessionId',sessionId)
|
||||
}
|
||||
uni.reLaunch({
|
||||
url: '/pages/Chat/Chat'
|
||||
})
|
||||
}
|
||||
|
||||
// 底部Tab相关
|
||||
// 当前选中的tab索引 (0:新建群聊, 1:添加好友, 2:视频会议, 3:好友申请, 4:通讯录)
|
||||
const currentTab = ref(0)
|
||||
// Tab列表
|
||||
const tabList = reactive([{
|
||||
name: 'contacts',
|
||||
label: '通讯录',
|
||||
icon: '📞'
|
||||
},
|
||||
{
|
||||
name: 'createGroup',
|
||||
label: '新建群聊',
|
||||
icon: '👥'
|
||||
},
|
||||
{
|
||||
name: 'addFriend',
|
||||
label: '添加好友',
|
||||
icon: '➕'
|
||||
},
|
||||
{
|
||||
name: 'videoCall',
|
||||
label: '视频会议',
|
||||
icon: '📹'
|
||||
},
|
||||
{
|
||||
name: 'friendRequest',
|
||||
label: '好友申请',
|
||||
icon: '📨'
|
||||
}
|
||||
])
|
||||
|
||||
const onSwiperChange = (e) => {
|
||||
currentTab.value = e.detail.current
|
||||
}
|
||||
|
||||
const switchTab = (index) => {
|
||||
currentTab.value = index
|
||||
}
|
||||
|
||||
// 用户token
|
||||
const userToken = ref('')
|
||||
// 用户id
|
||||
const UserId = ref('')
|
||||
|
||||
// 通讯录相关
|
||||
|
||||
// AI好友
|
||||
const FriendAI = {
|
||||
|
||||
id: 'ai_robot',
|
||||
|
||||
name: '宇恒一号',
|
||||
|
||||
avatar: '',
|
||||
|
||||
type: 'ai',
|
||||
|
||||
description: 'AI智能助手',
|
||||
|
||||
lastMessage: null
|
||||
|
||||
}
|
||||
// 好友列表
|
||||
// const FriendList = ref([])
|
||||
// 好友消息列表(不包括头像)
|
||||
const FriendInfoList = ref([])
|
||||
// 获取用户好友列表
|
||||
const takeFriendList = async () => {
|
||||
try {
|
||||
console.log("开始获取好友列表");
|
||||
userToken.value = getToken();
|
||||
const userInfo = await getUserInfo(userToken.value)
|
||||
UserId.value = userInfo._id
|
||||
console.log("UserId.value:", UserId.value);
|
||||
const friendList = await getChatFriend(UserId.value)
|
||||
console.log("friendList:", friendList);
|
||||
if (friendList && friendList.length) {
|
||||
FriendInfoList.value = await takeUserAvatar(friendList)
|
||||
} else {
|
||||
FriendInfoList.value = []
|
||||
console.log("好友列表为空");
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("获取好友列表失败:", error);
|
||||
FriendInfoList.value = []
|
||||
}
|
||||
}
|
||||
// 获取好友头像
|
||||
const takeUserAvatar = async (friendList) => {
|
||||
if (!friendList?.length) return []
|
||||
try {
|
||||
const friendIds = friendList.map(item => item.receiver)
|
||||
const friendAvatarList = await getUserAvatar(userToken.value, friendIds)
|
||||
// 创建map,用于快速查找
|
||||
const userMap = new Map(friendAvatarList.map(user => [user.user_id, user]) || [])
|
||||
// 合并数据
|
||||
return friendList.map(friend => {
|
||||
const userInfo = userMap.get(friend.receiver)
|
||||
return {
|
||||
...friend,
|
||||
avatar: userInfo?.avatar || null
|
||||
}
|
||||
})
|
||||
} catch (err) {
|
||||
console.error('获取好友头像失败', err);
|
||||
return friendList
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(async () => {
|
||||
await takeFriendList()
|
||||
await takeGroupList()
|
||||
handleFriendConnect()
|
||||
})
|
||||
// 群聊相关
|
||||
// 群聊列表
|
||||
const GroupList = ref([])
|
||||
// 获取用户群聊列表
|
||||
const takeGroupList = async () => {
|
||||
try {
|
||||
console.log("开始获取群聊列表");
|
||||
userToken.value = getToken();
|
||||
const userInfo = await getUserInfo(userToken.value)
|
||||
UserId.value = userInfo._id
|
||||
console.log("UserId.value:", UserId.value);
|
||||
GroupList.value = await getGroup(UserId.value)
|
||||
} catch (error) {
|
||||
console.error("获取群聊列表失败:", error);
|
||||
GroupList.value = []
|
||||
}
|
||||
}
|
||||
// 新建群聊相关
|
||||
const createGroupName = ref('')
|
||||
const createGroupData = ref()
|
||||
|
||||
// 确保 friendSocket 已连接
|
||||
const ensureFriendSocketConnected = () => {
|
||||
return new Promise((resolve, reject) => {
|
||||
// 已连接则直接返回
|
||||
if (friendSocketStore.isConnected) {
|
||||
resolve()
|
||||
return
|
||||
}
|
||||
// 未连接,先建立连接
|
||||
if (!userToken.value || !UserId.value) {
|
||||
reject(new Error('Token或UserId未准备好'))
|
||||
return
|
||||
}
|
||||
console.log('friendSocket 未连接,正在建立连接...')
|
||||
friendSocketStore.connect({
|
||||
token: userToken.value,
|
||||
UserId: UserId.value
|
||||
})
|
||||
// 等待连接建立
|
||||
const checkInterval = setInterval(() => {
|
||||
if (friendSocketStore.isConnected) {
|
||||
clearInterval(checkInterval)
|
||||
console.log('friendSocket 连接已建立')
|
||||
resolve()
|
||||
}
|
||||
}, 100)
|
||||
// 最多等待10秒
|
||||
setTimeout(() => {
|
||||
clearInterval(checkInterval)
|
||||
if (!friendSocketStore.isConnected) {
|
||||
reject(new Error('连接超时'))
|
||||
}
|
||||
}, 10000)
|
||||
})
|
||||
}
|
||||
|
||||
const createGroup = async () => {
|
||||
try {
|
||||
//检查是否有群成员和群名称
|
||||
if(!createGroupName.value) {
|
||||
uni.showToast({
|
||||
title:'群名称不能为空',
|
||||
icon:'none'
|
||||
})
|
||||
return
|
||||
}
|
||||
//检查是否有群成员和群名称
|
||||
if(selectGroupMember.value.length === 0) {
|
||||
uni.showToast({
|
||||
title:'请选择群成员',
|
||||
icon:'none'
|
||||
})
|
||||
return
|
||||
}
|
||||
// 确保 socket 已连接
|
||||
await ensureFriendSocketConnected()
|
||||
|
||||
const memberIds = selectGroupMember.value.map(member => member.id)
|
||||
|
||||
createGroupData.value = {
|
||||
"version": "1.1",
|
||||
"body": {
|
||||
"command": 3,
|
||||
"userIds": memberIds,
|
||||
"message": "我来邀请你们了",
|
||||
"sender": UserId.value,
|
||||
"callBackMessage": true,
|
||||
"groupName": createGroupName.value,
|
||||
"teamCreateReq": {
|
||||
"access_token": userToken.value
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const isSend = await friendSocketStore.send(createGroupData.value)
|
||||
if (isSend) {
|
||||
await sendCreateGroup();
|
||||
} else {
|
||||
console.log("发送新建群聊消息失败");
|
||||
}
|
||||
} catch (err) {
|
||||
console.log(err);
|
||||
uni.showToast({
|
||||
title: `新建群聊失败${err}`,
|
||||
icon: 'none'
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// 发送创建群聊的socket消息
|
||||
const sendCreateGroup = () => {
|
||||
return new Promise((resolve, reject) => {
|
||||
const timeout = setTimeout(() => {
|
||||
reject(new Error('超时未返回群聊创建结果'))
|
||||
}, 180000)
|
||||
|
||||
// 创建一个一次性监听器, // 监听command的值,如果是3就检查有没有创建群聊成功
|
||||
const unwatch =
|
||||
watch(() => friendSocketStore.command, async (newVal) => {
|
||||
console.log("创建一个一次性监听器");
|
||||
if (newVal && friendSocketStore.command === 3) {
|
||||
console.log("监听到command的值是3,检查群聊是否创建成功", friendSocketStore.command);
|
||||
try {
|
||||
await takeGroupList()
|
||||
const newGroup = GroupList.value.find(g => g.id === friendSocketStore
|
||||
.groupId)
|
||||
// 2. 判断是否新建成功
|
||||
if (newGroup) {
|
||||
console.log("✅ 新建群聊成功", newGroup);
|
||||
selectGroupMember.value = []
|
||||
currentTab.value = 0
|
||||
|
||||
} else {
|
||||
console.log("❌ 新建群聊失败 / 群组不存在");
|
||||
}
|
||||
|
||||
} catch (error) {
|
||||
console.error('保存AI回复失败:', error);
|
||||
|
||||
reject(error);
|
||||
} finally {
|
||||
friendSocketStore.command = null
|
||||
friendSocketStore.groupId = null
|
||||
unwatch();
|
||||
clearTimeout(timeout);
|
||||
}
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// 已选群成员列表
|
||||
const selectGroupMember = ref([]);
|
||||
const handlCreateEmember = (id) => {
|
||||
console.log("选择的好友id:",id);
|
||||
console.log("selectGroupMember.value=",JSON.stringify(selectGroupMember.value));
|
||||
const index = selectGroupMember.value.findIndex(item => item.id === id);
|
||||
if (index === -1) {
|
||||
const friendItem = FriendInfoList.value.find(item => item.receiver === id);
|
||||
if (friendItem) {
|
||||
selectGroupMember.value.push({
|
||||
id: friendItem.receiver,
|
||||
friendNickName: friendItem.friendNickName
|
||||
})
|
||||
}
|
||||
} else {
|
||||
selectGroupMember.value.splice(index, 1);
|
||||
}
|
||||
}
|
||||
|
||||
// 添加好友相关
|
||||
const isSearchFriend = ref(false)
|
||||
const searchFriendName = ref('')
|
||||
const searchResultList = ref([]);
|
||||
const searchFriend = async() => {
|
||||
if (!searchFriendName.value.trim()) {
|
||||
searchResultList.value = []
|
||||
return
|
||||
}
|
||||
// 模糊查询:遍历 mockFriendDB,匹配 nickname、username 或 email
|
||||
const keyword = searchFriendName.value.toLowerCase().trim();
|
||||
searchResultList.value = await searchUsers(userToken.value,keyword)
|
||||
console.log("searchResultList.value:",searchResultList.value);
|
||||
// const results = mockFriendDB.value.filter(friend => {
|
||||
// const isMatch = friend.nickname.toLowerCase().includes(keyword) || friend.username.toLowerCase()
|
||||
// .includes(keyword) || friend.email.toLowerCase().includes(keyword);
|
||||
// return isMatch
|
||||
// })
|
||||
// searchResultList.value = results
|
||||
}
|
||||
const handleFriendSearchFocus = () => {
|
||||
isSearchFriend.value = !isSearchFriend.value
|
||||
}
|
||||
|
||||
const currentAddFriend = ref(null)
|
||||
const addNewFriend = (id) => {
|
||||
const friend = mockFriendDB.value.find(friend => friend.id === id)
|
||||
if (friend) {
|
||||
// 创建副本避免引用问题
|
||||
currentAddFriend.value = {
|
||||
...friend
|
||||
}
|
||||
} else {
|
||||
console.warn('未找到该好友')
|
||||
currentAddFriend.value = null
|
||||
}
|
||||
}
|
||||
const closeAddFriendCard = () => {
|
||||
currentAddFriend.value = null
|
||||
isAgreeBeFriend.value = false
|
||||
}
|
||||
|
||||
// 视频会议相关
|
||||
const isVoice = ref(false);
|
||||
const isCamera = ref(false)
|
||||
const togglesVoice = () => {
|
||||
isVoice.value = !isVoice.value
|
||||
}
|
||||
const togglesCamera = () => {
|
||||
isCamera.value = !isCamera.value
|
||||
}
|
||||
|
||||
// 好友申请相关
|
||||
const isAgreeBeFriend = ref(false)
|
||||
const refuseBeFriend = (friend) => {
|
||||
|
||||
}
|
||||
const agreeBeFriend = (friend) => {
|
||||
isAgreeBeFriend.value = true
|
||||
currentAddFriend.value = {
|
||||
...friend
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// 模拟好友数据库
|
||||
const mockFriendDB = ref([{
|
||||
id: 1,
|
||||
nickname: '张三',
|
||||
username: 'zhangsan',
|
||||
email: 'zhangsan@example.com',
|
||||
avatar: '👤'
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
nickname: '李四',
|
||||
username: 'lisi',
|
||||
email: 'lisi@example.com',
|
||||
avatar: '👥'
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
nickname: '王小明',
|
||||
username: 'wangxm',
|
||||
email: 'wang@example.com',
|
||||
avatar: '👪'
|
||||
},
|
||||
{
|
||||
id: 4,
|
||||
nickname: '赵磊',
|
||||
username: 'zhaolei',
|
||||
email: 'zhao@example.com',
|
||||
avatar: '🗣️'
|
||||
},
|
||||
{
|
||||
id: 5,
|
||||
nickname: '张三2',
|
||||
username: 'zhangsan',
|
||||
email: 'zhangsan@example.com',
|
||||
avatar: '👤'
|
||||
},
|
||||
{
|
||||
id: 6,
|
||||
nickname: '李四2',
|
||||
username: 'lisi',
|
||||
email: 'lisi@example.com',
|
||||
avatar: '👥'
|
||||
},
|
||||
{
|
||||
id: 7,
|
||||
nickname: '王小明2',
|
||||
username: 'wangxm',
|
||||
email: 'wang@example.com',
|
||||
avatar: '👪'
|
||||
},
|
||||
{
|
||||
id: 8,
|
||||
nickname: '赵磊2',
|
||||
username: 'zhaolei',
|
||||
email: 'zhao@example.com',
|
||||
avatar: '🗣️'
|
||||
}
|
||||
|
||||
])
|
||||
|
||||
// 通讯录相关
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
@import url("ContactPages.css");
|
||||
</style>
|
||||
Reference in New Issue
Block a user