aslan-h5/src/views/BDCenterView.vue
2025-09-25 18:20:30 +08:00

405 lines
7.8 KiB
Vue
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<div class="bd-center gradient-background-circles">
<!-- 顶部导航 -->
<MobileHeader title="BD Center" :isHomePage="true" />
<!-- 主要内容 -->
<div class="content">
<!-- 用户信息卡片 -->
<div class="user-card">
<!-- APP连接状态指示 -->
<div v-if="isInApp() && !appConnected" class="app-status connecting">
<div class="status-indicator"></div>
<span>正在连接APP...</span>
</div>
<div class="user-info">
<div class="avatar">
<img
v-if="userInfo.userAvatar"
:src="userInfo.userAvatar"
:alt="userInfo.name"
@error="handleImageError"
/>
<span v-else class="avatar-placeholder">{{ getAvatarPlaceholder() }}</span>
</div>
<div class="user-details">
<h3>{{ userInfo.userNickname || userInfo.name }}</h3>
<p>ID: {{ userInfo.id || userInfo.account }}</p>
</div>
<!-- <button class="notification-btn" @click="goToNotification">-->
<!-- <span></span>-->
<!-- </button>-->
</div>
<!-- 账户状态标签 -->
<div class="account-tags">
<span class="tag bd-tag">👑 BD</span>
</div>
</div>
<!-- Total team salary 区域 -->
<div class="salary-section">
<h3>Total team salary:</h3>
<div class="salary-content">
<div class="salary-item">
<p class="salary-label">Last month:</p>
<p class="salary-amount">${{ salaryInfo.lastMonth }}</p>
</div>
<div class="salary-separator"></div>
<div class="salary-item">
<p class="salary-label">This month:</p>
<p class="salary-amount">${{ salaryInfo.thisMonth }}</p>
</div>
</div>
</div>
<!-- Team Member 卡片 -->
<div class="team-member-section">
<div class="team-member-card" @click="goToTeamMember">
<div class="card-content">
<span class="member-title">
Team Member
<span v-if="loadingMemberCount">(Loading...)</span>
<span v-else>({{ teamMemberCount }})</span>
</span>
<span class="arrow">></span>
</div>
</div>
</div>
<!-- 操作按钮 -->
<div class="action-buttons">
<button class="action-btn exchange-btn" @click="exchangeGoldCoins">
Exchange
</button>
<button class="action-btn transfer-btn" @click="transfer">
Transfer
</button>
</div>
</div>
</div>
</template>
<script setup>
import { ref } from 'vue'
import { useRouter } from 'vue-router'
import MobileHeader from '../components/MobileHeader.vue'
import {getAgentMonthLastTarget, getAgentMonthTarget, getBdAgentList} from '../api/teamBill.js'
import { getTeamId } from '@/utils/userStore.js'
import {usePageInitializationWithConfig} from "@/utils/pageConfig.js";
import {isInApp} from "@/utils/appBridge.js";
const router = useRouter()
// 当前身份
const teamMemberCount = ref(0)
const loadingMemberCount = ref(false)
const getAgentMonth = async () => {
const res = await getAgentMonthTarget()
if (res.status === true) {
salaryInfo.thisMonth = res.body.thisMonthTotalTarget
teamMemberCount.value = res.body.agentQuantity
}
const res2 = await getAgentMonthLastTarget()
if (res2.status === true) {
salaryInfo.lastMonth = res.body.thisMonthTotalTarget
}
}
const goToTeamMember = () => {
router.push({ path: '/team-member', query: { source: 'bd-center', members: teamMemberCount.value } })
}
const exchangeGoldCoins = () => {
router.push('/exchange-gold-coins')
}
const transfer = () => {
router.push('/transfer')
}
const {
appConnected,
userInfo,
salaryInfo,
handleImageError,
getAvatarPlaceholder
} = usePageInitializationWithConfig('BD_CENTER', {
needsTeamInfo: true,
onDataLoaded: () => {
getAgentMonth()
}
})
</script>
<style scoped>
.bd-center {
font-family: -apple-system, BlinkMacSystemFont, sans-serif;
}
.content {
padding: 16px;
position: relative;
z-index: 2;
}
/* 用户信息卡片 */
.user-card {
background-color: white;
padding: 16px;
border-radius: 12px;
margin-bottom: 12px;
box-shadow: 0 2px 8px rgba(0,0,0,0.1);
}
/* APP连接状态 */
.app-status {
display: flex;
align-items: center;
gap: 8px;
padding: 8px 12px;
border-radius: 8px;
margin-bottom: 12px;
font-size: 12px;
font-weight: 500;
}
.app-status.connecting {
background-color: #fef3c7;
color: #d97706;
}
.app-status.connected {
background-color: #d1fae5;
color: #059669;
}
.status-indicator {
width: 8px;
height: 8px;
border-radius: 50%;
background-color: currentColor;
}
.app-status.connecting .status-indicator {
animation: pulse 1.5s ease-in-out infinite;
}
@keyframes pulse {
0%, 100% {
opacity: 1;
}
50% {
opacity: 0.5;
}
}
.user-info {
display: flex;
align-items: center;
margin-bottom: 12px;
}
.avatar {
width: 50px;
height: 50px;
border-radius: 25px;
background-color: #8B5CF6;
display: flex;
align-items: center;
justify-content: center;
color: white;
font-size: 20px;
font-weight: 600;
margin-right: 12px;
overflow: hidden;
position: relative;
}
.avatar img {
width: 100%;
height: 100%;
object-fit: cover;
border-radius: 25px;
}
.avatar .avatar-placeholder {
color: white;
font-size: 20px;
font-weight: 600;
}
.user-details {
flex: 1;
}
.user-details h3 {
margin: 0 0 4px 0;
font-size: 16px;
font-weight: 600;
color: #333;
}
.user-details p {
margin: 0;
font-size: 14px;
color: #666;
}
.system-info {
font-size: 12px !important;
color: #8B5CF6 !important;
margin-top: 2px !important;
}
.notification-btn {
width: 32px;
height: 32px;
border: none;
background: none;
font-size: 16px;
cursor: pointer;
}
.account-tags {
display: flex;
gap: 8px;
}
.tag {
padding: 4px 12px;
border-radius: 16px;
font-size: 12px;
font-weight: 600;
}
.bd-tag {
background-color: #E0E7FF;
color: #5B21B6;
}
/* Total team salary 区域 */
.salary-section {
background-color: white;
padding: 16px;
border-radius: 12px;
margin-bottom: 12px;
box-shadow: 0 2px 8px rgba(0,0,0,0.1);
}
.salary-section h3 {
margin: 0 0 16px 0;
font-size: 16px;
font-weight: 600;
color: #333;
}
.salary-content {
display: flex;
align-items: center;
gap: 20px;
}
.salary-item {
flex: 1;
text-align: center;
}
.salary-label {
margin: 0 0 8px 0;
font-size: 14px;
color: #666;
}
.salary-amount {
margin: 0;
font-size: 20px;
font-weight: 600;
color: #333;
}
.salary-separator {
width: 1px;
height: 40px;
background-color: #8B5CF6;
}
/* Team Member 独立区域 */
.team-member-section {
margin-bottom: 16px;
}
.team-member-card {
background-color: white;
border-radius: 12px;
box-shadow: 0 2px 8px rgba(0,0,0,0.1);
cursor: pointer;
transition: all 0.2s;
border: 1px solid #e5e7eb;
}
.team-member-card:active {
transform: scale(0.98);
}
.team-member-card .card-content {
display: flex;
justify-content: space-between;
align-items: center;
padding: 16px;
}
.member-title {
font-size: 16px;
font-weight: 600;
color: #1F2937;
}
/* 操作按钮 */
.action-buttons {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 12px;
}
.action-btn {
padding: 14px 12px;
border: none;
border-radius: 12px;
font-size: 14px;
font-weight: 600;
cursor: pointer;
text-align: center;
line-height: 1.2;
transition: all 0.2s;
width: 100%;
}
.action-btn:active {
transform: scale(0.98);
}
.exchange-btn {
background-color: #FDE68A;
color: #D97706;
}
.transfer-btn {
background-color: #8B5CF6;
color: white;
}
/* 通用箭头样式 */
.arrow {
font-size: 16px;
font-weight: bold;
color: #8B5CF6;
}
</style>