fix: 加载优化、vip状态优化、apikey优化
This commit is contained in:
@@ -1,10 +1,14 @@
|
||||
import type { ConfigEnv, PluginOption } from 'vite';
|
||||
import path from 'node:path';
|
||||
import vue from '@vitejs/plugin-vue';
|
||||
import { visualizer } from 'rollup-plugin-visualizer';
|
||||
import UnoCSS from 'unocss/vite';
|
||||
import AutoImport from 'unplugin-auto-import/vite';
|
||||
import { ElementPlusResolver } from 'unplugin-vue-components/resolvers';
|
||||
|
||||
import Components from 'unplugin-vue-components/vite';
|
||||
import viteCompression from 'vite-plugin-compression';
|
||||
|
||||
import envTyped from 'vite-plugin-env-typed';
|
||||
import createSvgIcon from './svg-icon';
|
||||
|
||||
@@ -33,6 +37,26 @@ function plugins({ mode, command }: ConfigEnv): PluginOption[] {
|
||||
dts: path.join(root, 'types', 'components.d.ts'),
|
||||
}),
|
||||
createSvgIcon(command === 'build'),
|
||||
|
||||
// ✅ Gzip 构建产物压缩(仅生产构建)
|
||||
command === 'build'
|
||||
&& viteCompression({
|
||||
verbose: true,
|
||||
disable: false,
|
||||
threshold: 10240,
|
||||
algorithm: 'gzip',
|
||||
ext: '.gz',
|
||||
}),
|
||||
|
||||
// ✅ 构建分析图(仅生产构建)
|
||||
command === 'build'
|
||||
&& visualizer({
|
||||
filename: './dist/stats.html',
|
||||
open: false, // 打包后自动打开分析图(true 可开启)
|
||||
gzipSize: true,
|
||||
brotliSize: true,
|
||||
}),
|
||||
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
@@ -111,49 +111,19 @@
|
||||
|
||||
<body>
|
||||
<!-- 加载动画容器 -->
|
||||
<div id="loader" class="loader-container">
|
||||
<div id="yixinai-loader" class="loader-container">
|
||||
<div class="loader-title">意心Ai</div>
|
||||
<div class="loader-subtitle">海外地址,仅首次访问预计加载约10秒</div>
|
||||
<div class="loader-logo">
|
||||
<div class="pulse-box"></div>
|
||||
</div>
|
||||
<div class="loader-text" id="progress-text">0%</div>
|
||||
<div class="loader-progress-bar">
|
||||
<div id="progress-bar" class="loader-progress"></div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<!-- 加载进度脚本:放在 main.ts 之前,保证先执行 -->
|
||||
<script>
|
||||
// 立即执行函数改为更简单的写法,减少解析时间
|
||||
(function(){
|
||||
const bar = document.getElementById('progress-bar');
|
||||
const text = document.getElementById('progress-text');
|
||||
let progress = 0;
|
||||
|
||||
function update() {
|
||||
progress = Math.min(progress + 2 + Math.random() * 3, 95);
|
||||
bar.style.width = progress + '%';
|
||||
text.textContent = Math.floor(progress) + '%';
|
||||
if(progress < 95) requestAnimationFrame(update);
|
||||
}
|
||||
|
||||
update();
|
||||
|
||||
window.finishLoading = function() {
|
||||
bar.style.width = '100%';
|
||||
text.textContent = '100%';
|
||||
setTimeout(() => {
|
||||
document.getElementById('loader').style.opacity = '0';
|
||||
setTimeout(() => document.getElementById('loader').remove(), 500);
|
||||
}, 300);
|
||||
};
|
||||
})();
|
||||
</script>
|
||||
<div id="app"></div>
|
||||
|
||||
|
||||
|
||||
<script async type="module" src="/src/main.ts"></script>
|
||||
<script type="module" src="/src/main.ts"></script>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
|
||||
@@ -67,6 +67,7 @@
|
||||
"postcss": "8.4.31",
|
||||
"postcss-html": "1.5.0",
|
||||
"prettier": "^3.6.2",
|
||||
"rollup-plugin-visualizer": "^6.0.3",
|
||||
"sass-embedded": "^1.89.2",
|
||||
"stylelint": "^16.21.1",
|
||||
"stylelint-config-html": "^1.1.0",
|
||||
@@ -81,6 +82,7 @@
|
||||
"unplugin-auto-import": "^19.3.0",
|
||||
"unplugin-vue-components": "^28.8.0",
|
||||
"vite": "^6.3.5",
|
||||
"vite-plugin-compression": "^0.5.1",
|
||||
"vite-plugin-env-typed": "^0.0.2",
|
||||
"vite-plugin-svg-icons": "^2.0.1",
|
||||
"vue-tsc": "^3.0.1"
|
||||
|
||||
85
Yi.Ai.Vue3/pnpm-lock.yaml
generated
85
Yi.Ai.Vue3/pnpm-lock.yaml
generated
@@ -117,6 +117,9 @@ importers:
|
||||
prettier:
|
||||
specifier: ^3.6.2
|
||||
version: 3.6.2
|
||||
rollup-plugin-visualizer:
|
||||
specifier: ^6.0.3
|
||||
version: 6.0.3(rollup@4.41.1)
|
||||
sass-embedded:
|
||||
specifier: ^1.89.2
|
||||
version: 1.89.2
|
||||
@@ -159,6 +162,9 @@ importers:
|
||||
vite:
|
||||
specifier: ^6.3.5
|
||||
version: 6.3.5(@types/node@22.15.30)(jiti@2.4.2)(sass-embedded@1.89.2)(yaml@2.8.0)
|
||||
vite-plugin-compression:
|
||||
specifier: ^0.5.1
|
||||
version: 0.5.1(vite@6.3.5(@types/node@22.15.30)(jiti@2.4.2)(sass-embedded@1.89.2)(yaml@2.8.0))
|
||||
vite-plugin-env-typed:
|
||||
specifier: ^0.0.2
|
||||
version: 0.0.2(vite@6.3.5(@types/node@22.15.30)(jiti@2.4.2)(sass-embedded@1.89.2)(yaml@2.8.0))
|
||||
@@ -1813,6 +1819,10 @@ packages:
|
||||
resolution: {integrity: sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
||||
define-lazy-prop@2.0.0:
|
||||
resolution: {integrity: sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==}
|
||||
engines: {node: '>=8'}
|
||||
|
||||
define-properties@1.2.1:
|
||||
resolution: {integrity: sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==}
|
||||
engines: {node: '>= 0.4'}
|
||||
@@ -2731,6 +2741,11 @@ packages:
|
||||
resolution: {integrity: sha512-JCNNGbwWZEVaSPtS45mdtrneRWJFp07LLmykxeFV5F6oBvNF8vHSfJuJgoT472pSfk+Mf8VnlrspaFBHWM8JAw==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
||||
is-docker@2.2.1:
|
||||
resolution: {integrity: sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==}
|
||||
engines: {node: '>=8'}
|
||||
hasBin: true
|
||||
|
||||
is-extendable@0.1.1:
|
||||
resolution: {integrity: sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
@@ -2859,6 +2874,10 @@ packages:
|
||||
resolution: {integrity: sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
|
||||
is-wsl@2.2.0:
|
||||
resolution: {integrity: sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==}
|
||||
engines: {node: '>=8'}
|
||||
|
||||
isarray@1.0.0:
|
||||
resolution: {integrity: sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==}
|
||||
|
||||
@@ -3414,6 +3433,10 @@ packages:
|
||||
resolution: {integrity: sha512-VXJjc87FScF88uafS3JllDgvAm+c/Slfz06lorj2uAY34rlUu0Nt+v8wreiImcrgAjjIHp1rXpTDlLOGw29WwQ==}
|
||||
engines: {node: '>=18'}
|
||||
|
||||
open@8.4.2:
|
||||
resolution: {integrity: sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==}
|
||||
engines: {node: '>=12'}
|
||||
|
||||
optionator@0.9.4:
|
||||
resolution: {integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==}
|
||||
engines: {node: '>= 0.8.0'}
|
||||
@@ -3859,6 +3882,19 @@ packages:
|
||||
rfdc@1.4.1:
|
||||
resolution: {integrity: sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==}
|
||||
|
||||
rollup-plugin-visualizer@6.0.3:
|
||||
resolution: {integrity: sha512-ZU41GwrkDcCpVoffviuM9Clwjy5fcUxlz0oMoTXTYsK+tcIFzbdacnrr2n8TXcHxbGKKXtOdjxM2HUS4HjkwIw==}
|
||||
engines: {node: '>=18'}
|
||||
hasBin: true
|
||||
peerDependencies:
|
||||
rolldown: 1.x || ^1.0.0-beta
|
||||
rollup: 2.x || 3.x || 4.x
|
||||
peerDependenciesMeta:
|
||||
rolldown:
|
||||
optional: true
|
||||
rollup:
|
||||
optional: true
|
||||
|
||||
rollup@4.41.1:
|
||||
resolution: {integrity: sha512-cPmwD3FnFv8rKMBc1MxWCwVQFxwf1JEmSX3iQXrRVVG15zerAIXRjMFVWnd5Q5QvgKF7Aj+5ykXFhUl+QGnyOw==}
|
||||
engines: {node: '>=18.0.0', npm: '>=8.0.0'}
|
||||
@@ -4106,6 +4142,10 @@ packages:
|
||||
resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
|
||||
source-map@0.7.6:
|
||||
resolution: {integrity: sha512-i5uvt8C3ikiWeNZSVZNWcfZPItFQOsYTUAOkcUPGd8DqDy1uOUikjt5dG+uRlwyvR108Fb9DOd4GvXfT0N2/uQ==}
|
||||
engines: {node: '>= 12'}
|
||||
|
||||
space-separated-tokens@2.0.2:
|
||||
resolution: {integrity: sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==}
|
||||
|
||||
@@ -4606,6 +4646,11 @@ packages:
|
||||
vfile@6.0.3:
|
||||
resolution: {integrity: sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q==}
|
||||
|
||||
vite-plugin-compression@0.5.1:
|
||||
resolution: {integrity: sha512-5QJKBDc+gNYVqL/skgFAP81Yuzo9R+EAf19d+EtsMF/i8kFUpNi3J/H01QD3Oo8zBQn+NzoCIFkpPLynoOzaJg==}
|
||||
peerDependencies:
|
||||
vite: '>=2.0.0'
|
||||
|
||||
vite-plugin-env-typed@0.0.2:
|
||||
resolution: {integrity: sha512-IloScAeDfhG81diZuvoozs73LvELSG7h3q5Eim035TUbFpou4FanMLpVZqD0lZNH2oMMHILbzx6udmkg3/NFbA==}
|
||||
peerDependencies:
|
||||
@@ -6634,6 +6679,8 @@ snapshots:
|
||||
es-errors: 1.3.0
|
||||
gopd: 1.2.0
|
||||
|
||||
define-lazy-prop@2.0.0: {}
|
||||
|
||||
define-properties@1.2.1:
|
||||
dependencies:
|
||||
define-data-property: 1.1.4
|
||||
@@ -7800,6 +7847,8 @@ snapshots:
|
||||
is-accessor-descriptor: 1.0.1
|
||||
is-data-descriptor: 1.0.1
|
||||
|
||||
is-docker@2.2.1: {}
|
||||
|
||||
is-extendable@0.1.1: {}
|
||||
|
||||
is-extendable@1.0.1:
|
||||
@@ -7909,6 +7958,10 @@ snapshots:
|
||||
|
||||
is-windows@1.0.2: {}
|
||||
|
||||
is-wsl@2.2.0:
|
||||
dependencies:
|
||||
is-docker: 2.2.1
|
||||
|
||||
isarray@1.0.0: {}
|
||||
|
||||
isarray@2.0.5: {}
|
||||
@@ -8668,6 +8721,12 @@ snapshots:
|
||||
dependencies:
|
||||
mimic-function: 5.0.1
|
||||
|
||||
open@8.4.2:
|
||||
dependencies:
|
||||
define-lazy-prop: 2.0.0
|
||||
is-docker: 2.2.1
|
||||
is-wsl: 2.2.0
|
||||
|
||||
optionator@0.9.4:
|
||||
dependencies:
|
||||
deep-is: 0.1.4
|
||||
@@ -9109,6 +9168,15 @@ snapshots:
|
||||
|
||||
rfdc@1.4.1: {}
|
||||
|
||||
rollup-plugin-visualizer@6.0.3(rollup@4.41.1):
|
||||
dependencies:
|
||||
open: 8.4.2
|
||||
picomatch: 4.0.3
|
||||
source-map: 0.7.6
|
||||
yargs: 17.7.2
|
||||
optionalDependencies:
|
||||
rollup: 4.41.1
|
||||
|
||||
rollup@4.41.1:
|
||||
dependencies:
|
||||
'@types/estree': 1.0.7
|
||||
@@ -9388,6 +9456,8 @@ snapshots:
|
||||
|
||||
source-map@0.6.1: {}
|
||||
|
||||
source-map@0.7.6: {}
|
||||
|
||||
space-separated-tokens@2.0.2: {}
|
||||
|
||||
spawndamnit@3.0.1:
|
||||
@@ -9826,7 +9896,7 @@ snapshots:
|
||||
|
||||
unctx@2.4.1:
|
||||
dependencies:
|
||||
acorn: 8.14.1
|
||||
acorn: 8.15.0
|
||||
estree-walker: 3.0.3
|
||||
magic-string: 0.30.17
|
||||
unplugin: 2.3.5
|
||||
@@ -9865,14 +9935,14 @@ snapshots:
|
||||
|
||||
unimport@5.0.1:
|
||||
dependencies:
|
||||
acorn: 8.14.1
|
||||
acorn: 8.15.0
|
||||
escape-string-regexp: 5.0.0
|
||||
estree-walker: 3.0.3
|
||||
local-pkg: 1.1.1
|
||||
magic-string: 0.30.17
|
||||
mlly: 1.7.4
|
||||
pathe: 2.0.3
|
||||
picomatch: 4.0.2
|
||||
picomatch: 4.0.3
|
||||
pkg-types: 2.1.0
|
||||
scule: 1.3.0
|
||||
strip-literal: 3.0.0
|
||||
@@ -10042,6 +10112,15 @@ snapshots:
|
||||
'@types/unist': 3.0.3
|
||||
vfile-message: 4.0.2
|
||||
|
||||
vite-plugin-compression@0.5.1(vite@6.3.5(@types/node@22.15.30)(jiti@2.4.2)(sass-embedded@1.89.2)(yaml@2.8.0)):
|
||||
dependencies:
|
||||
chalk: 4.1.2
|
||||
debug: 4.4.1
|
||||
fs-extra: 10.1.0
|
||||
vite: 6.3.5(@types/node@22.15.30)(jiti@2.4.2)(sass-embedded@1.89.2)(yaml@2.8.0)
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
vite-plugin-env-typed@0.0.2(vite@6.3.5(@types/node@22.15.30)(jiti@2.4.2)(sass-embedded@1.89.2)(yaml@2.8.0)):
|
||||
dependencies:
|
||||
handlebars: 4.7.8
|
||||
|
||||
@@ -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(() => {
|
||||
|
||||
@@ -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">
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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>
|
||||
|
||||
|
||||
@@ -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',
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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`;
|
||||
|
||||
Reference in New Issue
Block a user