修复地图定位bug

This commit is contained in:
2025-11-28 09:21:37 +08:00
parent 089b8d708e
commit 2a249d04da
11 changed files with 602 additions and 441 deletions
+290 -297
View File
@@ -1,41 +1,40 @@
<template>
<view class="container fullscreen">
<!-- 自定义导航栏 -->
<view class="custom-navbar" :style="{ paddingTop: statusBarHeight + 'px' }">
<view class="navbar-content" :style="{ height: navBarHeight + 'px' }">
<text class="navbar-title">{{ $t('home.title') }}</text>
</view>
</view>
<!-- 顶部信息区域通知招商等 -->
<view class="top-info-section" :style="{ top: (statusBarHeight + navBarHeight) + 'px' }">
<!-- 通知栏 -->
<view class="notice-wrapper" v-if="noticeText" @click="openNoticePopup">
<uv-notice-bar :text="noticeText" :speed="50" :show-icon="true" color="#07c160" bg-color="#E8F8EF"
icon="volume"></uv-notice-bar>
</view>
</view>
<!-- 内容区域 -->
<view class="main-content" :style="{ paddingTop: (statusBarHeight + navBarHeight + noticeHeight) + 'px' }">
<!-- 全屏地图组件 -->
<MapComponent v-if="!isLoading && userLocation" ref="mapRef" :userLocation="userLocation"
:positionList="positionList" :filteredPositions="filteredPositions" :searchKeyword="searchKeyword"
:enableMarkers="true"
:hideMapOverlays="showGuidePopup || showNoticePopup || showActivityPopup"
@relocate="handleRelocate" @scan="handleScan" @showList="showLocationList" @markerTap="selectPosition"
@mapCenterChange="onMapCenterChange" />
<!-- 地图加载状态 -->
<view v-if="isLoading || !userLocation" class="map-loading-placeholder">
<view class="loading-content">
<view class="loading-spinner"></view>
<text>{{ $t('common.loadingLocation') }}</text>
<!-- 自定义导航栏 -->
<view class="custom-navbar" :style="{ paddingTop: statusBarHeight + 'px' }">
<view class="navbar-content" :style="{ height: navBarHeight + 'px' }">
<text class="navbar-title">{{ $t('home.title') }}</text>
</view>
</view>
</view>
<!-- 底部操作栏附近设备 / 扫码使用 / 我的 -->
<!-- 顶部信息区域通知招商等 -->
<view class="top-info-section" :style="{ top: (statusBarHeight + navBarHeight) + 'px' }">
<!-- 通知栏 -->
<view class="notice-wrapper" v-if="noticeText" @click="openNoticePopup">
<uv-notice-bar :text="noticeText" :speed="50" :show-icon="true" color="#07c160" bg-color="#E8F8EF"
icon="volume"></uv-notice-bar>
</view>
</view>
<!-- 内容区域 -->
<view class="main-content" :style="{ paddingTop: (statusBarHeight + navBarHeight + noticeHeight) + 'px' }">
<!-- 全屏地图组件 -->
<MapComponent v-if="!isLoading && userLocation" ref="mapRef" :userLocation="userLocation"
:positionList="positionList" :filteredPositions="filteredPositions" :searchKeyword="searchKeyword"
:enableMarkers="true" :hideMapOverlays="showGuidePopup || showNoticePopup || showActivityPopup"
@relocate="handleRelocate" @scan="handleScan" @showList="showLocationList" @markerTap="selectPosition"
@mapCenterChange="onMapCenterChange" />
<!-- 地图加载状态 -->
<view v-if="isLoading || !userLocation" class="map-loading-placeholder">
<view class="loading-content">
<view class="loading-spinner"></view>
<text>{{ $t('common.loadingLocation') }}</text>
</view>
</view>
</view>
<!-- 底部操作栏附近设备 / 扫码使用 / 我的 -->
<view class="bottom-actions">
<!-- <view class="action-btn secondary small btn-nearby" @click="showLocationList">
<view class="icon-wrap">
@@ -67,16 +66,9 @@
</view>
<!-- 场地列表弹窗组件 -->
<LocationListSheet
:show="showLocationPopup"
:expanded="isExpanded"
:positions="filteredPositions"
:isLoading="isLoading"
:title="$t('home.nearbyDeviceLocation')"
@close="hideLocationList"
@select="selectPositionFromPopup"
@navigate="navigateToPosition"
/>
<LocationListSheet :show="showLocationPopup" :expanded="isExpanded" :positions="filteredPositions"
:isLoading="isLoading" :title="$t('home.nearbyDeviceLocation')" @close="hideLocationList"
@select="selectPositionFromPopup" @navigate="navigateToPosition" />
<!-- 加载状态 -->
<view class="loading-overlay" v-if="isLoading">
@@ -107,90 +99,82 @@
</view>
</view>
<!-- 使用指南居中弹出ref 控制 open/close -->
<uv-popup ref="guidePopup" mode="center" round="24" :overlay="true" :closeOnClickOverlay="false" :safeAreaInsetBottom="false">
<view class="guide-popup">
<view class="guide-header">
<text class="guide-title">{{ $t('guide.title') }}</text>
<!-- <view class="guide-close" @click="closeGuidePopup">
<!-- 使用指南居中弹出ref 控制 open/close -->
<uv-popup ref="guidePopup" mode="center" :overlay="true" :closeOnClickOverlay="false"
:safeAreaInsetBottom="false">
<view class="guide-popup">
<view class="guide-header">
<text class="guide-title">{{ $t('guide.title') }}</text>
<!-- <view class="guide-close" @click="closeGuidePopup">
<uv-icon name="close" size="20"></uv-icon>
</view> -->
</view>
<view class="guide-content">
<view class="guide-step" v-for="(step, idx) in guideSteps" :key="idx">
<view class="step-index">{{ idx + 1 }}</view>
<view class="step-info">
<view class="step-title">{{ $t('guide.step' + (idx + 1) + 'Title') }}</view>
<view class="step-desc">{{ $t('guide.step' + (idx + 1) + 'Desc') }}</view>
</view>
<view class="guide-content">
<view class="guide-step" v-for="(step, idx) in guideSteps" :key="idx">
<view class="step-index">{{ idx + 1 }}</view>
<view class="step-info">
<view class="step-title">{{ $t('guide.step' + (idx + 1) + 'Title') }}</view>
<view class="step-desc">{{ $t('guide.step' + (idx + 1) + 'Desc') }}</view>
</view>
</view>
</view>
</view>
<view class="guide-actions">
<!-- <view class="primary-btn" @click="closeGuidePopup"></view> -->
<view class="primary-btn" @click="closeGuidePopup">
<view class="primary-btn" @click="closeGuidePopup">
<uv-icon name="close" size="20"></uv-icon>
</view>
</view>
</view>
</uv-popup>
</uv-popup>
<!-- 通知详情弹窗居中弹出 -->
<uv-popup ref="noticePopup" mode="center" :overlay="true" :closeOnClickOverlay="true"
:safeAreaInsetBottom="false">
<view class="notice-popup">
<view class="notice-header">
<text class="notice-title">{{ $t('home.noticeTitle') }}</text>
</view>
<view class="notice-content">
<text class="notice-text">{{ noticeText }}</text>
</view>
<!-- 通知详情弹窗居中弹出 -->
<uv-popup ref="noticePopup" mode="center" round="24" :overlay="true" :closeOnClickOverlay="true" :safeAreaInsetBottom="false">
<view class="notice-popup">
<view class="notice-header">
<text class="notice-title">{{ $t('home.noticeTitle') }}</text>
</view>
<view class="notice-content">
<text class="notice-text">{{ noticeText }}</text>
</view>
<view class="notice-actions">
<view class="primary-btn" @click="closeNoticePopup">
<uv-icon name="close" size="20"></uv-icon>
</view>
</view>
</view>
</uv-popup>
</uv-popup>
<!-- 活动弹窗居中弹出支持多个活动轮播 -->
<uv-popup ref="activityPopup" mode="center" round="16" :overlay="true" :closeOnClickOverlay="false" :safeAreaInsetBottom="false" :customStyle="{ background: 'transparent' }">
<view class="activity-popup" v-if="activityList && activityList.length > 0">
<!-- 轮播图 -->
<swiper
class="activity-swiper"
:indicator-dots="activityList.length > 1"
:autoplay="false"
:circular="false"
@change="onActivitySwiperChange"
:current="currentActivityIndex"
>
<swiper-item v-for="(activity, index) in activityList" :key="index">
<view class="activity-poster-wrapper">
<image
:src="activity.coverImageUrl || activity.imageUrl || activity.posterUrl"
mode="aspectFit"
class="activity-poster"
></image>
<!-- 活动弹窗居中弹出支持多个活动轮播 -->
<uv-popup ref="activityPopup" mode="center" round="16" :overlay="true" :closeOnClickOverlay="false"
:safeAreaInsetBottom="false" :customStyle="{ background: 'transparent' }">
<view class="activity-popup" v-if="activityList && activityList.length > 0">
<!-- 轮播图 -->
<swiper class="activity-swiper" :indicator-dots="activityList.length > 1" :autoplay="false"
:circular="false" @change="onActivitySwiperChange" :current="currentActivityIndex">
<swiper-item v-for="(activity, index) in activityList" :key="index">
<view class="activity-poster-wrapper">
<image :src="activity.coverImageUrl || activity.imageUrl || activity.posterUrl"
mode="aspectFit" class="activity-poster"></image>
</view>
</swiper-item>
</swiper>
<!-- 自定义指示器 -->
<view class="activity-indicators" v-if="activityList.length > 1">
<view v-for="(item, index) in activityList" :key="index" class="indicator-dot"
:class="{ active: index === currentActivityIndex }"></view>
</view>
<!-- 关闭按钮 -->
<view class="activity-close-btn" @click="closeActivityPopup">
<text class="close-text">{{ $t('common.close') }}</text>
</view>
</view>
</swiper-item>
</swiper>
<!-- 自定义指示器 -->
<view class="activity-indicators" v-if="activityList.length > 1">
<view
v-for="(item, index) in activityList"
:key="index"
class="indicator-dot"
:class="{ active: index === currentActivityIndex }"
></view>
</view>
<!-- 关闭按钮 -->
<view class="activity-close-btn" @click="closeActivityPopup">
<text class="close-text">{{ $t('common.close') }}</text>
</view>
</view>
</uv-popup>
</view>
</uv-popup>
</view>
</template>
<script setup>
@@ -230,8 +214,10 @@
// 注意:从 pages/index/ 目录访问 components/ 需要使用 ../../components/ 路径
import MapComponent from '../../components/MapComponent.vue'
import LocationListSheet from '../../components/LocationListSheet.vue'
import { useI18n } from '../../utils/i18n.js'
import {
useI18n
} from '../../utils/i18n.js'
// 开启右上角分享菜单(仅 mp-weixin 有效)
// #ifdef MP-WEIXIN
wx.showShareMenu({
@@ -240,7 +226,9 @@
})
// #endif
const { t: $t } = useI18n()
const {
t: $t
} = useI18n()
// 响应式数据
const searchKeyword = ref('')
@@ -251,26 +239,37 @@
const isLoading = ref(false)
const showPhoneAuthPopup = ref(false)
const isLocationInitialized = ref(false)
const showLocationPopup = ref(false)
const isRelocating = ref(false) // 防抖标志:是否正在重新定位
const showGuidePopup = ref(false) // 使用指南弹窗显示状态
const showNoticePopup = ref(false) // 通知详情弹窗显示状态
const showActivityPopup = ref(false) // 活动弹窗显示状态
const activityList = ref([]) // 活动列表
const currentActivityIndex = ref(0) // 当前活动索引
const hasShownActivityThisSession = ref(false) // 本次会话是否已显示过活动(内存变量)
// 导航栏高度相关
const statusBarHeight = ref(0)
const showLocationPopup = ref(false)
const isRelocating = ref(false) // 防抖标志:是否正在重新定位
const showGuidePopup = ref(false) // 使用指南弹窗显示状态
const showNoticePopup = ref(false) // 通知详情弹窗显示状态
const showActivityPopup = ref(false) // 活动弹窗显示状态
const activityList = ref([]) // 活动列表
const currentActivityIndex = ref(0) // 当前活动索引
const hasShownActivityThisSession = ref(false) // 本次会话是否已显示过活动(内存变量)
// 导航栏高度相关
const statusBarHeight = ref(0)
const navBarHeight = ref(44) // 默认导航栏内容高度
const noticeHeight = ref(0) // 通知栏高度
// 使用指南步骤
const guideSteps = ref([
{ title: '扫码使用', desc: '找到附近设备,扫描设备上的二维码' },
{ title: '免押金支付', desc: '无需支付押金,使用支付分免押即可完成租借' },
{ title: '开始使用', desc: '设备自动解锁,风扇弹出后取出即可开始使用' },
{ title: '归还设备', desc: '使用完毕后,按照设备规格要求将风扇还入即可结束订单' }
const guideSteps = ref([{
title: '扫码使用',
desc: '找到附近设备,扫描设备上的二维码'
},
{
title: '免押金支付',
desc: '无需支付押金,使用支付分免押即可完成租借'
},
{
title: '开始使用',
desc: '设备自动解锁,风扇弹出后取出即可开始使用'
},
{
title: '归还设备',
desc: '使用完毕后,按照设备规格要求将风扇还入即可结束订单'
}
])
const redirectToLogin = () => {
@@ -298,12 +297,12 @@ const statusBarHeight = ref(0)
}
const res = await getNoticeTextData(parasm);
noticeText.value = res.data.noticeContent;
// 设置通知栏高度
if (res.data.noticeContent) {
noticeHeight.value = 50 // 通知栏高度约50px
}
// 将通知内容存储到本地缓存
try {
uni.setStorageSync('noticeContent', res.data.noticeContent);
@@ -312,7 +311,7 @@ const statusBarHeight = ref(0)
console.warn('缓存通知内容失败:', e);
}
}
// 查询最近的活动
const checkActiveActivity = async () => {
try {
@@ -321,13 +320,13 @@ const statusBarHeight = ref(0)
console.log('本次会话已显示过活动弹窗,跳过');
return;
}
const res = await getActiveActivity();
console.log('活动接口返回:', res);
if (res.code === 200) {
let activities = [];
// 处理活动数据:兼容多种返回格式
if (res.rows && Array.isArray(res.rows)) {
// 格式1: { code: 200, rows: [...] }
@@ -342,14 +341,14 @@ const statusBarHeight = ref(0)
// 格式4: { code: 200, data: {...} } 单个对象
activities = [res.data];
}
// 过滤有效的活动(必须有封面图)
activityList.value = activities.filter(item => {
return item && (item.coverImageUrl || item.imageUrl || item.posterUrl);
});
console.log('过滤后的活动列表:', activityList.value);
// 如果有活动数据,则显示弹窗
if (activityList.value.length > 0) {
currentActivityIndex.value = 0; // 重置索引
@@ -376,11 +375,11 @@ const statusBarHeight = ref(0)
}
// 组件引用
const mapRef = ref(null)
const guidePopup = ref(null)
const noticePopup = ref(null)
const activityPopup = ref(null)
// 组件引用
const mapRef = ref(null)
const guidePopup = ref(null)
const noticePopup = ref(null)
const activityPopup = ref(null)
// 计算属性
const searchPlaceholder = computed(() => {
@@ -395,19 +394,19 @@ const activityPopup = ref(null)
try {
const systemInfo = uni.getSystemInfoSync()
statusBarHeight.value = systemInfo.statusBarHeight || 0
// #ifdef MP-WEIXIN
// 获取胶囊按钮位置信息
const menuButtonInfo = uni.getMenuButtonBoundingClientRect()
// 计算导航栏内容高度:(胶囊底部坐标 - 状态栏高度) 确保与胶囊对齐
navBarHeight.value = (menuButtonInfo.top - systemInfo.statusBarHeight) * 2 + menuButtonInfo.height
// #endif
// #ifndef MP-WEIXIN
// 非微信小程序使用默认高度
navBarHeight.value = 44
// #endif
console.log('状态栏高度:', statusBarHeight.value)
console.log('导航栏内容高度:', navBarHeight.value)
} catch (error) {
@@ -438,7 +437,7 @@ const activityPopup = ref(null)
} catch (e) {
console.warn('清理旧缓存失败:', e);
}
// 开发环境测试距离计算
if (process.env.NODE_ENV === 'development') {
testDistanceCalculation()
@@ -446,90 +445,82 @@ const activityPopup = ref(null)
await getNoticeText();
// 1. 先获取用户位置
await getUserLocationAndAddress()
await getUserLocationAndAddress()
// 2. 加载场地列表
await loadPositions()
// 2. 加载场地列表(依赖定位)
await loadPositions()
// 3. 查询活动并显示弹窗
await checkActiveActivity()
} catch (error) {
console.error('初始化失败:', error)
// 即使失败也要加载场地列表
await loadPositions()
uni.showToast({
title: $t('home.getLocationFailed'),
icon: 'none'
})
} finally {
isLoading.value = false
}
}
const getUserLocationAndAddress = async () => {
try {
// 使用腾讯地图SDK获取位置
const location = await getUserLocation()
// 使用腾讯地图SDK获取位置(若失败抛出,由调用方统一处理)
const location = await getUserLocation()
// 保存用户位置
userLocation.value = {
longitude: location.longitude,
latitude: location.latitude
}
if (!location?.longitude || !location?.latitude) {
throw new Error('invalid location result')
}
console.log(userLocation.value);
// 将经纬度写入本地缓存(基础信息)
// 保存用户位置
userLocation.value = {
longitude: location.longitude,
latitude: location.latitude
}
console.log(userLocation.value);
// 将经纬度写入本地缓存(基础信息)
try {
uni.setStorageSync('userLocation', {
longitude: location.longitude,
latitude: location.latitude
})
} catch (e) {
console.warn('缓存基础定位信息失败:', e)
}
// 只在首次初始化时设置标记
if (!isLocationInitialized.value) {
isLocationInitialized.value = true
}
// 获取详细地址信息
try {
const addressResult = await getRegeo(location.longitude, location.latitude)
if (addressResult.success) {
const addressInfo = addressResult.data
userLocation.value.address = addressInfo.formatted_address
userLocation.value.city = addressInfo.addressComponent.city
userLocation.value.district = addressInfo.addressComponent.district
// 更新本地缓存,包含地址信息
try {
uni.setStorageSync('userLocation', {
longitude: location.longitude,
latitude: location.latitude
longitude: userLocation.value.longitude,
latitude: userLocation.value.latitude,
address: userLocation.value.address,
city: userLocation.value.city,
district: userLocation.value.district
})
} catch (e) {
console.warn('缓存基础定位信息失败:', e)
console.warn('缓存带地址的定位信息失败:', e)
}
// 只在首次初始化时设置标记
if (!isLocationInitialized.value) {
isLocationInitialized.value = true
}
// 获取详细地址信息
try {
const addressResult = await getRegeo(location.longitude, location.latitude)
if (addressResult.success) {
const addressInfo = addressResult.data
userLocation.value.address = addressInfo.formatted_address
userLocation.value.city = addressInfo.addressComponent.city
userLocation.value.district = addressInfo.addressComponent.district
// 更新本地缓存,包含地址信息
try {
uni.setStorageSync('userLocation', {
longitude: userLocation.value.longitude,
latitude: userLocation.value.latitude,
address: userLocation.value.address,
city: userLocation.value.city,
district: userLocation.value.district
})
} catch (e) {
console.warn('缓存带地址的定位信息失败:', e)
}
}
} catch (error) {
// 忽略地址信息错误,使用基础定位信息
}
// 等待地图组件响应位置变化后,重新加载场地列表
setTimeout(async () => {
await loadPositions()
uni.hideLoading()
}, 800)
} catch (error) {
console.error('获取位置失败:', error)
uni.showToast({
title: $t('home.getLocationFailed'),
icon: 'none'
})
}
} catch (error) {
// 忽略地址信息错误,使用基础定位信息
}
return userLocation.value
}
const loadPositions = async () => {
@@ -547,7 +538,7 @@ const activityPopup = ref(null)
pageNum: 1,
pageSize: 100
})
console.log('查询附近设备结果:', res)
if (res.code === 200) {
@@ -607,9 +598,9 @@ const activityPopup = ref(null)
console.warn('loadPositionsByCenter: 无效的中心点', center)
return
}
console.log('根据地图中心加载设备:', center)
try {
// 使用新的附近设备查询接口
const res = await getNearbyDevices({
@@ -624,10 +615,10 @@ const activityPopup = ref(null)
if (res.code === 200) {
const devices = res.data?.records || []
console.log('加载到设备数量:', devices.length)
// 将设备数据转换为统一格式
positionList.value = devices.map(transformDeviceData)
// 基于地图中心计算距离
calculateDistances(center)
@@ -636,7 +627,7 @@ const activityPopup = ref(null)
filteredPositions.value = positionList.value.filter(item => {
return !item.distanceInMeters || item.distanceInMeters <= maxDistanceInMeters
})
console.log('过滤后设备数量:', filteredPositions.value.length)
} else {
@@ -656,50 +647,50 @@ const activityPopup = ref(null)
console.log('正在定位中,请勿重复点击')
return
}
try {
isRelocating.value = true
uni.showLoading({
title: $t('home.relocating'),
mask: true
})
// 重新获取用户真实位置(不使用缓存)
const loc = await getUserLocation()
const newLocation = {
longitude: Number(loc.longitude),
latitude: Number(loc.latitude)
}
console.log('重新定位成功,新位置:', newLocation)
console.log('当前位置:', userLocation.value)
// 更新用户位置(触发地图组件的watch,自动移动地图)
userLocation.value = {
...newLocation
}
// 保存到本地缓存
try {
uni.setStorageSync('userLocation', newLocation)
} catch (e) {
console.warn('缓存位置失败:', e)
}
// 确保地图移动到新位置
if (mapRef.value && typeof mapRef.value.moveToLocation === 'function') {
mapRef.value.moveToLocation(newLocation)
}
// 延迟一下,等待地图移动完成后再查询场地
await new Promise(resolve => setTimeout(resolve, 300))
// 加载新位置的场地
await loadPositionsByCenter(newLocation)
uni.hideLoading()
uni.showToast({
title: $t('home.locateSuccess'),
icon: 'success',
@@ -708,7 +699,7 @@ const activityPopup = ref(null)
} catch (e) {
console.error('定位失败:', e)
uni.hideLoading()
uni.showToast({
title: e.errMsg || $t('home.locateFailed'),
icon: 'none',
@@ -723,8 +714,7 @@ const activityPopup = ref(null)
}
const onMapCenterChange = (center) => {
console.log('onMapCenterChange 被调用,中心点:', center)
if (center && typeof center.longitude !== 'undefined' && typeof center.latitude !== 'undefined') {
userLocation.value = {
longitude: Number(center.longitude),
@@ -733,7 +723,7 @@ const activityPopup = ref(null)
try {
uni.setStorageSync('userLocation', userLocation.value)
} catch (_) {}
// 调用加载场地方法
loadPositionsByCenter(center)
} else {
@@ -830,16 +820,16 @@ const activityPopup = ref(null)
}
})
if (inUseRes.statusCode === 401 || inUseRes.data?.code === 401 || inUseRes.data?.code === 40101) {
redirectToLogin()
return
} else if (inUseRes.statusCode == 200 && inUseRes.data.code == 200 && inUseRes.data.data) {
const inUseOrder = inUseRes.data.data
uni.reLaunch({
url: `/pages/order/detail?orderId=${inUseOrder.orderId}&deviceId=${deviceNo || inUseOrder.deviceNo}`
})
return
}
if (inUseRes.statusCode === 401 || inUseRes.data?.code === 401 || inUseRes.data?.code === 40101) {
redirectToLogin()
return
} else if (inUseRes.statusCode == 200 && inUseRes.data.code == 200 && inUseRes.data.data) {
const inUseOrder = inUseRes.data.data
uni.reLaunch({
url: `/pages/order/detail?orderId=${inUseOrder.orderId}&deviceId=${deviceNo || inUseOrder.deviceNo}`
})
return
}
// 检查是否有待支付订单
const orderRes = await uni.request({
@@ -920,58 +910,58 @@ const activityPopup = ref(null)
showPhoneAuthPopup.value = false
}
}
// 使用指南弹窗控制
const openPopup = () => {
try {
showGuidePopup.value = true
guidePopup.value && typeof guidePopup.value.open === 'function' && guidePopup.value.open()
} catch (e) {}
}
const closeGuidePopup = () => {
try {
showGuidePopup.value = false
guidePopup.value && typeof guidePopup.value.close === 'function' && guidePopup.value.close()
} catch (e) {}
}
// 使用指南弹窗控制
const openPopup = () => {
try {
showGuidePopup.value = true
guidePopup.value && typeof guidePopup.value.open === 'function' && guidePopup.value.open()
} catch (e) {}
}
// 通知弹窗控制
const openNoticePopup = () => {
try {
showNoticePopup.value = true
noticePopup.value && typeof noticePopup.value.open === 'function' && noticePopup.value.open()
} catch (e) {}
}
const closeGuidePopup = () => {
try {
showGuidePopup.value = false
guidePopup.value && typeof guidePopup.value.close === 'function' && guidePopup.value.close()
} catch (e) {}
}
const closeNoticePopup = () => {
try {
showNoticePopup.value = false
noticePopup.value && typeof noticePopup.value.close === 'function' && noticePopup.value.close()
} catch (e) {}
}
// 通知弹窗控制
const openNoticePopup = () => {
try {
showNoticePopup.value = true
noticePopup.value && typeof noticePopup.value.open === 'function' && noticePopup.value.open()
} catch (e) {}
}
// 活动弹窗控制
const openActivityPopup = () => {
try {
showActivityPopup.value = true
activityPopup.value && typeof activityPopup.value.open === 'function' && activityPopup.value.open()
} catch (e) {}
}
const closeNoticePopup = () => {
try {
showNoticePopup.value = false
noticePopup.value && typeof noticePopup.value.close === 'function' && noticePopup.value.close()
} catch (e) {}
}
const closeActivityPopup = () => {
try {
showActivityPopup.value = false
activityPopup.value && typeof activityPopup.value.close === 'function' && activityPopup.value.close()
// 重置索引
currentActivityIndex.value = 0
} catch (e) {}
}
// 活动弹窗控制
const openActivityPopup = () => {
try {
showActivityPopup.value = true
activityPopup.value && typeof activityPopup.value.open === 'function' && activityPopup.value.open()
} catch (e) {}
}
// 活动轮播图切换
const onActivitySwiperChange = (e) => {
currentActivityIndex.value = e.detail.current
}
const closeActivityPopup = () => {
try {
showActivityPopup.value = false
activityPopup.value && typeof activityPopup.value.close === 'function' && activityPopup.value.close()
// 重置索引
currentActivityIndex.value = 0
} catch (e) {}
}
// 活动轮播图切换
const onActivitySwiperChange = (e) => {
currentActivityIndex.value = e.detail.current
}
</script>
<script>
@@ -1040,7 +1030,8 @@ const onActivitySwiperChange = (e) => {
position: relative;
width: 100%;
height: 100%;
padding-bottom: 180rpx; /* 为底部按钮留出空间 */
padding-bottom: 180rpx;
/* 为底部按钮留出空间 */
box-sizing: border-box;
}
@@ -1509,7 +1500,8 @@ const onActivitySwiperChange = (e) => {
top: 0;
left: 0;
right: 0;
bottom: 180rpx; /* 为底部按钮留出空间 */
bottom: 180rpx;
/* 为底部按钮留出空间 */
background: #f6f7fb;
display: flex;
align-items: center;
@@ -1630,12 +1622,12 @@ const onActivitySwiperChange = (e) => {
line-height: 1.2;
text-align: center;
}
.primary-label {
color: #ffffff;
line-height: 1;
}
/* 顶部信息区域 */
.top-info-section {
position: fixed;
@@ -1659,6 +1651,7 @@ const onActivitySwiperChange = (e) => {
border-radius: 24rpx;
padding: 24rpx 24rpx 16rpx;
box-sizing: border-box;
// padding-bottom:100rpx;
}
.guide-header {
@@ -1732,7 +1725,7 @@ const onActivitySwiperChange = (e) => {
}
.guide-actions {
margin-top:20rpx;
margin-top: 20rpx;
}
.primary-btn {
@@ -1752,8 +1745,8 @@ const onActivitySwiperChange = (e) => {
}
.primary-label{
color:#ffffff;
.primary-label {
color: #ffffff;
font-size: 32rpx;
font-weight: 600;
}
@@ -1813,7 +1806,7 @@ const onActivitySwiperChange = (e) => {
overflow: visible;
padding-bottom: 120rpx;
}
/* 覆盖 uv-popup 的默认背景色 */
:deep(.uv-popup__content) {
background: transparent !important;
@@ -1825,11 +1818,11 @@ const onActivitySwiperChange = (e) => {
max-height: 70vh;
border-radius: 16rpx;
background: transparent;
:deep(swiper) {
background: transparent;
}
:deep(swiper-item) {
background: transparent;
}
@@ -1892,13 +1885,13 @@ const onActivitySwiperChange = (e) => {
transition: all 0.3s ease;
background: rgba(0, 0, 0, 0.6);
border-radius: 40rpx;
.close-text {
font-size: 28rpx;
color: #ffffff;
font-weight: 500;
}
&:active {
transform: translateX(-50%) scale(0.95);
background: rgba(0, 0, 0, 0.8);