index.vue 6.46 KB
<template>
  <view class="min-h-screen flex flex-col bg-white pb-16" style="background-color: #F9FAFB;">
    <!-- Hero section with family name and background image -->
    <view class="relative h-48">
      <image src="https://placehold.co/800x400/e2f3ff/0369a1?text=LFX&font=roboto" alt="Family background" class="w-full h-full object-cover" />
      <view class="absolute inset-0 bg-black bg-opacity-30 flex flex-col justify-end p-5">
        <view class="absolute top-4 right-4 text-white flex items-center" @click="goToProfile">
          <Setting size="24" />
          <text class="ml-2">家庭设置</text>
        </view>
        <h1 class="text-white text-2xl font-bold">张爷爷的家庭</h1>
        <p class="text-white opacity-90">每日走万步,全家一起行</p>
      </view>
    </view>

    <!-- Today's steps section -->
    <view class="px-5 py-6 bg-white rounded-xl shadow-md mx-4 mt-4">
      <view class="flex justify-between items-center mb-1">
        <span class="text-gray-500">今日</span>
      </view>
      <view class="flex justify-between items-center">
        <view class="flex items-baseline">
          <span class="text-4xl font-bold">
            {{ todaySteps.toLocaleString() }}
          </span>
          <span class="ml-1 text-gray-500">步</span>
        </view>
        <view class="bg-blue-500 text-white px-4 py-2 rounded-full text-sm" @click="handleCollectAll">
          一键收取
        </view>
      </view>
    </view>

    <!-- Points circles -->
    <view class="flex justify-between px-5 py-6 my-4 bg-white rounded-xl shadow-md mx-4">
      <PointsCollector ref="pointsCollectorRef" height="30vh" />
    </view>

    <!-- Photo button -->
    <view class="px-5 mb-4">
      <view @tap="openCamera" class="w-full bg-blue-500 text-white py-3 rounded-lg flex flex-col items-center justify-center">
        <view class="flex items-center justify-center">
          <Photograph size="20" class="mr-2" />
          拍照留念,奖励积分
        </view>
      </view>
    </view>

    <!-- Family step ranking -->
    <view class="p-5 bg-white rounded-xl shadow-md mx-4">
      <view class="flex justify-between items-center mb-4">
        <h2 class="font-medium text-lg">今日家庭步数排行</h2>
        <span class="text-sm text-gray-500">
          总计 {{ totalSteps.toLocaleString() }} 步
        </span>
      </view>
      <view class="grid grid-cols-4 gap-2">
        <view v-for="member in familyMembers" :key="member.id" class="flex flex-col items-center">
          <image :src="member.avatar" :alt="member.name" class="w-16 h-16 rounded-full mb-1" />
          <span class="text-sm text-gray-700">
            {{ member.steps.toLocaleString() }}步
          </span>
        </view>
      </view>
    </view>

    <!-- Family album -->
    <view class="p-5 mt-4 mb-6 bg-white rounded-xl shadow-md mx-4">
      <view class="flex justify-between items-center mb-2">
        <h2 class="font-medium text-lg">家庭相册</h2>
        <view class="text-blue-500 flex items-center" @click="openAlbumList">
          打开相册
        </view>
      </view>
      <p class="text-sm text-gray-500 mb-3">记录每一个家庭活动瞬间</p>
      <view class="grid grid-cols-2 gap-3">
        <view class="rounded-lg overflow-hidden">
          <image src="https://placehold.co/400x400/e2f3ff/0369a1?text=LFX&font=roboto" alt="家庭活动照片" class="w-full h-32 object-cover" />
        </view>
        <view class="rounded-lg overflow-hidden">
          <image src="https://placehold.co/400x400/e2f3ff/0369a1?text=LFX&font=roboto" alt="家庭活动照片" class="w-full h-32 object-cover" />
        </view>
      </view>
    </view>

    <BottomNav />
  </view>
</template>

<script setup>
import { ref, computed } from 'vue';
import Taro from '@tarojs/taro';
import { Setting, Photograph, Right } from '@nutui/icons-vue-taro';
import BottomNav from '../../components/BottomNav.vue';
import PointsCollector from '@/components/PointsCollector.vue'
import BASE_URL from '@/utils/config';

const todaySteps = ref(2000);
const pointsCollectorRef = ref(null)

/**
 * 触发积分收集组件的一键收取
 */
const handleCollectAll = () => {
  if (pointsCollectorRef.value) {
    pointsCollectorRef.value.collectAll()
  }
}

// Mock data for family members
const familyMembers = ref([
  {
    id: 1,
    name: '妈妈',
    steps: 7000,
    avatar: 'https://randomuser.me/api/portraits/women/44.jpg'
  },
  {
    id: 2,
    name: '爸爸',
    steps: 6000,
    avatar: 'https://randomuser.me/api/portraits/men/32.jpg'
  },
  {
    id: 3,
    name: '儿子',
    steps: 5000,
    avatar: 'https://randomuser.me/api/portraits/men/22.jpg'
  },
  {
    id: 4,
    name: '女儿',
    steps: 4000,
    avatar: 'https://randomuser.me/api/portraits/women/29.jpg'
  }
]);

// Calculate total family steps
const totalSteps = computed(() =>
  familyMembers.value.reduce((sum, member) => sum + member.steps, 0) + todaySteps.value
);

const handleSyncSteps = () => {
  // In a real app, this would sync with a health API
  // For demo purposes, we'll just log and do nothing
  console.log('Syncing steps...');
};

const goToProfile = () => {
  Taro.navigateTo({ url: '/pages/EditFamily/index' });
};

const openAlbumList = () => {
  Taro.navigateTo({ url: '/pages/AlbumList/index' });
};

/**
 * 显示提示信息
 */
const showToast = (message, type = 'success') => {
  const icon = type === 'error' ? 'error' : 'success';
  Taro.showToast({
    title: message,
    icon: icon,
    duration: 2000
  });
};

/**
 * 上传文件到服务器
 */
const uploadFile = (filePath) => {
  // 显示上传中提示
  Taro.showLoading({
    title: '上传中',
    mask: true
  });

  wx.uploadFile({
    url: BASE_URL + '/admin/?m=srv&a=upload',
    filePath,
    name: 'file',
    header: {
      'content-type': 'multipart/form-data',
    },
    success: function (res) {
      let upload_data = JSON.parse(res.data);
      Taro.hideLoading({
        success: () => {
          if (res.statusCode === 200) {
            console.log('上传成功', upload_data.data.src);
            showToast('上传成功', 'success');
          } else {
            showToast('服务器错误,稍后重试!', 'error');
          }
        },
      });
    },
    fail: function (res) {
      Taro.hideLoading({
        success: () => {
          showToast('上传失败,稍后重试!', 'error');
        }
      });
    }
  });
};

/**
 * 打开拍照上传页面
 */
const openCamera = () => {
  Taro.navigateTo({ url: '/pages/UploadMedia/index' });
}
</script>