355 lines
8.0 KiB
Vue
355 lines
8.0 KiB
Vue
|
|
<template>
|
|||
|
|
<view class="page fc">
|
|||
|
|
<uni-nav-bar fixed statusBar background-color="transparent" :border="false" @clickLeft="back"
|
|||
|
|
title="好友列表"></uni-nav-bar>
|
|||
|
|
<view class="back"></view>
|
|||
|
|
<view class="head fa end">
|
|||
|
|
<image @click="tosearch" src="/static/friends/friends_add.png"></image>
|
|||
|
|
<image @click="tosearch" src="/static/friends/friends_search.png" mode="widthFix"></image>
|
|||
|
|
<view class="head_content" @click="tomessageList">
|
|||
|
|
<image src="/static/friends/friends_message.png" mode="widthFix"></image>
|
|||
|
|
<text class="head_number faj" v-if="requestsInfo">{{ requestsInfo }}</text>
|
|||
|
|
</view>
|
|||
|
|
<view class="head_content" @click="toofficialList">
|
|||
|
|
<image src="/static/friends/friends_messageA.png" mode="widthFix"></image>
|
|||
|
|
<text class="head_number faj" v-if="msgCountInfo">{{ msgCountInfo }}</text>
|
|||
|
|
</view>
|
|||
|
|
</view>
|
|||
|
|
<scroll-view scroll-y="true" class="scroll-view f1" show-scrollbar @scrolltolower="onScrollToLower">
|
|||
|
|
<view class="body">
|
|||
|
|
<view class="list">
|
|||
|
|
<view class="list_content fa" v-for="(item, index) in friendList" :key="index"
|
|||
|
|
@click="toFriendsChat(item)">
|
|||
|
|
<view class="list_avatar">
|
|||
|
|
<image :src="item.friend.avatar ? item.friend.avatar : ''" mode="aspectFill"></image>
|
|||
|
|
<text class="list_round" v-if="item.is_online"></text>
|
|||
|
|
</view>
|
|||
|
|
<view class="list_module f1">
|
|||
|
|
<view class="list_name h1">{{ item.friend.nickname ? item.friend.nickname : '' }}</view>
|
|||
|
|
<view class="list_id h1">ID:{{ item.friend.user_number ? item.friend.user_number : '' }}
|
|||
|
|
</view>
|
|||
|
|
</view>
|
|||
|
|
</view>
|
|||
|
|
</view>
|
|||
|
|
<view class="not" v-if="friendList.length == 0">
|
|||
|
|
<image
|
|||
|
|
src="https://nvlovers.oss-cn-qingdao.aliyuncs.com/uploads/20251226/ff9c872002cc5a5c91154cce12e8342c.png"
|
|||
|
|
mode="widthFix"></image>
|
|||
|
|
<view class="not_title">暂无好友</view>
|
|||
|
|
</view>
|
|||
|
|
</view>
|
|||
|
|
</scroll-view>
|
|||
|
|
<tab-bar></tab-bar>
|
|||
|
|
</view>
|
|||
|
|
</template>
|
|||
|
|
|
|||
|
|
<script>
|
|||
|
|
import {
|
|||
|
|
Friend,
|
|||
|
|
MsgCount
|
|||
|
|
} from '@/utils/api.js'
|
|||
|
|
import { getTokenApi, getOnlineApi } from '@/utils/Huanxin.js'
|
|||
|
|
import notHave from '@/components/not-have.vue';
|
|||
|
|
import topSafety from '@/components/top-safety.vue';
|
|||
|
|
import tabBar from '@/components/tab-bar.vue';
|
|||
|
|
|
|||
|
|
import { emConnect, emConversation } from '@/EaseIM/imApis';
|
|||
|
|
import { useLoginStore } from '@/stores/login';
|
|||
|
|
import { useConversationStore } from '@/stores/conversation';
|
|||
|
|
|
|||
|
|
export default {
|
|||
|
|
components: {
|
|||
|
|
notHave,
|
|||
|
|
topSafety,
|
|||
|
|
tabBar,
|
|||
|
|
},
|
|||
|
|
data() {
|
|||
|
|
return {
|
|||
|
|
form: {
|
|||
|
|
page: 1,
|
|||
|
|
},
|
|||
|
|
friendList: [],
|
|||
|
|
msgCountInfo: 0,
|
|||
|
|
requestsInfo: 0,
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
onLoad() {
|
|||
|
|
this.getToken() //获取环信token
|
|||
|
|
|
|||
|
|
},
|
|||
|
|
onShow() {
|
|||
|
|
this.page = 1;
|
|||
|
|
this.friendList = [];
|
|||
|
|
this.friend();
|
|||
|
|
this.msgCount();
|
|||
|
|
},
|
|||
|
|
methods: {
|
|||
|
|
|
|||
|
|
setUserTokenToStorage(userId, token) {
|
|||
|
|
const params = {
|
|||
|
|
key: `EM_${userId}_TOKEN`,
|
|||
|
|
data: { token: token },
|
|||
|
|
};
|
|||
|
|
uni.setStorage({ ...params });
|
|||
|
|
},
|
|||
|
|
async getToken() {
|
|||
|
|
getTokenApi({}).then(res => {
|
|||
|
|
if (res.code == 1) {
|
|||
|
|
// if (!uni.getStorageSync('hxtoken')) {
|
|||
|
|
const loginStore = useLoginStore();
|
|||
|
|
let chatUserName = uni.getStorageSync('userinfo').user_number
|
|||
|
|
let token = res.data.access_token
|
|||
|
|
const { loginWithPassword, loginWithAccessToken } = emConnect();
|
|||
|
|
loginWithPassword(String(chatUserName), 'xuni123');
|
|||
|
|
// loginWithAccessToken(chatUserName, token);
|
|||
|
|
uni.setStorage({
|
|||
|
|
key: 'myUsername',
|
|||
|
|
data: chatUserName
|
|||
|
|
});
|
|||
|
|
loginStore.setLoginUserBaseInfos({ loginUserId: chatUserName });
|
|||
|
|
this.setUserTokenToStorage(chatUserName, token);
|
|||
|
|
// }
|
|||
|
|
// uni.setStorageSync('hxtoken', res.data.access_token)
|
|||
|
|
}
|
|||
|
|
})
|
|||
|
|
},
|
|||
|
|
async friend() {
|
|||
|
|
const res = await Friend(this.form)
|
|||
|
|
let data = ''
|
|||
|
|
let ids = ''
|
|||
|
|
let onlineData = ''
|
|||
|
|
if (res.code == 1) {
|
|||
|
|
data = res.data.data
|
|||
|
|
ids = data.map(item => {
|
|||
|
|
return item.friend_id
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
if (ids.length == 0) {
|
|||
|
|
return
|
|||
|
|
}
|
|||
|
|
const onlineRes = await getOnlineApi({
|
|||
|
|
'user_ids': ids.join(',')
|
|||
|
|
})
|
|||
|
|
if (onlineRes.code == 1) {
|
|||
|
|
onlineData = onlineRes.data
|
|||
|
|
data.forEach(item => {
|
|||
|
|
const onlineStatus = onlineData.find(onlineItem => onlineItem.id == item.friend_id)
|
|||
|
|
if (onlineStatus) {
|
|||
|
|
item.is_online = onlineStatus.is_online
|
|||
|
|
} else {
|
|||
|
|
item.is_online = false
|
|||
|
|
}
|
|||
|
|
})
|
|||
|
|
}
|
|||
|
|
this.friendList.push(...data)
|
|||
|
|
},
|
|||
|
|
msgCount() {
|
|||
|
|
MsgCount({}).then(res => {
|
|||
|
|
if (res.code == 1) {
|
|||
|
|
this.msgCountInfo = res.data.msg_count
|
|||
|
|
this.requestsInfo = res.data.requests
|
|||
|
|
} else {
|
|||
|
|
uni.showToast({
|
|||
|
|
title: res.msg,
|
|||
|
|
icon: 'none',
|
|||
|
|
position: 'top'
|
|||
|
|
})
|
|||
|
|
}
|
|||
|
|
})
|
|||
|
|
},
|
|||
|
|
onScrollToLower() {
|
|||
|
|
++this.form.page
|
|||
|
|
console.log('触底事件')
|
|||
|
|
this.friend()
|
|||
|
|
},
|
|||
|
|
tosearch() {
|
|||
|
|
uni.navigateTo({
|
|||
|
|
url: '/pages/friends/search'
|
|||
|
|
})
|
|||
|
|
},
|
|||
|
|
tomessageList() {
|
|||
|
|
uni.navigateTo({
|
|||
|
|
url: '/pages/friends/messageList'
|
|||
|
|
})
|
|||
|
|
},
|
|||
|
|
toofficialList() {
|
|||
|
|
uni.navigateTo({
|
|||
|
|
url: '/pages/friends/officialList'
|
|||
|
|
})
|
|||
|
|
},
|
|||
|
|
toFriendsChat(item) {
|
|||
|
|
const {
|
|||
|
|
fetchConversationFromServer,
|
|||
|
|
removeConversationFromServer,
|
|||
|
|
sendChannelAck,
|
|||
|
|
} = emConversation();
|
|||
|
|
const conversationStore = useConversationStore();
|
|||
|
|
let channel_id = item.friend.user_number
|
|||
|
|
//好友的信息openid
|
|||
|
|
let listener = {
|
|||
|
|
nickname: item.friend.nickname,
|
|||
|
|
headImage: item.friend.avatar, // 头像,自行修改
|
|||
|
|
openid: item.friend.open_id, //获取小程序用户的openId
|
|||
|
|
}
|
|||
|
|
sendChannelAck(channel_id, 'singleChat');
|
|||
|
|
conversationStore.clearConversationUnReadNum(channel_id);
|
|||
|
|
conversationStore.setChattingUserId(channel_id); //存贮当前聊天对象环信账号
|
|||
|
|
conversationStore.setUserId(item.friend_id); //存贮当前聊天对象i用户id
|
|||
|
|
conversationStore.setUserLevel(item.intimacy_level); //存贮当前聊天对象i用户id
|
|||
|
|
conversationStore.setFriendInfo(listener); //存贮当前聊天对象好友信息
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
let avatarurl = uni.getStorageSync('userinfo').avatar
|
|||
|
|
let friendAvatar = item.friend.avatar
|
|||
|
|
conversationStore.setAvatar(avatarurl);
|
|||
|
|
conversationStore.setFriendAvatar(friendAvatar);
|
|||
|
|
let data = {
|
|||
|
|
id: item.friend_id,
|
|||
|
|
intimacy_level: item.intimacy_level,
|
|||
|
|
avatar: item.friend.avatar,
|
|||
|
|
nickname: item.friend.nickname,
|
|||
|
|
}
|
|||
|
|
uni.navigateTo({
|
|||
|
|
url: '/pages/friends/chat?item=' + encodeURIComponent(JSON.stringify(data))
|
|||
|
|
})
|
|||
|
|
},
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
</script>
|
|||
|
|
|
|||
|
|
<style>
|
|||
|
|
page {
|
|||
|
|
background: #F6F8FA;
|
|||
|
|
}
|
|||
|
|
</style>
|
|||
|
|
<style scoped>
|
|||
|
|
.page {
|
|||
|
|
position: relative;
|
|||
|
|
height: 100vh;
|
|||
|
|
overflow: hidden;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.scroll-view {
|
|||
|
|
overflow: hidden;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.body {
|
|||
|
|
position: relative;
|
|||
|
|
padding: 0 60rpx;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.back {
|
|||
|
|
position: absolute;
|
|||
|
|
left: 0;
|
|||
|
|
top: 0;
|
|||
|
|
width: 100%;
|
|||
|
|
height: 436rpx;
|
|||
|
|
background: linear-gradient(180deg, #EAD6FF 0%, rgba(255, 255, 255, 0) 100%);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.head {
|
|||
|
|
position: relative;
|
|||
|
|
padding: 50rpx 60rpx 0 22rpx;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.head image {
|
|||
|
|
position: relative;
|
|||
|
|
margin: 0 0 0 32rpx;
|
|||
|
|
width: 48rpx;
|
|||
|
|
height: 48rpx;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.head_content {
|
|||
|
|
position: relative;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.head_number {
|
|||
|
|
position: absolute;
|
|||
|
|
right: -26rpx;
|
|||
|
|
top: -30rpx;
|
|||
|
|
padding: 5rpx 15rpx;
|
|||
|
|
font-size: 24rpx;
|
|||
|
|
color: #FFFFFF;
|
|||
|
|
background: #F55726;
|
|||
|
|
border: 3rpx solid #FFFFFF;
|
|||
|
|
border-radius: 100rpx;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.list {
|
|||
|
|
position: relative;
|
|||
|
|
padding: 30rpx 0 200rpx 0;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.list_content {
|
|||
|
|
position: relative;
|
|||
|
|
margin: 0 0 30rpx 0;
|
|||
|
|
padding: 32rpx 30rpx;
|
|||
|
|
background: #FFFFFF;
|
|||
|
|
border-radius: 16rpx;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.list_avatar {
|
|||
|
|
position: relative;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.list_avatar image {
|
|||
|
|
width: 96rpx;
|
|||
|
|
height: 96rpx;
|
|||
|
|
display: block;
|
|||
|
|
flex-shrink: 0;
|
|||
|
|
border-radius: 100rpx;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.list_round {
|
|||
|
|
position: absolute;
|
|||
|
|
left: 0;
|
|||
|
|
top: 0;
|
|||
|
|
width: 20rpx;
|
|||
|
|
height: 20rpx;
|
|||
|
|
background: #02AD41;
|
|||
|
|
border: 3rpx solid #FFFFFF;
|
|||
|
|
border-radius: 100rpx;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.list_module {
|
|||
|
|
position: relative;
|
|||
|
|
margin: 0 0 0 20rpx;
|
|||
|
|
overflow: hidden;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.list_name {
|
|||
|
|
font-weight: 500;
|
|||
|
|
font-size: 32rpx;
|
|||
|
|
color: #222222;
|
|||
|
|
line-height: 50rpx;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.list_id {
|
|||
|
|
font-weight: 400;
|
|||
|
|
font-size: 28rpx;
|
|||
|
|
color: #B5B5B5;
|
|||
|
|
line-height: 50rpx;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.not {
|
|||
|
|
position: relative;
|
|||
|
|
margin: 88rpx 0 0 0;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.not image {
|
|||
|
|
width: 344rpx;
|
|||
|
|
display: block;
|
|||
|
|
margin: 0 auto;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.not_title {
|
|||
|
|
margin: 14rpx 0 0 0;
|
|||
|
|
font-weight: 400;
|
|||
|
|
font-size: 30rpx;
|
|||
|
|
color: #9E9E9E;
|
|||
|
|
line-height: 50rpx;
|
|||
|
|
text-align: center;
|
|||
|
|
}
|
|||
|
|
</style>
|