488 lines
24 KiB
Vue
488 lines
24 KiB
Vue
<template>
|
||
<div class="box-border min-h-screen">
|
||
<div class="flex flex-col p-4 space-y-6">
|
||
<!-- 用户信息和资产卡片(合并) -->
|
||
<div class="profile-section group relative rounded-xl p-0.5 transition-all hover:shadow-xl"
|
||
:class="isAgent ? levelGradient.cardBorder : 'bg-gray-200'"
|
||
@click="!isLoggedIn ? redirectToLogin() : null">
|
||
<div class="rounded-xl bg-white p-6">
|
||
<!-- 上半部分:用户信息 -->
|
||
<div class="flex items-center gap-4 mb-4">
|
||
<div class="relative">
|
||
<!-- 头像容器添加overflow-hidden解决边框问题 -->
|
||
<div class="overflow-hidden rounded-full p-0.5" :class="levelGradient.border">
|
||
<img :src="userAvatar || getDefaultAvatar()" alt="User Avatar"
|
||
class="h-20 w-20 rounded-full border-4 border-white" />
|
||
</div>
|
||
|
||
<!-- 代理标识 -->
|
||
<div v-if="isAgent" class="absolute -bottom-2 -right-2">
|
||
<div class="flex items-center justify-center rounded-full px-3 py-1 text-xs font-bold text-white shadow-sm"
|
||
:class="levelGradient.badge">
|
||
{{ levelNamesMap[level] || levelNamesMap[1] }}
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="flex-1 space-y-1">
|
||
<h2 class="text-2xl font-bold" style="color: var(--van-text-color);">
|
||
{{
|
||
!isLoggedIn
|
||
? "点击登录"
|
||
: mobile
|
||
? mobile
|
||
: isWeChat
|
||
? "微信用户"
|
||
: "未绑定手机号"
|
||
}}
|
||
</h2>
|
||
<!-- 手机号绑定提示 -->
|
||
<template v-if="isLoggedIn && !mobile">
|
||
<p @click.stop="showRegisterAgentDialog" class="text-sm cursor-pointer hover:underline"
|
||
style="color: var(--van-theme-primary);">
|
||
点击注册成为代理
|
||
</p>
|
||
</template>
|
||
<!-- 普通用户申请成为代理提示 -->
|
||
<template v-else-if="isLoggedIn && mobile && !isAgent">
|
||
<p @click.stop="toRegister" class="text-sm cursor-pointer hover:underline"
|
||
style="color: var(--van-theme-primary);">
|
||
点击申请成为代理
|
||
</p>
|
||
</template>
|
||
<p v-if="isAgent" class="font-bold" :class="levelGradient.text">
|
||
ID: {{ agentCode }}
|
||
</p>
|
||
</div>
|
||
<!-- 右侧资产信息(仅代理显示) -->
|
||
<div v-if="isAgent" class="text-right">
|
||
<div class="text-sm mb-1" style="color: var(--van-text-color-2);">余额</div>
|
||
<div class="text-2xl font-bold"
|
||
:style="(revenueData?.balance || 0) < 0 ? 'color: #ef4444;' : 'color: var(--van-theme-primary);'">
|
||
¥ {{ (revenueData?.balance || 0).toFixed(2) }}
|
||
</div>
|
||
<!-- 负数余额提示 -->
|
||
<div v-if="(revenueData?.balance || 0) < 0" class="text-xs mt-1" style="color: #ef4444;">
|
||
账户存在欠款,需补足后才能提现
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<!-- 下半部分:资产详情和操作按钮(仅代理显示) -->
|
||
<template v-if="isAgent">
|
||
<div class="grid grid-cols-3 gap-3 mb-4 pt-4 border-t"
|
||
style="border-color: var(--van-border-color);">
|
||
<div class="text-center">
|
||
<div class="text-sm mb-1" style="color: var(--van-text-color-2);">累计收益</div>
|
||
<div class="text-base font-semibold" style="color: var(--van-text-color);">
|
||
¥ {{ (revenueData?.total_earnings || 0).toFixed(2) }}
|
||
</div>
|
||
</div>
|
||
<div class="text-center">
|
||
<div class="text-sm mb-1" style="color: var(--van-text-color-2);">风险保障金</div>
|
||
<div class="text-base font-semibold" style="color: var(--van-text-color);">
|
||
¥ {{ (revenueData?.frozen_balance || 0).toFixed(2) }}
|
||
</div>
|
||
</div>
|
||
<div class="text-center">
|
||
<div class="text-sm mb-1" style="color: var(--van-text-color-2);">累计提现</div>
|
||
<div class="text-base font-semibold" style="color: var(--van-text-color);">
|
||
¥ {{ (revenueData?.withdrawn_amount || 0).toFixed(2) }}
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="grid grid-cols-2 gap-3">
|
||
<button @click.stop="toWithdraw"
|
||
class="text-white rounded-full py-1.5 px-4 shadow-md flex items-center justify-center text-base"
|
||
style="background: linear-gradient(135deg, var(--van-theme-primary), var(--van-theme-primary-dark)); min-height: 36px;">
|
||
<van-icon name="gold-coin" class="mr-1" />
|
||
提现
|
||
</button>
|
||
<button @click.stop="toWithdrawDetails"
|
||
class="bg-white/90 border rounded-full py-1.5 px-4 shadow-sm flex items-center justify-center text-base"
|
||
style="color: var(--van-text-color-2); border-color: var(--van-border-color); min-height: 36px;">
|
||
<van-icon name="notes" class="mr-1" />
|
||
提现记录
|
||
</button>
|
||
</div>
|
||
</template>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 佣金和下级推广收益(合并) -->
|
||
<div v-if="isAgent" class="rounded-xl shadow-lg bg-white p-5">
|
||
<div class="grid grid-cols-2 gap-4">
|
||
<!-- 我的推广收益部分 -->
|
||
<div class="pr-4 border-r" style="border-color: var(--van-border-color);">
|
||
<div class="flex items-center justify-between mb-3">
|
||
<div class="flex items-center">
|
||
<van-icon name="balance-list" class="text-lg mr-2"
|
||
style="color: var(--color-warning);" />
|
||
<span class="text-base font-bold" style="color: var(--van-text-color);">我的推广收益</span>
|
||
</div>
|
||
</div>
|
||
<div class="text-center mb-3">
|
||
<div class="text-xl font-bold" style="color: var(--color-warning);">
|
||
¥ {{ (revenueData?.commission_total || 0).toFixed(2) }}
|
||
</div>
|
||
<div class="text-sm mt-0.5" style="color: var(--van-text-color-2);">累计总收益</div>
|
||
</div>
|
||
<div class="grid grid-cols-2 gap-2 mb-3">
|
||
<div class="text-center">
|
||
<div class="text-sm mb-1" style="color: var(--van-text-color-2);">今日</div>
|
||
<div class="text-base font-semibold" style="color: var(--color-warning);">
|
||
¥ {{ (revenueData?.commission_today || 0).toFixed(2) }}
|
||
</div>
|
||
</div>
|
||
<div class="text-center">
|
||
<div class="text-sm mb-1" style="color: var(--van-text-color-2);">本月</div>
|
||
<div class="text-base font-semibold" style="color: var(--color-warning);">
|
||
¥ {{ (revenueData?.commission_month || 0).toFixed(2) }}
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="flex items-center justify-center text-sm font-semibold cursor-pointer"
|
||
style="color: var(--color-warning);" @click="goToPromoteDetail">
|
||
<span>查看明细</span>
|
||
<span class="ml-1 text-base">→</span>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 下级推广收益部分 -->
|
||
<div class="pl-4">
|
||
<div class="flex items-center justify-between mb-3">
|
||
<div class="flex items-center">
|
||
<van-icon name="gift-o" class="text-lg mr-2" style="color: var(--color-success);" />
|
||
<span class="text-base font-bold" style="color: var(--van-text-color);">下级推广收益</span>
|
||
</div>
|
||
</div>
|
||
<div class="text-center mb-3">
|
||
<div class="text-xl font-bold" style="color: var(--color-success);">
|
||
¥ {{ (revenueData?.rebate_total || 0).toFixed(2) }}
|
||
</div>
|
||
<div class="text-sm mt-0.5" style="color: var(--van-text-color-2);">累计总收益</div>
|
||
</div>
|
||
<div class="grid grid-cols-2 gap-2 mb-3">
|
||
<div class="text-center">
|
||
<div class="text-sm mb-1" style="color: var(--van-text-color-2);">今日</div>
|
||
<div class="text-base font-semibold" style="color: var(--color-success);">
|
||
¥ {{ (revenueData?.rebate_today || 0).toFixed(2) }}
|
||
</div>
|
||
</div>
|
||
<div class="text-center">
|
||
<div class="text-sm mb-1" style="color: var(--van-text-color-2);">本月</div>
|
||
<div class="text-base font-semibold" style="color: var(--color-success);">
|
||
¥ {{ (revenueData?.rebate_month || 0).toFixed(2) }}
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="flex items-center justify-center text-sm font-semibold cursor-pointer"
|
||
style="color: var(--color-success);" @click="goToRebateDetail">
|
||
<span>查看明细</span>
|
||
<span class="ml-1 text-base">→</span>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 功能菜单 -->
|
||
<div class="">
|
||
<div class="bg-white rounded-xl shadow-sm p-4">
|
||
<div class="grid grid-cols-4 gap-4">
|
||
<!-- 升级功能入口(如果不是钻石代理) -->
|
||
<button v-if="isAgent && level !== 3"
|
||
class="flex flex-col items-center justify-center gap-2 py-4 rounded-lg hover:bg-purple-50 transition-colors"
|
||
@click="toUpgrade">
|
||
<img src="@/assets/images/me/sjdl.svg" class="w-8 h-8 object-contain" alt="升级代理" />
|
||
<span class="text-xs text-gray-700 font-medium text-center">升级代理</span>
|
||
</button>
|
||
<!-- 升级下级入口(仅钻石代理) -->
|
||
<button v-if="isAgent && level === 3"
|
||
class="flex flex-col items-center justify-center gap-2 py-4 rounded-lg hover:bg-purple-50 transition-colors"
|
||
@click="toUpgradeSubordinate">
|
||
<img src="@/assets/images/me/sjxj.svg" class="w-8 h-8 object-contain" alt="调整下级级别" />
|
||
<span class="text-xs text-gray-700 font-medium text-center">调整级别</span>
|
||
</button>
|
||
<!-- 邀请码管理入口 -->
|
||
<button v-if="isAgent"
|
||
class="flex flex-col items-center justify-center gap-2 py-4 rounded-lg hover:bg-blue-50 transition-colors"
|
||
@click="toInviteCodeManage">
|
||
<img src="@/assets/images/me/yqmgl.svg" class="w-8 h-8 object-contain" alt="邀请码管理" />
|
||
<span class="text-xs text-gray-700 font-medium text-center">邀请码管理</span>
|
||
</button>
|
||
<!-- 实名认证入口(所有代理) -->
|
||
<button v-if="isAgent"
|
||
class="flex flex-col items-center justify-center gap-2 py-4 rounded-lg hover:bg-green-50 transition-colors"
|
||
@click="toRealNameAuth">
|
||
<img src="@/assets/images/me/smrz.svg" class="w-8 h-8 object-contain" alt="提现" />
|
||
<span class="text-xs text-gray-700 font-medium text-center">实名认证</span>
|
||
</button>
|
||
<!-- 提现入口(所有代理) -->
|
||
<!-- <button v-if="isAgent"
|
||
class="flex flex-col items-center justify-center gap-2 py-4 rounded-lg hover:bg-blue-50 transition-colors"
|
||
@click="toWithdraw">
|
||
<img src="@/assets/images/me/tx.svg" class="w-8 h-8 object-contain" alt="提现" />
|
||
<span class="text-xs text-gray-700 font-medium text-center">提现</span>
|
||
</button> -->
|
||
<button
|
||
class="flex flex-col items-center justify-center gap-2 py-4 rounded-lg hover:bg-purple-50 transition-colors"
|
||
@click="toAgentSystemGuide">
|
||
<img src="@/assets/images/me/yhxy.svg" class="w-8 h-8 object-contain" alt="代理系统指南" />
|
||
<span class="text-xs text-gray-700 font-medium text-center">代理系统指南</span>
|
||
</button>
|
||
<!-- 推广查询记录 -->
|
||
<button v-if="isAgent"
|
||
class="flex flex-col items-center justify-center gap-2 py-4 rounded-lg hover:bg-blue-50 transition-colors"
|
||
@click="toAgentReport">
|
||
<img src="@/assets/images/me/tgcxjl.svg" class="w-8 h-8 object-contain" alt="推广查询记录" />
|
||
<span class="text-xs text-gray-700 font-medium text-center">推广查询记录</span>
|
||
</button>
|
||
<button
|
||
class="flex flex-col items-center justify-center gap-2 py-4 rounded-lg hover:bg-blue-50 transition-colors"
|
||
@click="toUserAgreement">
|
||
<img src="@/assets/images/me/yhxy.svg" class="w-8 h-8 object-contain" alt="用户协议" />
|
||
<span class="text-xs text-gray-700 font-medium text-center">用户协议</span>
|
||
</button>
|
||
<button
|
||
class="flex flex-col items-center justify-center gap-2 py-4 rounded-lg hover:bg-blue-50 transition-colors"
|
||
@click="toPrivacyPolicy">
|
||
<img src="@/assets/images/me/yszc.svg" class="w-8 h-8 object-contain" alt="隐私政策" />
|
||
<span class="text-xs text-gray-700 font-medium text-center">隐私政策</span>
|
||
</button>
|
||
<button
|
||
class="flex flex-col items-center justify-center gap-2 py-4 rounded-lg hover:bg-blue-50 transition-colors"
|
||
@click="toService">
|
||
<img src="@/assets/images/me/lxkf.svg" class="w-8 h-8 object-contain" alt="联系客服" />
|
||
<span class="text-xs text-gray-700 font-medium text-center">联系客服</span>
|
||
</button>
|
||
<button v-if="isLoggedIn && !isWeChat"
|
||
class="flex flex-col items-center justify-center gap-2 py-4 rounded-lg hover:bg-red-50 transition-colors"
|
||
@click="handleLogout">
|
||
<img src="@/assets/images/me/tcdl.png" class="w-8 h-8 object-contain" alt="退出登录" />
|
||
<span class="text-xs text-gray-700 font-medium text-center">退出登录</span>
|
||
</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<BindPhoneDialog />
|
||
</div>
|
||
</template>
|
||
|
||
<script setup>
|
||
import { storeToRefs } from "pinia";
|
||
import { ref, computed, onBeforeMount, onMounted } from "vue";
|
||
import { useRouter } from "vue-router";
|
||
import headShot from "@/assets/images/head_shot.webp";
|
||
import { useAgentStore } from "@/stores/agentStore";
|
||
import { useUserStore } from "@/stores/userStore";
|
||
import { useEnv } from "@/composables/useEnv";
|
||
import { useDialogStore } from "@/stores/dialogStore";
|
||
import useApiFetch from "@/composables/useApiFetch";
|
||
import { getRevenueInfo } from '@/api/agent';
|
||
import BindPhoneDialog from "@/components/BindPhoneDialog.vue";
|
||
|
||
const router = useRouter();
|
||
const agentStore = useAgentStore();
|
||
const userStore = useUserStore();
|
||
const dialogStore = useDialogStore();
|
||
const { isAgent, level, levelName, agentCode } = storeToRefs(agentStore);
|
||
const { userName, userAvatar, isLoggedIn, mobile } = storeToRefs(userStore);
|
||
const { isWeChat } = useEnv();
|
||
const revenueData = ref(null);
|
||
|
||
// 等级名称映射(数字等级)
|
||
const levelNamesMap = {
|
||
1: "普通代理",
|
||
2: "黄金代理",
|
||
3: "钻石代理",
|
||
};
|
||
|
||
const levelTextMap = {
|
||
1: "基础代理特权",
|
||
2: "高级代理特权",
|
||
3: "尊享代理特权",
|
||
};
|
||
|
||
const levelGradient = computed(() => {
|
||
const currentLevel = level.value || 1;
|
||
const gradients = {
|
||
1: {
|
||
border: "bg-gradient-to-r from-gray-300 to-gray-400",
|
||
badge: "bg-gradient-to-r from-gray-500 to-gray-600",
|
||
text: "text-gray-600",
|
||
cardBorder: "bg-gradient-to-r from-gray-300 to-gray-400",
|
||
},
|
||
2: {
|
||
border: "bg-gradient-to-r from-yellow-400 to-amber-500",
|
||
badge: "bg-gradient-to-r from-yellow-500 to-amber-600",
|
||
text: "text-amber-600",
|
||
cardBorder: "bg-gradient-to-r from-yellow-400 to-amber-500",
|
||
},
|
||
3: {
|
||
border: "bg-gradient-to-r from-purple-400 to-pink-400 shadow-[0_0_15px_rgba(163,51,200,0.2)]",
|
||
badge: "bg-gradient-to-r from-purple-500 to-pink-500",
|
||
text: "text-purple-600",
|
||
cardBorder: "bg-gradient-to-r from-purple-400 to-pink-400 shadow-[0_0_20px_rgba(163,51,200,0.3)]",
|
||
},
|
||
};
|
||
return gradients[currentLevel] || gradients[1];
|
||
});
|
||
|
||
const maskName = (name) => {
|
||
if (!name || name.length < 11) return name;
|
||
return name.substring(0, 3) + "****" + name.substring(7);
|
||
};
|
||
|
||
function toUserAgreement() {
|
||
router.push(`/userAgreement`);
|
||
}
|
||
|
||
function toPrivacyPolicy() {
|
||
router.push(`/privacyPolicy`); // 新增隐私政策路由
|
||
}
|
||
|
||
|
||
function redirectToLogin() {
|
||
router.push(`/login`);
|
||
}
|
||
|
||
function handleLogout() {
|
||
// 改进的存储管理
|
||
localStorage.removeItem("token");
|
||
localStorage.removeItem("refreshAfter");
|
||
localStorage.removeItem("accessExpire");
|
||
localStorage.removeItem("userInfo");
|
||
localStorage.removeItem("agentInfo");
|
||
|
||
// 重置状态
|
||
userStore.resetUser();
|
||
agentStore.resetAgent();
|
||
|
||
location.reload();
|
||
}
|
||
const toBigData = () => {
|
||
window.location.href = "https://www.tybigdata.com/";
|
||
};
|
||
function handleCancelAccount() {
|
||
// 账号注销功能
|
||
if (confirm("注销账号后,您的所有数据将被清除且无法恢复,确定要继续吗?")) {
|
||
useApiFetch("/user/cancelOut")
|
||
.post()
|
||
.json()
|
||
.then(({ data, error }) => {
|
||
if (!error && data.value && data.value.code === 200) {
|
||
alert("账号已注销");
|
||
handleLogout();
|
||
}
|
||
})
|
||
.catch((error) => {
|
||
console.error("注销账号失败:", error);
|
||
});
|
||
}
|
||
}
|
||
|
||
function toService() {
|
||
window.location.href =
|
||
"https://work.weixin.qq.com/kfid/kfc82d4424e4b19e5f3"; // 跳转到客服页面
|
||
}
|
||
|
||
const toUpgrade = () => {
|
||
router.push({ name: "agentUpgrade" });
|
||
};
|
||
|
||
const toUpgradeSubordinate = () => {
|
||
router.push({ name: "upgradeSubordinate" });
|
||
};
|
||
|
||
const toInviteCodeManage = () => {
|
||
router.push({ name: "invitation" });
|
||
};
|
||
|
||
const toRealNameAuth = () => {
|
||
dialogStore.openRealNameAuth();
|
||
};
|
||
const toAgentReport = () => {
|
||
router.push({ name: "agentPromotionQueryList" })
|
||
}
|
||
const toWithdraw = () => {
|
||
router.push({ name: "withdraw" });
|
||
};
|
||
const toAgentSystemGuide = () => {
|
||
router.push({ name: "agentSystemGuide" });
|
||
};
|
||
|
||
const toWithdrawDetails = () => {
|
||
router.push({ name: "withdrawDetails" });
|
||
};
|
||
|
||
const goToPromoteDetail = () => {
|
||
router.push({ name: "promoteDetails" });
|
||
};
|
||
|
||
const goToRebateDetail = () => {
|
||
router.push({ name: "rewardsDetails" });
|
||
};
|
||
|
||
const getRevenueData = async () => {
|
||
if (!isAgent.value) return;
|
||
const { data: revenueResponse, error: revenueError } = await getRevenueInfo();
|
||
if (revenueResponse.value?.code === 200 && !revenueError.value) {
|
||
revenueData.value = revenueResponse.value.data;
|
||
}
|
||
};
|
||
|
||
const getDefaultAvatar = () => {
|
||
if (!isAgent.value) return headShot;
|
||
|
||
const currentLevel = level.value || 1;
|
||
switch (currentLevel) {
|
||
case 1:
|
||
return "/image/shot_nonal.png";
|
||
case 2:
|
||
return "/image/shot_vip.png";
|
||
case 3:
|
||
return "/image/shot_svip.png";
|
||
default:
|
||
return headShot;
|
||
}
|
||
};
|
||
|
||
const showRegisterAgentDialog = () => {
|
||
dialogStore.openRegisterAgent();
|
||
};
|
||
|
||
const toRegister = () => {
|
||
router.push("/register");
|
||
};
|
||
|
||
onBeforeMount(() => {
|
||
// 获取存储的用户和代理信息
|
||
const userInfo = localStorage.getItem("userInfo");
|
||
if (userInfo) {
|
||
try {
|
||
const parsedUserInfo = JSON.parse(userInfo);
|
||
userStore.updateUserInfo(parsedUserInfo);
|
||
} catch (e) {
|
||
console.error("解析用户信息失败", e);
|
||
}
|
||
}
|
||
|
||
const agentInfo = localStorage.getItem("agentInfo");
|
||
if (agentInfo) {
|
||
try {
|
||
const parsedAgentInfo = JSON.parse(agentInfo);
|
||
agentStore.updateAgentInfo(parsedAgentInfo);
|
||
} catch (e) {
|
||
console.error("解析代理信息失败", e);
|
||
}
|
||
}
|
||
});
|
||
|
||
onMounted(() => {
|
||
if (isAgent.value) {
|
||
getRevenueData();
|
||
}
|
||
});
|
||
</script>
|
||
|
||
<style scoped></style>
|