149 lines
3.9 KiB
Vue
149 lines
3.9 KiB
Vue
<template>
|
||
<view class="content column">
|
||
<view class="row" style="width: 90%; margin: 100rpx auto 0; justify-content: space-between;">
|
||
<image src="/static/back.png" style="width: 40rpx; height: 40rpx;" @click="goBack()" mode=""></image>
|
||
<text style="font-size: 30rpx;">黑名单</text>
|
||
<view style="width: 40rpx;"></view>
|
||
</view>
|
||
|
||
<view class="" style=" overflow-y: auto; margin-top: 30rpx;">
|
||
<view class="column" style="width: 90%; margin: 0 auto 0;">
|
||
<!-- 加载状态 -->
|
||
<view v-if="loading" class="loading-container">
|
||
<text>加载中...</text>
|
||
</view>
|
||
|
||
<!-- 空状态 -->
|
||
<view v-else-if="blackList.length === 0" class="empty-container">
|
||
<text>暂无黑名单用户</text>
|
||
</view>
|
||
|
||
<!-- 黑名单列表 -->
|
||
<view v-else class="column item" v-for="(item, index) in blackList" :key="item.id"
|
||
style="width: 100%;margin-bottom: 10rpx;">
|
||
<view class="row" style="align-items: center;">
|
||
<image :src="item.blockedAvatarImage || '/static/default-avatar.png'"
|
||
style="width: 130rpx; height: 130rpx; background-color: burlywood; border-radius: 50%; margin: 20rpx;"
|
||
mode="aspectFill">
|
||
</image>
|
||
|
||
<view class="column" style="font-size: 24rpx; margin-left: 30rpx;">
|
||
<text>{{ item.blockedNickName || '未知用户' }}</text>
|
||
<text style="margin-top: 20rpx;">UID:{{ item.blockedUserId }}</text>
|
||
</view>
|
||
|
||
<view class="center cancel-btn"
|
||
style="width: 180rpx; height: 80rpx; background-color: #1989FA; font-size: 26rpx; border-radius: 10rpx; margin-left: auto; margin-right: 20rpx;"
|
||
@click="handleCancelBlack(item.blockedUserId, index)">
|
||
{{ cancelingIndex === index ? '取消中...' : '取消拉黑' }}
|
||
</view>
|
||
</view>
|
||
|
||
<text style="margin-top: 20rpx; font-size: 24rpx; margin-left: 20rpx; margin-bottom: 20rpx;">
|
||
拉黑时间:{{ formatDate(item.createdTime) }}
|
||
</text>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</template>
|
||
|
||
<script setup>
|
||
import { ref, onMounted } from 'vue'
|
||
import { userInterface } from '@/common/server/interface/user.js'
|
||
import { showModalConfirm } from '@/common/utils.js'
|
||
import { cancelBlack } from '@/common/server/user.js'
|
||
// 响应式数据
|
||
const loading = ref(true)
|
||
const blackList = ref([])
|
||
const cancelingIndex = ref(-1)
|
||
|
||
// 获取黑名单列表
|
||
const getBlackList = async () => {
|
||
try {
|
||
loading.value = true
|
||
const data = await userInterface.getMyBlackList()
|
||
if (data) {
|
||
blackList.value = data
|
||
}
|
||
} catch (error) {
|
||
console.error('获取黑名单失败:', error)
|
||
uni.showToast({
|
||
title: '获取黑名单失败',
|
||
icon: 'none'
|
||
})
|
||
} finally {
|
||
loading.value = false
|
||
}
|
||
}
|
||
|
||
// 取消拉黑
|
||
const handleCancelBlack = async (userId, index) => {
|
||
try {
|
||
|
||
cancelingIndex.value = index;
|
||
var isSuccess = await cancelBlack(userId);
|
||
if (isSuccess) {
|
||
blackList.value.splice(index, 1)
|
||
}
|
||
} finally {
|
||
cancelingIndex.value = -1
|
||
}
|
||
}
|
||
|
||
// 格式化日期
|
||
const formatDate = (dateString) => {
|
||
if (!dateString) return '未知时间'
|
||
const date = new Date(dateString)
|
||
const year = date.getFullYear()
|
||
const month = String(date.getMonth() + 1).padStart(2, '0')
|
||
const day = String(date.getDate()).padStart(2, '0')
|
||
const hours = String(date.getHours()).padStart(2, '0')
|
||
const minutes = String(date.getMinutes()).padStart(2, '0')
|
||
return `${year}/${month}/${day} ${hours}:${minutes}`
|
||
}
|
||
|
||
// 返回上一页
|
||
const goBack = () => {
|
||
uni.navigateBack({
|
||
delta: 1
|
||
})
|
||
}
|
||
|
||
// 页面加载时获取黑名单
|
||
onMounted(() => {
|
||
getBlackList()
|
||
})
|
||
</script>
|
||
|
||
<style lang="scss">
|
||
.content {
|
||
width: 100%;
|
||
height: 100vh;
|
||
background: #F7F7F7;
|
||
}
|
||
|
||
.loading-container,
|
||
.empty-container {
|
||
display: flex;
|
||
justify-content: center;
|
||
align-items: center;
|
||
height: 400rpx;
|
||
font-size: 28rpx;
|
||
color: #999;
|
||
}
|
||
|
||
.cancel-btn {
|
||
transition: opacity 0.3s;
|
||
|
||
&:active {
|
||
opacity: 0.7;
|
||
}
|
||
}
|
||
|
||
.item {
|
||
box-shadow: 0rpx 0rpx 10rpx 0rpx rgba(0, 0, 0, 0.25);
|
||
background: #FFFFFF;
|
||
border-radius: 30rpx;
|
||
}
|
||
</style> |