cloudroam
2025-08-12 8dd9360a0e4cfd22ea9e261bec3821eff3f57fe8
sub-pages/mine/index.vue
@@ -103,27 +103,29 @@
<!--      </swiper>-->
      <swiper class="swiper-box" :current="current" @change="onSwiperChange" duration="300">
        <swiper-item v-for="(item, index) in tabList" :key="index">
          <view class="list-view">
            <up-waterfall v-model="getCurrentList">
              <template #left="{ leftList }">
                <FlowCard
                    v-for="(item, index) in leftList"
                    :key="index"
                    :item="item"
                    @click="handleDetailClick"
                />
              </template>
              <template #right="{ rightList }">
                <FlowCard
                    v-for="(item, index) in rightList"
                    :key="index"
                    :item="item"
                    @click="handleDetailClick"
                />
              </template>
            </up-waterfall>
            <up-loadmore :status="loading ? 'loading' : 'nomore'" :line="true" />
          </view>
          <scroll-view scroll-y style="height: 60vh; min-height: 400rpx; background: #fff;">
            <view class="list-view">
              <up-waterfall v-model="getCurrentList">
                <template #left="{ leftList }">
                  <FlowCard
                      v-for="(item, index) in leftList"
                      :key="index"
                      :item="item"
                      @click="handleDetailClick"
                  />
                </template>
                <template #right="{ rightList }">
                  <FlowCard
                      v-for="(item, index) in rightList"
                      :key="index"
                      :item="item"
                      @click="handleDetailClick"
                  />
                </template>
              </up-waterfall>
              <up-loadmore :status="current.value === 0 ? collectStatus : likeStatus" :line="true" />
            </view>
          </scroll-view>
        </swiper-item>
      </swiper>
    </view>
@@ -135,7 +137,7 @@
<script setup lang="ts">
import { ref, computed, watch } from 'vue';
import { onShow } from '@dcloudio/uni-app'
import { onShow, onPullDownRefresh, onReachBottom } from '@dcloudio/uni-app'
import SettingPopup from '@/components/setting/setting-popup.vue';
import { usePlatformLoginType } from '@/composables/usePlatformLoginType'
import { useUserStore } from '@/store/user'
@@ -179,6 +181,24 @@
  }
});
onPullDownRefresh(async () => {
  if (current.value === 0) {
    collectPage.value = 1;
    collectList.value = [];
    collectStatus.value = 'loadmore';
  } else {
    likePage.value = 1;
    likeList.value = [];
    likeStatus.value = 'loadmore';
  }
  await fetchList(true);
  uni.stopPullDownRefresh();
});
onReachBottom(() => {
  fetchList();
});
// 当前 tab 索引
const current = ref(0);
@@ -193,6 +213,13 @@
const collectList = ref<FilmWorks[]>([]);
const loading = ref(false);
const noMore = ref(false);
// 分页相关状态
const collectPage = ref(1);
const collectSize = 10;
const collectStatus = ref('loadmore');
const likePage = ref(1);
const likeSize = 10;
const likeStatus = ref('loadmore');
// tab 列表
const tabList = ref([
  // { name: '笔记' },
@@ -222,12 +249,21 @@
}
const onTabChange=(item: { index: number })=> {
  // 如果切到相同的 tab,直接返回,避免重复触发
  if (current.value === item.index) return;
  current.value = item.index;
  // 切换tab时检查是否需要加载数据
  if (userStore.hasLogin &&
      ((current.value === 0 && collectList.value.length === 0) ||
          (current.value === 1 && likeList.value.length === 0))) {
    fetchList();
  // 切换tab时重置对应列表和页码,防止数据重复
  if (current.value === 0) {
    collectPage.value = 1;
    collectList.value = [];
    collectStatus.value = 'loadmore';
  } else {
    likePage.value = 1;
    likeList.value = [];
    likeStatus.value = 'loadmore';
  }
  if (userStore.hasLogin) {
    fetchList(true); // 强制刷新
  }
}
@@ -243,24 +279,68 @@
const getCurrentList = computed(() => {
  return current.value === 0 ? collectList.value : likeList.value;
});
const fetchList = async () => {
  if (!userStore.hasLogin || loading.value || noMore.value) return;
const fetchList = async (isRefresh = false) => {
  if (!userStore.hasLogin) return;
  // 并发加载守卫:防止切换或多事件同时触发导致重复请求
  if (loading.value) return;
  loading.value = true;
  try {
    if (current.value === 0) {
      // 获取收藏列表
      collectList.value = [];
      // 收藏分页
      if (isRefresh) {
        collectPage.value = 1;
        collectList.value = [];
        collectStatus.value = 'loadmore';
      }
      if (collectStatus.value === 'nomore') return;
      const res = await getFilmCollectList({
        userId: userStore.userInfo?.customerDTO?.id
        userId: userStore.userInfo?.customerDTO?.id,
        current: collectPage.value,
        size: collectSize
      });
      collectList.value = res || [];
      if (res && res.length > 0) {
        // 去重
        const existingIds = new Set(collectList.value.map(item => item.id));
        const uniqueRecords = res.filter(item => !existingIds.has(item.id));
        if (uniqueRecords.length > 0) {
          collectList.value = [...collectList.value, ...uniqueRecords];
        }
        if (res.length < collectSize) {
          collectStatus.value = 'nomore';
        }
        // 无论是否有去重,当前页已消费,推进页码,避免下一次重复拉取相同页
        collectPage.value++;
      } else {
        collectStatus.value = 'nomore';
      }
    } else {
      // 获取点赞列表
      likeList.value = [];
      // 点赞分页
      if (isRefresh) {
        likePage.value = 1;
        likeList.value = [];
        likeStatus.value = 'loadmore';
      }
      if (likeStatus.value === 'nomore') return;
      const res = await getFilmLikeList({
        userId: userStore.userInfo?.customerDTO?.id
        userId: userStore.userInfo?.customerDTO?.id,
        current: likePage.value,
        size: likeSize
      });
      likeList.value = res || [];
      if (res && res.length > 0) {
        // 去重
        const existingIds = new Set(likeList.value.map(item => item.id));
        const uniqueRecords = res.filter(item => !existingIds.has(item.id));
        if (uniqueRecords.length > 0) {
          likeList.value = [...likeList.value, ...uniqueRecords];
        }
        if (res.length < likeSize) {
          likeStatus.value = 'nomore';
        }
        // 同理,推进页码,避免重复拉取相同页
        likePage.value++;
      } else {
        likeStatus.value = 'nomore';
      }
    }
  } catch (error) {
    console.error('获取列表失败:', error);
@@ -279,6 +359,26 @@
    icon: 'none'
  });
}
defineExpose({
  onShareAppMessage() {
    return {
      title: '影视地标推荐',
      path: '/pages/home/home',
      imageUrl: '', // 可以设置默认分享图片
      desc: '发现全球影视拍摄地,探索电影背后的故事'
    }
  },
  // 分享到朋友圈
  onShareTimeline() {
    return {
      title: '影视地标推荐',
      query: '',
      imageUrl: '', // 可以设置默认分享图片
      desc: '发现全球影视拍摄地,探索电影背后的故事'
    }
  }
})
</script>