index.vue 6.14 KB
<template>
  <view class="activities-container">
    <!-- WebView内容 -->
    <!-- 添加 key 属性,强制 WebView 在 URL 变化时重新渲染 -->
    <web-view
      v-if="webUrl"
      :src="webUrl"
      :key="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'

/**
 * 活动页面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, activityId) => {
  if (lng && lat && baseUrl.value) {
    const separator = baseUrl.value.includes('?') ? '&' : '?'
    // 添加时间戳参数 _t 确保每次 URL 都不同,强制 WebView 重新加载
    const timestamp = Date.now()
    return `${baseUrl.value}${separator}current_lng=${lng}&current_lat=${lat}&openid=${openid}&discount_title=${discount_title}&activityId=${activityId}&_t=${timestamp}`
  }
  // 如果没有位置参数,也添加时间戳破坏缓存
  const separator = baseUrl.value.includes('?') ? '&' : '?'
  const timestamp = Date.now()
  return baseUrl.value ? `${baseUrl.value}${separator}_t=${timestamp}` : ''
}

/**
 * 初始化页面数据
 */
const initPageData = async () => {
  try {
    console.log('=== WebView 初始化开始 ===')

    // 从 URL 参数中获取地图 URL(由 ActivitiesDetail 页面传递)
    const instance = Taro.getCurrentInstance()
    const { mapUrl, current_lng, current_lat, discount_title, activityId } =
      instance.router?.params || {}

    // 解码地图 URL
    if (mapUrl) {
      baseUrl.value = decodeURIComponent(mapUrl)
      console.log('✅ 从 URL 参数获取到的地图URL:', baseUrl.value)
    } else {
      console.error('❌ 未接收到地图URL参数')
      // 显示错误提示
      error.value = true
      loading.value = false
      Taro.showToast({
        title: '缺少地图信息',
        icon: 'none',
      })
      return
    }

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

      console.log('🔗 最终WebView URL (完整):', webUrl.value)
      console.log('📋 URL 长度:', webUrl.value.length, '字符')
    }
  } 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>