parent
b2ccf76fd0
commit
1f42e5d713
|
|
@ -1,405 +0,0 @@
|
||||||
<template>
|
|
||||||
<div class="spring-couple-container">
|
|
||||||
<!-- 背景图 -->
|
|
||||||
<div class="background">
|
|
||||||
<img
|
|
||||||
v-lazy="backgroundImage"
|
|
||||||
alt="四合院背景"
|
|
||||||
@error="handleImageError"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- 春联展示区 -->
|
|
||||||
<div class="couplet-display" v-if="couplet">
|
|
||||||
<div class="couplet-item top-couplet">{{ couplet.top }}</div>
|
|
||||||
<div class="couplet-item bottom-couplet">{{ couplet.bottom }}</div>
|
|
||||||
<div class="couplet-item横批">{{ couplet.横批 }}</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- 输入区域 -->
|
|
||||||
<div class="input-section">
|
|
||||||
<h2 class="title">AI春联生成</h2>
|
|
||||||
<p class="subtitle">输入两个字的关键词,生成个性化春联</p>
|
|
||||||
|
|
||||||
<div class="input-container">
|
|
||||||
<input
|
|
||||||
v-model="keyword"
|
|
||||||
type="text"
|
|
||||||
placeholder="请输入关键词(如:吉祥、如意)"
|
|
||||||
maxlength="2"
|
|
||||||
@input="handleKeywordInput"
|
|
||||||
class="keyword-input"
|
|
||||||
/>
|
|
||||||
<button
|
|
||||||
@click="generateCouple"
|
|
||||||
:disabled="loading || keyword.length < 2"
|
|
||||||
class="generate-btn"
|
|
||||||
>
|
|
||||||
<span v-if="loading">生成中...</span>
|
|
||||||
<span v-else>生成春联</span>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- 推荐关键词 -->
|
|
||||||
<div class="recommended-keywords">
|
|
||||||
<span
|
|
||||||
v-for="word in recommendedWords"
|
|
||||||
:key="word"
|
|
||||||
@click="selectKeyword(word)"
|
|
||||||
class="keyword-tag"
|
|
||||||
>
|
|
||||||
{{ word }}
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- 分享按钮 -->
|
|
||||||
<div class="share-section" v-if="couplet">
|
|
||||||
<button @click="shareCouple" class="share-btn">
|
|
||||||
📤 分享春联
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- 加载动画 -->
|
|
||||||
<div v-if="loading" class="loading-overlay">
|
|
||||||
<uni-spinner type="circle" size="48" color="#fff"></uni-spinner>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup>
|
|
||||||
import { ref, reactive } from 'vue';
|
|
||||||
import { generateSpringCouple } from '../api/ai';
|
|
||||||
import { share } from '../utils/share';
|
|
||||||
|
|
||||||
// 响应式数据
|
|
||||||
const keyword = ref('');
|
|
||||||
const couplet = ref(null);
|
|
||||||
const loading = ref(false);
|
|
||||||
const backgroundImage = ref('https://placeholder.pics/svg/640x1136/E8F5E9/4CAF50/四合院背景');
|
|
||||||
|
|
||||||
// 推荐关键词
|
|
||||||
const recommendedWords = [
|
|
||||||
'吉祥', '如意', '幸福', '安康', '财源', '富贵', '团圆', '快乐',
|
|
||||||
'平安', '健康', '顺利', '成功', '美满', '和谐', '兴旺', '发达'
|
|
||||||
];
|
|
||||||
|
|
||||||
// 处理关键词输入
|
|
||||||
const handleKeywordInput = () => {
|
|
||||||
// 限制关键词长度为2个字符
|
|
||||||
if (keyword.value.length > 2) {
|
|
||||||
keyword.value = keyword.value.slice(0, 2);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// 选择推荐关键词
|
|
||||||
const selectKeyword = (word) => {
|
|
||||||
keyword.value = word;
|
|
||||||
generateCouple();
|
|
||||||
};
|
|
||||||
|
|
||||||
// 生成春联
|
|
||||||
const generateCouple = async () => {
|
|
||||||
if (!keyword.value || keyword.value.length < 2) {
|
|
||||||
uni.uni.showToast({title: '请输入两个字的关键词', duration: 2000});
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
loading.value = true;
|
|
||||||
|
|
||||||
try {
|
|
||||||
const result = await generateSpringCouple(keyword.value);
|
|
||||||
|
|
||||||
if (result.code === 200) {
|
|
||||||
couplet.value = result.data;
|
|
||||||
uni.uni.showToast({title: '春联生成成功', duration: 2000});
|
|
||||||
// 添加生成动画效果
|
|
||||||
setTimeout(() => {
|
|
||||||
const coupletElements = document.querySelectorAll('.couplet-item');
|
|
||||||
coupletElements.forEach((el, index) => {
|
|
||||||
el.style.opacity = '0';
|
|
||||||
el.style.transform = 'translateY(20px)';
|
|
||||||
|
|
||||||
setTimeout(() => {
|
|
||||||
el.style.transition = 'opacity 0.5s ease, transform 0.5s ease';
|
|
||||||
el.style.opacity = '1';
|
|
||||||
el.style.transform = 'translateY(0)';
|
|
||||||
}, index * 200);
|
|
||||||
});
|
|
||||||
}, 100);
|
|
||||||
} else {
|
|
||||||
uni.uni.showToast({title: '生成失败,请重试', duration: 2000});
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
console.error('生成春联失败:', error);
|
|
||||||
uni.uni.showToast({title: '网络异常,请稍后重试', duration: 2000});
|
|
||||||
} finally {
|
|
||||||
loading.value = false;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// 分享春联
|
|
||||||
const shareCouple = () => {
|
|
||||||
if (!couplet.value) {
|
|
||||||
uni.uni.showToast({title: '请先生成春联', duration: 2000});
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const shareText = `
|
|
||||||
我用AI生成了一副春联:
|
|
||||||
${couplet.value.top}
|
|
||||||
${couplet.value.bottom}
|
|
||||||
${couplet.value.横批}
|
|
||||||
#2026新春东城商圈#
|
|
||||||
`;
|
|
||||||
|
|
||||||
// 调用分享工具函数
|
|
||||||
share({
|
|
||||||
title: 'AI春联生成',
|
|
||||||
text: shareText,
|
|
||||||
image: backgroundImage.value
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
// 处理图片加载错误
|
|
||||||
const handleImageError = (event) => {
|
|
||||||
event.target.src = 'https://placeholder.pics/svg/640x1136/E8F5E9/4CAF50/四合院背景';
|
|
||||||
};
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped>
|
|
||||||
.spring-couple-container {
|
|
||||||
position: relative;
|
|
||||||
min-height: 100vh;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
align-items: center;
|
|
||||||
padding: 20px;
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
|
||||||
|
|
||||||
.background {
|
|
||||||
position: absolute;
|
|
||||||
top: 0;
|
|
||||||
left: 0;
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
z-index: -1;
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
|
||||||
|
|
||||||
.background img {
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
object-fit: cover;
|
|
||||||
}
|
|
||||||
|
|
||||||
.couplet-display {
|
|
||||||
position: relative;
|
|
||||||
width: 100%;
|
|
||||||
max-width: 600px;
|
|
||||||
margin: 40px 0;
|
|
||||||
padding: 60px 20px;
|
|
||||||
display: flex;
|
|
||||||
justify-content: space-between;
|
|
||||||
align-items: center;
|
|
||||||
z-index: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
.couplet-item {
|
|
||||||
font-family: 'STKaiti', 'Kaiti SC', serif;
|
|
||||||
font-size: 24px;
|
|
||||||
font-weight: bold;
|
|
||||||
color: #e67e22;
|
|
||||||
text-align: center;
|
|
||||||
line-height: 1.8;
|
|
||||||
writing-mode: vertical-rl;
|
|
||||||
text-orientation: upright;
|
|
||||||
text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.3);
|
|
||||||
opacity: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.top-couplet,
|
|
||||||
.bottom-couplet {
|
|
||||||
width: 60px;
|
|
||||||
height: 240px;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.横批 {
|
|
||||||
position: absolute;
|
|
||||||
top: 20px;
|
|
||||||
left: 50%;
|
|
||||||
transform: translateX(-50%);
|
|
||||||
writing-mode: horizontal-tb;
|
|
||||||
font-size: 32px;
|
|
||||||
width: 200px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.input-section {
|
|
||||||
background: rgba(255, 255, 255, 0.9);
|
|
||||||
border-radius: 20px;
|
|
||||||
padding: 30px;
|
|
||||||
width: 100%;
|
|
||||||
max-width: 500px;
|
|
||||||
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.1);
|
|
||||||
backdrop-filter: blur(10px);
|
|
||||||
z-index: 2;
|
|
||||||
margin-top: auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
.title {
|
|
||||||
font-size: 28px;
|
|
||||||
color: #e67e22;
|
|
||||||
margin-bottom: 10px;
|
|
||||||
text-align: center;
|
|
||||||
font-weight: bold;
|
|
||||||
}
|
|
||||||
|
|
||||||
.subtitle {
|
|
||||||
font-size: 16px;
|
|
||||||
color: #666;
|
|
||||||
margin-bottom: 25px;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.input-container {
|
|
||||||
display: flex;
|
|
||||||
gap: 10px;
|
|
||||||
margin-bottom: 25px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.keyword-input {
|
|
||||||
flex: 1;
|
|
||||||
padding: 15px;
|
|
||||||
border: 2px solid #ddd;
|
|
||||||
border-radius: 10px;
|
|
||||||
font-size: 18px;
|
|
||||||
text-align: center;
|
|
||||||
transition: border-color 0.3s ease;
|
|
||||||
}
|
|
||||||
|
|
||||||
.keyword-input:focus {
|
|
||||||
outline: none;
|
|
||||||
border-color: #e67e22;
|
|
||||||
}
|
|
||||||
|
|
||||||
.generate-btn {
|
|
||||||
padding: 15px 25px;
|
|
||||||
background: linear-gradient(135deg, #e67e22, #d35400);
|
|
||||||
color: white;
|
|
||||||
border: none;
|
|
||||||
border-radius: 10px;
|
|
||||||
font-size: 18px;
|
|
||||||
font-weight: bold;
|
|
||||||
cursor: pointer;
|
|
||||||
transition: all 0.3s ease;
|
|
||||||
}
|
|
||||||
|
|
||||||
.generate-btn:hover:not(:disabled) {
|
|
||||||
transform: translateY(-2px);
|
|
||||||
box-shadow: 0 4px 12px rgba(230, 126, 34, 0.4);
|
|
||||||
}
|
|
||||||
|
|
||||||
.generate-btn:disabled {
|
|
||||||
background: #ddd;
|
|
||||||
cursor: not-allowed;
|
|
||||||
}
|
|
||||||
|
|
||||||
.recommended-keywords {
|
|
||||||
display: flex;
|
|
||||||
flex-wrap: wrap;
|
|
||||||
gap: 10px;
|
|
||||||
justify-content: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.keyword-tag {
|
|
||||||
padding: 8px 16px;
|
|
||||||
background: #f39c12;
|
|
||||||
color: white;
|
|
||||||
border-radius: 20px;
|
|
||||||
font-size: 14px;
|
|
||||||
cursor: pointer;
|
|
||||||
transition: all 0.3s ease;
|
|
||||||
}
|
|
||||||
|
|
||||||
.keyword-tag:hover {
|
|
||||||
background: #e67e22;
|
|
||||||
transform: translateY(-2px);
|
|
||||||
}
|
|
||||||
|
|
||||||
.share-section {
|
|
||||||
margin-top: 20px;
|
|
||||||
margin-bottom: 20px;
|
|
||||||
z-index: 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
.share-btn {
|
|
||||||
padding: 15px 30px;
|
|
||||||
background: linear-gradient(135deg, #3498db, #2980b9);
|
|
||||||
color: white;
|
|
||||||
border: none;
|
|
||||||
border-radius: 25px;
|
|
||||||
font-size: 18px;
|
|
||||||
font-weight: bold;
|
|
||||||
cursor: pointer;
|
|
||||||
transition: all 0.3s ease;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
gap: 8px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.share-btn:hover {
|
|
||||||
transform: translateY(-2px);
|
|
||||||
box-shadow: 0 4px 12px rgba(52, 152, 219, 0.4);
|
|
||||||
}
|
|
||||||
|
|
||||||
.loading-overlay {
|
|
||||||
position: fixed;
|
|
||||||
top: 0;
|
|
||||||
left: 0;
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
background: rgba(0, 0, 0, 0.5);
|
|
||||||
display: flex;
|
|
||||||
justify-content: center;
|
|
||||||
align-items: center;
|
|
||||||
z-index: 999;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 响应式设计 */
|
|
||||||
@media (max-width: 480px) {
|
|
||||||
.spring-couple-container {
|
|
||||||
padding: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.couplet-item {
|
|
||||||
font-size: 20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.top-couplet,
|
|
||||||
.bottom-couplet {
|
|
||||||
height: 200px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.input-section {
|
|
||||||
padding: 20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.title {
|
|
||||||
font-size: 24px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.keyword-input,
|
|
||||||
.generate-btn {
|
|
||||||
font-size: 16px;
|
|
||||||
padding: 12px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.input-container {
|
|
||||||
flex-direction: column;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
@ -1,437 +0,0 @@
|
||||||
<script setup>
|
|
||||||
import { ref, onMounted, computed } from 'vue'
|
|
||||||
import { useRouter } from 'vue-router'
|
|
||||||
import { useSceneStore } from '../../src/store/scene'
|
|
||||||
import { useCollectionStore } from '../../src/store/collection'
|
|
||||||
import LongImageViewer from '../components/LongImageViewer.vue'
|
|
||||||
import MediaPlayer from '../components/MediaPlayer.vue'
|
|
||||||
|
|
||||||
const router = useRouter()
|
|
||||||
const sceneStore = useSceneStore()
|
|
||||||
const collectionStore = useCollectionStore()
|
|
||||||
|
|
||||||
// 场景数据
|
|
||||||
const sceneData = ref({
|
|
||||||
id: 'chongwen',
|
|
||||||
name: '崇文商圈',
|
|
||||||
description: '融合传统文化与现代商业的活力区域',
|
|
||||||
image: 'https://picsum.photos/id/1016/750/1600', // 长图占位图
|
|
||||||
thumbnail: 'https://picsum.photos/id/1016/200/100',
|
|
||||||
location: '北京市东城区崇文门外大街',
|
|
||||||
history: '崇文商圈历史悠久,曾是明清时期的文化中心,如今成为现代化的商业区域。',
|
|
||||||
attractions: [
|
|
||||||
{ name: '北京新世界百货', description: '大型综合性购物中心' },
|
|
||||||
{ name: '红桥市场', description: '著名的珍珠和工艺品市场' },
|
|
||||||
{ name: '天坛公园', description: '世界文化遗产,明清皇帝祭天的场所' }
|
|
||||||
],
|
|
||||||
audio: 'https://example.com/audio/chongwen.mp3', // 音频占位符
|
|
||||||
video: 'https://example.com/video/chongwen.mp4' // 视频占位符
|
|
||||||
})
|
|
||||||
|
|
||||||
// 交互状态
|
|
||||||
const isInteractive = ref(false)
|
|
||||||
const sealCollected = ref(false)
|
|
||||||
const showInfoPanel = ref(false)
|
|
||||||
|
|
||||||
// 福印收集状态
|
|
||||||
const sealStatus = computed(() => {
|
|
||||||
return collectionStore.isSceneSealCollected(sceneData.value.id)
|
|
||||||
})
|
|
||||||
|
|
||||||
// 组件挂载后初始化
|
|
||||||
onMounted(() => {
|
|
||||||
// 激活当前场景
|
|
||||||
sceneStore.activateScene(sceneData.value.id)
|
|
||||||
|
|
||||||
// 设置当前场景索引
|
|
||||||
const sceneIndex = sceneStore.scenes.findIndex(scene => scene.id === sceneData.value.id)
|
|
||||||
if (sceneIndex !== -1) {
|
|
||||||
sceneStore.setCurrentScene(sceneIndex)
|
|
||||||
}
|
|
||||||
|
|
||||||
// 检查福印是否已收集
|
|
||||||
sealCollected.value = sealStatus.value
|
|
||||||
})
|
|
||||||
|
|
||||||
// 点击场景交互区域
|
|
||||||
const handleSceneInteraction = () => {
|
|
||||||
if (!isInteractive.value) {
|
|
||||||
isInteractive.value = true
|
|
||||||
|
|
||||||
// 模拟交互过程
|
|
||||||
setTimeout(() => {
|
|
||||||
collectSeal()
|
|
||||||
}, 1000)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 收集福印
|
|
||||||
const collectSeal = () => {
|
|
||||||
if (!sealCollected.value) {
|
|
||||||
const success = collectionStore.collectSealBySceneId(sceneData.value.id)
|
|
||||||
if (success) {
|
|
||||||
sealCollected.value = true
|
|
||||||
showToast({
|
|
||||||
message: '恭喜获得崇文门福印!',
|
|
||||||
icon: 'success',
|
|
||||||
duration: 2000
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
showFailToast({
|
|
||||||
message: '福印收集失败',
|
|
||||||
duration: 2000
|
|
||||||
})
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
showToast({
|
|
||||||
message: '福印已收集',
|
|
||||||
duration: 1500
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 查看场景信息
|
|
||||||
const showSceneInfo = () => {
|
|
||||||
showInfoPanel.value = true
|
|
||||||
}
|
|
||||||
|
|
||||||
// 关闭信息面板
|
|
||||||
const closeInfoPanel = () => {
|
|
||||||
showInfoPanel.value = false
|
|
||||||
}
|
|
||||||
|
|
||||||
// 跳转到下一个场景
|
|
||||||
const goToNextScene = () => {
|
|
||||||
router.push('/wangfujing')
|
|
||||||
}
|
|
||||||
|
|
||||||
// 跳转到上一个场景
|
|
||||||
const goToPreviousScene = () => {
|
|
||||||
router.push('/qianmen')
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<template>
|
|
||||||
<div class="scene-page">
|
|
||||||
<!-- 场景标题 -->
|
|
||||||
<div class="scene-header">
|
|
||||||
<h1 class="scene-title">{{ sceneData.name }}</h1>
|
|
||||||
<p class="scene-description">{{ sceneData.description }}</p>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- 长图查看器 -->
|
|
||||||
<div class="long-image-container">
|
|
||||||
<LongImageViewer
|
|
||||||
:image-url="sceneData.image"
|
|
||||||
:description="sceneData.name"
|
|
||||||
@click="handleSceneInteraction"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- 交互提示 -->
|
|
||||||
<div class="interaction-tip" v-if="!isInteractive">
|
|
||||||
<div class="tip-icon">👆</div>
|
|
||||||
<p>点击图片查看详情</p>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- 福印收集提示 -->
|
|
||||||
<div class="seal-collect-tip" v-if="sealCollected">
|
|
||||||
<div class="seal-icon">🏮</div>
|
|
||||||
<p>已收集崇文福印</p>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- 场景信息面板 -->
|
|
||||||
<div class="info-panel" v-if="showInfoPanel">
|
|
||||||
<div class="info-panel-content">
|
|
||||||
<div class="info-panel-header">
|
|
||||||
<h2>场景信息</h2>
|
|
||||||
<button class="close-btn" @click="closeInfoPanel">×</button>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="info-panel-body">
|
|
||||||
<div class="info-item">
|
|
||||||
<label>名称:</label>
|
|
||||||
<span>{{ sceneData.name }}</span>
|
|
||||||
</div>
|
|
||||||
<div class="info-item">
|
|
||||||
<label>位置:</label>
|
|
||||||
<span>{{ sceneData.location }}</span>
|
|
||||||
</div>
|
|
||||||
<div class="info-item">
|
|
||||||
<label>历史:</label>
|
|
||||||
<span>{{ sceneData.history }}</span>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="attractions-section">
|
|
||||||
<h3>主要景点:</h3>
|
|
||||||
<ul class="attractions-list">
|
|
||||||
<li v-for="(attraction, index) in sceneData.attractions" :key="index">
|
|
||||||
<div class="attraction-name">{{ attraction.name }}</div>
|
|
||||||
<div class="attraction-description">{{ attraction.description }}</div>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- 媒体播放器 -->
|
|
||||||
<div class="media-player-container">
|
|
||||||
<MediaPlayer
|
|
||||||
:audio-url="sceneData.audio"
|
|
||||||
:video-url="sceneData.video"
|
|
||||||
:scene-name="sceneData.name"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- 场景导航 -->
|
|
||||||
<div class="scene-navigation">
|
|
||||||
<button class="nav-btn prev-btn" @click="goToPreviousScene">
|
|
||||||
上一个
|
|
||||||
</button>
|
|
||||||
<button class="nav-btn info-btn" @click="showSceneInfo">
|
|
||||||
场景信息
|
|
||||||
</button>
|
|
||||||
<button class="nav-btn next-btn" @click="goToNextScene">
|
|
||||||
下一个
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<style scoped>
|
|
||||||
.scene-page {
|
|
||||||
width: 100%;
|
|
||||||
min-height: 100vh;
|
|
||||||
background-color: #f5f5f5;
|
|
||||||
padding-top: 0.88rem;
|
|
||||||
padding-bottom: 1.2rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.scene-header {
|
|
||||||
padding: 0.2rem;
|
|
||||||
text-align: center;
|
|
||||||
background-color: #fff;
|
|
||||||
margin-bottom: 0.1rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.scene-title {
|
|
||||||
font-size: 0.4rem;
|
|
||||||
font-weight: bold;
|
|
||||||
color: #333;
|
|
||||||
margin-bottom: 0.1rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.scene-description {
|
|
||||||
font-size: 0.28rem;
|
|
||||||
color: #666;
|
|
||||||
}
|
|
||||||
|
|
||||||
.long-image-container {
|
|
||||||
width: 100%;
|
|
||||||
height: 5rem;
|
|
||||||
overflow: hidden;
|
|
||||||
background-color: #000;
|
|
||||||
position: relative;
|
|
||||||
}
|
|
||||||
|
|
||||||
.interaction-tip {
|
|
||||||
position: absolute;
|
|
||||||
top: 50%;
|
|
||||||
left: 50%;
|
|
||||||
transform: translate(-50%, -50%);
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
background-color: rgba(0, 0, 0, 0.7);
|
|
||||||
color: #fff;
|
|
||||||
padding: 0.3rem 0.5rem;
|
|
||||||
border-radius: 0.2rem;
|
|
||||||
z-index: 10;
|
|
||||||
animation: pulse 1.5s infinite;
|
|
||||||
}
|
|
||||||
|
|
||||||
@keyframes pulse {
|
|
||||||
0% {
|
|
||||||
transform: translate(-50%, -50%) scale(1);
|
|
||||||
}
|
|
||||||
50% {
|
|
||||||
transform: translate(-50%, -50%) scale(1.1);
|
|
||||||
}
|
|
||||||
100% {
|
|
||||||
transform: translate(-50%, -50%) scale(1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.tip-icon {
|
|
||||||
font-size: 0.6rem;
|
|
||||||
margin-bottom: 0.1rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.seal-collect-tip {
|
|
||||||
position: absolute;
|
|
||||||
top: 1rem;
|
|
||||||
right: 0.2rem;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
background-color: rgba(255, 107, 53, 0.9);
|
|
||||||
color: #fff;
|
|
||||||
padding: 0.15rem 0.3rem;
|
|
||||||
border-radius: 0.2rem;
|
|
||||||
font-size: 0.28rem;
|
|
||||||
z-index: 10;
|
|
||||||
}
|
|
||||||
|
|
||||||
.seal-icon {
|
|
||||||
font-size: 0.4rem;
|
|
||||||
margin-right: 0.1rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.info-panel {
|
|
||||||
position: fixed;
|
|
||||||
top: 0;
|
|
||||||
left: 0;
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
background-color: rgba(0, 0, 0, 0.5);
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
z-index: 100;
|
|
||||||
}
|
|
||||||
|
|
||||||
.info-panel-content {
|
|
||||||
width: 90%;
|
|
||||||
max-width: 500px;
|
|
||||||
background-color: #fff;
|
|
||||||
border-radius: 0.2rem;
|
|
||||||
overflow: hidden;
|
|
||||||
max-height: 80vh;
|
|
||||||
overflow-y: auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
.info-panel-header {
|
|
||||||
display: flex;
|
|
||||||
justify-content: space-between;
|
|
||||||
align-items: center;
|
|
||||||
padding: 0.3rem;
|
|
||||||
background-color: #ff6b35;
|
|
||||||
color: #fff;
|
|
||||||
}
|
|
||||||
|
|
||||||
.info-panel-header h2 {
|
|
||||||
font-size: 0.36rem;
|
|
||||||
margin: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.close-btn {
|
|
||||||
background: none;
|
|
||||||
border: none;
|
|
||||||
color: #fff;
|
|
||||||
font-size: 0.4rem;
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
|
|
||||||
.info-panel-body {
|
|
||||||
padding: 0.3rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.info-item {
|
|
||||||
margin-bottom: 0.2rem;
|
|
||||||
font-size: 0.28rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.info-item label {
|
|
||||||
font-weight: bold;
|
|
||||||
color: #333;
|
|
||||||
}
|
|
||||||
|
|
||||||
.info-item span {
|
|
||||||
color: #666;
|
|
||||||
}
|
|
||||||
|
|
||||||
.attractions-section {
|
|
||||||
margin-top: 0.3rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.attractions-section h3 {
|
|
||||||
font-size: 0.32rem;
|
|
||||||
margin-bottom: 0.2rem;
|
|
||||||
color: #333;
|
|
||||||
}
|
|
||||||
|
|
||||||
.attractions-list {
|
|
||||||
list-style: none;
|
|
||||||
padding: 0;
|
|
||||||
margin: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.attractions-list li {
|
|
||||||
margin-bottom: 0.2rem;
|
|
||||||
padding: 0.2rem;
|
|
||||||
background-color: #f9f9f9;
|
|
||||||
border-radius: 0.1rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.attraction-name {
|
|
||||||
font-weight: bold;
|
|
||||||
color: #333;
|
|
||||||
margin-bottom: 0.05rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.attraction-description {
|
|
||||||
color: #666;
|
|
||||||
font-size: 0.26rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.media-player-container {
|
|
||||||
margin: 0.2rem;
|
|
||||||
background-color: #fff;
|
|
||||||
border-radius: 0.1rem;
|
|
||||||
padding: 0.2rem;
|
|
||||||
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
|
|
||||||
}
|
|
||||||
|
|
||||||
.scene-navigation {
|
|
||||||
display: flex;
|
|
||||||
justify-content: space-between;
|
|
||||||
padding: 0.2rem;
|
|
||||||
margin-top: 0.2rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.nav-btn {
|
|
||||||
flex: 1;
|
|
||||||
padding: 0.2rem;
|
|
||||||
margin: 0 0.1rem;
|
|
||||||
font-size: 0.3rem;
|
|
||||||
border: none;
|
|
||||||
border-radius: 0.15rem;
|
|
||||||
cursor: pointer;
|
|
||||||
transition: background-color 0.3s ease;
|
|
||||||
}
|
|
||||||
|
|
||||||
.prev-btn {
|
|
||||||
background-color: #2196f3;
|
|
||||||
color: #fff;
|
|
||||||
}
|
|
||||||
|
|
||||||
.prev-btn:disabled {
|
|
||||||
opacity: 0.5;
|
|
||||||
cursor: not-allowed;
|
|
||||||
}
|
|
||||||
|
|
||||||
.info-btn {
|
|
||||||
background-color: #4caf50;
|
|
||||||
color: #fff;
|
|
||||||
}
|
|
||||||
|
|
||||||
.next-btn {
|
|
||||||
background-color: #ff9800;
|
|
||||||
color: #fff;
|
|
||||||
}
|
|
||||||
|
|
||||||
.nav-btn:hover:not(:disabled) {
|
|
||||||
opacity: 0.8;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
@ -1,437 +0,0 @@
|
||||||
<script setup>
|
|
||||||
import { ref, onMounted, computed } from 'vue'
|
|
||||||
import { useRouter } from 'vue-router'
|
|
||||||
import { useSceneStore } from '../../src/store/scene'
|
|
||||||
import { useCollectionStore } from '../../src/store/collection'
|
|
||||||
import LongImageViewer from '../components/LongImageViewer.vue'
|
|
||||||
import MediaPlayer from '../components/MediaPlayer.vue'
|
|
||||||
|
|
||||||
const router = useRouter()
|
|
||||||
const sceneStore = useSceneStore()
|
|
||||||
const collectionStore = useCollectionStore()
|
|
||||||
|
|
||||||
// 场景数据
|
|
||||||
const sceneData = ref({
|
|
||||||
id: 'dongzhimen',
|
|
||||||
name: '东直门商圈',
|
|
||||||
description: '国际化的交通枢纽与商业中心',
|
|
||||||
image: 'https://picsum.photos/id/1019/750/1600', // 长图占位图
|
|
||||||
thumbnail: 'https://picsum.photos/id/1019/200/100',
|
|
||||||
location: '北京市东城区东直门内大街',
|
|
||||||
history: '东直门商圈是北京重要的交通枢纽,连接着多条地铁线路和长途汽车站,如今成为国际化的商业中心。',
|
|
||||||
attractions: [
|
|
||||||
{ name: '东直门交通枢纽', description: '大型综合交通枢纽' },
|
|
||||||
{ name: '东方银座', description: '高端商务中心' },
|
|
||||||
{ name: '簋街', description: '著名的美食街' }
|
|
||||||
],
|
|
||||||
audio: 'https://example.com/audio/dongzhimen.mp3', // 音频占位符
|
|
||||||
video: 'https://example.com/video/dongzhimen.mp4' // 视频占位符
|
|
||||||
})
|
|
||||||
|
|
||||||
// 交互状态
|
|
||||||
const isInteractive = ref(false)
|
|
||||||
const sealCollected = ref(false)
|
|
||||||
const showInfoPanel = ref(false)
|
|
||||||
|
|
||||||
// 福印收集状态
|
|
||||||
const sealStatus = computed(() => {
|
|
||||||
return collectionStore.isSceneSealCollected(sceneData.value.id)
|
|
||||||
})
|
|
||||||
|
|
||||||
// 组件挂载后初始化
|
|
||||||
onMounted(() => {
|
|
||||||
// 激活当前场景
|
|
||||||
sceneStore.activateScene(sceneData.value.id)
|
|
||||||
|
|
||||||
// 设置当前场景索引
|
|
||||||
const sceneIndex = sceneStore.scenes.findIndex(scene => scene.id === sceneData.value.id)
|
|
||||||
if (sceneIndex !== -1) {
|
|
||||||
sceneStore.setCurrentScene(sceneIndex)
|
|
||||||
}
|
|
||||||
|
|
||||||
// 检查福印是否已收集
|
|
||||||
sealCollected.value = sealStatus.value
|
|
||||||
})
|
|
||||||
|
|
||||||
// 点击场景交互区域
|
|
||||||
const handleSceneInteraction = () => {
|
|
||||||
if (!isInteractive.value) {
|
|
||||||
isInteractive.value = true
|
|
||||||
|
|
||||||
// 模拟交互过程
|
|
||||||
setTimeout(() => {
|
|
||||||
collectSeal()
|
|
||||||
}, 1000)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 收集福印
|
|
||||||
const collectSeal = () => {
|
|
||||||
if (!sealCollected.value) {
|
|
||||||
const success = collectionStore.collectSealBySceneId(sceneData.value.id)
|
|
||||||
if (success) {
|
|
||||||
sealCollected.value = true
|
|
||||||
showToast({
|
|
||||||
message: '恭喜获得东直门福印!',
|
|
||||||
icon: 'success',
|
|
||||||
duration: 2000
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
showFailToast({
|
|
||||||
message: '福印收集失败',
|
|
||||||
duration: 2000
|
|
||||||
})
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
showToast({
|
|
||||||
message: '福印已收集',
|
|
||||||
duration: 1500
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 查看场景信息
|
|
||||||
const showSceneInfo = () => {
|
|
||||||
showInfoPanel.value = true
|
|
||||||
}
|
|
||||||
|
|
||||||
// 关闭信息面板
|
|
||||||
const closeInfoPanel = () => {
|
|
||||||
showInfoPanel.value = false
|
|
||||||
}
|
|
||||||
|
|
||||||
// 跳转到下一个场景
|
|
||||||
const goToNextScene = () => {
|
|
||||||
router.push('/ai-spring')
|
|
||||||
}
|
|
||||||
|
|
||||||
// 跳转到上一个场景
|
|
||||||
const goToPreviousScene = () => {
|
|
||||||
router.push('/longfusi')
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<template>
|
|
||||||
<div class="scene-page">
|
|
||||||
<!-- 场景标题 -->
|
|
||||||
<div class="scene-header">
|
|
||||||
<h1 class="scene-title">{{ sceneData.name }}</h1>
|
|
||||||
<p class="scene-description">{{ sceneData.description }}</p>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- 长图查看器 -->
|
|
||||||
<div class="long-image-container">
|
|
||||||
<LongImageViewer
|
|
||||||
:image-url="sceneData.image"
|
|
||||||
:description="sceneData.name"
|
|
||||||
@click="handleSceneInteraction"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- 交互提示 -->
|
|
||||||
<div class="interaction-tip" v-if="!isInteractive">
|
|
||||||
<div class="tip-icon">👆</div>
|
|
||||||
<p>点击图片查看详情</p>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- 福印收集提示 -->
|
|
||||||
<div class="seal-collect-tip" v-if="sealCollected">
|
|
||||||
<div class="seal-icon">🏮</div>
|
|
||||||
<p>已收集东直门福印</p>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- 场景信息面板 -->
|
|
||||||
<div class="info-panel" v-if="showInfoPanel">
|
|
||||||
<div class="info-panel-content">
|
|
||||||
<div class="info-panel-header">
|
|
||||||
<h2>场景信息</h2>
|
|
||||||
<button class="close-btn" @click="closeInfoPanel">×</button>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="info-panel-body">
|
|
||||||
<div class="info-item">
|
|
||||||
<label>名称:</label>
|
|
||||||
<span>{{ sceneData.name }}</span>
|
|
||||||
</div>
|
|
||||||
<div class="info-item">
|
|
||||||
<label>位置:</label>
|
|
||||||
<span>{{ sceneData.location }}</span>
|
|
||||||
</div>
|
|
||||||
<div class="info-item">
|
|
||||||
<label>历史:</label>
|
|
||||||
<span>{{ sceneData.history }}</span>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="attractions-section">
|
|
||||||
<h3>主要景点:</h3>
|
|
||||||
<ul class="attractions-list">
|
|
||||||
<li v-for="(attraction, index) in sceneData.attractions" :key="index">
|
|
||||||
<div class="attraction-name">{{ attraction.name }}</div>
|
|
||||||
<div class="attraction-description">{{ attraction.description }}</div>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- 媒体播放器 -->
|
|
||||||
<div class="media-player-container">
|
|
||||||
<MediaPlayer
|
|
||||||
:audio-url="sceneData.audio"
|
|
||||||
:video-url="sceneData.video"
|
|
||||||
:scene-name="sceneData.name"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- 场景导航 -->
|
|
||||||
<div class="scene-navigation">
|
|
||||||
<button class="nav-btn prev-btn" @click="goToPreviousScene">
|
|
||||||
上一个
|
|
||||||
</button>
|
|
||||||
<button class="nav-btn info-btn" @click="showSceneInfo">
|
|
||||||
场景信息
|
|
||||||
</button>
|
|
||||||
<button class="nav-btn next-btn" @click="goToNextScene">
|
|
||||||
下一个
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<style scoped>
|
|
||||||
.scene-page {
|
|
||||||
width: 100%;
|
|
||||||
min-height: 100vh;
|
|
||||||
background-color: #f5f5f5;
|
|
||||||
padding-top: 0.88rem;
|
|
||||||
padding-bottom: 1.2rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.scene-header {
|
|
||||||
padding: 0.2rem;
|
|
||||||
text-align: center;
|
|
||||||
background-color: #fff;
|
|
||||||
margin-bottom: 0.1rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.scene-title {
|
|
||||||
font-size: 0.4rem;
|
|
||||||
font-weight: bold;
|
|
||||||
color: #333;
|
|
||||||
margin-bottom: 0.1rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.scene-description {
|
|
||||||
font-size: 0.28rem;
|
|
||||||
color: #666;
|
|
||||||
}
|
|
||||||
|
|
||||||
.long-image-container {
|
|
||||||
width: 100%;
|
|
||||||
height: 5rem;
|
|
||||||
overflow: hidden;
|
|
||||||
background-color: #000;
|
|
||||||
position: relative;
|
|
||||||
}
|
|
||||||
|
|
||||||
.interaction-tip {
|
|
||||||
position: absolute;
|
|
||||||
top: 50%;
|
|
||||||
left: 50%;
|
|
||||||
transform: translate(-50%, -50%);
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
background-color: rgba(0, 0, 0, 0.7);
|
|
||||||
color: #fff;
|
|
||||||
padding: 0.3rem 0.5rem;
|
|
||||||
border-radius: 0.2rem;
|
|
||||||
z-index: 10;
|
|
||||||
animation: pulse 1.5s infinite;
|
|
||||||
}
|
|
||||||
|
|
||||||
@keyframes pulse {
|
|
||||||
0% {
|
|
||||||
transform: translate(-50%, -50%) scale(1);
|
|
||||||
}
|
|
||||||
50% {
|
|
||||||
transform: translate(-50%, -50%) scale(1.1);
|
|
||||||
}
|
|
||||||
100% {
|
|
||||||
transform: translate(-50%, -50%) scale(1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.tip-icon {
|
|
||||||
font-size: 0.6rem;
|
|
||||||
margin-bottom: 0.1rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.seal-collect-tip {
|
|
||||||
position: absolute;
|
|
||||||
top: 1rem;
|
|
||||||
right: 0.2rem;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
background-color: rgba(255, 107, 53, 0.9);
|
|
||||||
color: #fff;
|
|
||||||
padding: 0.15rem 0.3rem;
|
|
||||||
border-radius: 0.2rem;
|
|
||||||
font-size: 0.28rem;
|
|
||||||
z-index: 10;
|
|
||||||
}
|
|
||||||
|
|
||||||
.seal-icon {
|
|
||||||
font-size: 0.4rem;
|
|
||||||
margin-right: 0.1rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.info-panel {
|
|
||||||
position: fixed;
|
|
||||||
top: 0;
|
|
||||||
left: 0;
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
background-color: rgba(0, 0, 0, 0.5);
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
z-index: 100;
|
|
||||||
}
|
|
||||||
|
|
||||||
.info-panel-content {
|
|
||||||
width: 90%;
|
|
||||||
max-width: 500px;
|
|
||||||
background-color: #fff;
|
|
||||||
border-radius: 0.2rem;
|
|
||||||
overflow: hidden;
|
|
||||||
max-height: 80vh;
|
|
||||||
overflow-y: auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
.info-panel-header {
|
|
||||||
display: flex;
|
|
||||||
justify-content: space-between;
|
|
||||||
align-items: center;
|
|
||||||
padding: 0.3rem;
|
|
||||||
background-color: #ff6b35;
|
|
||||||
color: #fff;
|
|
||||||
}
|
|
||||||
|
|
||||||
.info-panel-header h2 {
|
|
||||||
font-size: 0.36rem;
|
|
||||||
margin: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.close-btn {
|
|
||||||
background: none;
|
|
||||||
border: none;
|
|
||||||
color: #fff;
|
|
||||||
font-size: 0.4rem;
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
|
|
||||||
.info-panel-body {
|
|
||||||
padding: 0.3rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.info-item {
|
|
||||||
margin-bottom: 0.2rem;
|
|
||||||
font-size: 0.28rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.info-item label {
|
|
||||||
font-weight: bold;
|
|
||||||
color: #333;
|
|
||||||
}
|
|
||||||
|
|
||||||
.info-item span {
|
|
||||||
color: #666;
|
|
||||||
}
|
|
||||||
|
|
||||||
.attractions-section {
|
|
||||||
margin-top: 0.3rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.attractions-section h3 {
|
|
||||||
font-size: 0.32rem;
|
|
||||||
margin-bottom: 0.2rem;
|
|
||||||
color: #333;
|
|
||||||
}
|
|
||||||
|
|
||||||
.attractions-list {
|
|
||||||
list-style: none;
|
|
||||||
padding: 0;
|
|
||||||
margin: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.attractions-list li {
|
|
||||||
margin-bottom: 0.2rem;
|
|
||||||
padding: 0.2rem;
|
|
||||||
background-color: #f9f9f9;
|
|
||||||
border-radius: 0.1rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.attraction-name {
|
|
||||||
font-weight: bold;
|
|
||||||
color: #333;
|
|
||||||
margin-bottom: 0.05rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.attraction-description {
|
|
||||||
color: #666;
|
|
||||||
font-size: 0.26rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.media-player-container {
|
|
||||||
margin: 0.2rem;
|
|
||||||
background-color: #fff;
|
|
||||||
border-radius: 0.1rem;
|
|
||||||
padding: 0.2rem;
|
|
||||||
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
|
|
||||||
}
|
|
||||||
|
|
||||||
.scene-navigation {
|
|
||||||
display: flex;
|
|
||||||
justify-content: space-between;
|
|
||||||
padding: 0.2rem;
|
|
||||||
margin-top: 0.2rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.nav-btn {
|
|
||||||
flex: 1;
|
|
||||||
padding: 0.2rem;
|
|
||||||
margin: 0 0.1rem;
|
|
||||||
font-size: 0.3rem;
|
|
||||||
border: none;
|
|
||||||
border-radius: 0.15rem;
|
|
||||||
cursor: pointer;
|
|
||||||
transition: background-color 0.3s ease;
|
|
||||||
}
|
|
||||||
|
|
||||||
.prev-btn {
|
|
||||||
background-color: #f44336;
|
|
||||||
color: #fff;
|
|
||||||
}
|
|
||||||
|
|
||||||
.prev-btn:disabled {
|
|
||||||
opacity: 0.5;
|
|
||||||
cursor: not-allowed;
|
|
||||||
}
|
|
||||||
|
|
||||||
.info-btn {
|
|
||||||
background-color: #4caf50;
|
|
||||||
color: #fff;
|
|
||||||
}
|
|
||||||
|
|
||||||
.next-btn {
|
|
||||||
background-color: #2196f3;
|
|
||||||
color: #fff;
|
|
||||||
}
|
|
||||||
|
|
||||||
.nav-btn:hover:not(:disabled) {
|
|
||||||
opacity: 0.8;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
@ -1,489 +0,0 @@
|
||||||
<template>
|
|
||||||
<div class="end-page-container">
|
|
||||||
<!-- 背景图 -->
|
|
||||||
<div class="background">
|
|
||||||
<img
|
|
||||||
v-lazy="backgroundImage"
|
|
||||||
alt="结束页背景"
|
|
||||||
@error="handleImageError"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- 标题 -->
|
|
||||||
<h1 class="title">🎉 恭喜完成全部场景游览 🎉</h1>
|
|
||||||
|
|
||||||
<!-- 福印收集展示 -->
|
|
||||||
<div class="seal-collection-section">
|
|
||||||
<h2 class="section-title">福印收集成果</h2>
|
|
||||||
|
|
||||||
<!-- 收集进度 -->
|
|
||||||
<div class="collection-progress">
|
|
||||||
<div class="progress-bar">
|
|
||||||
<div
|
|
||||||
class="progress-fill"
|
|
||||||
:style="{ width: `${progressPercentage}%` }"
|
|
||||||
></div>
|
|
||||||
</div>
|
|
||||||
<p class="progress-text">
|
|
||||||
已收集 {{ collectedSeals.length }} / {{ totalSeals }} 个福印
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- 福印列表 -->
|
|
||||||
<div class="seal-grid">
|
|
||||||
<div
|
|
||||||
v-for="seal in allSeals"
|
|
||||||
:key="seal.id"
|
|
||||||
class="seal-item"
|
|
||||||
:class="{ 'collected': seal.collected }"
|
|
||||||
>
|
|
||||||
<div class="seal-image">
|
|
||||||
<img
|
|
||||||
v-lazy="seal.collected ? seal.image : uncollectedImage"
|
|
||||||
:alt="seal.name"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div class="seal-name">{{ seal.name }}</div>
|
|
||||||
<div class="seal-status" :class="{ 'collected-status': seal.collected }">
|
|
||||||
{{ seal.collected ? '已收集' : '未收集' }}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- 全部收集奖励 -->
|
|
||||||
<div class="full-collection-reward" v-if="allCollected">
|
|
||||||
<div class="reward-content">
|
|
||||||
<div class="reward-icon">🏆</div>
|
|
||||||
<h3>恭喜集齐全部福印!</h3>
|
|
||||||
<p>您已完成所有商圈的探索,获得了完整的福印收集成就!</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- 操作按钮 -->
|
|
||||||
<div class="action-buttons">
|
|
||||||
<button @click="restartTour" class="btn restart-btn">
|
|
||||||
重新游览
|
|
||||||
</button>
|
|
||||||
<button @click="generateCouple" class="btn couple-btn">
|
|
||||||
生成AI春联
|
|
||||||
</button>
|
|
||||||
<button @click="participateLottery" class="btn lottery-btn">
|
|
||||||
参与抽奖
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- 分享按钮 -->
|
|
||||||
<div class="share-section">
|
|
||||||
<button @click="shareResult" class="share-btn">
|
|
||||||
📤 分享我的成果
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- 加载动画 -->
|
|
||||||
<div v-if="loading" class="loading-overlay">
|
|
||||||
<uni-spinner type="circle" size="48" color="#fff"></uni-spinner>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup>
|
|
||||||
import { ref, computed, onMounted } from 'vue';
|
|
||||||
import { useRouter } from 'vue-router';
|
|
||||||
import { useCollectionStore } from '../../src/store/collection';
|
|
||||||
import { share } from '../utils/share';
|
|
||||||
|
|
||||||
const router = useRouter();
|
|
||||||
const collectionStore = useCollectionStore();
|
|
||||||
|
|
||||||
// 响应式数据
|
|
||||||
const loading = ref(false);
|
|
||||||
const backgroundImage = ref('/static/bg/bg_finish.jpg');
|
|
||||||
const uncollectedImage = ref('https://placeholder.pics/svg/100x100/CCCCCC/999999/未收集');
|
|
||||||
|
|
||||||
// 计算属性
|
|
||||||
const allSeals = computed(() => {
|
|
||||||
return collectionStore.seals;
|
|
||||||
});
|
|
||||||
|
|
||||||
const collectedSeals = computed(() => {
|
|
||||||
return collectionStore.collectedSeals;
|
|
||||||
});
|
|
||||||
|
|
||||||
const totalSeals = computed(() => {
|
|
||||||
return allSeals.value.length;
|
|
||||||
});
|
|
||||||
|
|
||||||
const progressPercentage = computed(() => {
|
|
||||||
return collectionStore.getCollectionProgress;
|
|
||||||
});
|
|
||||||
|
|
||||||
const allCollected = computed(() => {
|
|
||||||
return collectionStore.isAllCollected;
|
|
||||||
});
|
|
||||||
|
|
||||||
// 组件挂载后初始化
|
|
||||||
onMounted(() => {
|
|
||||||
// 如果是全部收集,显示特殊效果
|
|
||||||
if (allCollected.value) {
|
|
||||||
uni.showToast({
|
|
||||||
title: '恭喜集齐全部福印!',
|
|
||||||
icon: 'success',
|
|
||||||
duration: 3000
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// 重新游览
|
|
||||||
const restartTour = () => {
|
|
||||||
// 重置收集状态
|
|
||||||
collectionStore.resetCollection();
|
|
||||||
// 跳转到首页
|
|
||||||
router.push('/');
|
|
||||||
};
|
|
||||||
|
|
||||||
// 生成AI春联
|
|
||||||
const generateCouple = () => {
|
|
||||||
router.push('/ai-spring');
|
|
||||||
};
|
|
||||||
|
|
||||||
// 参与抽奖
|
|
||||||
const participateLottery = () => {
|
|
||||||
router.push('/');
|
|
||||||
uni.showToast({
|
|
||||||
title: '抽奖功能请在首页参与',
|
|
||||||
icon: 'none',
|
|
||||||
duration: 2000
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
// 分享成果
|
|
||||||
const shareResult = () => {
|
|
||||||
const shareText = `
|
|
||||||
我在2026新春东城商圈H5中完成了全部场景游览!
|
|
||||||
已收集 ${collectedSeals.value.length} / ${totalSeals.value} 个福印
|
|
||||||
#2026新春东城商圈#
|
|
||||||
`;
|
|
||||||
|
|
||||||
// 调用分享工具函数
|
|
||||||
share(
|
|
||||||
'新春商圈游览成果',
|
|
||||||
shareText,
|
|
||||||
backgroundImage.value
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
// 处理图片加载错误
|
|
||||||
const handleImageError = (event) => {
|
|
||||||
event.target.src = 'https://placeholder.pics/svg/640x1136/FDF2E9/F39C12/结束页背景';
|
|
||||||
};
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped>
|
|
||||||
.end-page-container {
|
|
||||||
position: relative;
|
|
||||||
min-height: 100vh;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
align-items: center;
|
|
||||||
padding: 20px;
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
|
||||||
|
|
||||||
.background {
|
|
||||||
position: absolute;
|
|
||||||
top: 0;
|
|
||||||
left: 0;
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
z-index: -1;
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
|
||||||
|
|
||||||
.background img {
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
object-fit: cover;
|
|
||||||
}
|
|
||||||
|
|
||||||
.title {
|
|
||||||
font-size: 28px;
|
|
||||||
color: #f39c12;
|
|
||||||
text-align: center;
|
|
||||||
margin: 40px 0 30px;
|
|
||||||
text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.3);
|
|
||||||
}
|
|
||||||
|
|
||||||
.seal-collection-section {
|
|
||||||
background: rgba(255, 255, 255, 0.95);
|
|
||||||
border-radius: 20px;
|
|
||||||
padding: 25px;
|
|
||||||
width: 100%;
|
|
||||||
max-width: 600px;
|
|
||||||
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.1);
|
|
||||||
backdrop-filter: blur(10px);
|
|
||||||
margin-bottom: 30px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.section-title {
|
|
||||||
font-size: 24px;
|
|
||||||
color: #e67e22;
|
|
||||||
text-align: center;
|
|
||||||
margin-bottom: 20px;
|
|
||||||
font-weight: bold;
|
|
||||||
}
|
|
||||||
|
|
||||||
.collection-progress {
|
|
||||||
margin-bottom: 30px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.progress-bar {
|
|
||||||
width: 100%;
|
|
||||||
height: 15px;
|
|
||||||
background: #e0e0e0;
|
|
||||||
border-radius: 10px;
|
|
||||||
overflow: hidden;
|
|
||||||
margin-bottom: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.progress-fill {
|
|
||||||
height: 100%;
|
|
||||||
background: linear-gradient(135deg, #f39c12, #e67e22);
|
|
||||||
border-radius: 10px;
|
|
||||||
transition: width 0.5s ease;
|
|
||||||
}
|
|
||||||
|
|
||||||
.progress-text {
|
|
||||||
text-align: center;
|
|
||||||
font-size: 16px;
|
|
||||||
color: #666;
|
|
||||||
margin: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.seal-grid {
|
|
||||||
display: grid;
|
|
||||||
grid-template-columns: repeat(2, 1fr);
|
|
||||||
gap: 20px;
|
|
||||||
margin-bottom: 30px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.seal-item {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
align-items: center;
|
|
||||||
padding: 15px;
|
|
||||||
background: #f9f9f9;
|
|
||||||
border-radius: 15px;
|
|
||||||
transition: all 0.3s ease;
|
|
||||||
border: 2px solid #ddd;
|
|
||||||
}
|
|
||||||
|
|
||||||
.seal-item.collected {
|
|
||||||
background: linear-gradient(135deg, #fff9c4, #fff59d);
|
|
||||||
border-color: #ffd740;
|
|
||||||
transform: scale(1.05);
|
|
||||||
}
|
|
||||||
|
|
||||||
.seal-image {
|
|
||||||
width: 80px;
|
|
||||||
height: 80px;
|
|
||||||
border-radius: 50%;
|
|
||||||
overflow: hidden;
|
|
||||||
margin-bottom: 10px;
|
|
||||||
background: #fff;
|
|
||||||
border: 3px solid #e67e22;
|
|
||||||
display: flex;
|
|
||||||
justify-content: center;
|
|
||||||
align-items: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.seal-image img {
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
object-fit: cover;
|
|
||||||
}
|
|
||||||
|
|
||||||
.seal-name {
|
|
||||||
font-size: 16px;
|
|
||||||
font-weight: bold;
|
|
||||||
color: #333;
|
|
||||||
margin-bottom: 5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.seal-status {
|
|
||||||
font-size: 14px;
|
|
||||||
color: #999;
|
|
||||||
padding: 3px 8px;
|
|
||||||
border-radius: 10px;
|
|
||||||
background: #eee;
|
|
||||||
}
|
|
||||||
|
|
||||||
.seal-status.collected-status {
|
|
||||||
color: #4caf50;
|
|
||||||
background: #e8f5e9;
|
|
||||||
}
|
|
||||||
|
|
||||||
.full-collection-reward {
|
|
||||||
background: linear-gradient(135deg, #ffeb3b, #ffc107);
|
|
||||||
border-radius: 15px;
|
|
||||||
padding: 20px;
|
|
||||||
text-align: center;
|
|
||||||
box-shadow: 0 4px 12px rgba(255, 193, 7, 0.3);
|
|
||||||
animation: glow 2s infinite;
|
|
||||||
}
|
|
||||||
|
|
||||||
@keyframes glow {
|
|
||||||
0%, 100% {
|
|
||||||
box-shadow: 0 4px 12px rgba(255, 193, 7, 0.3);
|
|
||||||
}
|
|
||||||
50% {
|
|
||||||
box-shadow: 0 6px 18px rgba(255, 193, 7, 0.6);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.reward-content {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
align-items: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.reward-icon {
|
|
||||||
font-size: 64px;
|
|
||||||
margin-bottom: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.reward-content h3 {
|
|
||||||
font-size: 22px;
|
|
||||||
color: #e65100;
|
|
||||||
margin-bottom: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.reward-content p {
|
|
||||||
font-size: 16px;
|
|
||||||
color: #8d6e63;
|
|
||||||
margin: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.action-buttons {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
gap: 15px;
|
|
||||||
width: 100%;
|
|
||||||
max-width: 400px;
|
|
||||||
margin-bottom: 20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.btn {
|
|
||||||
padding: 15px 25px;
|
|
||||||
border: none;
|
|
||||||
border-radius: 25px;
|
|
||||||
font-size: 18px;
|
|
||||||
font-weight: bold;
|
|
||||||
cursor: pointer;
|
|
||||||
transition: all 0.3s ease;
|
|
||||||
display: flex;
|
|
||||||
justify-content: center;
|
|
||||||
align-items: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.restart-btn {
|
|
||||||
background: linear-gradient(135deg, #95a5a6, #7f8c8d);
|
|
||||||
color: white;
|
|
||||||
}
|
|
||||||
|
|
||||||
.restart-btn:hover {
|
|
||||||
transform: translateY(-2px);
|
|
||||||
box-shadow: 0 4px 12px rgba(149, 165, 166, 0.4);
|
|
||||||
}
|
|
||||||
|
|
||||||
.couple-btn {
|
|
||||||
background: linear-gradient(135deg, #e67e22, #d35400);
|
|
||||||
color: white;
|
|
||||||
}
|
|
||||||
|
|
||||||
.couple-btn:hover {
|
|
||||||
transform: translateY(-2px);
|
|
||||||
box-shadow: 0 4px 12px rgba(230, 126, 34, 0.4);
|
|
||||||
}
|
|
||||||
|
|
||||||
.lottery-btn {
|
|
||||||
background: linear-gradient(135deg, #e74c3c, #c0392b);
|
|
||||||
color: white;
|
|
||||||
}
|
|
||||||
|
|
||||||
.lottery-btn:hover {
|
|
||||||
transform: translateY(-2px);
|
|
||||||
box-shadow: 0 4px 12px rgba(231, 76, 60, 0.4);
|
|
||||||
}
|
|
||||||
|
|
||||||
.share-section {
|
|
||||||
margin-bottom: 30px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.share-btn {
|
|
||||||
padding: 15px 30px;
|
|
||||||
background: linear-gradient(135deg, #3498db, #2980b9);
|
|
||||||
color: white;
|
|
||||||
border: none;
|
|
||||||
border-radius: 25px;
|
|
||||||
font-size: 18px;
|
|
||||||
font-weight: bold;
|
|
||||||
cursor: pointer;
|
|
||||||
transition: all 0.3s ease;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
gap: 8px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.share-btn:hover {
|
|
||||||
transform: translateY(-2px);
|
|
||||||
box-shadow: 0 4px 12px rgba(52, 152, 219, 0.4);
|
|
||||||
}
|
|
||||||
|
|
||||||
.loading-overlay {
|
|
||||||
position: fixed;
|
|
||||||
top: 0;
|
|
||||||
left: 0;
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
background: rgba(0, 0, 0, 0.5);
|
|
||||||
display: flex;
|
|
||||||
justify-content: center;
|
|
||||||
align-items: center;
|
|
||||||
z-index: 999;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 响应式设计 */
|
|
||||||
@media (max-width: 480px) {
|
|
||||||
.title {
|
|
||||||
font-size: 24px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.seal-collection-section {
|
|
||||||
padding: 20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.section-title {
|
|
||||||
font-size: 20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.seal-grid {
|
|
||||||
grid-template-columns: repeat(2, 1fr);
|
|
||||||
gap: 15px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.seal-image {
|
|
||||||
width: 70px;
|
|
||||||
height: 70px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.seal-name {
|
|
||||||
font-size: 14px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.btn {
|
|
||||||
font-size: 16px;
|
|
||||||
padding: 12px 20px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
@ -1,437 +0,0 @@
|
||||||
<script setup>
|
|
||||||
import { ref, onMounted, computed } from 'vue'
|
|
||||||
import { useRouter } from 'vue-router'
|
|
||||||
import { useSceneStore } from '../../src/store/scene'
|
|
||||||
import { useCollectionStore } from '../../src/store/collection'
|
|
||||||
import LongImageViewer from '../components/LongImageViewer.vue'
|
|
||||||
import MediaPlayer from '../components/MediaPlayer.vue'
|
|
||||||
|
|
||||||
const router = useRouter()
|
|
||||||
const sceneStore = useSceneStore()
|
|
||||||
const collectionStore = useCollectionStore()
|
|
||||||
|
|
||||||
// 场景数据
|
|
||||||
const sceneData = ref({
|
|
||||||
id: 'longfusi',
|
|
||||||
name: '隆福寺商圈',
|
|
||||||
description: '融合传统文化与现代艺术的新兴商圈',
|
|
||||||
image: 'https://picsum.photos/id/1018/750/1600', // 长图占位图
|
|
||||||
thumbnail: 'https://picsum.photos/id/1018/200/100',
|
|
||||||
location: '北京市东城区隆福寺街',
|
|
||||||
history: '隆福寺商圈历史悠久,曾是明清时期的重要庙会场所,如今成为融合传统文化与现代艺术的新兴商业区域。',
|
|
||||||
attractions: [
|
|
||||||
{ name: '隆福寺', description: '历史悠久的佛教寺院' },
|
|
||||||
{ name: '隆福文化中心', description: '现代化的文化艺术中心' },
|
|
||||||
{ name: '隆福广场', description: '时尚潮流的购物中心' }
|
|
||||||
],
|
|
||||||
audio: 'https://example.com/audio/longfusi.mp3', // 音频占位符
|
|
||||||
video: 'https://example.com/video/longfusi.mp4' // 视频占位符
|
|
||||||
})
|
|
||||||
|
|
||||||
// 交互状态
|
|
||||||
const isInteractive = ref(false)
|
|
||||||
const sealCollected = ref(false)
|
|
||||||
const showInfoPanel = ref(false)
|
|
||||||
|
|
||||||
// 福印收集状态
|
|
||||||
const sealStatus = computed(() => {
|
|
||||||
return collectionStore.isSceneSealCollected(sceneData.value.id)
|
|
||||||
})
|
|
||||||
|
|
||||||
// 组件挂载后初始化
|
|
||||||
onMounted(() => {
|
|
||||||
// 激活当前场景
|
|
||||||
sceneStore.activateScene(sceneData.value.id)
|
|
||||||
|
|
||||||
// 设置当前场景索引
|
|
||||||
const sceneIndex = sceneStore.scenes.findIndex(scene => scene.id === sceneData.value.id)
|
|
||||||
if (sceneIndex !== -1) {
|
|
||||||
sceneStore.setCurrentScene(sceneIndex)
|
|
||||||
}
|
|
||||||
|
|
||||||
// 检查福印是否已收集
|
|
||||||
sealCollected.value = sealStatus.value
|
|
||||||
})
|
|
||||||
|
|
||||||
// 点击场景交互区域
|
|
||||||
const handleSceneInteraction = () => {
|
|
||||||
if (!isInteractive.value) {
|
|
||||||
isInteractive.value = true
|
|
||||||
|
|
||||||
// 模拟交互过程
|
|
||||||
setTimeout(() => {
|
|
||||||
collectSeal()
|
|
||||||
}, 1000)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 收集福印
|
|
||||||
const collectSeal = () => {
|
|
||||||
if (!sealCollected.value) {
|
|
||||||
const success = collectionStore.collectSealBySceneId(sceneData.value.id)
|
|
||||||
if (success) {
|
|
||||||
sealCollected.value = true
|
|
||||||
showToast({
|
|
||||||
message: '恭喜获得隆福寺福印!',
|
|
||||||
icon: 'success',
|
|
||||||
duration: 2000
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
showFailToast({
|
|
||||||
message: '福印收集失败',
|
|
||||||
duration: 2000
|
|
||||||
})
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
showToast({
|
|
||||||
message: '福印已收集',
|
|
||||||
duration: 1500
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 查看场景信息
|
|
||||||
const showSceneInfo = () => {
|
|
||||||
showInfoPanel.value = true
|
|
||||||
}
|
|
||||||
|
|
||||||
// 关闭信息面板
|
|
||||||
const closeInfoPanel = () => {
|
|
||||||
showInfoPanel.value = false
|
|
||||||
}
|
|
||||||
|
|
||||||
// 跳转到下一个场景
|
|
||||||
const goToNextScene = () => {
|
|
||||||
router.push('/dongzhimen')
|
|
||||||
}
|
|
||||||
|
|
||||||
// 跳转到上一个场景
|
|
||||||
const goToPreviousScene = () => {
|
|
||||||
router.push('/wangfujing')
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<template>
|
|
||||||
<div class="scene-page">
|
|
||||||
<!-- 场景标题 -->
|
|
||||||
<div class="scene-header">
|
|
||||||
<h1 class="scene-title">{{ sceneData.name }}</h1>
|
|
||||||
<p class="scene-description">{{ sceneData.description }}</p>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- 长图查看器 -->
|
|
||||||
<div class="long-image-container">
|
|
||||||
<LongImageViewer
|
|
||||||
:image-url="sceneData.image"
|
|
||||||
:description="sceneData.name"
|
|
||||||
@click="handleSceneInteraction"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- 交互提示 -->
|
|
||||||
<div class="interaction-tip" v-if="!isInteractive">
|
|
||||||
<div class="tip-icon"><EFBFBD><EFBFBD></div>
|
|
||||||
<p>点击图片查看详情</p>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- 福印收集提示 -->
|
|
||||||
<div class="seal-collect-tip" v-if="sealCollected">
|
|
||||||
<div class="seal-icon"><EFBFBD><EFBFBD></div>
|
|
||||||
<p>已收集隆福寺福印</p>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- 场景信息面板 -->
|
|
||||||
<div class="info-panel" v-if="showInfoPanel">
|
|
||||||
<div class="info-panel-content">
|
|
||||||
<div class="info-panel-header">
|
|
||||||
<h2>场景信息</h2>
|
|
||||||
<button class="close-btn" @click="closeInfoPanel">×</button>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="info-panel-body">
|
|
||||||
<div class="info-item">
|
|
||||||
<label>名称:</label>
|
|
||||||
<span>{{ sceneData.name }}</span>
|
|
||||||
</div>
|
|
||||||
<div class="info-item">
|
|
||||||
<label>位置:</label>
|
|
||||||
<span>{{ sceneData.location }}</span>
|
|
||||||
</div>
|
|
||||||
<div class="info-item">
|
|
||||||
<label>历史:</label>
|
|
||||||
<span>{{ sceneData.history }}</span>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="attractions-section">
|
|
||||||
<h3>主要景点:</h3>
|
|
||||||
<ul class="attractions-list">
|
|
||||||
<li v-for="(attraction, index) in sceneData.attractions" :key="index">
|
|
||||||
<div class="attraction-name">{{ attraction.name }}</div>
|
|
||||||
<div class="attraction-description">{{ attraction.description }}</div>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- 媒体播放器 -->
|
|
||||||
<div class="media-player-container">
|
|
||||||
<MediaPlayer
|
|
||||||
:audio-url="sceneData.audio"
|
|
||||||
:video-url="sceneData.video"
|
|
||||||
:scene-name="sceneData.name"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- 场景导航 -->
|
|
||||||
<div class="scene-navigation">
|
|
||||||
<button class="nav-btn prev-btn" @click="goToPreviousScene">
|
|
||||||
上一个
|
|
||||||
</button>
|
|
||||||
<button class="nav-btn info-btn" @click="showSceneInfo">
|
|
||||||
场景信息
|
|
||||||
</button>
|
|
||||||
<button class="nav-btn next-btn" @click="goToNextScene">
|
|
||||||
下一个
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<style scoped>
|
|
||||||
.scene-page {
|
|
||||||
width: 100%;
|
|
||||||
min-height: 100vh;
|
|
||||||
background-color: #f5f5f5;
|
|
||||||
padding-top: 0.88rem;
|
|
||||||
padding-bottom: 1.2rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.scene-header {
|
|
||||||
padding: 0.2rem;
|
|
||||||
text-align: center;
|
|
||||||
background-color: #fff;
|
|
||||||
margin-bottom: 0.1rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.scene-title {
|
|
||||||
font-size: 0.4rem;
|
|
||||||
font-weight: bold;
|
|
||||||
color: #333;
|
|
||||||
margin-bottom: 0.1rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.scene-description {
|
|
||||||
font-size: 0.28rem;
|
|
||||||
color: #666;
|
|
||||||
}
|
|
||||||
|
|
||||||
.long-image-container {
|
|
||||||
width: 100%;
|
|
||||||
height: 5rem;
|
|
||||||
overflow: hidden;
|
|
||||||
background-color: #000;
|
|
||||||
position: relative;
|
|
||||||
}
|
|
||||||
|
|
||||||
.interaction-tip {
|
|
||||||
position: absolute;
|
|
||||||
top: 50%;
|
|
||||||
left: 50%;
|
|
||||||
transform: translate(-50%, -50%);
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
background-color: rgba(0, 0, 0, 0.7);
|
|
||||||
color: #fff;
|
|
||||||
padding: 0.3rem 0.5rem;
|
|
||||||
border-radius: 0.2rem;
|
|
||||||
z-index: 10;
|
|
||||||
animation: pulse 1.5s infinite;
|
|
||||||
}
|
|
||||||
|
|
||||||
@keyframes pulse {
|
|
||||||
0% {
|
|
||||||
transform: translate(-50%, -50%) scale(1);
|
|
||||||
}
|
|
||||||
50% {
|
|
||||||
transform: translate(-50%, -50%) scale(1.1);
|
|
||||||
}
|
|
||||||
100% {
|
|
||||||
transform: translate(-50%, -50%) scale(1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.tip-icon {
|
|
||||||
font-size: 0.6rem;
|
|
||||||
margin-bottom: 0.1rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.seal-collect-tip {
|
|
||||||
position: absolute;
|
|
||||||
top: 1rem;
|
|
||||||
right: 0.2rem;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
background-color: rgba(255, 107, 53, 0.9);
|
|
||||||
color: #fff;
|
|
||||||
padding: 0.15rem 0.3rem;
|
|
||||||
border-radius: 0.2rem;
|
|
||||||
font-size: 0.28rem;
|
|
||||||
z-index: 10;
|
|
||||||
}
|
|
||||||
|
|
||||||
.seal-icon {
|
|
||||||
font-size: 0.4rem;
|
|
||||||
margin-right: 0.1rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.info-panel {
|
|
||||||
position: fixed;
|
|
||||||
top: 0;
|
|
||||||
left: 0;
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
background-color: rgba(0, 0, 0, 0.5);
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
z-index: 100;
|
|
||||||
}
|
|
||||||
|
|
||||||
.info-panel-content {
|
|
||||||
width: 90%;
|
|
||||||
max-width: 500px;
|
|
||||||
background-color: #fff;
|
|
||||||
border-radius: 0.2rem;
|
|
||||||
overflow: hidden;
|
|
||||||
max-height: 80vh;
|
|
||||||
overflow-y: auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
.info-panel-header {
|
|
||||||
display: flex;
|
|
||||||
justify-content: space-between;
|
|
||||||
align-items: center;
|
|
||||||
padding: 0.3rem;
|
|
||||||
background-color: #ff6b35;
|
|
||||||
color: #fff;
|
|
||||||
}
|
|
||||||
|
|
||||||
.info-panel-header h2 {
|
|
||||||
font-size: 0.36rem;
|
|
||||||
margin: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.close-btn {
|
|
||||||
background: none;
|
|
||||||
border: none;
|
|
||||||
color: #fff;
|
|
||||||
font-size: 0.4rem;
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
|
|
||||||
.info-panel-body {
|
|
||||||
padding: 0.3rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.info-item {
|
|
||||||
margin-bottom: 0.2rem;
|
|
||||||
font-size: 0.28rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.info-item label {
|
|
||||||
font-weight: bold;
|
|
||||||
color: #333;
|
|
||||||
}
|
|
||||||
|
|
||||||
.info-item span {
|
|
||||||
color: #666;
|
|
||||||
}
|
|
||||||
|
|
||||||
.attractions-section {
|
|
||||||
margin-top: 0.3rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.attractions-section h3 {
|
|
||||||
font-size: 0.32rem;
|
|
||||||
margin-bottom: 0.2rem;
|
|
||||||
color: #333;
|
|
||||||
}
|
|
||||||
|
|
||||||
.attractions-list {
|
|
||||||
list-style: none;
|
|
||||||
padding: 0;
|
|
||||||
margin: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.attractions-list li {
|
|
||||||
margin-bottom: 0.2rem;
|
|
||||||
padding: 0.2rem;
|
|
||||||
background-color: #f9f9f9;
|
|
||||||
border-radius: 0.1rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.attraction-name {
|
|
||||||
font-weight: bold;
|
|
||||||
color: #333;
|
|
||||||
margin-bottom: 0.05rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.attraction-description {
|
|
||||||
color: #666;
|
|
||||||
font-size: 0.26rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.media-player-container {
|
|
||||||
margin: 0.2rem;
|
|
||||||
background-color: #fff;
|
|
||||||
border-radius: 0.1rem;
|
|
||||||
padding: 0.2rem;
|
|
||||||
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
|
|
||||||
}
|
|
||||||
|
|
||||||
.scene-navigation {
|
|
||||||
display: flex;
|
|
||||||
justify-content: space-between;
|
|
||||||
padding: 0.2rem;
|
|
||||||
margin-top: 0.2rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.nav-btn {
|
|
||||||
flex: 1;
|
|
||||||
padding: 0.2rem;
|
|
||||||
margin: 0 0.1rem;
|
|
||||||
font-size: 0.3rem;
|
|
||||||
border: none;
|
|
||||||
border-radius: 0.15rem;
|
|
||||||
cursor: pointer;
|
|
||||||
transition: background-color 0.3s ease;
|
|
||||||
}
|
|
||||||
|
|
||||||
.prev-btn {
|
|
||||||
background-color: #9c27b0;
|
|
||||||
color: #fff;
|
|
||||||
}
|
|
||||||
|
|
||||||
.prev-btn:disabled {
|
|
||||||
opacity: 0.5;
|
|
||||||
cursor: not-allowed;
|
|
||||||
}
|
|
||||||
|
|
||||||
.info-btn {
|
|
||||||
background-color: #4caf50;
|
|
||||||
color: #fff;
|
|
||||||
}
|
|
||||||
|
|
||||||
.next-btn {
|
|
||||||
background-color: #f44336;
|
|
||||||
color: #fff;
|
|
||||||
}
|
|
||||||
|
|
||||||
.nav-btn:hover:not(:disabled) {
|
|
||||||
opacity: 0.8;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
@ -1,437 +0,0 @@
|
||||||
<script setup>
|
|
||||||
import { ref, onMounted, computed } from 'vue'
|
|
||||||
import { useRouter } from 'vue-router'
|
|
||||||
import { useSceneStore } from '../../src/store/scene'
|
|
||||||
import { useCollectionStore } from '../../src/store/collection'
|
|
||||||
import LongImageViewer from '../components/LongImageViewer.vue'
|
|
||||||
import MediaPlayer from '../components/MediaPlayer.vue'
|
|
||||||
|
|
||||||
const router = useRouter()
|
|
||||||
const sceneStore = useSceneStore()
|
|
||||||
const collectionStore = useCollectionStore()
|
|
||||||
|
|
||||||
// 场景数据
|
|
||||||
const sceneData = ref({
|
|
||||||
id: 'qianmen',
|
|
||||||
name: '前门商圈',
|
|
||||||
description: '北京最具历史文化底蕴的商圈之一',
|
|
||||||
image: 'https://picsum.photos/id/1015/750/1600', // 长图占位图
|
|
||||||
thumbnail: 'https://picsum.photos/id/1015/200/100',
|
|
||||||
location: '北京市东城区前门大街',
|
|
||||||
history: '前门大街形成于明代,已有600多年历史,是北京最古老的商业街之一。',
|
|
||||||
attractions: [
|
|
||||||
{ name: '前门大街', description: '北京著名的商业街,汇集众多老字号' },
|
|
||||||
{ name: '大栅栏', description: '明清时期的商业中心,保留大量传统建筑' },
|
|
||||||
{ name: '天安门广场', description: '世界最大的城市广场,中国的象征' }
|
|
||||||
],
|
|
||||||
audio: 'https://example.com/audio/qianmen.mp3', // 音频占位符
|
|
||||||
video: 'https://example.com/video/qianmen.mp4' // 视频占位符
|
|
||||||
})
|
|
||||||
|
|
||||||
// 交互状态
|
|
||||||
const isInteractive = ref(false)
|
|
||||||
const sealCollected = ref(false)
|
|
||||||
const showInfoPanel = ref(false)
|
|
||||||
|
|
||||||
// 福印收集状态
|
|
||||||
const sealStatus = computed(() => {
|
|
||||||
return collectionStore.isSceneSealCollected(sceneData.value.id)
|
|
||||||
})
|
|
||||||
|
|
||||||
// 组件挂载后初始化
|
|
||||||
onMounted(() => {
|
|
||||||
// 激活当前场景
|
|
||||||
sceneStore.activateScene(sceneData.value.id)
|
|
||||||
|
|
||||||
// 设置当前场景索引
|
|
||||||
const sceneIndex = sceneStore.scenes.findIndex(scene => scene.id === sceneData.value.id)
|
|
||||||
if (sceneIndex !== -1) {
|
|
||||||
sceneStore.setCurrentScene(sceneIndex)
|
|
||||||
}
|
|
||||||
|
|
||||||
// 检查福印是否已收集
|
|
||||||
sealCollected.value = sealStatus.value
|
|
||||||
})
|
|
||||||
|
|
||||||
// 点击场景交互区域
|
|
||||||
const handleSceneInteraction = () => {
|
|
||||||
if (!isInteractive.value) {
|
|
||||||
isInteractive.value = true
|
|
||||||
|
|
||||||
// 模拟交互过程
|
|
||||||
setTimeout(() => {
|
|
||||||
collectSeal()
|
|
||||||
}, 1000)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 收集福印
|
|
||||||
const collectSeal = () => {
|
|
||||||
if (!sealCollected.value) {
|
|
||||||
const success = collectionStore.collectSealBySceneId(sceneData.value.id)
|
|
||||||
if (success) {
|
|
||||||
sealCollected.value = true
|
|
||||||
showToast({
|
|
||||||
message: '恭喜获得前门福印!',
|
|
||||||
icon: 'success',
|
|
||||||
duration: 2000
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
showFailToast({
|
|
||||||
message: '福印收集失败',
|
|
||||||
duration: 2000
|
|
||||||
})
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
showToast({
|
|
||||||
message: '福印已收集',
|
|
||||||
duration: 1500
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 查看场景信息
|
|
||||||
const showSceneInfo = () => {
|
|
||||||
showInfoPanel.value = true
|
|
||||||
}
|
|
||||||
|
|
||||||
// 关闭信息面板
|
|
||||||
const closeInfoPanel = () => {
|
|
||||||
showInfoPanel.value = false
|
|
||||||
}
|
|
||||||
|
|
||||||
// 跳转到下一个场景
|
|
||||||
const goToNextScene = () => {
|
|
||||||
router.push('/chongwen')
|
|
||||||
}
|
|
||||||
|
|
||||||
// 跳转到上一个场景
|
|
||||||
const goToPreviousScene = () => {
|
|
||||||
Toast('已经是第一个场景了')
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<template>
|
|
||||||
<div class="scene-page">
|
|
||||||
<!-- 场景标题 -->
|
|
||||||
<div class="scene-header">
|
|
||||||
<h1 class="scene-title">{{ sceneData.name }}</h1>
|
|
||||||
<p class="scene-description">{{ sceneData.description }}</p>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- 长图查看器 -->
|
|
||||||
<div class="long-image-container">
|
|
||||||
<LongImageViewer
|
|
||||||
:image-url="sceneData.image"
|
|
||||||
:description="sceneData.name"
|
|
||||||
@click="handleSceneInteraction"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- 交互提示 -->
|
|
||||||
<div class="interaction-tip" v-if="!isInteractive">
|
|
||||||
<div class="tip-icon">👆</div>
|
|
||||||
<p>点击图片查看详情</p>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- 福印收集提示 -->
|
|
||||||
<div class="seal-collect-tip" v-if="sealCollected">
|
|
||||||
<div class="seal-icon">🏮</div>
|
|
||||||
<p>已收集前门福印</p>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- 场景信息面板 -->
|
|
||||||
<div class="info-panel" v-if="showInfoPanel">
|
|
||||||
<div class="info-panel-content">
|
|
||||||
<div class="info-panel-header">
|
|
||||||
<h2>场景信息</h2>
|
|
||||||
<button class="close-btn" @click="closeInfoPanel">×</button>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="info-panel-body">
|
|
||||||
<div class="info-item">
|
|
||||||
<label>名称:</label>
|
|
||||||
<span>{{ sceneData.name }}</span>
|
|
||||||
</div>
|
|
||||||
<div class="info-item">
|
|
||||||
<label>位置:</label>
|
|
||||||
<span>{{ sceneData.location }}</span>
|
|
||||||
</div>
|
|
||||||
<div class="info-item">
|
|
||||||
<label>历史:</label>
|
|
||||||
<span>{{ sceneData.history }}</span>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="attractions-section">
|
|
||||||
<h3>主要景点:</h3>
|
|
||||||
<ul class="attractions-list">
|
|
||||||
<li v-for="(attraction, index) in sceneData.attractions" :key="index">
|
|
||||||
<div class="attraction-name">{{ attraction.name }}</div>
|
|
||||||
<div class="attraction-description">{{ attraction.description }}</div>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- 媒体播放器 -->
|
|
||||||
<div class="media-player-container">
|
|
||||||
<MediaPlayer
|
|
||||||
:audio-url="sceneData.audio"
|
|
||||||
:video-url="sceneData.video"
|
|
||||||
:scene-name="sceneData.name"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- 场景导航 -->
|
|
||||||
<div class="scene-navigation">
|
|
||||||
<button class="nav-btn prev-btn" @click="goToPreviousScene">
|
|
||||||
上一个
|
|
||||||
</button>
|
|
||||||
<button class="nav-btn info-btn" @click="showSceneInfo">
|
|
||||||
场景信息
|
|
||||||
</button>
|
|
||||||
<button class="nav-btn next-btn" @click="goToNextScene">
|
|
||||||
下一个
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<style scoped>
|
|
||||||
.scene-page {
|
|
||||||
width: 100%;
|
|
||||||
min-height: 100vh;
|
|
||||||
background-color: #f5f5f5;
|
|
||||||
padding-top: 0.88rem;
|
|
||||||
padding-bottom: 1.2rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.scene-header {
|
|
||||||
padding: 0.2rem;
|
|
||||||
text-align: center;
|
|
||||||
background-color: #fff;
|
|
||||||
margin-bottom: 0.1rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.scene-title {
|
|
||||||
font-size: 0.4rem;
|
|
||||||
font-weight: bold;
|
|
||||||
color: #333;
|
|
||||||
margin-bottom: 0.1rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.scene-description {
|
|
||||||
font-size: 0.28rem;
|
|
||||||
color: #666;
|
|
||||||
}
|
|
||||||
|
|
||||||
.long-image-container {
|
|
||||||
width: 100%;
|
|
||||||
height: 5rem;
|
|
||||||
overflow: hidden;
|
|
||||||
background-color: #000;
|
|
||||||
position: relative;
|
|
||||||
}
|
|
||||||
|
|
||||||
.interaction-tip {
|
|
||||||
position: absolute;
|
|
||||||
top: 50%;
|
|
||||||
left: 50%;
|
|
||||||
transform: translate(-50%, -50%);
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
background-color: rgba(0, 0, 0, 0.7);
|
|
||||||
color: #fff;
|
|
||||||
padding: 0.3rem 0.5rem;
|
|
||||||
border-radius: 0.2rem;
|
|
||||||
z-index: 10;
|
|
||||||
animation: pulse 1.5s infinite;
|
|
||||||
}
|
|
||||||
|
|
||||||
@keyframes pulse {
|
|
||||||
0% {
|
|
||||||
transform: translate(-50%, -50%) scale(1);
|
|
||||||
}
|
|
||||||
50% {
|
|
||||||
transform: translate(-50%, -50%) scale(1.1);
|
|
||||||
}
|
|
||||||
100% {
|
|
||||||
transform: translate(-50%, -50%) scale(1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.tip-icon {
|
|
||||||
font-size: 0.6rem;
|
|
||||||
margin-bottom: 0.1rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.seal-collect-tip {
|
|
||||||
position: absolute;
|
|
||||||
top: 1rem;
|
|
||||||
right: 0.2rem;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
background-color: rgba(255, 107, 53, 0.9);
|
|
||||||
color: #fff;
|
|
||||||
padding: 0.15rem 0.3rem;
|
|
||||||
border-radius: 0.2rem;
|
|
||||||
font-size: 0.28rem;
|
|
||||||
z-index: 10;
|
|
||||||
}
|
|
||||||
|
|
||||||
.seal-icon {
|
|
||||||
font-size: 0.4rem;
|
|
||||||
margin-right: 0.1rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.info-panel {
|
|
||||||
position: fixed;
|
|
||||||
top: 0;
|
|
||||||
left: 0;
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
background-color: rgba(0, 0, 0, 0.5);
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
z-index: 100;
|
|
||||||
}
|
|
||||||
|
|
||||||
.info-panel-content {
|
|
||||||
width: 90%;
|
|
||||||
max-width: 500px;
|
|
||||||
background-color: #fff;
|
|
||||||
border-radius: 0.2rem;
|
|
||||||
overflow: hidden;
|
|
||||||
max-height: 80vh;
|
|
||||||
overflow-y: auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
.info-panel-header {
|
|
||||||
display: flex;
|
|
||||||
justify-content: space-between;
|
|
||||||
align-items: center;
|
|
||||||
padding: 0.3rem;
|
|
||||||
background-color: #ff6b35;
|
|
||||||
color: #fff;
|
|
||||||
}
|
|
||||||
|
|
||||||
.info-panel-header h2 {
|
|
||||||
font-size: 0.36rem;
|
|
||||||
margin: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.close-btn {
|
|
||||||
background: none;
|
|
||||||
border: none;
|
|
||||||
color: #fff;
|
|
||||||
font-size: 0.4rem;
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
|
|
||||||
.info-panel-body {
|
|
||||||
padding: 0.3rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.info-item {
|
|
||||||
margin-bottom: 0.2rem;
|
|
||||||
font-size: 0.28rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.info-item label {
|
|
||||||
font-weight: bold;
|
|
||||||
color: #333;
|
|
||||||
}
|
|
||||||
|
|
||||||
.info-item span {
|
|
||||||
color: #666;
|
|
||||||
}
|
|
||||||
|
|
||||||
.attractions-section {
|
|
||||||
margin-top: 0.3rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.attractions-section h3 {
|
|
||||||
font-size: 0.32rem;
|
|
||||||
margin-bottom: 0.2rem;
|
|
||||||
color: #333;
|
|
||||||
}
|
|
||||||
|
|
||||||
.attractions-list {
|
|
||||||
list-style: none;
|
|
||||||
padding: 0;
|
|
||||||
margin: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.attractions-list li {
|
|
||||||
margin-bottom: 0.2rem;
|
|
||||||
padding: 0.2rem;
|
|
||||||
background-color: #f9f9f9;
|
|
||||||
border-radius: 0.1rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.attraction-name {
|
|
||||||
font-weight: bold;
|
|
||||||
color: #333;
|
|
||||||
margin-bottom: 0.05rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.attraction-description {
|
|
||||||
color: #666;
|
|
||||||
font-size: 0.26rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.media-player-container {
|
|
||||||
margin: 0.2rem;
|
|
||||||
background-color: #fff;
|
|
||||||
border-radius: 0.1rem;
|
|
||||||
padding: 0.2rem;
|
|
||||||
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
|
|
||||||
}
|
|
||||||
|
|
||||||
.scene-navigation {
|
|
||||||
display: flex;
|
|
||||||
justify-content: space-between;
|
|
||||||
padding: 0.2rem;
|
|
||||||
margin-top: 0.2rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.nav-btn {
|
|
||||||
flex: 1;
|
|
||||||
padding: 0.2rem;
|
|
||||||
margin: 0 0.1rem;
|
|
||||||
font-size: 0.3rem;
|
|
||||||
border: none;
|
|
||||||
border-radius: 0.15rem;
|
|
||||||
cursor: pointer;
|
|
||||||
transition: background-color 0.3s ease;
|
|
||||||
}
|
|
||||||
|
|
||||||
.prev-btn {
|
|
||||||
background-color: #e0e0e0;
|
|
||||||
color: #666;
|
|
||||||
}
|
|
||||||
|
|
||||||
.prev-btn:disabled {
|
|
||||||
opacity: 0.5;
|
|
||||||
cursor: not-allowed;
|
|
||||||
}
|
|
||||||
|
|
||||||
.info-btn {
|
|
||||||
background-color: #4caf50;
|
|
||||||
color: #fff;
|
|
||||||
}
|
|
||||||
|
|
||||||
.next-btn {
|
|
||||||
background-color: #2196f3;
|
|
||||||
color: #fff;
|
|
||||||
}
|
|
||||||
|
|
||||||
.nav-btn:hover:not(:disabled) {
|
|
||||||
opacity: 0.8;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
@ -1,437 +0,0 @@
|
||||||
<script setup>
|
|
||||||
import { ref, onMounted, computed } from 'vue'
|
|
||||||
import { useRouter } from 'vue-router'
|
|
||||||
import { useSceneStore } from '../../src/store/scene'
|
|
||||||
import { useCollectionStore } from '../../src/store/collection'
|
|
||||||
import LongImageViewer from '../components/LongImageViewer.vue'
|
|
||||||
import MediaPlayer from '../components/MediaPlayer.vue'
|
|
||||||
|
|
||||||
const router = useRouter()
|
|
||||||
const sceneStore = useSceneStore()
|
|
||||||
const collectionStore = useCollectionStore()
|
|
||||||
|
|
||||||
// 场景数据
|
|
||||||
const sceneData = ref({
|
|
||||||
id: 'wangfujing',
|
|
||||||
name: '王府井商圈',
|
|
||||||
description: '北京最繁华的商业中心之一',
|
|
||||||
image: 'https://picsum.photos/id/1018/750/1600', // 长图占位图
|
|
||||||
thumbnail: 'https://picsum.photos/id/1018/200/100',
|
|
||||||
location: '北京市东城区王府井大街',
|
|
||||||
history: '王府井商圈已有百年历史,是北京著名的商业步行街,汇聚了众多国内外知名品牌。',
|
|
||||||
attractions: [
|
|
||||||
{ name: '王府井步行街', description: '北京最著名的商业步行街' },
|
|
||||||
{ name: '东方新天地', description: '高端购物中心' },
|
|
||||||
{ name: '北京apm', description: '时尚潮流购物中心' }
|
|
||||||
],
|
|
||||||
audio: 'https://example.com/audio/wangfujing.mp3', // 音频占位符
|
|
||||||
video: 'https://example.com/video/wangfujing.mp4' // 视频占位符
|
|
||||||
})
|
|
||||||
|
|
||||||
// 交互状态
|
|
||||||
const isInteractive = ref(false)
|
|
||||||
const sealCollected = ref(false)
|
|
||||||
const showInfoPanel = ref(false)
|
|
||||||
|
|
||||||
// 福印收集状态
|
|
||||||
const sealStatus = computed(() => {
|
|
||||||
return collectionStore.isSceneSealCollected(sceneData.value.id)
|
|
||||||
})
|
|
||||||
|
|
||||||
// 组件挂载后初始化
|
|
||||||
onMounted(() => {
|
|
||||||
// 激活当前场景
|
|
||||||
sceneStore.activateScene(sceneData.value.id)
|
|
||||||
|
|
||||||
// 设置当前场景索引
|
|
||||||
const sceneIndex = sceneStore.scenes.findIndex(scene => scene.id === sceneData.value.id)
|
|
||||||
if (sceneIndex !== -1) {
|
|
||||||
sceneStore.setCurrentScene(sceneIndex)
|
|
||||||
}
|
|
||||||
|
|
||||||
// 检查福印是否已收集
|
|
||||||
sealCollected.value = sealStatus.value
|
|
||||||
})
|
|
||||||
|
|
||||||
// 点击场景交互区域
|
|
||||||
const handleSceneInteraction = () => {
|
|
||||||
if (!isInteractive.value) {
|
|
||||||
isInteractive.value = true
|
|
||||||
|
|
||||||
// 模拟交互过程
|
|
||||||
setTimeout(() => {
|
|
||||||
collectSeal()
|
|
||||||
}, 1000)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 收集福印
|
|
||||||
const collectSeal = () => {
|
|
||||||
if (!sealCollected.value) {
|
|
||||||
const success = collectionStore.collectSealBySceneId(sceneData.value.id)
|
|
||||||
if (success) {
|
|
||||||
sealCollected.value = true
|
|
||||||
showToast({
|
|
||||||
message: '恭喜获得王府井福印!',
|
|
||||||
icon: 'success',
|
|
||||||
duration: 2000
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
showFailToast({
|
|
||||||
message: '福印收集失败',
|
|
||||||
duration: 2000
|
|
||||||
})
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
showToast({
|
|
||||||
message: '福印已收集',
|
|
||||||
duration: 1500
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 查看场景信息
|
|
||||||
const showSceneInfo = () => {
|
|
||||||
showInfoPanel.value = true
|
|
||||||
}
|
|
||||||
|
|
||||||
// 关闭信息面板
|
|
||||||
const closeInfoPanel = () => {
|
|
||||||
showInfoPanel.value = false
|
|
||||||
}
|
|
||||||
|
|
||||||
// 跳转到下一个场景
|
|
||||||
const goToNextScene = () => {
|
|
||||||
router.push('/longfusi')
|
|
||||||
}
|
|
||||||
|
|
||||||
// 跳转到上一个场景
|
|
||||||
const goToPreviousScene = () => {
|
|
||||||
router.push('/chongwen')
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<template>
|
|
||||||
<div class="scene-page">
|
|
||||||
<!-- 场景标题 -->
|
|
||||||
<div class="scene-header">
|
|
||||||
<h1 class="scene-title">{{ sceneData.name }}</h1>
|
|
||||||
<p class="scene-description">{{ sceneData.description }}</p>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- 长图查看器 -->
|
|
||||||
<div class="long-image-container">
|
|
||||||
<LongImageViewer
|
|
||||||
:image-url="sceneData.image"
|
|
||||||
:description="sceneData.name"
|
|
||||||
@click="handleSceneInteraction"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- 交互提示 -->
|
|
||||||
<div class="interaction-tip" v-if="!isInteractive">
|
|
||||||
<div class="tip-icon"><EFBFBD><EFBFBD></div>
|
|
||||||
<p>点击图片查看详情</p>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- 福印收集提示 -->
|
|
||||||
<div class="seal-collect-tip" v-if="sealCollected">
|
|
||||||
<div class="seal-icon"><EFBFBD><EFBFBD></div>
|
|
||||||
<p>已收集王府井福印</p>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- 场景信息面板 -->
|
|
||||||
<div class="info-panel" v-if="showInfoPanel">
|
|
||||||
<div class="info-panel-content">
|
|
||||||
<div class="info-panel-header">
|
|
||||||
<h2>场景信息</h2>
|
|
||||||
<button class="close-btn" @click="closeInfoPanel">×</button>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="info-panel-body">
|
|
||||||
<div class="info-item">
|
|
||||||
<label>名称:</label>
|
|
||||||
<span>{{ sceneData.name }}</span>
|
|
||||||
</div>
|
|
||||||
<div class="info-item">
|
|
||||||
<label>位置:</label>
|
|
||||||
<span>{{ sceneData.location }}</span>
|
|
||||||
</div>
|
|
||||||
<div class="info-item">
|
|
||||||
<label>历史:</label>
|
|
||||||
<span>{{ sceneData.history }}</span>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="attractions-section">
|
|
||||||
<h3>主要景点:</h3>
|
|
||||||
<ul class="attractions-list">
|
|
||||||
<li v-for="(attraction, index) in sceneData.attractions" :key="index">
|
|
||||||
<div class="attraction-name">{{ attraction.name }}</div>
|
|
||||||
<div class="attraction-description">{{ attraction.description }}</div>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- 媒体播放器 -->
|
|
||||||
<div class="media-player-container">
|
|
||||||
<MediaPlayer
|
|
||||||
:audio-url="sceneData.audio"
|
|
||||||
:video-url="sceneData.video"
|
|
||||||
:scene-name="sceneData.name"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- 场景导航 -->
|
|
||||||
<div class="scene-navigation">
|
|
||||||
<button class="nav-btn prev-btn" @click="goToPreviousScene">
|
|
||||||
上一个
|
|
||||||
</button>
|
|
||||||
<button class="nav-btn info-btn" @click="showSceneInfo">
|
|
||||||
场景信息
|
|
||||||
</button>
|
|
||||||
<button class="nav-btn next-btn" @click="goToNextScene">
|
|
||||||
下一个
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<style scoped>
|
|
||||||
.scene-page {
|
|
||||||
width: 100%;
|
|
||||||
min-height: 100vh;
|
|
||||||
background-color: #f5f5f5;
|
|
||||||
padding-top: 0.88rem;
|
|
||||||
padding-bottom: 1.2rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.scene-header {
|
|
||||||
padding: 0.2rem;
|
|
||||||
text-align: center;
|
|
||||||
background-color: #fff;
|
|
||||||
margin-bottom: 0.1rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.scene-title {
|
|
||||||
font-size: 0.4rem;
|
|
||||||
font-weight: bold;
|
|
||||||
color: #333;
|
|
||||||
margin-bottom: 0.1rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.scene-description {
|
|
||||||
font-size: 0.28rem;
|
|
||||||
color: #666;
|
|
||||||
}
|
|
||||||
|
|
||||||
.long-image-container {
|
|
||||||
width: 100%;
|
|
||||||
height: 5rem;
|
|
||||||
overflow: hidden;
|
|
||||||
background-color: #000;
|
|
||||||
position: relative;
|
|
||||||
}
|
|
||||||
|
|
||||||
.interaction-tip {
|
|
||||||
position: absolute;
|
|
||||||
top: 50%;
|
|
||||||
left: 50%;
|
|
||||||
transform: translate(-50%, -50%);
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
background-color: rgba(0, 0, 0, 0.7);
|
|
||||||
color: #fff;
|
|
||||||
padding: 0.3rem 0.5rem;
|
|
||||||
border-radius: 0.2rem;
|
|
||||||
z-index: 10;
|
|
||||||
animation: pulse 1.5s infinite;
|
|
||||||
}
|
|
||||||
|
|
||||||
@keyframes pulse {
|
|
||||||
0% {
|
|
||||||
transform: translate(-50%, -50%) scale(1);
|
|
||||||
}
|
|
||||||
50% {
|
|
||||||
transform: translate(-50%, -50%) scale(1.1);
|
|
||||||
}
|
|
||||||
100% {
|
|
||||||
transform: translate(-50%, -50%) scale(1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.tip-icon {
|
|
||||||
font-size: 0.6rem;
|
|
||||||
margin-bottom: 0.1rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.seal-collect-tip {
|
|
||||||
position: absolute;
|
|
||||||
top: 1rem;
|
|
||||||
right: 0.2rem;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
background-color: rgba(255, 107, 53, 0.9);
|
|
||||||
color: #fff;
|
|
||||||
padding: 0.15rem 0.3rem;
|
|
||||||
border-radius: 0.2rem;
|
|
||||||
font-size: 0.28rem;
|
|
||||||
z-index: 10;
|
|
||||||
}
|
|
||||||
|
|
||||||
.seal-icon {
|
|
||||||
font-size: 0.4rem;
|
|
||||||
margin-right: 0.1rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.info-panel {
|
|
||||||
position: fixed;
|
|
||||||
top: 0;
|
|
||||||
left: 0;
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
background-color: rgba(0, 0, 0, 0.5);
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
z-index: 100;
|
|
||||||
}
|
|
||||||
|
|
||||||
.info-panel-content {
|
|
||||||
width: 90%;
|
|
||||||
max-width: 500px;
|
|
||||||
background-color: #fff;
|
|
||||||
border-radius: 0.2rem;
|
|
||||||
overflow: hidden;
|
|
||||||
max-height: 80vh;
|
|
||||||
overflow-y: auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
.info-panel-header {
|
|
||||||
display: flex;
|
|
||||||
justify-content: space-between;
|
|
||||||
align-items: center;
|
|
||||||
padding: 0.3rem;
|
|
||||||
background-color: #ff6b35;
|
|
||||||
color: #fff;
|
|
||||||
}
|
|
||||||
|
|
||||||
.info-panel-header h2 {
|
|
||||||
font-size: 0.36rem;
|
|
||||||
margin: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.close-btn {
|
|
||||||
background: none;
|
|
||||||
border: none;
|
|
||||||
color: #fff;
|
|
||||||
font-size: 0.4rem;
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
|
|
||||||
.info-panel-body {
|
|
||||||
padding: 0.3rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.info-item {
|
|
||||||
margin-bottom: 0.2rem;
|
|
||||||
font-size: 0.28rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.info-item label {
|
|
||||||
font-weight: bold;
|
|
||||||
color: #333;
|
|
||||||
}
|
|
||||||
|
|
||||||
.info-item span {
|
|
||||||
color: #666;
|
|
||||||
}
|
|
||||||
|
|
||||||
.attractions-section {
|
|
||||||
margin-top: 0.3rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.attractions-section h3 {
|
|
||||||
font-size: 0.32rem;
|
|
||||||
margin-bottom: 0.2rem;
|
|
||||||
color: #333;
|
|
||||||
}
|
|
||||||
|
|
||||||
.attractions-list {
|
|
||||||
list-style: none;
|
|
||||||
padding: 0;
|
|
||||||
margin: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.attractions-list li {
|
|
||||||
margin-bottom: 0.2rem;
|
|
||||||
padding: 0.2rem;
|
|
||||||
background-color: #f9f9f9;
|
|
||||||
border-radius: 0.1rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.attraction-name {
|
|
||||||
font-weight: bold;
|
|
||||||
color: #333;
|
|
||||||
margin-bottom: 0.05rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.attraction-description {
|
|
||||||
color: #666;
|
|
||||||
font-size: 0.26rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.media-player-container {
|
|
||||||
margin: 0.2rem;
|
|
||||||
background-color: #fff;
|
|
||||||
border-radius: 0.1rem;
|
|
||||||
padding: 0.2rem;
|
|
||||||
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
|
|
||||||
}
|
|
||||||
|
|
||||||
.scene-navigation {
|
|
||||||
display: flex;
|
|
||||||
justify-content: space-between;
|
|
||||||
padding: 0.2rem;
|
|
||||||
margin-top: 0.2rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.nav-btn {
|
|
||||||
flex: 1;
|
|
||||||
padding: 0.2rem;
|
|
||||||
margin: 0 0.1rem;
|
|
||||||
font-size: 0.3rem;
|
|
||||||
border: none;
|
|
||||||
border-radius: 0.15rem;
|
|
||||||
cursor: pointer;
|
|
||||||
transition: background-color 0.3s ease;
|
|
||||||
}
|
|
||||||
|
|
||||||
.prev-btn {
|
|
||||||
background-color: #ff9800;
|
|
||||||
color: #fff;
|
|
||||||
}
|
|
||||||
|
|
||||||
.prev-btn:disabled {
|
|
||||||
opacity: 0.5;
|
|
||||||
cursor: not-allowed;
|
|
||||||
}
|
|
||||||
|
|
||||||
.info-btn {
|
|
||||||
background-color: #4caf50;
|
|
||||||
color: #fff;
|
|
||||||
}
|
|
||||||
|
|
||||||
.next-btn {
|
|
||||||
background-color: #9c27b0;
|
|
||||||
color: #fff;
|
|
||||||
}
|
|
||||||
|
|
||||||
.nav-btn:hover:not(:disabled) {
|
|
||||||
opacity: 0.8;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
@ -17,7 +17,7 @@ onLoad((options) => {
|
||||||
console.log('Webview loading URL:', url.value)
|
console.log('Webview loading URL:', url.value)
|
||||||
} else {
|
} else {
|
||||||
// 默认URL
|
// 默认URL
|
||||||
url.value = 'https://www.720yun.com/t/1dvktq8b0fl?scene_id=74010726'
|
url.value = 'https://www.720yun.com/vr/cd4jtOyusw4'
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue