296 lines
8.5 KiB
Vue
296 lines
8.5 KiB
Vue
<!-- 头像 -->
|
|
<script setup lang="ts">
|
|
import { useRouter } from 'vue-router';
|
|
import Popover from '@/components/Popover/index.vue';
|
|
import SvgIcon from '@/components/SvgIcon/index.vue';
|
|
import { useUserStore } from '@/stores';
|
|
import { useSessionStore } from '@/stores/modules/session';
|
|
import { getUserProfilePicture, isUserVip } from '@/utils/user';
|
|
|
|
const router = useRouter();
|
|
|
|
const userStore = useUserStore();
|
|
const sessionStore = useSessionStore();
|
|
|
|
// const src = computed(
|
|
// () => userStore.userInfo?.avatar ?? 'https://avatars.githubusercontent.com/u/76239030',
|
|
// );
|
|
const src = computed(
|
|
() => userStore.userInfo?.user?.icon ? `${import.meta.env.VITE_WEB_BASE_API}/file/${userStore.userInfo.user.icon}` : `@/assets/images/logo.png`,
|
|
);
|
|
|
|
/* 弹出面板 开始 */
|
|
const popoverStyle = ref({
|
|
width: '200px',
|
|
padding: '4px',
|
|
height: 'fit-content',
|
|
});
|
|
const popoverRef = ref();
|
|
|
|
// 弹出面板内容
|
|
const popoverList = ref([
|
|
// {
|
|
// key: '1',
|
|
// title: '收藏夹',
|
|
// icon: 'book-mark-fill',
|
|
// },
|
|
// {
|
|
// key: '2',
|
|
// title: '设置',
|
|
// icon: 'settings-4-fill',
|
|
// },
|
|
{
|
|
key: '5',
|
|
title: '用户中心',
|
|
icon: 'settings-4-fill',
|
|
},
|
|
{
|
|
key: '3',
|
|
divider: true,
|
|
},
|
|
{
|
|
key: '4',
|
|
title: '退出登录',
|
|
icon: 'logout-box-r-line',
|
|
},
|
|
]);
|
|
|
|
const dialogVisible = ref(false);
|
|
const navItems = [
|
|
// { name: 'user', label: '用户管理', icon: 'User' },
|
|
// { name: 'role', label: '角色管理', icon: 'Avatar' },
|
|
// { name: 'permission', label: '权限管理', icon: 'Key' },
|
|
{ name: 'apiKey', label: 'API密钥', icon: 'Key' },
|
|
{ name: 'rechargeLog', label: '充值记录', icon: 'Document' },
|
|
];
|
|
function openDialog() {
|
|
dialogVisible.value = true;
|
|
}
|
|
function handleConfirm(activeNav: string) {
|
|
console.log('确认操作,当前导航:', activeNav);
|
|
ElMessage.success('操作成功');
|
|
}
|
|
|
|
function handleNavChange(nav: string) {
|
|
console.log('导航切换:', nav);
|
|
}
|
|
|
|
// 点击
|
|
function handleClick(item: any) {
|
|
switch (item.key) {
|
|
case '1':
|
|
ElMessage.warning('暂未开放');
|
|
break;
|
|
case '2':
|
|
ElMessage.warning('暂未开放');
|
|
break;
|
|
case '5':
|
|
openDialog();
|
|
break;
|
|
case '4':
|
|
popoverRef.value?.hide?.();
|
|
ElMessageBox.confirm('退出登录不会丢失任何数据,你仍可以登录此账号。', '确认退出登录?', {
|
|
confirmButtonText: '确认退出',
|
|
cancelButtonText: '取消',
|
|
type: 'warning',
|
|
confirmButtonClass: 'el-button--danger',
|
|
cancelButtonClass: 'el-button--info',
|
|
roundButton: true,
|
|
autofocus: false,
|
|
})
|
|
.then(async () => {
|
|
// 在这里执行退出方法
|
|
await userStore.logout();
|
|
// 清空回话列表并回到默认页
|
|
await sessionStore.requestSessionList(1, true);
|
|
await sessionStore.createSessionBtn();
|
|
ElMessage({
|
|
type: 'success',
|
|
message: '退出成功',
|
|
});
|
|
})
|
|
.catch(() => {
|
|
// ElMessage({
|
|
// type: 'info',
|
|
// message: '取消',
|
|
// });
|
|
});
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
function openVipGuide() {
|
|
ElMessageBox.confirm(
|
|
`
|
|
<div class="text-center leading-relaxed">
|
|
<h3 class="text-lg font-bold mb-3">${isUserVip() ? 'YiXinAI-VIP 会员' : '成为 YiXinAI-VIP'}</h3>
|
|
<p class="mb-2">
|
|
${
|
|
isUserVip()
|
|
? '您已是尊贵会员,享受全部 AI 模型与专属服务。感谢支持!'
|
|
: '解锁所有 AI 模型,无限加速,专属客服,尽享尊贵体验。'
|
|
}
|
|
</p>
|
|
${
|
|
isUserVip()
|
|
? '<p class="text-sm text-gray-500">您可随时访问产品页面查看更多特权内容。</p>'
|
|
: '<p class="text-sm text-gray-500">点击下方按钮,立即升级为 VIP 会员!</p>'
|
|
}
|
|
</div>
|
|
`,
|
|
isUserVip() ? '会员状态' : '会员尊享',
|
|
{
|
|
confirmButtonText: '前往产品页面',
|
|
cancelButtonText: '关闭',
|
|
dangerouslyUseHTMLString: true,
|
|
type: 'info',
|
|
center: true,
|
|
roundButton: true,
|
|
},
|
|
)
|
|
.then(() => {
|
|
router.push({
|
|
name: 'products', // 使用命名路由
|
|
query: { from: isUserVip() ? 'vip' : 'user' }, // 可选:添加来源标识
|
|
});
|
|
})
|
|
.catch(() => {
|
|
// 点击右上角关闭或“关闭”按钮,不执行任何操作
|
|
});
|
|
}
|
|
|
|
/* 弹出面板 结束 */
|
|
</script>
|
|
|
|
<template>
|
|
<div class="flex items-center gap-2">
|
|
<!-- 用户信息区域 -->
|
|
<div class=" cursor-pointer flex flex-col text-right mr-2 leading-tight" @click="openVipGuide">
|
|
<div class="text-sm font-semibold text-gray-800">
|
|
{{ userStore.userInfo?.user.nick ?? '未登录用户' }}
|
|
</div>
|
|
|
|
<!-- 角色展示 -->
|
|
<div>
|
|
<span
|
|
v-if="isUserVip()"
|
|
class="inline-block px-2 py-0.5 text-xs text-yellow-700 bg-yellow-100 rounded-full font-semibold"
|
|
>
|
|
YiXinAI-VIP
|
|
</span>
|
|
|
|
<span
|
|
v-else
|
|
class="inline-block px-2 py-0.5 text-xs text-gray-600 bg-gray-100 rounded-full cursor-pointer hover:bg-yellow-50 hover:text-yellow-700 transition"
|
|
>
|
|
普通用户 · 开通 VIP
|
|
</span>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- 头像区域 -->
|
|
<div class="avatar-container">
|
|
<Popover
|
|
ref="popoverRef"
|
|
placement="bottom-end"
|
|
trigger="clickTarget"
|
|
:trigger-style="{ cursor: 'pointer' }"
|
|
popover-class="popover-content"
|
|
:popover-style="popoverStyle"
|
|
>
|
|
<template #trigger>
|
|
<el-avatar :src="getUserProfilePicture()" :size="28" fit="fit" shape="circle" />
|
|
</template>
|
|
|
|
<div class="popover-content-box shadow-lg">
|
|
<!-- 用户信息 -->
|
|
<div class="user-info-box flex items-center gap-8px p-8px rounded-lg mb-2">
|
|
<el-avatar :src="getUserProfilePicture()" :size="32" fit="fit" shape="circle" />
|
|
<div class="flex flex-col text-sm">
|
|
<div class="font-semibold text-gray-800">
|
|
{{ userStore.userInfo?.user.nick ?? '未登录用户' }}
|
|
</div>
|
|
<div class="text-xs text-gray-500">
|
|
<span
|
|
v-if="isUserVip()"
|
|
class="inline-block px-2 py-0.5 text-xs text-yellow-700 bg-yellow-100 rounded-full font-semibold"
|
|
>
|
|
YiXinAI-VIP
|
|
</span>
|
|
|
|
<span
|
|
v-else
|
|
class="inline-block px-2 py-0.5 text-xs text-gray-600 bg-gray-100 rounded-full cursor-pointer hover:bg-yellow-50 hover:text-yellow-700 transition"
|
|
>
|
|
普通用户 · 开通 VIP
|
|
</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="divder h-1px bg-gray-200 my-4px" />
|
|
|
|
<div v-for="item in popoverList" :key="item.key" class="popover-content-box-items h-full">
|
|
<div
|
|
v-if="!item.divider"
|
|
class="popover-content-box-item flex items-center h-full gap-8px p-8px pl-10px pr-12px rounded-lg hover:cursor-pointer hover:bg-[rgba(0,0,0,.04)]"
|
|
@click="handleClick(item)"
|
|
>
|
|
<SvgIcon :name="item.icon!" size="16" class-name="flex-none" />
|
|
<div class="popover-content-box-item-text font-size-14px text-overflow max-h-120px">
|
|
{{ item.title }}
|
|
</div>
|
|
</div>
|
|
|
|
<div v-if="item.divider" class="divder h-1px bg-gray-200 my-4px" />
|
|
</div>
|
|
</div>
|
|
</Popover>
|
|
</div>
|
|
<nav-dialog
|
|
v-model="dialogVisible"
|
|
title="用户中心"
|
|
:nav-items="navItems"
|
|
@confirm="handleConfirm"
|
|
@nav-change="handleNavChange"
|
|
>
|
|
<!-- 用户管理内容 -->
|
|
<template #user>
|
|
<user-management />
|
|
</template>
|
|
|
|
<!-- 角色管理内容 -->
|
|
<template #role>
|
|
<!-- < /> -->
|
|
</template>
|
|
|
|
<!-- 权限管理内容 -->
|
|
<template #permission>
|
|
<!-- <permission-management /> -->
|
|
</template>
|
|
|
|
<template #apiKey>
|
|
<APIKeyManagement />
|
|
</template>
|
|
<template #rechargeLog>
|
|
<recharge-log />
|
|
</template>
|
|
</nav-dialog>
|
|
</div>
|
|
</template>
|
|
|
|
<style scoped lang="scss">
|
|
.popover-content {
|
|
width: 520px;
|
|
height: 520px;
|
|
}
|
|
.popover-content-box {
|
|
padding: 8px;
|
|
background: #ffffff;
|
|
border: 1px solid #e5e7eb;
|
|
border-radius: 8px;
|
|
box-shadow: 0 4px 16px rgb(0 0 0 / 8%);
|
|
}
|
|
</style>
|