index.vue 10.2 KB
<!--
 * @Date: 2025-08-27 17:43:45
 * @LastEditors: hookehuyr hookehuyr@gmail.com
 * @LastEditTime: 2025-09-27 16:09:23
 * @FilePath: /lls_program/src/pages/Welcome/index.vue
 * @Description: 欢迎页
-->
<template>
  <view class="min-h-screen flex flex-col bg-white">
    <!-- Main content -->
    <view class="flex-1 flex flex-col px-4 pb-20">
      <!-- Hero Image -->
      <view class="w-full mb-6">
        <view class="w-full h-48 rounded-2xl overflow-hidden">
          <image
            :src="welcomeHomeImg"
            alt="家庭在上海外滩散步"
            class="w-full h-full object-cover"
          />
        </view>
      </view>
      <!-- Steps Section -->
      <view class="mb-8">
        <h2 class="text-xl font-bold mb-6">简单三步,开启健康生活</h2>
        <view class="space-y-6">
          <!-- Step 1 -->
          <view class="flex items-center">
            <view
              class="w-10 h-10 bg-blue-500 rounded-full flex items-center justify-center text-white font-bold text-lg mr-4 flex-shrink-0"
            >
              1
            </view>
            <view>
              <h3 class="font-bold">创建家庭</h3>
              <p class="text-gray-600 text-sm">60岁以上家长创建家庭,设置专属口令</p>
            </view>
          </view>
          <!-- Step 2 -->
          <view class="flex items-center">
            <view
              class="w-10 h-10 bg-blue-500 rounded-full flex items-center justify-center text-white font-bold text-lg mr-4 flex-shrink-0"
            >
              2
            </view>
            <view>
              <h3 class="font-bold">邀请家人</h3>
              <p class="text-gray-600 text-sm">分享口令,邀请家人加入</p>
            </view>
          </view>
          <!-- Step 3 -->
          <view class="flex items-center">
            <view
              class="w-10 h-10 bg-blue-500 rounded-full flex items-center justify-center text-white font-bold text-lg mr-4 flex-shrink-0"
            >
              3
            </view>
            <view>
              <h3 class="font-bold">同步步数,兑换好礼</h3>
              <p class="text-gray-600 text-sm">每日同步微信步数,兑换抵用券</p>
            </view>
          </view>
        </view>
      </view>
      <!-- Action Buttons -->
      <view class="space-y-4 mt-auto">
        <view
          @tap="handleNavigate('/pages/CreateFamily/index')"
          class="w-full py-3.5 bg-blue-500 text-white text-lg font-medium rounded-full text-center"
        >
          创建家庭
        </view>
        <view
          @tap="handleNavigate('/pages/JoinFamily/index')"
          class="w-full py-3.5 bg-white text-gray-800 text-lg font-medium rounded-full border border-gray-300 text-center"
          style="margin-bottom: 1rem"
        >
          加入家庭
        </view>
      </view>
    </view>
    <!-- Bottom Navigation -->
    <BottomNav />

    <!-- Dialog Components -->
    <!-- 个人信息收集说明弹窗 -->
    <nut-dialog v-model:visible="showPrivacyDialog" title="个人信息收集说明">
      <template #default>
        <view class="text-gray-700 leading-loose text-sm text-left break-words">
          {{ privacyContent }}
        </view>
      </template>
      <template #footer>
        <nut-row :gutter="10">
          <nut-col :span="12">
            <nut-button @click="onPrivacyCancel" type="default" size="normal" block>
              取消操作
            </nut-button>
          </nut-col>
          <nut-col :span="12">
            <nut-button
              @click="onPrivacyConfirm"
              type="primary"
              size="normal"
              :color="THEME_COLORS.PRIMARY"
              block
            >
              同意搜集
            </nut-button>
          </nut-col>
        </nut-row>
      </template>
    </nut-dialog>

    <!-- 年龄限制提示弹窗 -->
    <nut-dialog v-model:visible="showAgeDialog" title="温馨提示">
      <template #default>
        <view class="text-center text-gray-700 text-sm leading-loose">
          您需要年满60岁才能创建家庭
        </view>
      </template>
      <template #footer>
        <nut-row>
          <nut-col :span="24">
            <nut-button
              @click="onAgeConfirm"
              type="primary"
              size="normal"
              :color="THEME_COLORS.PRIMARY"
              block
            >
              了解
            </nut-button>
          </nut-col>
        </nut-row>
      </template>
    </nut-dialog>

    <!-- 广告遮罩层 -->
    <AdOverlay ref="adOverlayRef" @close="handleAdClose" @click="handleAdClick" />
  </view>
</template>

<script setup>
import { ref } from 'vue'
import Taro, { useDidShow, useLoad } from '@tarojs/taro'
import { handleSharePageAuth, addShareFlag } from '@/utils/authRedirect'
import BottomNav from '@/components/BottomNav.vue'
import AdOverlay from '@/components/AdOverlay.vue'
// 获取接口信息
import { getUserProfileAPI } from '@/api/user'
import { appendReturnUrlParam, normalizeReturnUrl } from '@/utils/returnUrl'
import { isUserProfileComplete } from '@/utils/userProfile'
// 导入主题颜色
import { THEME_COLORS } from '@/utils/config'

const welcomeHomeImg =
  'https://cdn.ipadbiz.cn/lls_prog/images/iwEcAqNqcGcDAQTRCAAF0QSABrA-9ERC3jG0pwiy88rQQ3IAB9IIwZFkCAAJomltCgAL0gADu3A.jpg'

