index.vue 5.5 KB
<template>
  <view class="activities-container">
    <!-- WebView内容 -->
    <web-view
      v-if="webUrl"
      :src="webUrl"
      class="web-view"
      @message="handleMessage"
      @load="handleLoad"
      @error="handleError"
    ></web-view>

    <!-- 加载状态 -->
    <view v-if="loading" class="loading-container">
      <view class="loading-spinner">⏳</view>
      <view class="loading-text">加载中...</view>
    </view>

    <!-- 错误状态 -->
    <view v-if="error" class="error-container">
      <view class="error-icon">⚠️</view>
      <view class="error-text">页面加载失败</view>
      <view class="error-buttons">
        <nut-button type="primary" size="small" @click="handleRetry">重试</nut-button>
        <nut-button type="default" size="small" @click="handleGoBack">返回</nut-button>
      </view>
    </view>

    <!-- 底部导航 -->
    <BottomNav />
  </view>
</template>

<script setup>
import { ref, onMounted } from 'vue'
import Taro from '@tarojs/taro'
import BottomNav from '../../components/BottomNav.vue'
// 获取接口信息
import { getUserProfileAPI } from '@/api/user'
import { getMapUrlAPI } from '@/api/map'

/**
 * 活动页面WebView组件
 * 用于显示活动相关的外部网页内容
 */

// 页面状态
const webUrl = ref('') // 动态设置URL
const loading = ref(true)
const error = ref(false)
const baseUrl = ref('') // 动态获取的基础URL

/**
 * 处理WebView加载完成
 */
const handleLoad = e => {
  console.log('WebView加载完成:', e)
  loading.value = false
  error.value = false
}

/**
 * 处理WebView加载错误
 */
const handleError = e => {
  console.error('WebView加载错误:', e)
  loading.value = false
  error.value = true

  Taro.showToast({
    title: '页面加载失败',
    icon: 'none',
  })
}

/**
 * 处理WebView消息
 */
const handleMessage = e => {
  console.log('WebView消息:', e)
  // 可以在这里处理来自WebView的消息
}

/**
 * 重试加载
 */
const handleRetry = () => {
  loading.value = true
  error.value = false
  // 重新初始化页面数据
  initPageData()
}

/**
 * 返回上一页
 */
const handleGoBack = () => {
  Taro.navigateBack({
    delta: 1,
  }).catch(() => {
    // 如果无法返回,则跳转到首页
    Taro.redirectTo({
      url: '/pages/Dashboard/index',
    })
  })
}

/**
 * 构建包含位置参数的URL
 */
const buildUrlWithLocation = (lng, lat, openid, discount_title) => {
  if (lng && lat && baseUrl.value) {
    const separator = baseUrl.value.includes('?') ? '&' : '?'
    return `${baseUrl.value}${separator}current_lng=${lng}&current_lat=${lat}&openid=${openid}&discount_title=${discount_title}`
  }
  return baseUrl.value || ''
}

/**
 * 初始化页面数据
 */
const initPageData = async () => {
  try {
    // 获取地图URL
    const mapUrlResponse = await getMapUrlAPI()
    if (mapUrlResponse.code && mapUrlResponse.data?.url) {
      baseUrl.value = mapUrlResponse.data.url
      console.log('获取到的地图URL:', baseUrl.value)
    } else {
      console.error('获取地图URL失败:', mapUrlResponse.msg)
      // 显示错误提示,不使用默认URL
      error.value = true
      loading.value = false
      Taro.showToast({
        title: mapUrlResponse.msg || '获取地图信息失败',
        icon: 'none',
      })
      return
    }

    // 获取用户信息
    const { code, data } = await getUserProfileAPI()
    if (code) {
      // 获取路由参数中的经纬度信息
      const instance = Taro.getCurrentInstance()
      const { current_lng, current_lat, discount_title } = instance.router?.params || {}

      console.log('接收到的位置参数:', { current_lng, current_lat, discount_title })
      // 处理用户信息
      const openid = data?.user.openid || ''
      // 构建完整的URL
      webUrl.value = buildUrlWithLocation(current_lng, current_lat, openid, discount_title)

      console.log('最终WebView URL:', webUrl.value)
    }
  } catch (error) {
    console.error('初始化页面数据失败:', error)
    // 显示错误状态,不使用默认URL
    error.value = true
    loading.value = false

    Taro.showToast({
      title: '获取地图信息失败',
      icon: 'none',
    })
  }
}

// 页面挂载时初始化
onMounted(async () => {
  console.log('活动页面WebView初始化')
  await initPageData()
})
</script>

<style lang="less">
.activities-container {
  width: 100%;
  height: 100vh;
  display: flex;
  flex-direction: column;
  background-color: #fff;
  position: relative;
}

.web-view {
  flex: 1;
  width: 100%;
  // 确保webview高度在底部导航以上
  height: calc(100vh - 120rpx); // 减去底部导航的高度
}

.loading-container {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  z-index: 10;
}

.loading-spinner {
  font-size: 48rpx;
  margin-bottom: 16rpx;
  animation: spin 1s linear infinite;
}

.loading-text {
  font-size: 28rpx;
  color: #666;
}

@keyframes spin {
  0% {
    transform: rotate(0deg);
  }
  100% {
    transform: rotate(360deg);
  }
}

.error-container {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  z-index: 10;
}

.error-icon {
  font-size: 80rpx;
  margin-bottom: 24rpx;
}

.error-text {
  font-size: 28rpx;
  color: #666;
  margin-bottom: 32rpx;
}

.error-buttons {
  display: flex;
  gap: 24rpx;
  align-items: center;
}
</style>