318 lines
9.0 KiB
Vue
318 lines
9.0 KiB
Vue
<template>
|
||
<view class="safe-area-top box-border min-h-screen">
|
||
<view class="flex flex-col p-4 space-y-6">
|
||
<!-- 用户信息卡片 -->
|
||
<view
|
||
class="mb-4 profile-section group relative flex items-center gap-4 rounded-xl bg-white p-6 shadow-lg transition-all hover:shadow-xl"
|
||
@click="!isLoggedIn ? redirectToLogin() : null">
|
||
<view class="relative">
|
||
<!-- 头像容器添加overflow-hidden解决边框问题 -->
|
||
<view class="flex items-center justify-center overflow-hidden rounded-full p-0.5"
|
||
:class="levelGradient.border">
|
||
<image :src="userAvatar || getDefaultAvatar()" alt="User Avatar"
|
||
class="h-24 w-24 rounded-full border-4 border-white">
|
||
</image>
|
||
</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 font-bold text-white shadow-sm"
|
||
:class="levelGradient.badge">
|
||
{{ levelNames[level] }}
|
||
</view>
|
||
</view>
|
||
</view>
|
||
<view class="space-y-1">
|
||
<!-- @click.stop="handleVersionClickForTest" -->
|
||
<view class="text-lg font-bold text-gray-800" @click="userType === 0 ? toBindPhone() : null"
|
||
:class="userType === 0 ? 'cursor-pointer text-blue-600' : ''">
|
||
{{ !isLoggedIn ? '点击登录' : (userType === 0 ? '绑定手机号' : maskName(userName)) }}
|
||
</view>
|
||
<view v-if="isAgent" class="text-sm font-medium" :class="levelGradient.text">
|
||
🎖️ {{ levelText[level] }}
|
||
</view>
|
||
</view>
|
||
</view>
|
||
|
||
<VipBanner v-if="isLoggedIn && !isVipOrSvip" />
|
||
<!-- 功能菜单 -->
|
||
<view class="features-section space-y-3">
|
||
<!-- 代理报告配置 + 续费:VIP/SVIP 代理 -->
|
||
<template v-if="isLoggedIn && isAgent && isVipOrSvip">
|
||
<button
|
||
class=" flex items-center p-3 rounded-xl bg-gradient-to-r from-purple-200/80 to-pink-200/80 text-purple-700 font-medium shadow-sm transition-all active:shadow-md"
|
||
hover-class="opacity-80 scale-98" @click="toVipConfig">
|
||
<text class="mr-2">⚙️</text> 代理报告配置
|
||
</button>
|
||
<button
|
||
class="flex flex-col items-start p-3 rounded-xl bg-gradient-to-r from-amber-200/80 to-orange-200/80 text-amber-700 font-medium shadow-sm transition-all active:shadow-md"
|
||
hover-class="opacity-80 scale-98" @click="toVipRenewal">
|
||
<view class="flex items-center">
|
||
<text class="mr-2">🔄</text> 续费代理会员
|
||
</view>
|
||
<view v-if="ExpiryTime" class="text-xs text-gray-500 mt-1 ml-6">有效期至 {{ formatExpiryTime(ExpiryTime) }}</view>
|
||
</button>
|
||
</template>
|
||
<!-- 升级/开通代理会员:登录后显示,非代理→申请,普通代理→升级 -->
|
||
<button
|
||
class=" flex items-center text-gray-600 p-3 rounded-xl bg-white font-medium shadow-sm transition-all active:shadow-md"
|
||
hover-class="opacity-80 bg-blue-50" @click="toUserAgreement">
|
||
<text class="mr-2">📜</text> 用户协议
|
||
</button>
|
||
<button
|
||
class=" flex items-center text-gray-600 p-3 rounded-xl bg-white font-medium shadow-sm transition-all active:shadow-md"
|
||
hover-class="opacity-80 bg-blue-50" @click="toPrivacyPolicy">
|
||
<text class="mr-2">🔒</text> 隐私政策
|
||
</button>
|
||
<button open-type="contact"
|
||
class=" flex items-center text-gray-600 p-3 rounded-xl bg-white font-medium shadow-sm transition-all active:shadow-md"
|
||
hover-class="opacity-80 bg-blue-50" @click="toAi">
|
||
<text class="mr-2">💬</text> 联系客服
|
||
</button>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 更新进度弹窗 -->
|
||
<view v-if="showUpdateProgress" class="update-progress-mask">
|
||
<view class="update-progress-dialog">
|
||
<view class="update-progress-title">应用更新中</view>
|
||
<view class="update-progress-bar-container">
|
||
<view class="update-progress-bar" :style="{ width: downloadProgress + '%' }"></view>
|
||
</view>
|
||
<view class="update-progress-text">{{ downloadProgress }}%</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</template>
|
||
|
||
<script setup>
|
||
import { ref, computed, onBeforeMount } from 'vue'
|
||
import { maskName, formatExpiryTime } from '@/utils/format'
|
||
|
||
// 分享给好友、分享到朋友圈
|
||
useShare({ title: '天远数据 - 大数据报告查询' })
|
||
|
||
// 用户数据
|
||
const userName = ref('')
|
||
const userAvatar = ref('')
|
||
const isLoggedIn = ref(false)
|
||
const userType = ref(null)
|
||
|
||
// 代理数据
|
||
const isAgent = ref(false)
|
||
const level = ref('normal')
|
||
const ExpiryTime = ref('')
|
||
|
||
|
||
const showUpdateProgress = ref(false)
|
||
|
||
// 检查平台环境
|
||
onBeforeMount(() => {
|
||
// 从缓存获取用户信息
|
||
const token = uni.getStorageSync('token')
|
||
if (token) {
|
||
isLoggedIn.value = true
|
||
// 从缓存获取用户信息
|
||
const userInfo = uni.getStorageSync('userInfo')
|
||
console.log("userInfo", userInfo)
|
||
if (userInfo) {
|
||
userName.value = userInfo.nickName || userInfo.mobile || '微信用户'
|
||
userAvatar.value = userInfo.avatar || ''
|
||
userType.value = userInfo.userType
|
||
}
|
||
|
||
// 从缓存获取代理信息
|
||
const agentInfo = uni.getStorageSync('agentInfo')
|
||
if (agentInfo?.isAgent) {
|
||
isAgent.value = agentInfo.isAgent
|
||
level.value = agentInfo.level || 'normal'
|
||
ExpiryTime.value = agentInfo.expiryTime || ''
|
||
}
|
||
}
|
||
})
|
||
|
||
|
||
const levelNames = {
|
||
normal: '普通代理',
|
||
'': '普通代理',
|
||
VIP: 'VIP代理',
|
||
SVIP: 'SVIP代理',
|
||
}
|
||
|
||
const levelText = {
|
||
normal: '基础代理特权',
|
||
'': '基础代理特权',
|
||
VIP: '高级代理特权',
|
||
SVIP: '尊享代理特权',
|
||
}
|
||
|
||
const isVipOrSvip = computed(() => {
|
||
const l = (level.value || '').toString()
|
||
return ['VIP', 'SVIP'].includes(l)
|
||
})
|
||
|
||
const levelGradient = computed(() => ({
|
||
border: {
|
||
normal: 'bg-green-300',
|
||
'': 'bg-green-300',
|
||
VIP: 'bg-gradient-to-r from-yellow-400 to-amber-500',
|
||
SVIP: 'bg-gradient-to-r from-purple-400 to-pink-400 shadow-[0_0_15px_rgba(163,51,200,0.2)]',
|
||
}[level.value],
|
||
|
||
badge: {
|
||
normal: 'bg-green-500',
|
||
'': 'bg-green-500',
|
||
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-green-600',
|
||
'': 'text-green-600',
|
||
VIP: 'text-amber-600',
|
||
SVIP: 'text-purple-600',
|
||
}[level.value],
|
||
}))
|
||
|
||
function toHistory() {
|
||
uni.navigateTo({
|
||
url: '/pages/queryHistory'
|
||
})
|
||
}
|
||
|
||
function toUserAgreement() {
|
||
uni.navigateTo({
|
||
url: '/pages/agreement?type=user'
|
||
})
|
||
}
|
||
|
||
function redirectToLogin() {
|
||
uni.navigateTo({
|
||
url: '/pages/login'
|
||
})
|
||
}
|
||
|
||
const toPrivacyPolicy = () => {
|
||
uni.navigateTo({
|
||
url: '/pages/agreement?type=privacy'
|
||
})
|
||
}
|
||
|
||
const toAi = () => {
|
||
uni.switchTab({
|
||
url: '/pages/ai'
|
||
})
|
||
}
|
||
|
||
|
||
function toVipConfig() {
|
||
uni.navigateTo({
|
||
url: '/pages/agentVipConfig'
|
||
})
|
||
}
|
||
|
||
function toVipRenewal() {
|
||
uni.navigateTo({ url: '/pages/agentVipApply' })
|
||
}
|
||
|
||
function toBindPhone() {
|
||
uni.navigateTo({
|
||
url: '/pages/login'
|
||
})
|
||
}
|
||
const getDefaultAvatar = () => {
|
||
if (!isAgent.value) return '/static/image/head_shot.webp'
|
||
|
||
switch (level.value) {
|
||
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 '/static/image/head_shot.webp'
|
||
}
|
||
}
|
||
</script>
|
||
|
||
<style scoped>
|
||
.profile-section {
|
||
background: linear-gradient(135deg, #ffffff 50%, rgba(236, 253, 245, 0.3));
|
||
border: 1px solid rgba(209, 213, 219, 0.2);
|
||
}
|
||
|
||
.profile-section .relative>view:first-child {
|
||
transition: all 0.3s ease;
|
||
}
|
||
|
||
.border-gradient-to-r {
|
||
border-image: linear-gradient(to right, var(--tw-gradient-from), var(--tw-gradient-to)) 1;
|
||
}
|
||
|
||
.shadow-glow {
|
||
box-shadow: 0 0 8px rgba(163, 51, 200, 0.2);
|
||
}
|
||
|
||
/* 更新进度样式 */
|
||
.update-progress-mask {
|
||
position: fixed;
|
||
top: 0;
|
||
left: 0;
|
||
right: 0;
|
||
bottom: 0;
|
||
background-color: rgba(0, 0, 0, 0.5);
|
||
display: flex;
|
||
justify-content: center;
|
||
align-items: center;
|
||
z-index: 9999;
|
||
}
|
||
|
||
.update-progress-dialog {
|
||
width: 80%;
|
||
background-color: white;
|
||
border-radius: 12px;
|
||
padding: 20px;
|
||
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
|
||
}
|
||
|
||
.update-progress-title {
|
||
font-size: 18px;
|
||
font-weight: bold;
|
||
text-align: center;
|
||
margin-bottom: 16px;
|
||
color: #333;
|
||
}
|
||
|
||
.update-progress-bar-container {
|
||
height: 10px;
|
||
background-color: #f0f0f0;
|
||
border-radius: 5px;
|
||
overflow: hidden;
|
||
margin-bottom: 8px;
|
||
}
|
||
|
||
.update-progress-bar {
|
||
height: 100%;
|
||
background: linear-gradient(to right, #4299e1, #667eea);
|
||
border-radius: 5px;
|
||
transition: width 0.3s ease;
|
||
}
|
||
|
||
.update-progress-text {
|
||
text-align: center;
|
||
font-size: 14px;
|
||
color: #666;
|
||
}
|
||
</style>
|
||
|
||
<route lang="json">{
|
||
"layout": "home",
|
||
"style": {
|
||
"navigationBarTextStyle": "black",
|
||
"navigationStyle": "default",
|
||
"navigationBarBackgroundColor": "#e3f0ff"
|
||
}
|
||
}</route>
|