Files
YwxAppThink/addon/wxchat/YwxMakeFriends/pages/friend/index.uvue
T

306 lines
6.7 KiB
Plaintext

<template>
<view class="page">
<view class="nav-bar">
<view class="nav-back" @click="goBack">
<uni-icons type="left" size="22" color="#333"></uni-icons>
</view>
<text class="nav-title">我的好友</text>
<view class="nav-right"></view>
</view>
<view class="add-bar">
<input class="add-input" v-model="newUid" type="number" placeholder="输入对方用户ID添加好友" />
<button class="add-btn" @click="sendRequest">添加</button>
</view>
<scroll-view class="tabs" direction="horizontal" :show-scrollbar="false">
<text class="tab" :class="{ active: tab == 0 }" @click="tab = 0">好友 ({{ friends.length }})</text>
<text class="tab" :class="{ active: tab == 1 }" @click="tab = 1">请求 ({{ requests.length }})</text>
</scroll-view>
<list-view class="list" v-if="tab == 0">
<list-item v-for="(f, i) in friends" :key="f.uid" class="item">
<image class="avatar" :src="f.avatar" mode="aspectFill"></image>
<view class="info">
<text class="name">{{ f.nickname }}</text>
<text class="meta">{{ f.remark && f.remark.length > 0 ? f.remark : '好友' }}</text>
</view>
<button class="del-btn" @click="removeFriend(f.friend_id)">删除</button>
</list-item>
<view v-if="friends.length == 0" class="empty">
<text>还没有好友,去真人匹配认识一下吧</text>
</view>
</list-view>
<list-view class="list" v-else>
<list-item v-for="(r, i) in requests" :key="r.uid" class="item">
<image class="avatar" :src="r.avatar" mode="aspectFill"></image>
<view class="info">
<text class="name">{{ r.nickname }}</text>
<text class="meta">请求添加你为好友</text>
</view>
<button class="ok-btn" @click="respond(r.friend_id, 1)">接受</button>
<button class="del-btn" @click="respond(r.friend_id, 2)">拒绝</button>
</list-item>
<view v-if="requests.length == 0" class="empty">
<text>暂无新的好友请求</text>
</view>
</list-view>
</view>
</template>
<script setup lang="uts">
import { ref, onMounted } from 'vue'
import { Api } from '@/common/api-service.uts'
const friends = ref<UTSJSONObject[]>([])
const requests = ref<UTSJSONObject[]>([])
const tab = ref(0)
const newUid = ref('')
const loadFriends = async () => {
try {
const data = await Api.friend.list({})
const list = data.getJSONArray('list')
const arr : UTSJSONObject[] = []
if (list != null) {
for (let i = 0; i < list.size(); i++) {
const it = list.get(i) as UTSJSONObject
if (it != null) {
arr.push({
uid: it.getNumber('uid') ?? 0,
nickname: it.getString('nickname') ?? '',
avatar: it.getString('avatar') ?? '',
remark: it.getString('remark') ?? '',
friend_id: it.getNumber('friend_id') ?? 0
} as UTSJSONObject)
}
}
}
friends.value = arr
} catch (e) {
console.warn('加载好友列表失败', e)
}
}
const loadRequests = async () => {
try {
const data = await Api.friend.requests({})
const list = data.getJSONArray('list')
const arr : UTSJSONObject[] = []
if (list != null) {
for (let i = 0; i < list.size(); i++) {
const it = list.get(i) as UTSJSONObject
if (it != null) {
arr.push({
uid: it.getNumber('uid') ?? 0,
nickname: it.getString('nickname') ?? '',
avatar: it.getString('avatar') ?? '',
friend_id: it.getNumber('friend_id') ?? 0
} as UTSJSONObject)
}
}
}
requests.value = arr
} catch (e) {
console.warn('加载好友请求失败', e)
}
}
const sendRequest = () => {
const fid = parseInt(newUid.value)
if (!fid || fid <= 0) {
uni.showToast({ title: '请输入有效ID', icon: 'none' })
return
}
Api.friend.create({ fid: fid }).then(() => {
uni.showToast({ title: '请求已发送', icon: 'success' })
newUid.value = ''
loadRequests()
}).catch((err : any) => {
uni.showToast({ title: err?.message ?? '失败', icon: 'none' })
})
}
const respond = (id : number, action : number) => {
Api.friend.respond(id, action).then(() => {
uni.showToast({ title: action == 1 ? '已添加' : '已拒绝', icon: 'success' })
loadRequests()
loadFriends()
}).catch((err : any) => {
uni.showToast({ title: err?.message ?? '失败', icon: 'none' })
})
}
const removeFriend = (id : number) => {
Api.friend.delete(id).then(() => {
uni.showToast({ title: '已删除', icon: 'success' })
loadFriends()
}).catch((err : any) => {
uni.showToast({ title: err?.message ?? '失败', icon: 'none' })
})
}
const goBack = () => {
uni.navigateBack()
}
onMounted(() => {
loadFriends()
loadRequests()
})
</script>
<style>
.page {
display: flex;
flex-direction: column;
background-color: #f6f6f6;
min-height: 100%;
}
.nav-bar {
display: flex;
flex-direction: row;
align-items: center;
padding: 20rpx 24rpx;
padding-top: 60rpx;
background-color: #fff;
}
.nav-back {
width: 60rpx;
display: flex;
align-items: center;
}
.nav-title {
flex: 1;
text-align: center;
font-size: 34rpx;
font-weight: bold;
color: #333;
}
.nav-right {
width: 60rpx;
}
.add-bar {
display: flex;
flex-direction: row;
padding: 20rpx 24rpx;
background-color: #fff;
}
.add-input {
flex: 1;
background-color: #f2f2f2;
border-radius: 40rpx;
padding: 18rpx 28rpx;
font-size: 26rpx;
margin-right: 16rpx;
}
.add-btn {
background: linear-gradient(to bottom right, #FF6B6B, #FF8E53);
color: #fff;
border: none;
border-radius: 40rpx;
font-size: 26rpx;
padding: 0 36rpx;
}
.tabs {
display: flex;
flex-direction: row;
background-color: #fff;
padding: 10rpx 24rpx;
border-top: 1rpx solid #f0f0f0;
}
.tab {
font-size: 28rpx;
color: #888;
margin-right: 40rpx;
padding: 12rpx 0;
}
.tab.active {
color: #FF6B6B;
font-weight: bold;
border-bottom: 4rpx solid #FF6B6B;
}
.list {
flex: 1;
}
.item {
display: flex;
flex-direction: row;
align-items: center;
background-color: #fff;
margin: 16rpx 24rpx;
padding: 24rpx;
border-radius: 20rpx;
}
.avatar {
width: 88rpx;
height: 88rpx;
border-radius: 50%;
background-color: #eee;
}
.info {
flex: 1;
display: flex;
flex-direction: column;
margin-left: 24rpx;
}
.name {
font-size: 30rpx;
font-weight: bold;
color: #333;
}
.meta {
font-size: 24rpx;
color: #999;
margin-top: 8rpx;
}
.ok-btn {
background-color: #4CD964;
color: #fff;
border: none;
border-radius: 40rpx;
font-size: 24rpx;
padding: 8rpx 24rpx;
margin-right: 12rpx;
}
.del-btn {
background-color: #ff3b30;
color: #fff;
border: none;
border-radius: 40rpx;
font-size: 24rpx;
padding: 8rpx 24rpx;
}
.empty {
padding: 80rpx 0;
display: flex;
align-items: center;
justify-content: center;
}
.empty text {
font-size: 26rpx;
color: #aaa;
}
</style>