2025-07-28 10:53:56 +08:00
|
|
|
|
<template>
|
2025-08-14 11:22:53 +08:00
|
|
|
|
<view class="page">
|
|
|
|
|
|
<!-- 加载状态指示器 -->
|
|
|
|
|
|
<view v-if="loading" class="loading-overlay">
|
|
|
|
|
|
<view class="loading-content">
|
|
|
|
|
|
<text>正在加载配置...</text>
|
|
|
|
|
|
</view>
|
|
|
|
|
|
</view>
|
|
|
|
|
|
|
|
|
|
|
|
<!-- 背景图 -->
|
|
|
|
|
|
<image class="bj" :src="templeData.imgUrl" mode="aspectFill"></image>
|
|
|
|
|
|
<!-- 公告 -->
|
|
|
|
|
|
<view class="announcement">
|
|
|
|
|
|
<image class="ggimg" :src="pageConfig.announcement.icon" mode="" />
|
|
|
|
|
|
<view class="marquee-wrap">
|
|
|
|
|
|
<view class="marquee" :style="{ transform: `translateX(${marqueeX}rpx)` }">
|
|
|
|
|
|
{{ templeData.bulletinContent }}
|
|
|
|
|
|
</view>
|
|
|
|
|
|
</view>
|
|
|
|
|
|
</view>
|
|
|
|
|
|
<!-- 音频与VR图标 -->
|
|
|
|
|
|
<view class="tubiao">
|
|
|
|
|
|
<view class="audio-controls">
|
|
|
|
|
|
<image
|
|
|
|
|
|
v-if="pageConfig.topIcons.leftIcon.hidden"
|
|
|
|
|
|
:src="pageConfig.topIcons.leftIcon.img"
|
|
|
|
|
|
mode=""
|
|
|
|
|
|
@click="playAudio"
|
|
|
|
|
|
:class="{ playing: isAudioPlaying }"
|
|
|
|
|
|
></image>
|
|
|
|
|
|
<image
|
|
|
|
|
|
:src="pageConfig.topIcons.rightIcon.img"
|
|
|
|
|
|
mode=""
|
|
|
|
|
|
@click="stopAudio"
|
|
|
|
|
|
:class="{ stopped: !isAudioPlaying }"
|
|
|
|
|
|
></image>
|
|
|
|
|
|
</view>
|
|
|
|
|
|
<view class="tubiao-item">
|
|
|
|
|
|
<image :src="pageConfig.topIcons.bottomIcon.img" mode=""></image>
|
|
|
|
|
|
</view>
|
|
|
|
|
|
</view>
|
|
|
|
|
|
<!-- 底部 -->
|
|
|
|
|
|
<view class="bot">
|
|
|
|
|
|
<view class="name">
|
|
|
|
|
|
<image :src="bottomSection.openingTime.decorationImg" mode=""></image>
|
|
|
|
|
|
<text>{{ bottomSection.openingTime.title }}</text>
|
|
|
|
|
|
<image :src="bottomSection.openingTime.decorationImg" mode=""></image>
|
|
|
|
|
|
</view>
|
|
|
|
|
|
<view class="time"> {{ templeData.startTime }} - {{ templeData.endTime }} </view>
|
|
|
|
|
|
<view class="hua">
|
|
|
|
|
|
<image
|
|
|
|
|
|
src="https://api.ccttiot.com/smartmeter/img/static/uyz1LDPTjPqeOzBMjLZ7"
|
|
|
|
|
|
mode=""
|
|
|
|
|
|
></image>
|
|
|
|
|
|
</view>
|
2025-08-04 16:17:43 +08:00
|
|
|
|
<view class="list-scroll">
|
2025-08-14 11:22:53 +08:00
|
|
|
|
<view class="list">
|
|
|
|
|
|
<!-- 导航项目列表 -->
|
|
|
|
|
|
<view
|
|
|
|
|
|
class="li"
|
|
|
|
|
|
v-for="(item, index) in navigationItems"
|
|
|
|
|
|
:key="index"
|
|
|
|
|
|
@click="navigateToPage(item, index)"
|
|
|
|
|
|
>
|
|
|
|
|
|
<image :src="item.img" mode=""></image>
|
|
|
|
|
|
<view class="da">
|
|
|
|
|
|
{{ item.title }}
|
|
|
|
|
|
</view>
|
|
|
|
|
|
<view class="xiao">
|
|
|
|
|
|
{{ item.subtitle }}
|
|
|
|
|
|
</view>
|
|
|
|
|
|
</view>
|
|
|
|
|
|
|
|
|
|
|
|
<!-- 空状态提示 -->
|
|
|
|
|
|
<view v-if="!loading && navigationItems.length === 0" class="empty-state">
|
|
|
|
|
|
<text>暂无功能项目</text>
|
|
|
|
|
|
</view>
|
|
|
|
|
|
</view>
|
|
|
|
|
|
</view>
|
|
|
|
|
|
<view
|
|
|
|
|
|
class="bottom"
|
|
|
|
|
|
v-if="bottomSection.prayerSection && bottomSection.prayerSection.backgroundImg"
|
|
|
|
|
|
>
|
|
|
|
|
|
<image :src="bottomSection.prayerSection.backgroundImg" mode=""></image>
|
|
|
|
|
|
<view class="rixing">
|
|
|
|
|
|
{{ bottomSection.prayerSection.title }}
|
|
|
|
|
|
</view>
|
|
|
|
|
|
<view class="qifu" @click="goToPray">
|
|
|
|
|
|
<image :src="bottomSection.prayerSection.prayerButton.icon" mode=""></image>
|
|
|
|
|
|
<view class="zaixian">
|
|
|
|
|
|
<view class="da">
|
|
|
|
|
|
{{ bottomSection.prayerSection.prayerButton.title }}
|
2025-08-06 12:04:17 +08:00
|
|
|
|
</view>
|
2025-08-14 11:22:53 +08:00
|
|
|
|
<view class="xiao">
|
|
|
|
|
|
{{ bottomSection.prayerSection.prayerButton.subtitle }}
|
|
|
|
|
|
</view>
|
|
|
|
|
|
</view>
|
|
|
|
|
|
</view>
|
|
|
|
|
|
</view>
|
|
|
|
|
|
</view>
|
|
|
|
|
|
</view>
|
2025-07-28 10:53:56 +08:00
|
|
|
|
</template>
|
|
|
|
|
|
|
|
|
|
|
|
<script>
|
2025-08-14 11:22:53 +08:00
|
|
|
|
import { navigateToPage } from '../../utils/router.js'
|
|
|
|
|
|
import { getHomeConfig, getTempleIndex } from '../../api/index/index.js'
|
|
|
|
|
|
import { getArticleById } from '../../api/article/article.js'
|
|
|
|
|
|
|
|
|
|
|
|
export default {
|
|
|
|
|
|
data() {
|
|
|
|
|
|
return {
|
|
|
|
|
|
marqueeX: '', // 初始位置,和marquee-wrap宽度一致
|
|
|
|
|
|
timer: null,
|
|
|
|
|
|
loading: true, // 默认为true,等待API数据加载
|
|
|
|
|
|
// 页面配置数据,完全依赖API
|
|
|
|
|
|
pageConfig: {
|
|
|
|
|
|
background: { img: '' },
|
|
|
|
|
|
announcement: { icon: '', text: '' },
|
|
|
|
|
|
topIcons: {
|
|
|
|
|
|
leftIcon: { hidden: false, img: '' },
|
|
|
|
|
|
rightIcon: { img: '' },
|
|
|
|
|
|
bottomIcon: { img: '' },
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
navigationItems: [],
|
|
|
|
|
|
bottomSection: {
|
|
|
|
|
|
openingTime: {
|
|
|
|
|
|
title: '',
|
|
|
|
|
|
time: '',
|
|
|
|
|
|
decorationImg: '',
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
templeData: {
|
|
|
|
|
|
imgUrl: '',
|
|
|
|
|
|
bulletinContent: '',
|
|
|
|
|
|
startTime: '',
|
|
|
|
|
|
endTime: '',
|
|
|
|
|
|
audioUrl: '',
|
|
|
|
|
|
},
|
|
|
|
|
|
isAudioPlaying: false,
|
|
|
|
|
|
audioContext: null,
|
|
|
|
|
|
}
|
|
|
|
|
|
},
|
|
|
|
|
|
onLoad() {
|
|
|
|
|
|
// 页面加载时获取配置
|
|
|
|
|
|
this.loadHomeConfig()
|
|
|
|
|
|
// 获取寺庙数据
|
|
|
|
|
|
this.loadTempleData()
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
// 添加下拉刷新支持
|
|
|
|
|
|
onPullDownRefresh() {
|
|
|
|
|
|
console.log('用户触发下拉刷新')
|
|
|
|
|
|
Promise.all([this.loadHomeConfig(), this.loadTempleData()]).finally(() => {
|
|
|
|
|
|
uni.stopPullDownRefresh()
|
|
|
|
|
|
})
|
|
|
|
|
|
},
|
|
|
|
|
|
onShow() {
|
|
|
|
|
|
// 启动跑马灯(方法内部会检查是否有文本)
|
|
|
|
|
|
this.startMarquee()
|
|
|
|
|
|
},
|
|
|
|
|
|
onUnload() {
|
|
|
|
|
|
this.stopMarquee()
|
|
|
|
|
|
// 停止音频播放
|
|
|
|
|
|
this.stopAudio()
|
|
|
|
|
|
},
|
|
|
|
|
|
methods: {
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 获取首页配置
|
|
|
|
|
|
*/
|
|
|
|
|
|
async loadHomeConfig() {
|
|
|
|
|
|
console.log('开始获取首页配置...')
|
|
|
|
|
|
this.loading = true
|
|
|
|
|
|
|
|
|
|
|
|
// 重试机制
|
|
|
|
|
|
const maxRetries = 3
|
|
|
|
|
|
let retryCount = 0
|
|
|
|
|
|
|
|
|
|
|
|
while (retryCount < maxRetries) {
|
|
|
|
|
|
try {
|
|
|
|
|
|
console.log(`第 ${retryCount + 1} 次尝试获取配置...`)
|
|
|
|
|
|
|
|
|
|
|
|
const response = await getHomeConfig()
|
|
|
|
|
|
console.log('API响应:', response)
|
|
|
|
|
|
|
|
|
|
|
|
// 简化验证:只检查关键字段
|
|
|
|
|
|
if (response?.code === 200 && response?.data?.[0]?.body) {
|
|
|
|
|
|
const parsedConfig = JSON.parse(response.data[0].body)
|
|
|
|
|
|
|
|
|
|
|
|
// 更新页面配置
|
|
|
|
|
|
this.updatePageConfig(parsedConfig)
|
|
|
|
|
|
|
|
|
|
|
|
// 重新启动跑马灯
|
|
|
|
|
|
this.stopMarquee()
|
|
|
|
|
|
this.startMarquee()
|
|
|
|
|
|
|
|
|
|
|
|
console.log('配置加载成功')
|
|
|
|
|
|
break
|
|
|
|
|
|
} else {
|
|
|
|
|
|
throw new Error('API响应数据无效')
|
|
|
|
|
|
}
|
|
|
|
|
|
} catch (error) {
|
|
|
|
|
|
retryCount++
|
|
|
|
|
|
console.error(`第 ${retryCount} 次尝试失败:`, error.message)
|
|
|
|
|
|
|
|
|
|
|
|
if (retryCount >= maxRetries) {
|
|
|
|
|
|
console.error('所有重试都失败了')
|
|
|
|
|
|
this.useDefaultConfig()
|
|
|
|
|
|
break
|
|
|
|
|
|
} else {
|
|
|
|
|
|
await new Promise(resolve => setTimeout(resolve, retryCount * 1000))
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
this.loading = false
|
|
|
|
|
|
console.log('配置加载完成')
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 处理配置加载失败
|
|
|
|
|
|
*/
|
|
|
|
|
|
useDefaultConfig() {
|
|
|
|
|
|
console.log('API获取失败,无法加载配置')
|
|
|
|
|
|
|
|
|
|
|
|
// 不设置任何默认配置,保持初始化的空状态
|
|
|
|
|
|
// 数据保持为初始化时的空结构
|
|
|
|
|
|
|
|
|
|
|
|
// 显示提示信息
|
|
|
|
|
|
uni.showModal({
|
|
|
|
|
|
title: '加载失败',
|
|
|
|
|
|
content: '无法获取页面配置,请检查网络连接后重试',
|
|
|
|
|
|
showCancel: true,
|
|
|
|
|
|
cancelText: '取消',
|
|
|
|
|
|
confirmText: '重试',
|
|
|
|
|
|
success: res => {
|
|
|
|
|
|
if (res.confirm) {
|
|
|
|
|
|
this.loadHomeConfig()
|
|
|
|
|
|
}
|
|
|
|
|
|
},
|
|
|
|
|
|
})
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 更新页面配置
|
|
|
|
|
|
*/
|
|
|
|
|
|
updatePageConfig(parsedConfig) {
|
|
|
|
|
|
// 直接更新配置,使用默认值防止undefined
|
|
|
|
|
|
this.pageConfig = parsedConfig.pageConfig || this.pageConfig
|
|
|
|
|
|
this.navigationItems = parsedConfig.navigationItems || []
|
|
|
|
|
|
this.bottomSection = parsedConfig.bottomSection || this.bottomSection
|
|
|
|
|
|
console.log('配置更新完成')
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 获取寺庙数据
|
|
|
|
|
|
*/
|
|
|
|
|
|
async loadTempleData() {
|
|
|
|
|
|
try {
|
|
|
|
|
|
console.log('开始获取寺庙数据...')
|
|
|
|
|
|
const response = await getTempleIndex()
|
|
|
|
|
|
console.log('寺庙数据API响应:', response)
|
|
|
|
|
|
|
|
|
|
|
|
if (response?.code === 200 && response?.data) {
|
|
|
|
|
|
this.templeData = {
|
|
|
|
|
|
imgUrl: response.data.imgUrl || '',
|
|
|
|
|
|
bulletinContent: response.data.bulletinContent || '',
|
|
|
|
|
|
startTime: response.data.startTime || '',
|
|
|
|
|
|
endTime: response.data.endTime || '',
|
|
|
|
|
|
audioUrl: response.data.audioUrl || '',
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
uni.setStorageSync('abbotId', response.data.abbotId)
|
|
|
|
|
|
|
|
|
|
|
|
// 重新启动跑马灯
|
|
|
|
|
|
this.stopMarquee()
|
|
|
|
|
|
this.startMarquee()
|
|
|
|
|
|
|
|
|
|
|
|
console.log('寺庙数据加载成功')
|
|
|
|
|
|
} else {
|
|
|
|
|
|
throw new Error('寺庙数据API响应无效')
|
|
|
|
|
|
}
|
|
|
|
|
|
} catch (error) {
|
|
|
|
|
|
console.error('获取寺庙数据失败:', error)
|
|
|
|
|
|
uni.showToast({
|
|
|
|
|
|
title: '获取寺庙数据失败',
|
|
|
|
|
|
icon: 'none',
|
|
|
|
|
|
})
|
|
|
|
|
|
}
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
startMarquee() {
|
|
|
|
|
|
// 简单检查公告文本是否存在
|
|
|
|
|
|
const announcementText =
|
|
|
|
|
|
this.templeData?.bulletinContent || this.pageConfig?.announcement?.text
|
|
|
|
|
|
if (!announcementText) {
|
|
|
|
|
|
return
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 停止之前的定时器
|
|
|
|
|
|
this.stopMarquee()
|
|
|
|
|
|
|
|
|
|
|
|
// 估算文字宽度(每个字24rpx)
|
|
|
|
|
|
const textWidth = announcementText.length * 24
|
|
|
|
|
|
this.timer = setInterval(() => {
|
|
|
|
|
|
this.marqueeX--
|
|
|
|
|
|
if (this.marqueeX < -textWidth) {
|
|
|
|
|
|
this.marqueeX = 600
|
|
|
|
|
|
}
|
|
|
|
|
|
}, 16)
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
stopMarquee() {
|
|
|
|
|
|
if (this.timer) {
|
|
|
|
|
|
clearInterval(this.timer)
|
|
|
|
|
|
this.timer = null
|
|
|
|
|
|
}
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
// 兼容两种跳转方式:page路由跳转 或 aid文章详情跳转
|
|
|
|
|
|
async navigateToPage(item, index) {
|
|
|
|
|
|
try {
|
|
|
|
|
|
console.log('导航项信息:', item)
|
|
|
|
|
|
console.log('导航项索引:', index)
|
|
|
|
|
|
// 优先使用page字段进行路由跳转
|
|
|
|
|
|
if (item.page) {
|
|
|
|
|
|
console.log('使用page字段进行路由跳转:', item.page)
|
|
|
|
|
|
// 导入路由工具
|
|
|
|
|
|
const { navigateToPage: routerNavigate } = await import('../../utils/router.js')
|
|
|
|
|
|
routerNavigate(item.page)
|
|
|
|
|
|
return
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 如果没有page字段,则使用aid进行文章详情跳转
|
|
|
|
|
|
if (item.aid) {
|
|
|
|
|
|
console.log('使用aid字段获取文章详情:', item.aid)
|
|
|
|
|
|
|
|
|
|
|
|
// 显示加载提示
|
|
|
|
|
|
uni.showLoading({
|
|
|
|
|
|
title: '加载中...',
|
|
|
|
|
|
mask: true,
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
|
|
// 调用API获取文章详情
|
|
|
|
|
|
const response = await getArticleById(item.aid)
|
|
|
|
|
|
|
|
|
|
|
|
// 隐藏加载提示
|
|
|
|
|
|
uni.hideLoading()
|
|
|
|
|
|
|
|
|
|
|
|
if (response.code === 200 && response.data) {
|
|
|
|
|
|
console.log('获取文章详情成功:', response.data)
|
|
|
|
|
|
|
|
|
|
|
|
// 将文章数据存储到本地,供目标页面使用
|
|
|
|
|
|
uni.setStorageSync('currentArticle', response.data)
|
|
|
|
|
|
|
|
|
|
|
|
// 直接跳转到文章详情页面
|
|
|
|
|
|
uni.navigateTo({
|
|
|
|
|
|
url: '/pages/article/article-detail',
|
|
|
|
|
|
fail: err => {
|
|
|
|
|
|
console.error('跳转到文章详情页面失败:', err)
|
|
|
|
|
|
uni.showToast({
|
|
|
|
|
|
title: '页面跳转失败',
|
|
|
|
|
|
icon: 'none',
|
|
|
|
|
|
})
|
|
|
|
|
|
},
|
|
|
|
|
|
})
|
|
|
|
|
|
} else {
|
|
|
|
|
|
console.error('获取文章详情失败:', response)
|
|
|
|
|
|
uni.showToast({
|
|
|
|
|
|
title: '获取内容失败',
|
|
|
|
|
|
icon: 'none',
|
|
|
|
|
|
})
|
|
|
|
|
|
}
|
|
|
|
|
|
} else {
|
|
|
|
|
|
console.error('导航项既没有page字段也没有aid字段:', item)
|
|
|
|
|
|
uni.showToast({
|
|
|
|
|
|
title: '配置错误',
|
|
|
|
|
|
icon: 'none',
|
|
|
|
|
|
})
|
|
|
|
|
|
}
|
|
|
|
|
|
} catch (error) {
|
|
|
|
|
|
// 隐藏加载提示
|
|
|
|
|
|
uni.hideLoading()
|
|
|
|
|
|
|
|
|
|
|
|
console.error('导航跳转出错:', error)
|
|
|
|
|
|
uni.showToast({
|
|
|
|
|
|
title: '网络错误',
|
|
|
|
|
|
icon: 'none',
|
|
|
|
|
|
})
|
|
|
|
|
|
}
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 跳转到祈福页面
|
|
|
|
|
|
*/
|
|
|
|
|
|
goToPray() {
|
|
|
|
|
|
try {
|
|
|
|
|
|
console.log('跳转到祈福页面')
|
|
|
|
|
|
// 使用navigateToPage方法,传入参数pray
|
|
|
|
|
|
navigateToPage('pray')
|
|
|
|
|
|
} catch (error) {
|
|
|
|
|
|
console.error('跳转到祈福页面失败:', error)
|
|
|
|
|
|
uni.showToast({
|
|
|
|
|
|
title: '页面跳转失败',
|
|
|
|
|
|
icon: 'none',
|
|
|
|
|
|
})
|
|
|
|
|
|
}
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 播放音频
|
|
|
|
|
|
*/
|
|
|
|
|
|
playAudio() {
|
|
|
|
|
|
if (!this.templeData.audioUrl) {
|
|
|
|
|
|
uni.showToast({
|
|
|
|
|
|
title: '暂无音频资源',
|
|
|
|
|
|
icon: 'none',
|
|
|
|
|
|
})
|
|
|
|
|
|
return
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
|
// 如果已经在播放,先停止
|
|
|
|
|
|
if (this.audioContext) {
|
|
|
|
|
|
this.stopAudio()
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 创建音频上下文
|
|
|
|
|
|
this.audioContext = uni.createInnerAudioContext()
|
|
|
|
|
|
this.audioContext.src = this.templeData.audioUrl
|
|
|
|
|
|
this.audioContext.loop = true // 循环播放
|
|
|
|
|
|
|
|
|
|
|
|
// 监听播放状态
|
|
|
|
|
|
this.audioContext.onPlay(() => {
|
|
|
|
|
|
console.log('音频开始播放')
|
|
|
|
|
|
this.isAudioPlaying = true
|
|
|
|
|
|
uni.showToast({
|
|
|
|
|
|
title: '音频已开启',
|
|
|
|
|
|
icon: 'none',
|
|
|
|
|
|
})
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
|
|
this.audioContext.onError(err => {
|
|
|
|
|
|
console.error('音频播放错误:', err)
|
|
|
|
|
|
this.isAudioPlaying = false
|
|
|
|
|
|
uni.showToast({
|
|
|
|
|
|
title: '音频播放失败',
|
|
|
|
|
|
icon: 'none',
|
|
|
|
|
|
})
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
|
|
this.audioContext.onEnded(() => {
|
|
|
|
|
|
console.log('音频播放结束')
|
|
|
|
|
|
this.isAudioPlaying = false
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
|
|
// 开始播放
|
|
|
|
|
|
this.audioContext.play()
|
|
|
|
|
|
} catch (error) {
|
|
|
|
|
|
console.error('音频播放失败:', error)
|
|
|
|
|
|
this.isAudioPlaying = false
|
|
|
|
|
|
uni.showToast({
|
|
|
|
|
|
title: '音频播放失败',
|
|
|
|
|
|
icon: 'none',
|
|
|
|
|
|
})
|
|
|
|
|
|
}
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 停止音频
|
|
|
|
|
|
*/
|
|
|
|
|
|
stopAudio() {
|
|
|
|
|
|
if (this.audioContext) {
|
|
|
|
|
|
this.audioContext.stop()
|
|
|
|
|
|
this.audioContext.destroy()
|
|
|
|
|
|
this.audioContext = null
|
|
|
|
|
|
}
|
|
|
|
|
|
this.isAudioPlaying = false
|
|
|
|
|
|
uni.showToast({
|
|
|
|
|
|
title: '音频已关闭',
|
|
|
|
|
|
icon: 'none',
|
|
|
|
|
|
})
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
}
|
2025-07-28 10:53:56 +08:00
|
|
|
|
</script>
|
|
|
|
|
|
|
|
|
|
|
|
<style lang="scss">
|
2025-08-14 11:22:53 +08:00
|
|
|
|
page {
|
|
|
|
|
|
background-color: #fff;
|
|
|
|
|
|
}
|
|
|
|
|
|
.bot {
|
|
|
|
|
|
position: fixed;
|
|
|
|
|
|
left: 50%;
|
|
|
|
|
|
transform: translateX(-50%);
|
|
|
|
|
|
bottom: 56rpx;
|
|
|
|
|
|
width: 100%;
|
|
|
|
|
|
max-width: 750rpx;
|
|
|
|
|
|
/* 确保不会限制子元素的滚动 */
|
|
|
|
|
|
overflow: visible;
|
|
|
|
|
|
.bottom {
|
|
|
|
|
|
margin-top: 64rpx;
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
padding: 0 118rpx;
|
|
|
|
|
|
box-sizing: border-box;
|
|
|
|
|
|
image {
|
|
|
|
|
|
width: 64rpx;
|
|
|
|
|
|
height: 64rpx;
|
|
|
|
|
|
}
|
|
|
|
|
|
.rixing {
|
|
|
|
|
|
width: 206rpx;
|
|
|
|
|
|
height: 64rpx;
|
|
|
|
|
|
background: #522510;
|
|
|
|
|
|
border-radius: 45rpx 45rpx 45rpx 45rpx;
|
|
|
|
|
|
text-align: center;
|
|
|
|
|
|
line-height: 64rpx;
|
|
|
|
|
|
font-weight: 600;
|
|
|
|
|
|
font-size: 24rpx;
|
|
|
|
|
|
color: #ffffff;
|
|
|
|
|
|
border-radius: 50rpx;
|
|
|
|
|
|
margin-left: 26rpx;
|
|
|
|
|
|
margin-right: 26rpx;
|
|
|
|
|
|
}
|
|
|
|
|
|
.qifu {
|
|
|
|
|
|
width: 194rpx;
|
|
|
|
|
|
height: 64rpx;
|
|
|
|
|
|
border-radius: 41rpx 41rpx 41rpx 41rpx;
|
|
|
|
|
|
border: 1rpx solid #522510;
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
align-items: center;
|
|
|
|
|
|
justify-content: center;
|
|
|
|
|
|
image {
|
|
|
|
|
|
width: 32rpx;
|
|
|
|
|
|
height: 32rpx;
|
|
|
|
|
|
}
|
|
|
|
|
|
.zaixian {
|
|
|
|
|
|
margin-left: 12rpx;
|
|
|
|
|
|
.da {
|
|
|
|
|
|
font-size: 24rpx;
|
|
|
|
|
|
color: #522510;
|
|
|
|
|
|
font-weight: 600;
|
|
|
|
|
|
}
|
|
|
|
|
|
.xiao {
|
|
|
|
|
|
font-size: 12rpx;
|
|
|
|
|
|
color: #522510;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
.list-scroll {
|
|
|
|
|
|
width: 100%;
|
|
|
|
|
|
margin-top: 20rpx;
|
|
|
|
|
|
height: 120rpx;
|
|
|
|
|
|
overflow-x: auto;
|
|
|
|
|
|
overflow-y: hidden;
|
|
|
|
|
|
-webkit-overflow-scrolling: touch;
|
|
|
|
|
|
/* 确保滚动容器不被父元素限制 */
|
|
|
|
|
|
position: relative;
|
|
|
|
|
|
z-index: 1;
|
|
|
|
|
|
/* 隐藏滚动条 */
|
|
|
|
|
|
scrollbar-width: none;
|
|
|
|
|
|
-ms-overflow-style: none;
|
|
|
|
|
|
&::-webkit-scrollbar {
|
|
|
|
|
|
display: none;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
.list {
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
width: 1600rpx; /* 更大的宽度确保滚动 */
|
|
|
|
|
|
padding: 0 20rpx;
|
|
|
|
|
|
box-sizing: border-box;
|
|
|
|
|
|
/* 确保内容不被压缩 */
|
|
|
|
|
|
flex-shrink: 0;
|
|
|
|
|
|
.li {
|
|
|
|
|
|
width: 150rpx;
|
|
|
|
|
|
flex: 0 0 150rpx;
|
|
|
|
|
|
text-align: center;
|
|
|
|
|
|
margin-right: 20rpx;
|
|
|
|
|
|
image {
|
|
|
|
|
|
width: 56rpx;
|
|
|
|
|
|
height: 56rpx;
|
|
|
|
|
|
}
|
|
|
|
|
|
.da {
|
|
|
|
|
|
font-size: 24rpx;
|
|
|
|
|
|
color: #522510;
|
|
|
|
|
|
margin-top: 8rpx;
|
|
|
|
|
|
}
|
|
|
|
|
|
.xiao {
|
|
|
|
|
|
font-size: 12rpx;
|
|
|
|
|
|
color: #522510;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.empty-state {
|
|
|
|
|
|
width: 100%;
|
|
|
|
|
|
text-align: center;
|
|
|
|
|
|
padding: 40rpx;
|
|
|
|
|
|
color: #999;
|
|
|
|
|
|
font-size: 28rpx;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
.hua {
|
|
|
|
|
|
width: 100%;
|
|
|
|
|
|
text-align: center;
|
|
|
|
|
|
margin-top: 30rpx;
|
|
|
|
|
|
image {
|
|
|
|
|
|
width: 656rpx;
|
|
|
|
|
|
height: 108rpx;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
.time {
|
|
|
|
|
|
font-weight: 600;
|
|
|
|
|
|
font-size: 32rpx;
|
|
|
|
|
|
color: #522510;
|
|
|
|
|
|
margin-top: 8rpx;
|
|
|
|
|
|
width: 100%;
|
|
|
|
|
|
text-align: center;
|
|
|
|
|
|
}
|
|
|
|
|
|
.name {
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
align-items: center;
|
|
|
|
|
|
width: 100%;
|
|
|
|
|
|
justify-content: center;
|
|
|
|
|
|
text {
|
|
|
|
|
|
font-weight: 600;
|
|
|
|
|
|
font-size: 32rpx;
|
|
|
|
|
|
color: #522510;
|
|
|
|
|
|
margin-left: 24rpx;
|
|
|
|
|
|
margin-right: 24rpx;
|
|
|
|
|
|
}
|
|
|
|
|
|
image {
|
|
|
|
|
|
width: 12rpx;
|
|
|
|
|
|
height: 12rpx;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
.tubiao {
|
|
|
|
|
|
width: 100%;
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
padding: 0 40rpx;
|
|
|
|
|
|
box-sizing: border-box;
|
|
|
|
|
|
justify-content: space-between;
|
|
|
|
|
|
|
|
|
|
|
|
.audio-controls {
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
align-items: center;
|
|
|
|
|
|
gap: 26rpx;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
image {
|
|
|
|
|
|
width: 82rpx;
|
|
|
|
|
|
height: 82rpx;
|
|
|
|
|
|
display: block;
|
|
|
|
|
|
margin-top: 50rpx;
|
|
|
|
|
|
transition: all 0.3s ease;
|
|
|
|
|
|
|
|
|
|
|
|
&:active {
|
|
|
|
|
|
transform: scale(0.9);
|
|
|
|
|
|
opacity: 0.8;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
&.playing {
|
|
|
|
|
|
animation: pulse 2s infinite;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
&.stopped {
|
|
|
|
|
|
opacity: 0.6;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@keyframes pulse {
|
|
|
|
|
|
0% {
|
|
|
|
|
|
transform: scale(1);
|
|
|
|
|
|
}
|
|
|
|
|
|
50% {
|
|
|
|
|
|
transform: scale(1.1);
|
|
|
|
|
|
}
|
|
|
|
|
|
100% {
|
|
|
|
|
|
transform: scale(1);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
.announcement {
|
|
|
|
|
|
width: 100%;
|
|
|
|
|
|
margin-top: 184rpx;
|
|
|
|
|
|
padding: 0 48rpx;
|
|
|
|
|
|
box-sizing: border-box;
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
align-items: center;
|
|
|
|
|
|
white-space: nowrap;
|
|
|
|
|
|
.ggimg {
|
|
|
|
|
|
width: 32rpx;
|
|
|
|
|
|
height: 32rpx;
|
|
|
|
|
|
margin-right: 14rpx;
|
|
|
|
|
|
}
|
|
|
|
|
|
.marquee-wrap {
|
|
|
|
|
|
width: 600rpx;
|
|
|
|
|
|
overflow: hidden;
|
|
|
|
|
|
position: relative;
|
|
|
|
|
|
height: 32rpx;
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
align-items: center;
|
|
|
|
|
|
}
|
|
|
|
|
|
.marquee {
|
|
|
|
|
|
white-space: nowrap;
|
|
|
|
|
|
position: absolute;
|
|
|
|
|
|
left: 0;
|
|
|
|
|
|
top: 0;
|
|
|
|
|
|
font-size: 24rpx;
|
|
|
|
|
|
color: #522510;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
.bj {
|
|
|
|
|
|
width: 100%;
|
|
|
|
|
|
height: 100vh;
|
|
|
|
|
|
position: fixed;
|
|
|
|
|
|
top: 0;
|
|
|
|
|
|
left: 0;
|
|
|
|
|
|
z-index: -1;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* 加载状态指示器样式 */
|
|
|
|
|
|
.loading-overlay {
|
|
|
|
|
|
position: fixed;
|
|
|
|
|
|
top: 0;
|
|
|
|
|
|
left: 0;
|
|
|
|
|
|
width: 100%;
|
|
|
|
|
|
height: 100%;
|
|
|
|
|
|
background-color: rgba(0, 0, 0, 0.5);
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
justify-content: center;
|
|
|
|
|
|
align-items: center;
|
|
|
|
|
|
z-index: 9999;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.loading-content {
|
|
|
|
|
|
background-color: rgba(255, 255, 255, 0.9);
|
|
|
|
|
|
padding: 40rpx 60rpx;
|
|
|
|
|
|
border-radius: 20rpx;
|
|
|
|
|
|
text-align: center;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.loading-content text {
|
|
|
|
|
|
font-size: 28rpx;
|
|
|
|
|
|
color: #333;
|
|
|
|
|
|
}
|
|
|
|
|
|
</style>
|