index.vue 8.43 KB
<!--
 * @Date: 2022-09-19 14:11:06
 * @LastEditors: hookehuyr hookehuyr@gmail.com
 * @LastEditTime: 2025-09-02 21:45:14
 * @FilePath: /lls_program/src/pages/MyFamily/index.vue
 * @Description: 我的家庭页面 - 展示用户加入的家庭列表
-->
<template>
  <view class="min-h-screen bg-gray-50 pb-20">
    <!-- 家庭列表 -->
    <view class="px-4 py-4 space-y-4">
      <view
        v-for="family in familyList"
        :key="family.id"
        class="bg-white rounded-lg overflow-hidden shadow-sm border border-gray-100"
      >
        <!-- 家庭封面图和基本信息 -->
        <view class="relative">
          <!-- 当前家庭标记 -->
          <view
            v-if="family.is_in"
            class="absolute top-2 right-2 bg-blue-500 text-white text-xs px-2 py-1 rounded-sm z-10"
          >
            当前家庭
          </view>

          <!-- 封面图 -->
          <image
            :src="family.avatar_url || defaultFamilyCoverSvg"
            class="w-full h-44 object-cover"
            mode="aspectFill"
          />

          <!-- 家庭名称和大家长信息覆盖层 -->
          <view class="absolute bottom-0 left-0 right-0 bg-gradient-to-t from-black/60 to-transparent p-4">
            <view class="text-white font-bold text-lg mb-1">{{ family.name }}</view>
            <view class="text-white/90 text-sm">大家长:{{ family.ownerName }}</view>
          </view>
        </view>

        <!-- 成员信息和操作按钮 -->
        <view class="p-4">
          <!-- 成员头像和数量 -->
          <view class="flex items-center justify-between mb-4">
            <view class="flex items-center">
              <!-- 成员头像叠加效果 -->
              <view class="avatar-overlap">
                <image
                  v-for="(member, index) in family?.members?.slice(0, 4) || []"
                  :key="member.id"
                  :src="member.avatar"
                  class="avatar-item w-8 h-8 rounded-full border-2 border-white object-cover"
                  :style="{ zIndex: 10 - index }"
                />
                <!-- 更多成员数量显示 -->
                <view
                  v-if="family?.members?.length > 4"
                  class="w-8 h-8 rounded-full bg-gray-300 border-2 border-white flex items-center justify-center text-xs text-gray-600"
                  :style="{ zIndex: 6 }"
                >
                  +{{ family?.members?.length - 4 }}
                </view>
              </view>
              <!-- 总成员数 -->
              <view class="ml-3 text-sm text-gray-600">
                {{ family?.members?.length || 0 }} 位家庭成员
              </view>
            </view>
          </view>

          <!-- 操作按钮 -->
          <view class="flex gap-3 justify-end">
            <view
              v-if="!family.is_in"
              @tap="switchToFamily(family.id)"
              class="px-4 py-2 bg-blue-500 text-white text-sm rounded-lg"
            >
              切换到此家庭
            </view>
            <view
              @tap="exitFamily(family.id)"
              class="px-4 py-2 bg-red-500 text-white text-sm rounded-lg"
            >
              退出家庭
            </view>
          </view>
        </view>
      </view>

      <!-- 空状态 -->
      <view v-if="familyList.length === 0" class="text-center py-12">
        <view class="text-gray-400 mb-4">
          <Home size="48" />
        </view>
        <view class="text-gray-500 mb-2">您还没有加入任何家庭</view>
      </view>
    </view>

    <!-- 底部固定按钮 -->
    <view v-if="isShowBtn" class="fixed bottom-0 left-0 right-0 bg-white border-t border-gray-100 p-4 z-10">
      <view
        @tap="joinNewFamily"
        class="w-full bg-blue-500 text-white text-center py-3 rounded-lg font-medium"
      >
        加入新家庭
      </view>
    </view>

    <!-- 确认弹窗已替换为Taro.showModal -->
  </view>
</template>

<script setup>
import { ref, onMounted, computed } from 'vue';
import Taro, { useDidShow } from '@tarojs/taro';
import { Home } from '@nutui/icons-vue-taro';
import './index.less';
import { getMyFamiliesAPI } from '@/api/family';
//
const defaultFamilyCoverSvg = 'https://cdn.ipadbiz.cn/lls_prog/images/default-family-cover.png';
// 获取接口数据

// 响应式数据
const familyList = ref([]);

/**
 * 初始化页面数据
 */
const initPageData = async () => {
  const { code, data } = await getMyFamiliesAPI();
  if (code) {
    familyList.value = data;
    console.warn(data);
  }
  // 模拟家庭数据
  // familyList.value = [
  //   {
  //     id: 1,
  //     name: '幸福之家',
  //     ownerName: '张明明',
  //     avatar_url: 'https://images.unsplash.com/photo-1511895426328-dc8714191300?w=400&h=200&fit=crop',
  //     is_in: true,
  //     members: [
  //       { id: 1, avatar: 'https://images.unsplash.com/photo-1507003211169-0a1dd7228f2d?w=100&h=100&fit=crop&crop=face' },
  //       { id: 2, avatar: 'https://images.unsplash.com/photo-1507003211169-0a1dd7228f2d?w=100&h=100&fit=crop&crop=face' },
  //       { id: 3, avatar: 'https://images.unsplash.com/photo-1507003211169-0a1dd7228f2d?w=100&h=100&fit=crop&crop=face' }
  //     ]
  //   },
  //   {
  //     id: 2,
  //     name: '欢乐之家',
  //     ownerName: '李志强',
  //     avatar_url: 'https://images.unsplash.com/photo-1502086223501-7ea6ecd79368?w=400&h=200&fit=crop',
  //     is_in: false,
  //     members: [
  //       { id: 4, avatar: 'https://images.unsplash.com/photo-1500648767791-00dcc994a43e?w=100&h=100&fit=crop&crop=face' },
  //       { id: 5, avatar: 'https://images.unsplash.com/photo-1438761681033-6461ffad8d80?w=100&h=100&fit=crop&crop=face' }
  //     ]
  //   },
  //   {
  //     id: 3,
  //     name: '快乐之家',
  //     ownerName: '王芳',
  //     avatar_url: 'https://images.unsplash.com/photo-1502086223501-7ea6ecd79368?w=400&h=200&fit=crop',
  //     is_in: false,
  //     members: [
  //       { id: 6, avatar: 'https://images.unsplash.com/photo-1500648767791-00dcc994a43e?w=100&h=100&fit=crop&crop=face' },
  //       { id: 7, avatar: 'https://images.unsplash.com/photo-1438761681033-6461ffad8d80?w=100&h=100&fit=crop&crop=face' }
  //     ]
  //   },
  // ];
};

// 如果家庭列表存在时, 才显示加入新家庭的按钮
const isShowBtn = computed(() => {
  return familyList.value.length > 0;
})

/**
 * 切换到指定家庭
 * @param {number} familyId - 家庭ID
 */
const switchToFamily = (familyId) => {
  const family = familyList.value.find(f => f.id === familyId);
  if (!family) return;

  Taro.showModal({
    title: '切换家庭',
    content: `确定要切换到「${family.name}」吗?`,
    success: (res) => {
      if (res.confirm) {
        // 切换家庭逻辑 - 先清除所有当前标记,再设置新的当前家庭
        familyList.value = familyList.value.map(f => ({
          ...f,
          is_in: f.id === familyId
        }));

        console.log('切换家庭后的列表:', familyList.value);

        Taro.showToast({
          title: '切换成功',
          icon: 'success'
        });
      }
    }
  });
};

/**
 * 退出家庭
 * @param {number} familyId - 家庭ID
 */
const exitFamily = (familyId) => {
  const family = familyList.value.find(f => f.id === familyId);
  if (!family) return;

  Taro.showModal({
    title: '退出家庭',
    content: `确定要退出「${family.name}」吗?退出后将无法查看该家庭的相关信息。`,
    success: (res) => {
      if (res.confirm) {
        // 退出家庭逻辑
        const exitingFamily = familyList.value.find(f => f.id === familyId);

        if (exitingFamily?.is_in) {
          // 如果退出的是当前家庭,需要返回我的页面
          familyList.value = familyList.value.filter(f => f.id !== familyId);

          Taro.showToast({
            title: '已退出家庭',
            icon: 'success'
          });

          // 延迟返回我的页面
          setTimeout(() => {
            Taro.navigateBack();
          }, 1500);
        } else {
          // 退出非当前家庭
          familyList.value = familyList.value.filter(f => f.id !== familyId);

          Taro.showToast({
            title: '已退出家庭',
            icon: 'success'
          });
        }
      }
    }
  });
};

/**
 * 加入新家庭
 */
const joinNewFamily = () => {
  Taro.navigateTo({
    url: '/pages/JoinFamily/index'
  });
};

// 页面加载时初始化数据
useDidShow(() => {
  initPageData();
});
</script>

<script>
export default {
  name: 'MyFamily',
};
</script>