个人信息卡片

This commit is contained in:
2025-12-06 08:37:24 +08:00
parent 9173d36763
commit ec14ee7b5c

View File

@@ -0,0 +1,212 @@
<template>
<div
v-if="show"
class="fixed inset-0 bg-black/80 z-[60] flex items-center justify-center p-4 backdrop-blur-sm"
@click.self="$emit('close')"
>
<div class="bg-[#111827] rounded-2xl w-full max-w-2xl shadow-2xl border border-gray-700 overflow-hidden animate-fade-in max-h-[90vh] flex flex-col relative">
<!-- 背景装饰 -->
<div class="absolute top-0 left-0 right-0 h-48 bg-gradient-to-b from-primary/20 to-transparent pointer-events-none"></div>
<!-- 关闭按钮 -->
<button
class="absolute top-5 right-5 z-50 w-9 h-9 rounded-full bg-black/20 hover:bg-white/10 text-gray-300 hover:text-white flex items-center justify-center transition backdrop-blur-md border border-white/5"
@click="$emit('close')"
>
<i class="fas fa-times"></i>
</button>
<!-- 内容区域 -->
<div class="flex-1 overflow-y-auto custom-scrollbar relative z-10 flex flex-col">
<!-- 头部头像与核心信息 -->
<div class="pt-14 pb-8 px-8 text-center flex flex-col items-center animate-fade-in">
<div class="relative group cursor-pointer" @click="viewAvatar">
<Avatar
:name="user?.name || '未知'"
:avatar="user?.avatar"
size="xl"
rounded="full"
class="border-[6px] border-[#111827] shadow-2xl relative z-10 transition-transform duration-300 group-hover:scale-105"
/>
<div v-if="user?.is_online" class="absolute bottom-1 right-1 w-5 h-5 bg-emerald-500 rounded-full border-4 border-[#111827] z-20" title="在线"></div>
</div>
<h3 class="text-2xl font-bold text-white mt-5 flex items-center gap-2 justify-center select-text">
{{ user?.name || '未知' }}
<span v-if="user?.gender" class="w-5 h-5 rounded-full flex items-center justify-center text-[10px]" :class="user.gender === 1 ? 'bg-blue-500/20 text-blue-400' : 'bg-pink-500/20 text-pink-400'">
<i :class="user.gender === 1 ? 'fas fa-mars' : 'fas fa-venus'"></i>
</span>
</h3>
<p class="text-gray-400 text-sm mt-2 max-w-md truncate px-4 opacity-80">
{{ user?.desc || '暂无签名' }}
</p>
<div class="flex gap-3 mt-4 text-xs font-medium text-gray-400">
<span class="bg-white/5 px-2.5 py-1 rounded-md border border-white/5 select-text">ID: {{ user?.id || '未知' }}</span>
<span v-if="user?.region" class="bg-white/5 px-2.5 py-1 rounded-md border border-white/5">{{ user.region }}</span>
</div>
</div>
<!-- 详细信息列表 -->
<div class="px-8 py-4 space-y-3 max-w-xl mx-auto w-full animate-slide-up">
<div class="bg-white/5 rounded-2xl border border-white/5 overflow-hidden">
<!-- 网名 -->
<div class="flex items-center p-4 hover:bg-white/5 transition-colors group relative border-b border-white/5">
<div class="w-9 h-9 rounded-lg bg-white/5 flex items-center justify-center text-gray-500 mr-4 shrink-0">
<i class="far fa-user"></i>
</div>
<div class="flex-1 min-w-0 mr-8">
<div class="text-[10px] text-gray-500 uppercase tracking-wider mb-0.5 font-bold">网名</div>
<div class="text-sm text-gray-200 font-medium truncate select-text">{{ user?.name || '未知' }}</div>
</div>
<button class="absolute right-4 w-8 h-8 rounded-lg hover:bg-white/10 text-gray-500 hover:text-primary transition flex items-center justify-center opacity-0 group-hover:opacity-100"
@click="copyText(user?.name)" title="复制">
<i class="far fa-copy"></i>
</button>
</div>
<!-- 手机号 -->
<div v-if="user?.phone" class="flex items-center p-4 hover:bg-white/5 transition-colors group relative border-b border-white/5 last:border-0">
<div class="w-9 h-9 rounded-lg bg-white/5 flex items-center justify-center text-gray-500 mr-4 shrink-0">
<i class="fas fa-phone-alt"></i>
</div>
<div class="flex-1 min-w-0 mr-8">
<div class="text-[10px] text-gray-500 uppercase tracking-wider mb-0.5 font-bold">手机号</div>
<div class="text-sm text-gray-200 font-medium truncate select-text font-mono">{{ user.phone }}</div>
</div>
<button class="absolute right-4 w-8 h-8 rounded-lg hover:bg-white/10 text-gray-500 hover:text-primary transition flex items-center justify-center opacity-0 group-hover:opacity-100"
@click="copyText(user.phone)" title="复制">
<i class="far fa-copy"></i>
</button>
</div>
<!-- 邮箱 -->
<div v-if="user?.email" class="flex items-center p-4 hover:bg-white/5 transition-colors group relative border-b border-white/5 last:border-0">
<div class="w-9 h-9 rounded-lg bg-white/5 flex items-center justify-center text-gray-500 mr-4 shrink-0">
<i class="far fa-envelope"></i>
</div>
<div class="flex-1 min-w-0 mr-8">
<div class="text-[10px] text-gray-500 uppercase tracking-wider mb-0.5 font-bold">邮箱</div>
<div class="text-sm text-gray-200 font-medium truncate select-text font-mono">{{ user.email }}</div>
</div>
<button class="absolute right-4 w-8 h-8 rounded-lg hover:bg-white/10 text-gray-500 hover:text-primary transition flex items-center justify-center opacity-0 group-hover:opacity-100"
@click="copyText(user.email)" title="复制">
<i class="far fa-copy"></i>
</button>
</div>
<!-- 地区 -->
<div v-if="user?.region" class="flex items-center p-4 hover:bg-white/5 transition-colors group relative border-b border-white/5 last:border-0">
<div class="w-9 h-9 rounded-lg bg-white/5 flex items-center justify-center text-gray-500 mr-4 shrink-0">
<i class="fas fa-map-marker-alt"></i>
</div>
<div class="flex-1 min-w-0 mr-8">
<div class="text-[10px] text-gray-500 uppercase tracking-wider mb-0.5 font-bold">地区</div>
<div class="text-sm text-gray-200 font-medium truncate select-text">{{ user.region }}</div>
</div>
</div>
</div>
</div>
<!-- 底部快捷操作栏 -->
<div class="mt-auto p-6 bg-gradient-to-t from-[#0f172a] via-[#0f172a]/80 to-transparent">
<div class="grid grid-cols-3 gap-4 max-w-lg mx-auto w-full">
<!-- 发消息 -->
<button class="flex flex-col items-center justify-center gap-1.5 py-3.5 px-2 rounded-2xl transition-all duration-200 active:scale-95 group bg-primary text-white shadow-lg shadow-primary/25 hover:bg-primary-hover hover:-translate-y-0.5"
@click="$emit('send-message')"
>
<i class="fas fa-comment-dots text-xl"></i>
<span class="text-xs font-bold">发消息</span>
</button>
<!-- 语音通话 -->
<button class="flex flex-col items-center justify-center gap-1.5 py-3.5 px-2 rounded-2xl transition-all duration-200 active:scale-95 group bg-white/5 text-gray-300 hover:bg-white/10 hover:text-white border border-white/5 hover:border-white/10"
@click="$emit('audio-call')"
>
<i class="fas fa-phone text-xl"></i>
<span class="text-xs font-medium">语音通话</span>
</button>
<!-- 视频通话 -->
<button class="flex flex-col items-center justify-center gap-1.5 py-3.5 px-2 rounded-2xl transition-all duration-200 active:scale-95 group bg-white/5 text-gray-300 hover:bg-white/10 hover:text-white border border-white/5 hover:border-white/10"
@click="$emit('video-call')"
>
<i class="fas fa-video text-xl"></i>
<span class="text-xs font-medium">视频通话</span>
</button>
</div>
</div>
</div>
</div>
</div>
</template>
<script setup lang="ts">
import { useToastStore } from '@/stores/toast'
import Avatar from '@/components/common/Avatar.vue'
import type { User } from '@/types/api'
interface Props {
show: boolean
user: User | null
}
defineProps<Props>()
const emit = defineEmits<{
close: []
'send-message': []
'audio-call': []
'video-call': []
}>()
const toastStore = useToastStore()
function copyText(text?: string) {
if (!text) return
navigator.clipboard.writeText(text).then(() => {
toastStore.success('复制成功')
}).catch(() => {
toastStore.error('复制失败')
})
}
function viewAvatar() {
// 可以添加查看大图逻辑
}
</script>
<style scoped>
.custom-scrollbar::-webkit-scrollbar {
width: 6px;
}
.custom-scrollbar::-webkit-scrollbar-thumb {
@apply bg-white/10 rounded-full hover:bg-white/20;
}
.animate-fade-in {
animation: fadeIn 0.4s ease-out;
}
.animate-slide-up {
animation: slideUp 0.4s ease-out;
}
@keyframes fadeIn {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
@keyframes slideUp {
from {
transform: translateY(20px);
opacity: 0;
}
to {
transform: translateY(0);
opacity: 1;
}
}
</style>