const userAge = ref(null)
const userInfo = ref({})
const canCreateFamily = ref(true)
const hasProfile = ref(false)
const returnUrl = ref('')
const regSource = ref('')
const regStageId = ref('')

// Dialog相关响应式数据
const showPrivacyDialog = ref(false)
const showAgeDialog = ref(false)
const pendingNavigateUrl = ref('')

// 个人信息收集说明内容
const privacyContent =
  '为了提供更好的服务,我们需要收集您的基本信息:\n1.头像和昵称:用于家庭成员识别 \n2.出生年月:验证年龄资格,60岁以上可创建家庭。\n我们承诺严格保护您的个人隐私,仅用于家庭功能和活动服务。'

const navigateTo = url => {
  Taro.navigateTo({ url })
}

// 广告遮罩层数据

const adOverlayRef = ref(null)

/**
 * 处理广告遮罩层关闭事件
 */
const handleAdClose = () => {
  console.log('广告遮罩层已关闭')
}

/**
 * 处理广告遮罩层点击事件
 * @param {string} targetPage - 跳转的目标页面
 */
const handleAdClick = targetPage => {
  // 如果跳转路径是欢迎页和首页,不跳转直接关闭弹框
  if (targetPage === '/pages/Dashboard/index' || targetPage === '/pages/Welcome/index') {
    handleAdClose()
    return
  }
  // 跳转到目标页面
  Taro.navigateTo({ url: targetPage })
}

useDidShow(async () => {
  // 获取用户的个人信息
  const { code, data } = await getUserProfileAPI()
  if (code) {
    userInfo.value = data?.user?.nickname
      ? data.user
      : {
          avatar_url: null,
          nickname: null,
          birth_date: null,
          wheelchair: null,
          wheelchair_text: null,
          phone: null,
        }

    // 计算用户年龄
    if (userInfo.value.birth_date) {
      const birthDate = new Date(userInfo.value.birth_date)
      const today = new Date()
      let age = today.getFullYear() - birthDate.getFullYear()
      const monthDiff = today.getMonth() - birthDate.getMonth()

      // 如果还没到生日,年龄减1
      if (monthDiff < 0 || (monthDiff === 0 && today.getDate() < birthDate.getDate())) {
        age--
      }

      userAge.value = age
      // 检查是否满60岁,可以创建家庭
      canCreateFamily.value = age >= 60
    } else {
      userAge.value = null
      canCreateFamily.value = false
    }

    // 检查用户是否完善了个人信息
    hasProfile.value = isUserProfileComplete(userInfo.value)
  }
})

const handleNavigate = url => {
  const nextUrl = appendReturnUrl(url)

  if (!hasProfile.value) {
    // 显示个人信息收集说明弹窗
    pendingNavigateUrl.value = buildAddProfileUrl()
    showPrivacyDialog.value = true
    return
  }

  if (url === '/pages/CreateFamily/index') {
    if (!canCreateFamily.value) {
      // 显示年龄限制提示弹窗
      showAgeDialog.value = true
      return
    }
  }

  navigateTo(nextUrl)
}

// Dialog事件处理方法
const onPrivacyCancel = () => {
  showPrivacyDialog.value = false
  pendingNavigateUrl.value = ''
}

const onPrivacyConfirm = () => {
  showPrivacyDialog.value = false
  if (pendingNavigateUrl.value) {
    navigateTo(pendingNavigateUrl.value)
    pendingNavigateUrl.value = ''
  }
}

const onAgeConfirm = () => {
  showAgeDialog.value = false
}

useLoad(options => {
  // 处理分享页面的授权逻辑
  handleSharePageAuth(options)
  returnUrl.value = normalizeReturnUrl(options?.return_url || '')
  regSource.value = options?.reg_source || ''
  regStageId.value = options?.reg_stage_id || ''
})

const appendReturnUrl = url => {
  return appendReturnUrlParam(url, returnUrl.value)
}

const buildAddProfileUrl = () => {
  if (!returnUrl.value && !regSource.value && !regStageId.value) {
    return '/pages/AddProfile/index'
  }

  // 从扫码链路进入 Welcome 时,补资料完成后应该先回 Welcome,
  // 继续完成创建/加入家庭,最后再由家庭流程回到打卡详情页。
  const params = new URLSearchParams()
  if (regSource.value) {
    params.set('reg_source', regSource.value)
  }
  if (regStageId.value) {
    params.set('reg_stage_id', regStageId.value)
  }
  params.set('return_url', buildWelcomeReturnUrl())

  return `/pages/AddProfile/index?${params.toString()}`
}

const buildWelcomeReturnUrl = () => {
  const params = new URLSearchParams()

  if (regSource.value) {
    params.set('reg_source', regSource.value)
  }
  if (regStageId.value) {
    params.set('reg_stage_id', regStageId.value)
  }
  if (returnUrl.value) {
    params.set('return_url', returnUrl.value)
  }

  const query = params.toString()
  return query ? `/pages/Welcome/index?${query}` : '/pages/Welcome/index'
}

/**
 * 定义分享给朋友的内容
 * @returns {Object} 分享配置对象
 */
const onShareAppMessage = res => {
  const shareData = {
    title: '欢迎加入老来赛',
    path: '/pages/Welcome/index',
    imageUrl: '',
  }

  return shareData
}

// 使用Taro的useShareAppMessage Hook来处理分享
Taro.useShareAppMessage(res => {
  return onShareAppMessage(res)
})
</script>