hookehuyr

refactor(views/checkin): 重构标签页逻辑为动态配置方式

将硬编码的标签页逻辑重构为基于配置的动态渲染方式
新增tab_configs配置数组管理标签页属性
优化图片点击事件处理逻辑使其支持动态标签页
<!--
* @Date: 2024-09-15 22:08:49
* @LastEditors: hookehuyr hookehuyr@gmail.com
* @LastEditTime: 2025-09-18 10:31:19
* @LastEditTime: 2025-09-18 11:31:33
* @FilePath: /map-demo/src/views/checkin/info.vue
* @Description: 文件描述
-->
......@@ -41,21 +41,16 @@
<div id="tab-wrapper" style="margin-top: 0.5rem;">
<van-config-provider :theme-vars="themeVars">
<van-tabs ref="tabsRef" v-model:active="active" @click-tab="clickTab" color="#DD7850" title-active-color="#DD7850" title-inactive-color="#DD7850" :shrink="show_shrink" sticky animated>
<van-tab :title="page_details.introduction_text" v-if="page_details.introduction">
<template v-for="config in tab_configs" :key="config.key">
<van-tab
:title="page_details[config.title_key]"
v-if="page_details[config.content_key]"
>
<div class="info-content">
<div id="introduction" v-html="page_details.introduction" style="padding: 0 1rem;"></div>
<div :id="config.id" v-html="page_details[config.content_key]" style="padding: 0 1rem;"></div>
</div>
</van-tab>
<van-tab :title="page_details.story_text" v-if="page_details.story">
<div class="info-content">
<div id="story" v-html="page_details.story" style="padding: 0 1rem;"></div>
</div>
</van-tab>
<van-tab :title="page_details.experience_text" v-if="page_details.experience">
<div class="info-content">
<div id="experience" v-html="page_details.experience" style="padding: 0 1rem;"></div>
</div>
<div v-if="page_details.experience_audio.length" class="audio-wrapper">
<!-- 音频播放器只在体验标签页显示 -->
<div v-if="config.key === 'experience' && page_details.experience_audio && page_details.experience_audio.length" class="audio-wrapper">
<div @click="toggleHandleAudio(item, index)" :class="['audio-item', play_audio_index === index ? 'click' : '']" v-for="(item, index) in page_details.experience_audio" :key="index">
<div>{{ item.description }}</div>
<van-icon @click.stop="stopAudio(item, index)" v-if="item.play" size="2rem" name="stop-circle-o" color="#DD7850" />
......@@ -63,6 +58,7 @@
</div>
</div>
</van-tab>
</template>
</van-tabs>
</van-config-provider>
</div>
......@@ -120,6 +116,31 @@ const props = defineProps({
const page_details = ref({});
// TAG: 动态标签页配置
const tab_configs = ref([
{
key: 'introduction',
title_key: 'introduction_text',
content_key: 'introduction',
default_title: '敬老月优惠',
id: 'introduction'
},
{
key: 'story',
title_key: 'story_text',
content_key: 'story',
default_title: '故 事',
id: 'story'
},
{
key: 'experience',
title_key: 'experience_text',
content_key: 'experience',
default_title: '体 验',
id: 'experience'
}
]);
// 监听props.info变化,更新页面数据并检查打卡状态
watch(
() => props.info,
......@@ -127,10 +148,10 @@ watch(
if (newInfo && newInfo.details && newInfo.details.length) {
// 更新page_details数据
page_details.value = { ...newInfo.details[0], position: newInfo.position, path: newInfo.path, current_lng: newInfo.current_lng, current_lat: newInfo.current_lat, openid: newInfo.openid };
// TODO: 模拟假的tab文字
page_details.value.introduction_text = '敬老月优惠';
page_details.value.story_text = '百联繁花里';
page_details.value.experience_text = '体 验';
// 动态设置标签页标题(使用默认值或接口返回值)
tab_configs.value.forEach(config => {
page_details.value[config.title_key] = page_details.value[config.title_key] || config.default_title;
});
// 获取浏览器可视范围的高度
$('.info-page').height(props.height + 'px');
// 检查打卡状态
......@@ -220,10 +241,10 @@ onMounted(async () => {
page_details.value.introduction = page_details.value.introduction?.replace(/\<hr\>/g, '<div class="van-hairline--bottom" style="margin: 1rem 0;"></div>')
page_details.value.story = page_details.value.story?.replace(/\<hr\>/g, '<div class="van-hairline--bottom" style="margin: 1rem 0;"></div>')
page_details.value.experience = page_details.value.experience?.replace(/\<hr\>/g, '<div class="van-hairline--bottom" style="margin: 1rem 0;"></div>')
// TODO: 模拟假的tab文字
page_details.value.introduction_text = '敬老月优惠';
page_details.value.story_text = '百联繁花里';
page_details.value.experience_text = '体 验';
// 动态设置标签页标题(使用默认值或接口返回值)
tab_configs.value.forEach(config => {
page_details.value[config.title_key] = page_details.value[config.title_key] || config.default_title;
});
// 定位
if (current_lng && current_lat) {
page_details.value.current_lng = current_lng;
......@@ -395,15 +416,11 @@ const tabsRef = ref(null);
const clickTab = (evt) => { // 标签切换
tabsRef.value.resize();
nextTick(() => {
if (evt.title === '敬老月优惠') { // 介绍
var imgs = $('#introduction').find('img');
}
if (evt.title === '百联繁花里') { // 故事
var imgs = $('#story').find('img');
}
if (evt.title === '体 验') { // 体验
var imgs = $('#experience').find('img');
}
// 根据当前激活的标签页动态获取对应的图片
const currentConfig = tab_configs.value[evt.index];
if (currentConfig) {
const imgs = $(`#${currentConfig.id}`).find('img');
// 图片点击事件
imgs.each(function(index, img) {
$(img).on('click', function (e) {
......@@ -418,7 +435,8 @@ const clickTab = (evt) => { // 标签切换
})
// 图片有5个像素的圆角
$(img).css('border-radius', '5px');
});
})
}
// 滚动高度大于tabs高度后才滚动到指定高度
let offsetTop = $('#tab-wrapper')[0].offsetTop;
if (scrollTop.value >= offsetTop) {
......