hookehuyr

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

将硬编码的标签页逻辑重构为基于配置的动态渲染方式
新增tab_configs配置数组管理标签页属性
优化图片点击事件处理逻辑使其支持动态标签页
1 <!-- 1 <!--
2 * @Date: 2024-09-15 22:08:49 2 * @Date: 2024-09-15 22:08:49
3 * @LastEditors: hookehuyr hookehuyr@gmail.com 3 * @LastEditors: hookehuyr hookehuyr@gmail.com
4 - * @LastEditTime: 2025-09-18 10:31:19 4 + * @LastEditTime: 2025-09-18 11:31:33
5 * @FilePath: /map-demo/src/views/checkin/info.vue 5 * @FilePath: /map-demo/src/views/checkin/info.vue
6 * @Description: 文件描述 6 * @Description: 文件描述
7 --> 7 -->
...@@ -41,21 +41,16 @@ ...@@ -41,21 +41,16 @@
41 <div id="tab-wrapper" style="margin-top: 0.5rem;"> 41 <div id="tab-wrapper" style="margin-top: 0.5rem;">
42 <van-config-provider :theme-vars="themeVars"> 42 <van-config-provider :theme-vars="themeVars">
43 <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> 43 <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>
44 - <van-tab :title="page_details.introduction_text" v-if="page_details.introduction"> 44 + <template v-for="config in tab_configs" :key="config.key">
45 + <van-tab
46 + :title="page_details[config.title_key]"
47 + v-if="page_details[config.content_key]"
48 + >
45 <div class="info-content"> 49 <div class="info-content">
46 - <div id="introduction" v-html="page_details.introduction" style="padding: 0 1rem;"></div> 50 + <div :id="config.id" v-html="page_details[config.content_key]" style="padding: 0 1rem;"></div>
47 </div> 51 </div>
48 - </van-tab> 52 + <!-- 音频播放器只在体验标签页显示 -->
49 - <van-tab :title="page_details.story_text" v-if="page_details.story"> 53 + <div v-if="config.key === 'experience' && page_details.experience_audio && page_details.experience_audio.length" class="audio-wrapper">
50 - <div class="info-content">
51 - <div id="story" v-html="page_details.story" style="padding: 0 1rem;"></div>
52 - </div>
53 - </van-tab>
54 - <van-tab :title="page_details.experience_text" v-if="page_details.experience">
55 - <div class="info-content">
56 - <div id="experience" v-html="page_details.experience" style="padding: 0 1rem;"></div>
57 - </div>
58 - <div v-if="page_details.experience_audio.length" class="audio-wrapper">
59 <div @click="toggleHandleAudio(item, index)" :class="['audio-item', play_audio_index === index ? 'click' : '']" v-for="(item, index) in page_details.experience_audio" :key="index"> 54 <div @click="toggleHandleAudio(item, index)" :class="['audio-item', play_audio_index === index ? 'click' : '']" v-for="(item, index) in page_details.experience_audio" :key="index">
60 <div>{{ item.description }}</div> 55 <div>{{ item.description }}</div>
61 <van-icon @click.stop="stopAudio(item, index)" v-if="item.play" size="2rem" name="stop-circle-o" color="#DD7850" /> 56 <van-icon @click.stop="stopAudio(item, index)" v-if="item.play" size="2rem" name="stop-circle-o" color="#DD7850" />
...@@ -63,6 +58,7 @@ ...@@ -63,6 +58,7 @@
63 </div> 58 </div>
64 </div> 59 </div>
65 </van-tab> 60 </van-tab>
61 + </template>
66 </van-tabs> 62 </van-tabs>
67 </van-config-provider> 63 </van-config-provider>
68 </div> 64 </div>
...@@ -120,6 +116,31 @@ const props = defineProps({ ...@@ -120,6 +116,31 @@ const props = defineProps({
120 116
121 const page_details = ref({}); 117 const page_details = ref({});
122 118
119 +// TAG: 动态标签页配置
120 +const tab_configs = ref([
121 + {
122 + key: 'introduction',
123 + title_key: 'introduction_text',
124 + content_key: 'introduction',
125 + default_title: '敬老月优惠',
126 + id: 'introduction'
127 + },
128 + {
129 + key: 'story',
130 + title_key: 'story_text',
131 + content_key: 'story',
132 + default_title: '故 事',
133 + id: 'story'
134 + },
135 + {
136 + key: 'experience',
137 + title_key: 'experience_text',
138 + content_key: 'experience',
139 + default_title: '体 验',
140 + id: 'experience'
141 + }
142 +]);
143 +
123 // 监听props.info变化,更新页面数据并检查打卡状态 144 // 监听props.info变化,更新页面数据并检查打卡状态
124 watch( 145 watch(
125 () => props.info, 146 () => props.info,
...@@ -127,10 +148,10 @@ watch( ...@@ -127,10 +148,10 @@ watch(
127 if (newInfo && newInfo.details && newInfo.details.length) { 148 if (newInfo && newInfo.details && newInfo.details.length) {
128 // 更新page_details数据 149 // 更新page_details数据
129 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 }; 150 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 };
130 - // TODO: 模拟假的tab文字 151 + // 动态设置标签页标题(使用默认值或接口返回值)
131 - page_details.value.introduction_text = '敬老月优惠'; 152 + tab_configs.value.forEach(config => {
132 - page_details.value.story_text = '百联繁花里'; 153 + page_details.value[config.title_key] = page_details.value[config.title_key] || config.default_title;
133 - page_details.value.experience_text = '体 验'; 154 + });
134 // 获取浏览器可视范围的高度 155 // 获取浏览器可视范围的高度
135 $('.info-page').height(props.height + 'px'); 156 $('.info-page').height(props.height + 'px');
136 // 检查打卡状态 157 // 检查打卡状态
...@@ -220,10 +241,10 @@ onMounted(async () => { ...@@ -220,10 +241,10 @@ onMounted(async () => {
220 page_details.value.introduction = page_details.value.introduction?.replace(/\<hr\>/g, '<div class="van-hairline--bottom" style="margin: 1rem 0;"></div>') 241 page_details.value.introduction = page_details.value.introduction?.replace(/\<hr\>/g, '<div class="van-hairline--bottom" style="margin: 1rem 0;"></div>')
221 page_details.value.story = page_details.value.story?.replace(/\<hr\>/g, '<div class="van-hairline--bottom" style="margin: 1rem 0;"></div>') 242 page_details.value.story = page_details.value.story?.replace(/\<hr\>/g, '<div class="van-hairline--bottom" style="margin: 1rem 0;"></div>')
222 page_details.value.experience = page_details.value.experience?.replace(/\<hr\>/g, '<div class="van-hairline--bottom" style="margin: 1rem 0;"></div>') 243 page_details.value.experience = page_details.value.experience?.replace(/\<hr\>/g, '<div class="van-hairline--bottom" style="margin: 1rem 0;"></div>')
223 - // TODO: 模拟假的tab文字 244 + // 动态设置标签页标题(使用默认值或接口返回值)
224 - page_details.value.introduction_text = '敬老月优惠'; 245 + tab_configs.value.forEach(config => {
225 - page_details.value.story_text = '百联繁花里'; 246 + page_details.value[config.title_key] = page_details.value[config.title_key] || config.default_title;
226 - page_details.value.experience_text = '体 验'; 247 + });
227 // 定位 248 // 定位
228 if (current_lng && current_lat) { 249 if (current_lng && current_lat) {
229 page_details.value.current_lng = current_lng; 250 page_details.value.current_lng = current_lng;
...@@ -395,15 +416,11 @@ const tabsRef = ref(null); ...@@ -395,15 +416,11 @@ const tabsRef = ref(null);
395 const clickTab = (evt) => { // 标签切换 416 const clickTab = (evt) => { // 标签切换
396 tabsRef.value.resize(); 417 tabsRef.value.resize();
397 nextTick(() => { 418 nextTick(() => {
398 - if (evt.title === '敬老月优惠') { // 介绍 419 + // 根据当前激活的标签页动态获取对应的图片
399 - var imgs = $('#introduction').find('img'); 420 + const currentConfig = tab_configs.value[evt.index];
400 - } 421 + if (currentConfig) {
401 - if (evt.title === '百联繁花里') { // 故事 422 + const imgs = $(`#${currentConfig.id}`).find('img');
402 - var imgs = $('#story').find('img'); 423 +
403 - }
404 - if (evt.title === '体 验') { // 体验
405 - var imgs = $('#experience').find('img');
406 - }
407 // 图片点击事件 424 // 图片点击事件
408 imgs.each(function(index, img) { 425 imgs.each(function(index, img) {
409 $(img).on('click', function (e) { 426 $(img).on('click', function (e) {
...@@ -418,7 +435,8 @@ const clickTab = (evt) => { // 标签切换 ...@@ -418,7 +435,8 @@ const clickTab = (evt) => { // 标签切换
418 }) 435 })
419 // 图片有5个像素的圆角 436 // 图片有5个像素的圆角
420 $(img).css('border-radius', '5px'); 437 $(img).css('border-radius', '5px');
421 - }); 438 + })
439 + }
422 // 滚动高度大于tabs高度后才滚动到指定高度 440 // 滚动高度大于tabs高度后才滚动到指定高度
423 let offsetTop = $('#tab-wrapper')[0].offsetTop; 441 let offsetTop = $('#tab-wrapper')[0].offsetTop;
424 if (scrollTop.value >= offsetTop) { 442 if (scrollTop.value >= offsetTop) {
......