Files
huihuiSquare/digital-avatar-app/src/views/AvatarContacts.vue
T

143 lines
5.7 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<template>
<div class="contacts-page">
<!-- 顶部导航 -->
<header class="page-header">
<div class="header-left">
<button class="back-btn" @click="goBack">‹</button>
<h1 class="page-title">分身人脉</h1>
</div>
<button class="add-btn" @click="addContact">+</button>
</header>
<!-- 搜索 -->
<section class="search-section">
<div class="search-box">
<span class="search-icon">🔍</span>
<input v-model="keyword" class="search-input" placeholder="搜索人脉" />
</div>
</section>
<!-- 人脉列表 -->
<section class="contacts-section">
<div class="contact-list" v-if="filteredContacts.length > 0">
<div class="contact-item" v-for="c in filteredContacts" :key="c.id">
<div class="contact-avatar">{{ c.emoji }}</div>
<div class="contact-info">
<div class="contact-name-row">
<span class="contact-name">{{ c.name }}</span>
<span class="relation-tag" :class="c.relation">{{ relationText(c.relation) }}</span>
</div>
<span class="contact-last">最近互动:{{ c.last }}</span>
</div>
<button class="chat-btn" @click="openChat(c)">💬</button>
</div>
</div>
<div class="empty-state" v-else>
<span class="empty-icon">🤝</span>
<p class="empty-text">还没有人脉,点击右上角添加</p>
</div>
</section>
<p class="toast" v-if="toast">{{ toast }}</p>
</div>
</template>
<script setup lang="ts">
import { ref, computed } from 'vue'
import { useRouter } from 'vue-router'
const router = useRouter()
const keyword = ref('')
const toast = ref('')
interface Contact { id: string; emoji: string; name: string; relation: string; last: string }
const contacts = ref<Contact[]>([
{ id: '1', emoji: '👩', name: '林小满', relation: 'friend', last: '今天 14:20' },
{ id: '2', emoji: '🧑', name: '陈工', relation: 'colleague', last: '昨天 09:10' },
{ id: '3', emoji: '👨', name: '王总', relation: 'client', last: '3 天前' },
{ id: '4', emoji: '🧑', name: 'Anna', relation: 'friend', last: '上周' }
])
const filteredContacts = computed(() =>
contacts.value.filter(c => c.name.includes(keyword.value))
)
const relationText = (r: string) => ({
friend: '好友', colleague: '同事', client: '客户'
}[r] || '好友')
const goBack = () => router.back()
const addContact = () => {
const sample = ['👤', '🧑', '👩', '🧑']
const names = ['新朋友', '合作伙伴', '张同学', '李经理']
const relations = ['friend', 'colleague', 'client']
const idx = contacts.value.length
contacts.value.unshift({
id: String(Date.now()),
emoji: sample[idx % sample.length],
name: names[idx % names.length],
relation: relations[idx % relations.length],
last: '刚刚添加'
})
toast.value = '已添加示例人脉'
setTimeout(() => (toast.value = ''), 2000)
}
const openChat = (c: Contact) => {
toast.value = `打开与 ${c.name} 的对话(示例)`
setTimeout(() => (toast.value = ''), 2000)
}
</script>
<style scoped>
.contacts-page { min-height: 100vh; background: #F8F9FA; padding-bottom: 40px; }
.page-header {
display: flex; align-items: center; justify-content: space-between;
padding: 16px 20px; background: linear-gradient(135deg, #F97316 0%, #FB923C 100%); color: white;
}
.header-left { display: flex; align-items: center; gap: 12px; }
.back-btn { background: none; border: none; color: white; font-size: 24px; cursor: pointer; padding: 4px; }
.page-title { font-size: 18px; font-weight: 600; margin: 0; }
.add-btn { background: rgba(255,255,255,0.2); border: none; color: white; font-size: 22px; width: 36px; height: 36px; border-radius: 50%; cursor: pointer; }
.search-section { padding: 16px 20px; }
.search-box { display: flex; align-items: center; gap: 8px; background: white; border-radius: 12px; padding: 10px 14px; box-shadow: 0 2px 8px rgba(0,0,0,0.05); }
.search-icon { font-size: 16px; }
.search-input { flex: 1; border: none; outline: none; font-size: 14px; color: #18191C; background: transparent; }
.contacts-section { padding: 0 20px; }
.contact-list { display: flex; flex-direction: column; gap: 10px; }
.contact-item {
display: flex; align-items: center; gap: 12px; padding: 14px 16px;
background: white; border-radius: 12px; box-shadow: 0 2px 8px rgba(0,0,0,0.05);
}
.contact-avatar {
width: 44px; height: 44px; border-radius: 50%; background: #FFF0E6;
display: flex; align-items: center; justify-content: center; font-size: 22px; flex-shrink: 0;
}
.contact-info { flex: 1; min-width: 0; }
.contact-name-row { display: flex; align-items: center; gap: 8px; margin-bottom: 4px; }
.contact-name { font-size: 15px; font-weight: 600; color: #18191C; }
.relation-tag { padding: 2px 8px; border-radius: 10px; font-size: 11px; font-weight: 500; }
.relation-tag.friend { background: #ECFDF5; color: #22C55E; }
.relation-tag.colleague { background: #EFF6FF; color: #3B82F6; }
.relation-tag.client { background: #FFF0E6; color: #F97316; }
.contact-last { font-size: 12px; color: #9398AE; }
.chat-btn {
width: 38px; height: 38px; border-radius: 50%; border: none; background: #FFF0E6;
font-size: 18px; cursor: pointer; flex-shrink: 0; transition: transform 0.2s;
}
.chat-btn:hover { transform: scale(1.08); }
.empty-state {
display: flex; flex-direction: column; align-items: center; justify-content: center;
padding: 40px 20px; background: white; border-radius: 12px; box-shadow: 0 2px 8px rgba(0,0,0,0.05);
}
.empty-icon { font-size: 48px; margin-bottom: 12px; }
.empty-text { font-size: 14px; color: #9398AE; margin: 0; }
.toast { text-align: center; font-size: 13px; color: #F97316; margin: 16px 20px 0; }
</style>