This commit is contained in:
2025-11-27 13:19:45 +08:00
commit c85b46c18e
612 changed files with 83497 additions and 0 deletions

331
src/views/Me.vue Normal file
View File

@@ -0,0 +1,331 @@
<template>
<div class="box-border min-h-screen">
<div class="flex flex-col p-4 space-y-6">
<!-- 用户信息卡片 -->
<div class="profile-section group relative flex items-center gap-4 rounded-xl bg-white p-6 transition-all hover:shadow-xl"
@click="!isLoggedIn ? redirectToLogin() : null">
<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-24 w-24 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">
{{ levelNames[level] }}
</div>
</div>
</div>
<div class="space-y-1">
<h2 class="text-2xl font-bold" style="color: var(--van-text-color);">
{{
!isLoggedIn
? "点击登录"
: mobile
? maskName(mobile)
: isWeChat
? "微信用户"
: "未绑定手机号"
}}
</h2>
<!-- 手机号绑定提示 -->
<template v-if="isLoggedIn && !mobile">
<p @click.stop="showBindPhoneDialog" class="text-sm cursor-pointer hover:underline"
style="color: var(--van-theme-primary);">
点击绑定手机号码
</p>
</template>
<p v-if="isAgent" class="text-sm font-medium" :class="levelGradient.text">
🎖 {{ levelText[level] }}
</p>
</div>
</div>
<VipBanner v-if="isAgent && (level === 'normal' || level === '')" />
<!-- 功能菜单 -->
<div class="">
<div class="bg-white rounded-xl shadow-sm overflow-hidden">
<template v-if="isAgent && ['VIP', 'SVIP'].includes(level)">
<button
class="w-full flex items-center justify-between px-6 py-4 hover:bg-purple-50 transition-colors border-b border-gray-100"
@click="toVipConfig">
<div class="flex items-center gap-3">
<img src="@/assets/images/me/dlbgpz.png" class="w-6 h-6 object-contain" alt="代理报告配置" />
<span class="text-purple-700 font-medium">代理报告配置</span>
</div>
<img src="@/assets/images/me/right.png" class="w-4 h-4" alt="右箭头" />
</button>
<button
class="w-full flex items-center justify-between px-6 py-4 hover:bg-amber-50 transition-colors border-b border-gray-100"
@click="toVipRenewal">
<div class="flex items-center gap-3">
<img src="@/assets/images/me/xfhy.png" class="w-6 h-6 object-contain" alt="代理会员" />
<div class="flex flex-col items-start">
<span class="text-amber-700 font-medium">续费代理会员</span>
<span class="text-xs text-gray-500">有效期至 {{ formatExpiryTime(ExpiryTime) }}</span>
</div>
</div>
<img src="@/assets/images/me/right.png" class="w-4 h-4" alt="右箭头" />
</button>
</template>
<button
class="w-full flex items-center justify-between px-6 py-4 hover:bg-blue-50 transition-colors border-b border-gray-100"
@click="toHistory">
<div class="flex items-center gap-3">
<img src="@/assets/images/me/wdbg.png" class="w-6 h-6 object-contain" alt="我的报告" />
<span class="text-gray-700 font-medium">我的报告</span>
</div>
<img src="@/assets/images/me/right.png" class="w-4 h-4" alt="右箭头" />
</button>
<button
class="w-full flex items-center justify-between px-6 py-4 hover:bg-blue-50 transition-colors border-b border-gray-100"
@click="toApiStore">
<div class="flex items-center gap-3">
<img src="@/assets/images/me/apisd.png" class="w-6 h-6 object-contain" alt="API商店" />
<span class="text-gray-700 font-medium">API商店</span>
</div>
<img src="@/assets/images/me/right.png" class="w-4 h-4" alt="右箭头" />
</button>
<!-- <button
class="w-full flex items-center justify-between px-6 py-4 hover:bg-blue-50 transition-colors border-b border-gray-100"
@click="toBigData">
<div class="flex items-center gap-3">
<img src="@/assets/images/me/qyfkyj.png" class="w-6 h-6 object-contain" alt="企业风控预警" />
<span class="text-gray-700 font-medium">企业风控预警</span>
</div>
<img src="@/assets/images/me/right.png" class="w-4 h-4" alt="右箭头" />
</button> -->
<button
class="w-full flex items-center justify-between px-6 py-4 hover:bg-blue-50 transition-colors border-b border-gray-100"
@click="toCooperation">
<div class="flex items-center gap-3">
<img src="@/assets/images/me/swhz.png" class="w-6 h-6 object-contain" alt="商务合作" />
<span class="text-gray-700 font-medium">商务合作</span>
</div>
<img src="@/assets/images/me/right.png" class="w-4 h-4" alt="右箭头" />
</button>
<button
class="w-full flex items-center justify-between px-6 py-4 hover:bg-blue-50 transition-colors border-b border-gray-100"
@click="toUserAgreement">
<div class="flex items-center gap-3">
<img src="@/assets/images/me/yhxy.png" class="w-6 h-6 object-contain" alt="用户协议" />
<span class="text-gray-700 font-medium">用户协议</span>
</div>
<img src="@/assets/images/me/right.png" class="w-4 h-4" alt="右箭头" />
</button>
<button
class="w-full flex items-center justify-between px-6 py-4 hover:bg-blue-50 transition-colors border-b border-gray-100"
@click="toPrivacyPolicy">
<div class="flex items-center gap-3">
<img src="@/assets/images/me/yszc.png" class="w-6 h-6 object-contain" alt="隐私政策" />
<span class="text-gray-700 font-medium">隐私政策</span>
</div>
<img src="@/assets/images/me/right.png" class="w-4 h-4" alt="右箭头" />
</button>
<button
class="w-full flex items-center justify-between px-6 py-4 hover:bg-blue-50 transition-colors"
@click="toService">
<div class="flex items-center gap-3">
<img src="@/assets/images/me/lxkf.png" class="w-6 h-6 object-contain" alt="联系客服" />
<span class="text-gray-700 font-medium">联系客服</span>
</div>
<img src="@/assets/images/me/right.png" class="w-4 h-4" alt="右箭头" />
</button>
<button v-if="isLoggedIn && !isWeChat"
class="w-full flex items-center justify-between px-6 py-4 hover:bg-red-50 transition-colors"
@click="handleLogout">
<div class="flex items-center gap-3">
<img src="@/assets/images/me/tcdl.png" class="w-6 h-6 object-contain" alt="退出登录" />
<span class="text-gray-700 font-medium">退出登录</span>
</div>
<img src="@/assets/images/me/right.png" class="w-4 h-4" alt="右箭头" />
</button>
</div>
</div>
</div>
</div>
</template>
<script setup>
import { storeToRefs } from "pinia";
import { ref, computed, onBeforeMount } from "vue";
const router = useRouter();
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";
const agentStore = useAgentStore();
const userStore = useUserStore();
const dialogStore = useDialogStore();
const { isAgent, level, ExpiryTime } = storeToRefs(agentStore);
const { userName, 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: "bg-gradient-to-r from-gray-300 to-gray-400",
"": "bg-gradient-to-r from-gray-300 to-gray-400",
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-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],
}));
const maskName = (name) => {
if (!name || name.length < 11) return name;
return name.substring(0, 3) + "****" + name.substring(7);
};
function toHistory() {
router.push(`/historyQuery`);
}
function toCooperation() {
window.location.href = "https://www.tianyuandata.com";
}
function toApiStore() {
window.location.href = "https://www.tianyuanapi.com/";
}
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/kfc8a32720024833f57"; // 跳转到客服页面
}
const toVipConfig = () => {
router.push({ name: "agentVipConfig" });
};
const toVipRenewal = () => {
router.push(`/agent/vipApply`);
};
function formatExpiryTime(expiryTimeStr) {
if (!expiryTimeStr) return "未知";
// 假设expiryTimeStr格式是 "YYYY-MM-DD HH:MM:SS"
// 只返回日期部分 "YYYY-MM-DD"
return expiryTimeStr.split(" ")[0];
}
const getDefaultAvatar = () => {
if (!isAgent.value) return headShot;
switch (level.value) {
case "normal":
case "":
return "/image/shot_nonal.png";
case "VIP":
return "/image/shot_vip.png";
case "SVIP":
return "/image/shot_svip.png";
default:
return headShot;
}
};
const showBindPhoneDialog = () => {
dialogStore.openBindPhone();
};
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);
}
}
});
</script>
<style scoped></style>