first commit
This commit is contained in:
360
src/pages/me.vue
Normal file
360
src/pages/me.vue
Normal file
@@ -0,0 +1,360 @@
|
||||
<script setup>
|
||||
import { storeToRefs } from 'pinia'
|
||||
import { computed, onBeforeMount, ref, watch } from 'vue'
|
||||
import { openCustomerService } from '@/composables/useCustomerService'
|
||||
import { useEnv } from '@/composables/useEnv'
|
||||
import { useAgentStore } from '@/stores/agentStore'
|
||||
import { useDialogStore } from '@/stores/dialogStore'
|
||||
import { useUserStore } from '@/stores/userStore'
|
||||
import headShot from '/static/images/head_shot.webp'
|
||||
|
||||
definePage({ layout: 'home' })
|
||||
|
||||
const agentStore = useAgentStore()
|
||||
const userStore = useUserStore()
|
||||
const dialogStore = useDialogStore()
|
||||
const { isAgent, level, ExpiryTime } = storeToRefs(agentStore)
|
||||
const { userAvatar, isLoggedIn, mobile } = storeToRefs(userStore)
|
||||
const { isWeChat } = useEnv()
|
||||
|
||||
const levelNames = {
|
||||
'normal': '普通代理',
|
||||
'': '普通代理',
|
||||
'VIP': 'VIP代理',
|
||||
'SVIP': 'SVIP代理',
|
||||
}
|
||||
|
||||
const levelText = {
|
||||
'normal': '基础代理特权',
|
||||
'': '基础代理特权',
|
||||
'VIP': '高级代理特权',
|
||||
'SVIP': '尊享代理特权',
|
||||
}
|
||||
|
||||
const levelGradient = computed(() => ({
|
||||
border: {
|
||||
'normal': '',
|
||||
'': '',
|
||||
'VIP': '',
|
||||
'SVIP': '',
|
||||
}[level.value],
|
||||
|
||||
badge: {
|
||||
'normal': 'bg-gradient-to-r from-gray-500 to-gray-600',
|
||||
'': 'bg-gradient-to-r from-gray-500 to-gray-600',
|
||||
'VIP': 'bg-gradient-to-r from-yellow-500 to-amber-600',
|
||||
'SVIP': 'bg-gradient-to-r from-purple-500 to-pink-500',
|
||||
}[level.value],
|
||||
|
||||
text: {
|
||||
'normal': 'text-gray-600',
|
||||
'': 'text-gray-600',
|
||||
'VIP': 'text-amber-600',
|
||||
'SVIP': 'text-purple-600',
|
||||
}[level.value],
|
||||
}))
|
||||
|
||||
function maskName(name) {
|
||||
if (!name || name.length < 11)
|
||||
return name
|
||||
return `${name.substring(0, 3)}****${name.substring(7)}`
|
||||
}
|
||||
|
||||
function toHistory() {
|
||||
uni.navigateTo({ url: '/pages/history-query' })
|
||||
}
|
||||
function toPromote() {
|
||||
uni.navigateTo({ url: '/pages/promote' })
|
||||
}
|
||||
function toInvitation() {
|
||||
uni.navigateTo({ url: '/pages/invitation' })
|
||||
}
|
||||
function toUserAgreement() {
|
||||
uni.navigateTo({ url: '/pages/user-agreement' })
|
||||
}
|
||||
|
||||
function toPrivacyPolicy() {
|
||||
uni.navigateTo({ url: '/pages/privacy-policy' })
|
||||
}
|
||||
|
||||
function redirectToLogin() {
|
||||
uni.navigateTo({ url: '/pages/login' })
|
||||
}
|
||||
|
||||
function handleLogout() {
|
||||
uni.removeStorageSync('token')
|
||||
uni.removeStorageSync('refreshAfter')
|
||||
uni.removeStorageSync('accessExpire')
|
||||
uni.removeStorageSync('userInfo')
|
||||
uni.removeStorageSync('agentInfo')
|
||||
|
||||
// 重置状态
|
||||
userStore.resetUser()
|
||||
agentStore.resetAgent()
|
||||
|
||||
uni.reLaunch({ url: '/pages/index' })
|
||||
}
|
||||
|
||||
function goCancelAccountPage() {
|
||||
if (!mobile.value) {
|
||||
uni.showToast({ title: '请先绑定手机号', icon: 'none' })
|
||||
return
|
||||
}
|
||||
uni.navigateTo({ url: '/pages/cancel-account' })
|
||||
}
|
||||
|
||||
function toService() {
|
||||
openCustomerService()
|
||||
}
|
||||
|
||||
function toVipConfig() {
|
||||
uni.navigateTo({ url: '/pages/agent-vip-config' })
|
||||
}
|
||||
|
||||
function toVipRenewal() {
|
||||
uni.navigateTo({ url: '/pages/agent-vip-apply' })
|
||||
}
|
||||
|
||||
function formatExpiryTime(expiryTimeStr) {
|
||||
if (!expiryTimeStr)
|
||||
return '未知'
|
||||
// 假设expiryTimeStr格式是 "YYYY-MM-DD HH:MM:SS"
|
||||
// 只返回日期部分 "YYYY-MM-DD"
|
||||
return expiryTimeStr.split(' ')[0]
|
||||
}
|
||||
|
||||
/** 与 bdrp-mini `/static/image/shot_*.png` 一致,资源放在 `src/static/image/` */
|
||||
function getDefaultAvatar() {
|
||||
if (!isAgent.value)
|
||||
return headShot
|
||||
|
||||
const normalizedLevel = String(level.value || '').toUpperCase()
|
||||
switch (normalizedLevel) {
|
||||
case 'NORMAL':
|
||||
case 'normal':
|
||||
case '':
|
||||
return '/static/image/shot_nonal.png'
|
||||
case 'VIP':
|
||||
return '/static/image/shot_vip.png'
|
||||
case 'SVIP':
|
||||
return '/static/image/shot_svip.png'
|
||||
default:
|
||||
return headShot
|
||||
}
|
||||
}
|
||||
|
||||
/** 用户头像 URL(store 已 resolve);默认图为本地资源,加载失败时回退到 headShot */
|
||||
const avatarDisplay = ref(headShot)
|
||||
|
||||
function syncAvatarDisplay() {
|
||||
avatarDisplay.value = userAvatar.value || getDefaultAvatar()
|
||||
}
|
||||
|
||||
watch([userAvatar, isAgent, level], syncAvatarDisplay, { immediate: true })
|
||||
|
||||
function onAvatarError() {
|
||||
avatarDisplay.value = headShot
|
||||
}
|
||||
|
||||
function showBindPhoneDialog() {
|
||||
dialogStore.openBindPhone()
|
||||
}
|
||||
|
||||
onBeforeMount(() => {
|
||||
// 获取存储的用户和代理信息
|
||||
const userInfo = uni.getStorageSync('userInfo')
|
||||
if (userInfo) {
|
||||
try {
|
||||
const parsedUserInfo = typeof userInfo === 'string' ? JSON.parse(userInfo) : userInfo
|
||||
userStore.updateUserInfo(parsedUserInfo)
|
||||
}
|
||||
catch (e) {
|
||||
console.error('解析用户信息失败', e)
|
||||
}
|
||||
}
|
||||
|
||||
const agentInfo = uni.getStorageSync('agentInfo')
|
||||
if (agentInfo) {
|
||||
try {
|
||||
const parsedAgentInfo = typeof agentInfo === 'string' ? JSON.parse(agentInfo) : agentInfo
|
||||
agentStore.updateAgentInfo(parsedAgentInfo)
|
||||
}
|
||||
catch (e) {
|
||||
console.error('解析代理信息失败', e)
|
||||
}
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<view class="box-border min-h-screen">
|
||||
<view class="flex flex-col p-4 space-y-6">
|
||||
<!-- 用户信息卡片 -->
|
||||
<view
|
||||
class="group profile-section relative flex items-center gap-4 rounded-xl bg-white p-6 transition-all hover:shadow-xl"
|
||||
@click="!isLoggedIn ? redirectToLogin() : null">
|
||||
<view class="relative">
|
||||
<!-- 头像容器添加overflow-hidden解决边框问题 -->
|
||||
<view class="overflow-hidden rounded-full p-0.5" :class="levelGradient.border">
|
||||
<image :src="avatarDisplay" mode="aspectFill" alt="User Avatar"
|
||||
class="h-24 w-24 border-4 border-white rounded-full" @error="onAvatarError" />
|
||||
</view>
|
||||
|
||||
<!-- 代理标识 -->
|
||||
<view v-if="isAgent" class="absolute -bottom-2 -right-2">
|
||||
<view class="flex items-center justify-center rounded-full px-3 py-1 text-xs text-white font-bold shadow-sm"
|
||||
:class="levelGradient.badge">
|
||||
{{ levelNames[level] }}
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="space-y-1">
|
||||
<view class="text-2xl text-gray-800 font-bold">
|
||||
{{
|
||||
!isLoggedIn
|
||||
? "点击登录"
|
||||
: mobile
|
||||
? maskName(mobile)
|
||||
: isWeChat
|
||||
? "微信用户"
|
||||
: "未绑定手机号"
|
||||
}}
|
||||
</view>
|
||||
<!-- 手机号绑定提示 -->
|
||||
<template v-if="isLoggedIn && !mobile">
|
||||
<view class="cursor-pointer text-sm text-blue-500 hover:underline" @click.stop="showBindPhoneDialog">
|
||||
点击绑定手机号码
|
||||
</view>
|
||||
</template>
|
||||
<view v-if="isAgent" class="text-sm font-medium" :class="levelGradient.text">
|
||||
🎖️ {{ levelText[level] }}
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<VipBanner v-if="isAgent && (level === 'normal' || level === '')" />
|
||||
<!-- 功能菜单 -->
|
||||
<view>
|
||||
<view class="overflow-hidden rounded-xl bg-white shadow-sm">
|
||||
<template v-if="isAgent && ['VIP', 'SVIP'].includes(level)">
|
||||
<view
|
||||
class="w-full flex items-center justify-between border-b border-gray-100 px-6 py-4 transition-colors hover:bg-purple-50"
|
||||
@click="toVipConfig">
|
||||
<view class="flex items-center gap-3">
|
||||
<image src="/static/images/me/dlbgpz.png" class="h-6 w-6" alt="代理报告配置" />
|
||||
<text class="text-purple-700 font-medium">
|
||||
代理报告配置
|
||||
</text>
|
||||
</view>
|
||||
<image src="/static/images/me/right.png" class="h-4 w-4" alt="右箭头" />
|
||||
</view>
|
||||
<view
|
||||
class="w-full flex items-center justify-between border-b border-gray-100 px-6 py-4 transition-colors hover:bg-amber-50"
|
||||
@click="toVipRenewal">
|
||||
<view class="flex items-center gap-3">
|
||||
<image src="/static/images/me/xfhy.png" class="h-6 w-6" alt="代理会员" />
|
||||
<view class="flex flex-col items-start">
|
||||
<text class="text-amber-700 font-medium">
|
||||
续费代理会员
|
||||
</text>
|
||||
<text class="text-xs text-gray-500">
|
||||
有效期至 {{ formatExpiryTime(ExpiryTime) }}
|
||||
</text>
|
||||
</view>
|
||||
</view>
|
||||
<image src="/static/images/me/right.png" class="h-4 w-4" alt="右箭头" />
|
||||
</view>
|
||||
</template>
|
||||
<view
|
||||
class="w-full flex items-center justify-between border-b border-gray-100 px-6 py-4 transition-colors hover:bg-blue-50"
|
||||
@click="toPromote">
|
||||
<view class="flex items-center gap-3">
|
||||
<image src="/static/images/index/tgbg.png" class="h-6 w-6" alt="推广报告" />
|
||||
<text class="text-gray-700 font-medium">
|
||||
推广报告
|
||||
</text>
|
||||
</view>
|
||||
<image src="/static/images/me/right.png" class="h-4 w-4" alt="右箭头" />
|
||||
</view>
|
||||
<view
|
||||
class="w-full flex items-center justify-between border-b border-gray-100 px-6 py-4 transition-colors hover:bg-blue-50"
|
||||
@click="toInvitation">
|
||||
<view class="flex items-center gap-3">
|
||||
<image src="/static/images/index/yqhy.png" class="h-6 w-6" alt="邀请下级" />
|
||||
<text class="text-gray-700 font-medium">
|
||||
邀请下级
|
||||
</text>
|
||||
</view>
|
||||
<image src="/static/images/me/right.png" class="h-4 w-4" alt="右箭头" />
|
||||
</view>
|
||||
<view
|
||||
class="w-full flex items-center justify-between border-b border-gray-100 px-6 py-4 transition-colors hover:bg-blue-50"
|
||||
@click="toHistory">
|
||||
<view class="flex items-center gap-3">
|
||||
<image src="/static/images/index/wdbg.png" class="h-6 w-6" alt="我的报告" />
|
||||
<text class="text-gray-700 font-medium">
|
||||
我的报告
|
||||
</text>
|
||||
</view>
|
||||
<image src="/static/images/me/right.png" class="h-4 w-4" alt="右箭头" />
|
||||
</view>
|
||||
<view
|
||||
class="w-full flex items-center justify-between border-b border-gray-100 px-6 py-4 transition-colors hover:bg-blue-50"
|
||||
@click="toUserAgreement">
|
||||
<view class="flex items-center gap-3">
|
||||
<image src="/static/images/me/yhxy.png" class="h-6 w-6" alt="用户协议" />
|
||||
<text class="text-gray-700 font-medium">
|
||||
用户协议
|
||||
</text>
|
||||
</view>
|
||||
<image src="/static/images/me/right.png" class="h-4 w-4" alt="右箭头" />
|
||||
</view>
|
||||
<view
|
||||
class="w-full flex items-center justify-between border-b border-gray-100 px-6 py-4 transition-colors hover:bg-blue-50"
|
||||
@click="toPrivacyPolicy">
|
||||
<view class="flex items-center gap-3">
|
||||
<image src="/static/images/me/yszc.png" class="h-6 w-6" alt="隐私政策" />
|
||||
<text class="text-gray-700 font-medium">
|
||||
隐私政策
|
||||
</text>
|
||||
</view>
|
||||
<image src="/static/images/me/right.png" class="h-4 w-4" alt="右箭头" />
|
||||
</view>
|
||||
<view class="w-full flex items-center justify-between px-6 py-4 transition-colors hover:bg-blue-50"
|
||||
@click="toService">
|
||||
<view class="flex items-center gap-3">
|
||||
<image src="/static/images/me/lxkf.png" class="h-6 w-6" alt="联系客服" />
|
||||
<text class="text-gray-700 font-medium">
|
||||
联系客服
|
||||
</text>
|
||||
</view>
|
||||
<image src="/static/images/me/right.png" class="h-4 w-4" alt="右箭头" />
|
||||
</view>
|
||||
<view v-if="isLoggedIn && mobile"
|
||||
class="w-full flex items-center justify-between border-b border-gray-100 px-6 py-4 transition-colors hover:bg-red-50"
|
||||
@click="goCancelAccountPage">
|
||||
<view class="flex items-center gap-3">
|
||||
<image src="/static/images/me/cancelAccount.svg" class="h-6 w-6" alt="注销账号" />
|
||||
<text class="text-gray-700 font-medium">
|
||||
注销账号
|
||||
</text>
|
||||
</view>
|
||||
<image src="/static/images/me/right.png" class="h-4 w-4" alt="右箭头" />
|
||||
</view>
|
||||
<view v-if="isLoggedIn && !isWeChat"
|
||||
class="w-full flex items-center justify-between px-6 py-4 transition-colors hover:bg-red-50"
|
||||
@click="handleLogout">
|
||||
<view class="flex items-center gap-3">
|
||||
<image src="/static/images/me/tcdl.png" class="h-6 w-6" alt="退出登录" />
|
||||
<text class="text-gray-700 font-medium">
|
||||
退出登录
|
||||
</text>
|
||||
</view>
|
||||
<image src="/static/images/me/right.png" class="h-4 w-4" alt="右箭头" />
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<style scoped></style>
|
||||
Reference in New Issue
Block a user