FamilyAlbum.vue 4.61 KB
<template>
  <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 text-xs" @click="openAlbumList">
          进入相册
        </view>
      </view>
      <p class="text-sm text-gray-500 mb-3">记录每一个家庭活动瞬间</p>
      <!-- 加载状态 -->
      <view v-if="loading" class="grid grid-cols-2 gap-3">
        <view
          v-for="n in 4"
          :key="n"
          class="rounded-lg h-32 bg-gray-200 animate-pulse"
        ></view>
      </view>

      <!-- 相册内容 -->
      <view v-else-if="albumData.length > 0" class="grid grid-cols-2 gap-3">
        <view
          v-for="(item, index) in albumData"
          :key="item.id || index"
          class="rounded-lg overflow-hidden h-32 relative cursor-pointer"
          @click="handleMediaClick(item, albumData)"
        >
          <image
            :src="item.media_type === 'VIDEO' ? item.thumbnail : item.media_url"
            alt="家庭活动照片"
            mode="aspectFill"
            class="w-full h-full object-cover rounded-lg"
          />
          <!-- 视频标识 -->
          <view
            v-if="item.media_type === 'VIDEO'"
            class="absolute top-2 left-2 px-2 py-1 bg-black bg-opacity-70 rounded text-white text-xs"
          >
            视频
          </view>
          <!-- 我的标识 -->
          <!-- <view
            v-if="item.is_my"
            class="absolute top-2 right-2 px-2 py-1 bg-blue-500 bg-opacity-80 rounded text-white text-xs"
          >
            我的
          </view> -->
        </view>
      </view>

      <!-- 空状态 -->
      <view v-else class="text-center py-8 text-gray-400">
        <view class="text-sm">暂无相册内容</view>
        <!-- <view class="text-xs mt-1">快去上传第一张照片吧~</view> -->
      </view>
    </view>

    <!-- 图片预览 -->
    <nut-image-preview
      v-model:show="previewVisible"
      :images="previewImages"
      :init-no="previewIndex"
      :show-index="false"
      @close="closePreview"
    />

    <!-- 视频播放器 -->
    <view
      v-if="videoVisible"
      class="fixed inset-0 bg-black"
      style="z-index: 9999;"
      @click="closeVideo"
    >
      <!-- 关闭按钮 -->
      <view
        @click.stop="closeVideo"
        class="absolute top-4 right-4 w-10 h-10 bg-black bg-opacity-50 rounded-full flex items-center justify-center"
        style="z-index: 10000;"
      >
        <Close size="24" class="text-white" />
      </view>

      <!-- 视频播放器 -->
      <video
        v-if="currentVideo"
        :id="'family-album-video-' + videoId"
        :src="currentVideo.url"
        :poster="currentVideo.thumbnail"
        :controls="true"
        :autoplay="false"
        :show-center-play-btn="true"
        :show-play-btn="true"
        :object-fit="'contain'"
        :show-fullscreen-btn="true"
        style="width: 100vw; height: 50vh; position: absolute; top: 20vh; left: 0;"
        @click.stop
        @play="handleVideoPlay"
        @pause="handleVideoPause"
        @error="handleVideoError"
        @fullscreenchange="handleFullscreenChange"
      />
    </view>
  </view>
</template>

<script setup>
import { ref, onMounted } from 'vue';
import Taro, { useDidShow } from '@tarojs/taro';
import { Close } from '@nutui/icons-vue-taro';
import { useMediaPreview } from '@/composables/useMediaPreview';
import { getPhotoListAPI } from '@/api/photo';

// 使用媒体预览 composable
const {
  previewVisible,
  previewImages,
  previewIndex,
  videoVisible,
  currentVideo,
  videoId,
  handleMediaClick,
  closePreview,
  closeVideo,
  handleVideoPlay,
  handleVideoPause,
  handleFullscreenChange,
  handleVideoError
} = useMediaPreview();

// 家庭相册数据
const albumData = ref([]);
const loading = ref(false);

/**
 * 获取家庭相册数据
 */
const fetchAlbumData = async () => {
  try {
    loading.value = true;
    const response = await getPhotoListAPI({
      page: 0,
      limit: 4 // 首页只显示4张
    });

    if (response.code) {
      albumData.value = response.data || [];
    }
  } catch (error) {
    console.error('获取相册数据失败:', error);
  } finally {
    loading.value = false;
  }
};

/**
 * 打开相册列表页面
 */
const openAlbumList = () => {
  Taro.navigateTo({ url: '/pages/AlbumList/index' });
};

// 组件挂载时获取数据
onMounted(() => {
  fetchAlbumData();
});

useDidShow(() => {
  fetchAlbumData();
});
</script>

<style lang="less" scoped>
// 组件样式
</style>