|
|
@ -1,4 +1,6 @@ |
|
|
|
<template> |
|
|
|
<!-- 顶部锚点 --> |
|
|
|
<div id="top-anchor" class="top-anchor"></div> |
|
|
|
<div class="ai-emotion-container" ref="userInputDisplayRef"> |
|
|
|
<!-- 金轮 --> |
|
|
|
<div class="golden-wheel"> |
|
|
@ -166,6 +168,13 @@ |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
|
|
|
|
<!-- 返回顶部按钮 --> |
|
|
|
<div class="back-to-top" @click="scrollToTop" v-show="isPageLoaded"> |
|
|
|
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> |
|
|
|
<path d="M12 4L12 20M12 4L6 10M12 4L18 10" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/> |
|
|
|
</svg> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</template> |
|
|
|
|
|
|
@ -297,6 +306,9 @@ const currentOnCompleteCallback = ref(null); |
|
|
|
const audioUrl = ref(''); |
|
|
|
const isAudioPlaying = ref(false); |
|
|
|
|
|
|
|
// 返回顶部按钮相关数据 |
|
|
|
const showBackToTop = ref(false); |
|
|
|
|
|
|
|
// 计算属性 - 从store获取当前股票数据 |
|
|
|
const currentStock = computed(() => emotionStore.activeStock); |
|
|
|
const stockName = computed(() => currentStock.value?.stockInfo.name || ""); |
|
|
@ -1688,6 +1700,46 @@ function triggerAutoScroll() { |
|
|
|
return; |
|
|
|
} |
|
|
|
|
|
|
|
// 返回顶部功能 |
|
|
|
const scrollToTop = () => { |
|
|
|
const topAnchor = document.getElementById('top-anchor'); |
|
|
|
if (topAnchor) { |
|
|
|
topAnchor.scrollIntoView({ |
|
|
|
behavior: 'smooth', |
|
|
|
block: 'start', |
|
|
|
inline: 'nearest' |
|
|
|
}); |
|
|
|
} else { |
|
|
|
window.scrollTo({ top: 0, behavior: 'smooth' }); |
|
|
|
} |
|
|
|
|
|
|
|
// 备用方案:直接滚动到页面顶部 |
|
|
|
setTimeout(() => { |
|
|
|
const currentScrollTop = window.pageYOffset || document.documentElement.scrollTop; |
|
|
|
if (currentScrollTop > 50) { |
|
|
|
document.documentElement.scrollTop = 0; |
|
|
|
document.body.scrollTop = 0; |
|
|
|
} |
|
|
|
}, 1000); |
|
|
|
}; |
|
|
|
|
|
|
|
// 监听页面滚动,控制返回顶部按钮显示 |
|
|
|
const handlePageScroll = () => { |
|
|
|
const scrollTop = window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop; |
|
|
|
showBackToTop.value = scrollTop > 200; |
|
|
|
}; |
|
|
|
|
|
|
|
// 监听容器滚动(备用方案) |
|
|
|
const handleContainerScroll = () => { |
|
|
|
const container = userInputDisplayRef.value; |
|
|
|
if (container) { |
|
|
|
const scrollTop = container.scrollTop; |
|
|
|
if (scrollTop > 200) { |
|
|
|
showBackToTop.value = true; |
|
|
|
} |
|
|
|
} |
|
|
|
}; |
|
|
|
|
|
|
|
// 页面挂载完成后触发图片旋转和设置滚动监听 |
|
|
|
onMounted(async () => { |
|
|
|
// 确保获取用户次数 |
|
|
@ -1758,8 +1810,16 @@ onMounted(async () => { |
|
|
|
container.addEventListener('wheel', handleWheel, { passive: true }); |
|
|
|
container.addEventListener('touchmove', handleTouchMove, { passive: true }); |
|
|
|
container.addEventListener('scroll', handleUserScroll, { passive: true }); |
|
|
|
// 添加容器滚动监听器用于返回顶部按钮 |
|
|
|
container.addEventListener('scroll', handleContainerScroll, { passive: true }); |
|
|
|
} |
|
|
|
|
|
|
|
// 添加页面滚动监听器,控制返回顶部按钮显示 |
|
|
|
window.addEventListener('scroll', handlePageScroll, { passive: true }); |
|
|
|
|
|
|
|
// 添加document滚动监听器(备用方案) |
|
|
|
document.addEventListener('scroll', handlePageScroll, { passive: true }); |
|
|
|
|
|
|
|
// 防抖函数定义 |
|
|
|
function debounce(func, wait) { |
|
|
|
let timeout; |
|
|
@ -1775,6 +1835,8 @@ onMounted(async () => { |
|
|
|
|
|
|
|
startImageRotation(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 检查是否有已保存的股票数据需要恢复 |
|
|
|
if (emotionStore.stockList.length > 0 && emotionStore.activeStock) { |
|
|
|
console.log('检测到已保存的股票数据,开始恢复页面状态(不自动播放音频)'); |
|
|
@ -1845,8 +1907,13 @@ onUnmounted(() => { |
|
|
|
container.removeEventListener('wheel', handleWheel); |
|
|
|
container.removeEventListener('touchmove', handleTouchMove); |
|
|
|
container.removeEventListener('scroll', handleUserScroll); |
|
|
|
container.removeEventListener('scroll', handleContainerScroll); |
|
|
|
} |
|
|
|
|
|
|
|
// 清理页面滚动监听器 |
|
|
|
window.removeEventListener('scroll', handlePageScroll); |
|
|
|
document.removeEventListener('scroll', handlePageScroll); |
|
|
|
|
|
|
|
// 清理滚动定时器 |
|
|
|
if (scrollTimeout.value) { |
|
|
|
clearTimeout(scrollTimeout.value); |
|
|
@ -3229,4 +3296,77 @@ defineExpose({ |
|
|
|
text-shadow: 0 2px 8px rgba(0, 212, 255, 0.5); |
|
|
|
letter-spacing: 1px; |
|
|
|
} |
|
|
|
|
|
|
|
/* 顶部锚点样式 */ |
|
|
|
.top-anchor { |
|
|
|
position: relative; |
|
|
|
top: 0; |
|
|
|
left: 0; |
|
|
|
width: 100%; |
|
|
|
height: 1px; |
|
|
|
display: block; |
|
|
|
visibility: visible; |
|
|
|
opacity: 0; |
|
|
|
pointer-events: none; |
|
|
|
} |
|
|
|
|
|
|
|
/* 返回顶部按钮样式 */ |
|
|
|
.back-to-top { |
|
|
|
position: sticky !important; |
|
|
|
bottom: 20px !important; |
|
|
|
left: calc(100% - 70px) !important; |
|
|
|
width: 50px !important; |
|
|
|
height: 50px !important; |
|
|
|
background: linear-gradient(135deg, #00d4ff 0%, #0066cc 100%) !important; |
|
|
|
border-radius: 50% !important; |
|
|
|
display: flex !important; |
|
|
|
align-items: center !important; |
|
|
|
justify-content: center !important; |
|
|
|
cursor: pointer !important; |
|
|
|
box-shadow: 0 4px 15px rgba(0, 212, 255, 0.3) !important; |
|
|
|
transition: all 0.3s ease !important; |
|
|
|
z-index: 100 !important; |
|
|
|
color: white !important; |
|
|
|
opacity: 1 !important; |
|
|
|
visibility: visible !important; |
|
|
|
margin-top: 20px !important; |
|
|
|
margin-bottom: 20px !important; |
|
|
|
} |
|
|
|
|
|
|
|
.back-to-top:hover { |
|
|
|
transform: translateY(-3px); |
|
|
|
box-shadow: 0 6px 20px rgba(0, 212, 255, 0.5); |
|
|
|
background: linear-gradient(135deg, #00e6ff 0%, #0077dd 100%); |
|
|
|
} |
|
|
|
|
|
|
|
.back-to-top:active { |
|
|
|
transform: translateY(-1px); |
|
|
|
} |
|
|
|
|
|
|
|
/* class01容器样式 */ |
|
|
|
.class01 { |
|
|
|
position: relative; |
|
|
|
} |
|
|
|
|
|
|
|
/* 移动端适配 */ |
|
|
|
@media only screen and (max-width: 768px) { |
|
|
|
.back-to-top { |
|
|
|
left: calc(100% - 65px) !important; |
|
|
|
width: 45px !important; |
|
|
|
height: 45px !important; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
@media only screen and (max-width: 480px) { |
|
|
|
.back-to-top { |
|
|
|
left: calc(100% - 60px) !important; |
|
|
|
width: 40px !important; |
|
|
|
height: 40px !important; |
|
|
|
} |
|
|
|
|
|
|
|
.back-to-top svg { |
|
|
|
width: 20px; |
|
|
|
height: 20px; |
|
|
|
} |
|
|
|
} |
|
|
|
</style> |