778 lines
22 KiB
Vue
778 lines
22 KiB
Vue
<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> |