feat: 新手引导优化
This commit is contained in:
@@ -7,6 +7,7 @@ import { getQrCode, getQrCodeResult, getUserInfo } from '@/api';
|
||||
import { useUserStore } from '@/stores';
|
||||
import { useSessionStore } from '@/stores/modules/session.ts';
|
||||
import { WECHAT_QRCODE_TYPE } from '@/utils/user.ts';
|
||||
import { useGuideTour } from '@/hooks/useGuideTour';
|
||||
|
||||
const props = defineProps({
|
||||
type: {
|
||||
@@ -29,6 +30,7 @@ const userStore = useUserStore();
|
||||
const router = useRouter();
|
||||
const sessionStore = useSessionStore();
|
||||
const isQrCodeError = ref(false);
|
||||
const { startFullTour } = useGuideTour();
|
||||
// 二维码倒计时实例
|
||||
const { start: qrStart, stop: qrStop } = useCountdown(shallowRef(600), {
|
||||
interval: 1000,
|
||||
@@ -126,6 +128,11 @@ async function handleLoginSuccess(token: string, refreshToken: string) {
|
||||
stopPolling();
|
||||
userStore.setToken(token, refreshToken);
|
||||
const resUserInfo = await getUserInfo();
|
||||
|
||||
// 判断是否为新用户(注册时间小于1小时)
|
||||
const creationTime = resUserInfo.data.user.creationTime; // 格式: "2024-11-01 12:01:34"
|
||||
const isNewUser = checkIsNewUser(creationTime);
|
||||
|
||||
userStore.setUserInfo(resUserInfo.data);
|
||||
// 提示用户
|
||||
ElMessage.success('登录成功');
|
||||
@@ -133,6 +140,34 @@ async function handleLoginSuccess(token: string, refreshToken: string) {
|
||||
await router.replace('/');
|
||||
await sessionStore.requestSessionList(1, true);
|
||||
userStore.closeLoginDialog();
|
||||
|
||||
// 如果是新用户,延迟500ms后自动触发新手引导
|
||||
if (isNewUser) {
|
||||
setTimeout(() => {
|
||||
startFullTour();
|
||||
}, 500);
|
||||
}
|
||||
}
|
||||
|
||||
// 判断是否为新用户(注册时间距离当前时间小于1小时)
|
||||
function checkIsNewUser(creationTimeStr: string): boolean {
|
||||
try {
|
||||
// 解析注册时间字符串 "2024-11-01 12:01:34"
|
||||
const creationTime = new Date(creationTimeStr.replace(' ', 'T'));
|
||||
const currentTime = new Date();
|
||||
|
||||
// 计算时间差(毫秒)
|
||||
const timeDiff = currentTime.getTime() - creationTime.getTime();
|
||||
|
||||
// 1小时 = 60分钟 * 60秒 * 1000毫秒 = 3600000毫秒
|
||||
const oneHourInMs = 60 * 60 * 1000;
|
||||
|
||||
return timeDiff < oneHourInMs;
|
||||
}
|
||||
catch (error) {
|
||||
console.error('解析注册时间失败:', error);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// 处理注册授权
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { driver } from 'driver.js';
|
||||
import 'driver.js/dist/driver.css';
|
||||
import { useGuideTourStore } from '@/stores';
|
||||
import 'driver.js/dist/driver.css';
|
||||
|
||||
// 引导步骤接口
|
||||
interface TourStep {
|
||||
@@ -47,7 +47,7 @@ export function useGuideTour() {
|
||||
element: '[data-tour="tutorial-btn"]',
|
||||
popover: {
|
||||
title: '新手教程',
|
||||
description: '欢迎使用YiXinAI!点击这里可以随时重新查看新手引导教程,帮助您快速了解系统功能。',
|
||||
description: '欢迎使用意心AI-YiXinAI!点击这里可以随时重新查看新手引导教程,帮助您快速了解系统功能。',
|
||||
side: 'bottom',
|
||||
align: 'center',
|
||||
},
|
||||
@@ -56,7 +56,7 @@ export function useGuideTour() {
|
||||
element: '[data-tour="model-select"]',
|
||||
popover: {
|
||||
title: '模型选择',
|
||||
description: '点击这里可以切换不同的AI模型,每个模型有不同的特点和能力。VIP用户可以使用所有高级模型。',
|
||||
description: '点击这里可以切换不同的AI模型,每个模型有不同的特点和能力。VIP用户可以更多高级模型。',
|
||||
side: 'top',
|
||||
align: 'start',
|
||||
},
|
||||
@@ -65,7 +65,7 @@ export function useGuideTour() {
|
||||
element: '[data-tour="chat-sender"]',
|
||||
popover: {
|
||||
title: '对话输入框',
|
||||
description: '在这里输入您的问题或指令,按回车或点击发送按钮即可与AI对话。支持语音输入和文件上传。',
|
||||
description: '在这里输入您的问题或指令,按回车或点击发送按钮即可与AI对话。支持语音输入',
|
||||
side: 'top',
|
||||
align: 'center',
|
||||
},
|
||||
@@ -92,7 +92,7 @@ export function useGuideTour() {
|
||||
element: '[data-tour="buy-btn"]',
|
||||
popover: {
|
||||
title: '立即购买',
|
||||
description: '点击这里可以购买Token套餐或升级VIP会员,享受更多专属服务和权益。',
|
||||
description: '点击这里可以成为VIP会员和升级尊享服务,享受更多专属服务和权益。',
|
||||
side: 'bottom',
|
||||
align: 'center',
|
||||
},
|
||||
@@ -123,7 +123,7 @@ export function useGuideTour() {
|
||||
element: '[data-tour="nav-user"]',
|
||||
popover: {
|
||||
title: '用户信息',
|
||||
description: '查看和修改您的个人信息,包括头像、昵称等。',
|
||||
description: '查看您的个人信息,包括头像、昵称等。',
|
||||
side: 'right',
|
||||
align: 'center',
|
||||
},
|
||||
@@ -171,7 +171,7 @@ export function useGuideTour() {
|
||||
element: '[data-tour="nav-premiumService"]',
|
||||
popover: {
|
||||
title: '尊享服务',
|
||||
description: '了解VIP会员专属特权和服务,我们将详细介绍这个页面的功能。',
|
||||
description: '了解尊享服务包专属特权和服务,我们将详细介绍这个页面的功能。',
|
||||
side: 'right',
|
||||
align: 'center',
|
||||
},
|
||||
@@ -250,7 +250,6 @@ export function useGuideTour() {
|
||||
},
|
||||
];
|
||||
|
||||
|
||||
// 开始 Header 引导
|
||||
async function startHeaderTour() {
|
||||
if (!driverInstance.value) {
|
||||
|
||||
@@ -32,7 +32,10 @@ function openAnnouncement() {
|
||||
class="announcement-btn"
|
||||
@click="openAnnouncement"
|
||||
>
|
||||
<el-icon :size="20">
|
||||
<!-- PC端显示文字 -->
|
||||
<span class="pc-text">公告/活动</span>
|
||||
<!-- 移动端显示图标 -->
|
||||
<el-icon class="mobile-icon" :size="20">
|
||||
<Bell />
|
||||
</el-icon>
|
||||
</div>
|
||||
@@ -44,65 +47,52 @@ function openAnnouncement() {
|
||||
.announcement-btn-container {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-right: 12px;
|
||||
|
||||
.announcement-badge {
|
||||
:deep(.el-badge__content) {
|
||||
background-color: #f56c6c;
|
||||
border: none;
|
||||
//font-size: 12px;
|
||||
//height: 18px;
|
||||
//line-height: 18px;
|
||||
//padding: 0 6px;
|
||||
}
|
||||
}
|
||||
|
||||
.announcement-btn {
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
border-radius: 50%;
|
||||
background: transparent;
|
||||
gap: 6px;
|
||||
cursor: pointer;
|
||||
transition: all 0.3s;
|
||||
|
||||
.el-icon {
|
||||
color: #606266;
|
||||
transition: color 0.3s;
|
||||
}
|
||||
font-size: 1.2rem;
|
||||
font-weight: bold;
|
||||
color: #e6a23c;
|
||||
transition: all 0.2s;
|
||||
|
||||
&:hover {
|
||||
background: rgba(0, 0, 0, 0.05);
|
||||
color: #ebb563;
|
||||
transform: translateY(-1px);
|
||||
}
|
||||
|
||||
.el-icon {
|
||||
color: #409eff;
|
||||
}
|
||||
// PC端显示文字,隐藏图标
|
||||
.pc-text {
|
||||
display: inline;
|
||||
margin: 0 12px;
|
||||
|
||||
}
|
||||
|
||||
.mobile-icon {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 移动端适配
|
||||
@media screen and (max-width: 768px) {
|
||||
// 移动端显示图标,隐藏文字
|
||||
@media (max-width: 768px) {
|
||||
.announcement-btn-container {
|
||||
margin-right: 8px;
|
||||
|
||||
.announcement-btn {
|
||||
width: 36px;
|
||||
height: 36px;
|
||||
|
||||
.el-icon {
|
||||
font-size: 18px;
|
||||
.pc-text {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
.announcement-badge {
|
||||
:deep(.el-badge__content) {
|
||||
//font-size: 10px;
|
||||
//height: 16px;
|
||||
//line-height: 16px;
|
||||
//padding: 0 4px;
|
||||
.mobile-icon {
|
||||
display: inline;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,16 +12,17 @@ function handleStartTutorial() {
|
||||
|
||||
<template>
|
||||
<div class="tutorial-btn-container" data-tour="tutorial-btn">
|
||||
<el-tooltip content="新手教程" placement="bottom">
|
||||
<div
|
||||
class="tutorial-btn"
|
||||
@click="handleStartTutorial"
|
||||
>
|
||||
<el-icon :size="20">
|
||||
<QuestionFilled />
|
||||
</el-icon>
|
||||
</div>
|
||||
</el-tooltip>
|
||||
<div
|
||||
class="tutorial-btn"
|
||||
@click="handleStartTutorial"
|
||||
>
|
||||
<!-- PC端显示文字 -->
|
||||
<span class="pc-text">新手引导</span>
|
||||
<!-- 移动端显示图标 -->
|
||||
<el-icon class="mobile-icon" :size="20">
|
||||
<QuestionFilled />
|
||||
</el-icon>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -29,45 +30,44 @@ function handleStartTutorial() {
|
||||
.tutorial-btn-container {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-right: 12px;
|
||||
|
||||
.tutorial-btn {
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
border-radius: 50%;
|
||||
background: transparent;
|
||||
gap: 6px;
|
||||
cursor: pointer;
|
||||
transition: all 0.3s;
|
||||
|
||||
.el-icon {
|
||||
color: #606266;
|
||||
transition: color 0.3s;
|
||||
}
|
||||
font-size: 1.2rem;
|
||||
font-weight: bold;
|
||||
color: #409eff;
|
||||
transition: all 0.2s;
|
||||
|
||||
&:hover {
|
||||
background: rgba(0, 0, 0, 0.05);
|
||||
color: #66b1ff;
|
||||
transform: translateY(-1px);
|
||||
}
|
||||
|
||||
.el-icon {
|
||||
color: #409eff;
|
||||
}
|
||||
// PC端显示文字,隐藏图标
|
||||
.pc-text {
|
||||
display: inline;
|
||||
margin: 0 12px;
|
||||
}
|
||||
|
||||
.mobile-icon {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 移动端适配
|
||||
@media screen and (max-width: 768px) {
|
||||
// 移动端显示图标,隐藏文字
|
||||
@media (max-width: 768px) {
|
||||
.tutorial-btn-container {
|
||||
margin-right: 8px;
|
||||
|
||||
.tutorial-btn {
|
||||
width: 36px;
|
||||
height: 36px;
|
||||
.pc-text {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.el-icon {
|
||||
font-size: 18px;
|
||||
.mobile-icon {
|
||||
display: inline;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -71,8 +71,8 @@ onKeyStroke(event => event.ctrlKey && event.key.toLowerCase() === 'k', handleCtr
|
||||
|
||||
<!-- 右边 -->
|
||||
<div class="right-box flex h-full items-center pr-20px flex-shrink-0 mr-auto flex-row">
|
||||
<TutorialBtn />
|
||||
<AnnouncementBtn />
|
||||
<TutorialBtn />
|
||||
<Avatar v-show="userStore.userInfo" />
|
||||
<LoginBtn v-show="!userStore.userInfo" />
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user