feat: 增加新手引导

This commit is contained in:
Gsh
2025-11-17 01:05:57 +08:00
parent 7919383be3
commit 695bd56a27
16 changed files with 734 additions and 15 deletions

View File

@@ -20,7 +20,7 @@ function openAnnouncement() {
</script>
<template>
<div class="announcement-btn-container">
<div class="announcement-btn-container" data-tour="announcement-btn">
<el-badge
is-dot
class="announcement-badge"

View File

@@ -6,7 +6,8 @@ import { computed, nextTick, onMounted, ref, watch } from 'vue';
import { useRouter } from 'vue-router';
import Popover from '@/components/Popover/index.vue';
import SvgIcon from '@/components/SvgIcon/index.vue';
import { useUserStore } from '@/stores';
import { useGuideTour } from '@/hooks/useGuideTour';
import { useGuideTourStore, useUserStore } from '@/stores';
import { useSessionStore } from '@/stores/modules/session';
import { showProductPackage } from '@/utils/product-package';
import { getUserProfilePicture, isUserVip } from '@/utils/user';
@@ -15,6 +16,8 @@ const router = useRouter();
const userStore = useUserStore();
const sessionStore = useSessionStore();
const guideTourStore = useGuideTourStore();
const { startUserCenterTour } = useGuideTour();
// const src = computed(
// () => userStore.userInfo?.avatar ?? 'https://avatars.githubusercontent.com/u/76239030',
@@ -243,6 +246,34 @@ onMounted(() => {
// URL 参数会在对话框关闭时清除
}
});
// ============ 监听引导状态,自动打开用户中心并开始引导 ============
watch(() => guideTourStore.shouldStartUserCenterTour, (shouldStart) => {
if (shouldStart) {
// 清除触发标记
guideTourStore.clearUserCenterTourTrigger();
// 注册导航切换回调
guideTourStore.setUserCenterNavChangeCallback((nav: string) => {
activeNav.value = nav;
});
// 注册关闭弹窗回调
guideTourStore.setUserCenterCloseCallback(() => {
dialogVisible.value = false;
});
// 打开用户中心弹窗
nextTick(() => {
dialogVisible.value = true;
// 等待弹窗打开后开始引导
setTimeout(() => {
startUserCenterTour();
}, 600);
});
}
});
</script>
<template>
@@ -259,7 +290,7 @@ onMounted(() => {
<!-- </a> -->
<!-- </div> -->
<div class="text-1.2xl font-bold text-gray-800 hover:text-blue-600 transition-colors">
<div class="text-1.2xl font-bold text-gray-800 hover:text-blue-600 transition-colors" data-tour="ai-tutorial-link">
<a
href="https://ccnetcore.com/article/3a1bc4d1-6a7d-751d-91cc-2817eb2ddcde"
target="_blank"
@@ -292,6 +323,7 @@ onMounted(() => {
<el-button
class="buy-btn flex items-center gap-2 px-5 py-2 font-semibold shadow-lg"
data-tour="buy-btn"
@click="onProductPackage"
>
<span>立即购买</span>
@@ -321,7 +353,7 @@ onMounted(() => {
</div>
<!-- 头像区域 -->
<div class="avatar-container">
<div class="avatar-container" data-tour="user-avatar">
<Popover
ref="popoverRef"
placement="bottom-end"

View File

@@ -0,0 +1,75 @@
<script setup lang="ts">
import { QuestionFilled } from '@element-plus/icons-vue';
import { useGuideTour } from '@/hooks/useGuideTour';
const { startHeaderTour } = useGuideTour();
// 开始引导教程
function handleStartTutorial() {
startHeaderTour();
}
</script>
<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>
</template>
<style scoped lang="scss">
.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;
cursor: pointer;
transition: all 0.3s;
.el-icon {
color: #606266;
transition: color 0.3s;
}
&:hover {
background: rgba(0, 0, 0, 0.05);
.el-icon {
color: #409eff;
}
}
}
}
// 移动端适配
@media screen and (max-width: 768px) {
.tutorial-btn-container {
margin-right: 8px;
.tutorial-btn {
width: 36px;
height: 36px;
.el-icon {
font-size: 18px;
}
}
}
}
</style>

View File

@@ -10,6 +10,7 @@ import Collapse from './components/Collapse.vue';
import CreateChat from './components/CreateChat.vue';
import LoginBtn from './components/LoginBtn.vue';
import TitleEditing from './components/TitleEditing.vue';
import TutorialBtn from './components/TutorialBtn.vue';
const userStore = useUserStore();
const designStore = useDesignStore();
@@ -70,6 +71,7 @@ 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 />
<Avatar v-show="userStore.userInfo" />
<LoginBtn v-show="!userStore.userInfo" />