buddhism/pages/nearbystores/index.vue
minimaxagent1 69c05c4911 换皮test1.3
公告,时间,背景图,已经可以使用temple/index接口进行修改
2025-08-06 14:12:33 +08:00

612 lines
14 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<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>
<!-- 右侧图标 -->
<view class="tubiao">
<view class="">
<image v-if="pageConfig.topIcons.leftIcon.hidden" :src="pageConfig.topIcons.leftIcon.img" mode=""></image>
<image :src="pageConfig.topIcons.rightIcon.img" mode=""></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>
<view class="list-scroll">
<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">
<!-- <image :src="bottomSection.prayerSection.backgroundImg" mode=""></image>-->
<!-- <view class="rixing">-->
<!-- {{ bottomSection.prayerSection.title }}-->
<!-- </view>-->
<!-- <view class="qifu">-->
<!-- <image :src="bottomSection.prayerSection.prayerButton.icon" mode=""></image>-->
<!-- <view class="zaixian">-->
<!-- <view class="da">-->
<!-- {{ bottomSection.prayerSection.prayerButton.title }}-->
<!-- </view>-->
<!-- <view class="xiao">-->
<!-- {{ bottomSection.prayerSection.prayerButton.subtitle }}-->
<!-- </view>-->
<!-- </view>-->
<!-- </view>-->
</view>
</view>
</view>
</template>
<script>
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 || ''
};
// 重新启动跑马灯
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'
});
}
}
}
}
</script>
<style lang="scss">
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 30rpx;
box-sizing: border-box;
justify-content: space-between;
image{
width: 82rpx;
height: 82rpx;
display: block;
margin-top: 50rpx;
}
}
.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>