From 8dd9360a0e4cfd22ea9e261bec3821eff3f57fe8 Mon Sep 17 00:00:00 2001
From: cloudroam <cloudroam>
Date: 星期二, 12 八月 2025 10:10:07 +0800
Subject: [PATCH] add:分享功能

---
 sub-pages/mine/index.vue |  174 +++++++++++++++++++++++++++++++++++++++++++++------------
 1 files changed, 137 insertions(+), 37 deletions(-)

diff --git a/sub-pages/mine/index.vue b/sub-pages/mine/index.vue
index 436e163..2b980a3 100644
--- a/sub-pages/mine/index.vue
+++ b/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>
 
 

--
Gitblit v1.9.3