fix: 加载优化、vip状态优化、apikey优化

This commit is contained in:
Gsh
2025-08-04 23:11:42 +08:00
parent 0a2710b865
commit 65d5f5ae86
11 changed files with 172 additions and 93 deletions

View File

@@ -8,19 +8,15 @@ import Popover from '@/components/Popover/index.vue';
import SvgIcon from '@/components/SvgIcon/index.vue';
import { useUserStore } from '@/stores';
import { useModelStore } from '@/stores/modules/model';
import { isUserVip } from '@/utils/user';
const router = useRouter();
// 用户角色
const isUserRoleVip = computed(() => {
const roles = userStore.userInfo?.roles ?? [];
return roles.some(role => role.roleCode === 'YiXinAi-Vip');
});
const userStore = useUserStore();
const modelStore = useModelStore();
// 检查模型是否可用
function isModelAvailable(item: GetSessionListVO) {
return isUserRoleVip.value || item.modelId?.includes('DeepSeek-R1-0528') || userStore.userInfo?.user?.userName === 'cc';
return isUserVip() || item.modelId?.includes('DeepSeek-R1-0528') || userStore.userInfo?.user?.userName === 'cc';
}
onMounted(async () => {
@@ -64,22 +60,22 @@ function handleModelClick(item: GetSessionListVO) {
ElMessageBox.confirm(
`
<div class="text-center leading-relaxed">
<h3 class="text-lg font-bold mb-3">${isUserRoleVip.value ? 'YiXinAI-VIP 会员' : '成为 YiXinAI-VIP'}</h3>
<h3 class="text-lg font-bold mb-3">${isUserVip() ? 'YiXinAI-VIP 会员' : '成为 YiXinAI-VIP'}</h3>
<p class="mb-2">
${
isUserRoleVip.value
isUserVip()
? '您已是尊贵会员,享受全部 AI 模型与专属服务。感谢支持!'
: '解锁所有 AI 模型,无限加速,专属客服,尽享尊贵体验。'
}
</p>
${
isUserRoleVip.value
isUserVip()
? '<p class="text-sm text-gray-500">您可随时访问产品页面查看更多特权内容。</p>'
: '<p class="text-sm text-gray-500">点击下方按钮,立即升级为 VIP 会员!</p>'
}
</div>
`,
isUserRoleVip.value ? '会员状态' : '会员尊享',
isUserVip() ? '会员状态' : '会员尊享',
{
confirmButtonText: '前往产品页面',
cancelButtonText: '关闭',
@@ -92,7 +88,7 @@ function handleModelClick(item: GetSessionListVO) {
.then(() => {
router.push({
name: 'products', // 使用命名路由
query: { from: isUserRoleVip.value ? 'vip' : 'user' }, // 可选:添加来源标识
query: { from: isUserVip() ? 'vip' : 'user' }, // 可选:添加来源标识
});
})
.catch(() => {

View File

@@ -3,7 +3,7 @@ import { CircleCheck } from '@element-plus/icons-vue';
import { ElMessage, ElMessageBox } from 'element-plus';
import { onMounted, ref } from 'vue';
import { useRouter } from 'vue-router';
import { applyApiKey, getApiKey, getRechargeLog } from '@/api/model/index.ts';
import { applyApiKey, getApiKey } from '@/api/model/index.ts';
import { isUserVip } from '@/utils/user';
const apiKey = ref('');
@@ -29,8 +29,6 @@ const router = useRouter();
async function fetchApiKey() {
try {
const res = await getApiKey();
const res2 = await getRechargeLog();
console.log('re2', res2);
if (res.data?.apiKey) {
apiKey.value = res.data.apiKey;
displayedKey.value = res.data.apiKey;
@@ -43,7 +41,7 @@ async function fetchApiKey() {
// 领取密钥
async function handleClaim() {
if (!isUserVip) {
if (!isUserVip()) {
ElMessageBox.confirm(
`
<div class="text-center leading-relaxed">
@@ -172,7 +170,7 @@ onMounted(async () => {
element-loading-background="rgba(122, 122, 122, 0.8)"
>
<!-- 未领取状态 -->
<div v-if="!apiKey " class="unclaimed-state">
<div v-if="!apiKey" class="unclaimed-state">
<div class="gift-container" @click="handleClaim">
<div class="gift-box" :class="{ opening: isOpening }">
<div class="gift-lid" />
@@ -239,7 +237,7 @@ onMounted(async () => {
</div>
</div>
<!-- 使用说明 -->
<div class="usage-guide">
<div v-if="apiKey" class="usage-guide">
<el-divider />
<h3>使用说明</h3>
<div class="guide-content">

View File

@@ -5,16 +5,12 @@ 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 { userProfilePicture } from '@/utils/user';
import { getUserProfilePicture, isUserVip } from '@/utils/user';
const router = useRouter();
const userStore = useUserStore();
const sessionStore = useSessionStore();
const userRole = computed(() => {
const roles = userStore.userInfo?.roles ?? [];
return roles.some(role => role.roleCode === 'YiXinAi-Vip') ? 'vip' : 'user';
});
// const src = computed(
// () => userStore.userInfo?.avatar ?? 'https://avatars.githubusercontent.com/u/76239030',
@@ -126,26 +122,25 @@ function handleClick(item: any) {
}
function openVipGuide() {
const isVip = userRole.value === 'vip' || userStore.userInfo?.user?.userName === 'cc';
ElMessageBox.confirm(
`
<div class="text-center leading-relaxed">
<h3 class="text-lg font-bold mb-3">${isVip ? 'YiXinAI-VIP 会员' : '成为 YiXinAI-VIP'}</h3>
<h3 class="text-lg font-bold mb-3">${isUserVip() ? 'YiXinAI-VIP 会员' : '成为 YiXinAI-VIP'}</h3>
<p class="mb-2">
${
isVip
isUserVip()
? '您已是尊贵会员,享受全部 AI 模型与专属服务。感谢支持!'
: '解锁所有 AI 模型,无限加速,专属客服,尽享尊贵体验。'
}
</p>
${
isVip
isUserVip()
? '<p class="text-sm text-gray-500">您可随时访问产品页面查看更多特权内容。</p>'
: '<p class="text-sm text-gray-500">点击下方按钮,立即升级为 VIP 会员!</p>'
}
</div>
`,
isVip ? '会员状态' : '会员尊享',
isUserVip() ? '会员状态' : '会员尊享',
{
confirmButtonText: '前往产品页面',
cancelButtonText: '关闭',
@@ -158,7 +153,7 @@ function openVipGuide() {
.then(() => {
router.push({
name: 'products', // 使用命名路由
query: { from: userRole.value }, // 可选:添加来源标识
query: { from: isUserVip() ? 'vip' : 'user' }, // 可选:添加来源标识
});
})
.catch(() => {
@@ -180,7 +175,7 @@ function openVipGuide() {
<!-- 角色展示 -->
<div>
<span
v-if="userRole === 'vip'"
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
@@ -206,20 +201,20 @@ function openVipGuide() {
:popover-style="popoverStyle"
>
<template #trigger>
<el-avatar :src="userProfilePicture" :size="28" fit="fit" shape="circle" />
<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="userProfilePicture" :size="32" fit="fit" shape="circle" />
<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="userRole === 'vip'"
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

View File

@@ -17,9 +17,27 @@ const designStore = useDesignStore();
/** 获取布局格式 */
const layout = computed((): LayoutType => designStore.layout);
onMounted(() => {
console.log('111--');
// 通知 index.html 的 loading 动画进度拉满并淡出
(window as any)?.finishLoading();
// 更好的做法是等待所有资源加载
window.addEventListener('load', () => {
const loader = document.getElementById('yixinai-loader');
if (loader) {
loader.style.opacity = '0';
setTimeout(() => {
loader.style.display = 'none';
}, 500); // 匹配过渡时间
}
});
// 设置超时作为兜底
setTimeout(() => {
const loader = document.getElementById('yixinai-loader');
if (loader) {
loader.style.opacity = '0';
setTimeout(() => {
loader.style.display = 'none';
}, 500);
}
}, 500); // 最多显示0.5秒
});
</script>

View File

@@ -17,7 +17,7 @@ import { useChatStore } from '@/stores/modules/chat';
import { useFilesStore } from '@/stores/modules/files';
import { useModelStore } from '@/stores/modules/model';
import { useUserStore } from '@/stores/modules/user';
import { systemProfilePicture, userProfilePicture } from '@/utils/user.ts';
import { getUserProfilePicture, systemProfilePicture } from '@/utils/user.ts';
import '@/styles/github-markdown.css';
import '@/styles/yixin-markdown.scss';
@@ -233,7 +233,7 @@ function addMessage(message: string, isUser: boolean) {
const obj: MessageItem = {
key: i,
avatar: isUser
? userProfilePicture
? getUserProfilePicture()
: systemProfilePicture,
avatarSize: '32px',
role: isUser ? 'user' : 'assistant',

View File

@@ -1,18 +1,12 @@
import type { ChatMessageVo } from '@/api/chat/types';
import { defineStore } from 'pinia';
import { getChatList } from '@/api';
import { systemProfilePicture, userProfilePicture } from '@/utils/user.ts';
import { getUserProfilePicture, systemProfilePicture } from '@/utils/user.ts';
import { useUserStore } from './user';
export const useChatStore = defineStore('chat', () => {
const userStore = useUserStore();
// 用户头像
const avatar = computed(() => {
const userInfo = userStore.userInfo;
return userInfo?.avatar || 'https://avatars.githubusercontent.com/u/76239030?v=4';
});
// 是否开启深度思考
const isDeepThinking = ref<boolean>(false);
@@ -35,7 +29,7 @@ export const useChatStore = defineStore('chat', () => {
// variant: 'shadow',
// shape: 'corner',
avatar: isUser
? userProfilePicture
? getUserProfilePicture()
: systemProfilePicture,
avatarSize: '32px',
typing: false,

View File

@@ -1,18 +1,21 @@
import { useUserStore } from '@/stores/index.js';
const userStore = useUserStore();
// 判断是否是 VIP 用户
export function isUserVip(): boolean {
const userStore = useUserStore();
console.log('isUserVip----', userStore);
// 获取用户角色信息
const userRoles = userStore.userInfo?.roles ?? [];
const isUserVip = userRoles.some((role: any) => role.roleCode === 'YiXinAi-Vip');
const userRoles = userStore.userInfo?.roles ?? [];
return userRoles.some((role: any) => role.roleCode === 'YiXinAi-Vip');
}
// 用户头像
const userProfilePicture = userStore.userInfo?.user?.icon ? `${import.meta.env.VITE_WEB_BASE_API}/file/${userStore.userInfo.user.icon}` : `/images/user.png`;
// 系统头像
const systemProfilePicture = `/images/logo.png`;
export function getUserProfilePicture(): string {
const userStore = useUserStore();
return userStore.userInfo?.user?.icon
? `${import.meta.env.VITE_WEB_BASE_API}/file/${userStore.userInfo.user.icon}`
: `/images/user.png`;
}
export {
isUserVip,
systemProfilePicture,
userProfilePicture,
};
// 系统头像(可以常量)
export const systemProfilePicture = `/images/logo.png`;