cloudroam
2025-08-12 8dd9360a0e4cfd22ea9e261bec3821eff3f57fe8
add:分享功能
已修改9个文件
502 ■■■■ 文件已修改
pages.json 48 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pages/home/home.vue 28 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pages/login/login.vue 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
sub-pages/community/index.vue 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
sub-pages/film-list/film-detail.vue 108 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
sub-pages/film-list/film-list.vue 58 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
sub-pages/hot-city/index.vue 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
sub-pages/hot-spot/index.vue 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
sub-pages/mine/index.vue 174 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pages.json
@@ -15,13 +15,17 @@
            "style": {
                "navigationBarTitleText": "影游四方",
                "enablePullDownRefresh": true,
                "onReachBottomDistance": 50
                "onReachBottomDistance": 50,
                "enableShareTimeline": true,
                "enableShareAppMessage": true
            }
        },
        {
            "path": "pages/login/login",
            "style": {
                "navigationBarTitleText": ""
                "navigationBarTitleText": "",
                "enableShareTimeline": true,
                "enableShareAppMessage": true
            }
        }
    ],
@@ -45,7 +49,9 @@
                    "path": "film-list",
                    "style": {
                        "navigationBarTitleText": "",
                        "enablePullDownRefresh": true
                        "enablePullDownRefresh": true,
                        "enableShareTimeline": true,
                        "enableShareAppMessage": true
                    }
                }
@@ -62,7 +68,9 @@
                    "path": "film-official-detail",
                    "style": {
                        "navigationBarTitleText": "",
                        "enablePullDownRefresh": true
                        "enablePullDownRefresh": true,
                        "enableShareTimeline": true,
                        "enableShareAppMessage": true
                        
                    }
                }
@@ -75,14 +83,18 @@
                    "path": "index",
                    "style": {
                        "navigationBarTitleText": "草原",
                        "enablePullDownRefresh": true
                        "enablePullDownRefresh": true,
                        "enableShareTimeline": true,
                        "enableShareAppMessage": true
                    }
                }
                ,{
                    "path": "search-page",
                    "style": {
                        "navigationBarTitleText": "搜索",
                        "enablePullDownRefresh": true
                        "enablePullDownRefresh": true,
                        "enableShareTimeline": true,
                        "enableShareAppMessage": true
                    }
                }
            ]
@@ -94,14 +106,18 @@
                    "path": "index",
                    "style": {
                        "navigationBarTitleText": "城市",
                        "enablePullDownRefresh": true
                        "enablePullDownRefresh": true,
                        "enableShareTimeline": true,
                        "enableShareAppMessage": true
                    }
                }
                ,{
                    "path": "hot-city-detail",
                    "style": {
                        "navigationBarTitleText": "城市详情",
                        "enablePullDownRefresh": true
                        "enablePullDownRefresh": true,
                        "enableShareTimeline": true,
                        "enableShareAppMessage": true
                    }
                }
            ]
@@ -113,21 +129,27 @@
                    "path": "index",
                    "style": {
                        "navigationBarTitleText": "我的",
                        "enablePullDownRefresh": true
                        "enablePullDownRefresh": true,
                        "enableShareTimeline": true,
                        "enableShareAppMessage": true
                    }
                }
                ,{
                    "path": "settings",
                    "style": {
                        "navigationBarTitleText": "设置",
                        "enablePullDownRefresh": true
                        "enablePullDownRefresh": true,
                        "enableShareTimeline": true,
                        "enableShareAppMessage": true
                    }
                }
                ,{
                    "path": "profile-edit",
                    "style": {
                        "navigationBarTitleText": "编辑资料",
                        "enablePullDownRefresh": true
                        "enablePullDownRefresh": true,
                        "enableShareTimeline": true,
                        "enableShareAppMessage": true
                    }
                }
            ]
@@ -151,7 +173,9 @@
                    "path": "index",
                    "style": {
                        "navigationBarTitleText": "场景博物馆",
                        "enablePullDownRefresh": true
                        "enablePullDownRefresh": true,
                        "enableShareTimeline": true,
                        "enableShareAppMessage": true
                    }
                }
                ,{
pages/home/home.vue
@@ -32,7 +32,7 @@
        </swiper>
      </view>
      <SectionTitle title="全球影视地标" optitle="查看全部" goUrl="/pages/home/home-more" />
      <SectionTitle title="全球影视地标" optitle="查看全部" goUrl="/sub-pages/hot-city/index" />
<!--      <GlobalGeo />-->
      <view class="continent-section">
        <view class="continent-item all" @click="navigateToAll">全部</view>
@@ -139,9 +139,7 @@
}
const navigateToNearby = () => {
  //附近功能跳转
  uni.navigateTo({
    url: '/pages/nearby/nearby'
  })
  $message.showToast('附近功能未开放!');
}
@@ -308,6 +306,28 @@
const onSwiperChange = (e: SwiperChangeEvent) => {
  currentPage.value = e.detail.current
}
// 小程序分享配置
defineExpose({
  onShareAppMessage() {
    return {
      title: '影视地标推荐',
      path: '/pages/home/home',
      imageUrl: '', // 可以设置默认分享图片
      desc: '发现全球影视拍摄地,探索电影背后的故事'
    }
  },
  // 分享到朋友圈
  onShareTimeline() {
    return {
      title: '影视地标推荐',
      query: '',
      imageUrl: '', // 可以设置默认分享图片
      desc: '发现全球影视拍摄地,探索电影背后的故事'
    }
  }
})
</script>
<style scoped>
pages/login/login.vue
@@ -310,6 +310,26 @@
        url: `/sub-pages/protocol/protocol?title=${encodeURIComponent(title)}`
    });
};
defineExpose({
  onShareAppMessage() {
    return {
      title: '影视地标推荐',
      path: '/pages/home/home',
      imageUrl: '', // 可以设置默认分享图片
      desc: '发现全球影视拍摄地,探索电影背后的故事'
    }
  },
  // 分享到朋友圈
  onShareTimeline() {
    return {
      title: '影视地标推荐',
      query: '',
      imageUrl: '', // 可以设置默认分享图片
      desc: '发现全球影视拍摄地,探索电影背后的故事'
    }
  }
})
</script>
<style lang="scss" scoped>
sub-pages/community/index.vue
@@ -156,6 +156,26 @@
  }
}
defineExpose({
  onShareAppMessage() {
    return {
      title: '影视地标推荐',
      path: '/pages/home/home',
      imageUrl: '', // 可以设置默认分享图片
      desc: '发现全球影视拍摄地,探索电影背后的故事'
    }
  },
  // 分享到朋友圈
  onShareTimeline() {
    return {
      title: '影视地标推荐',
      query: '',
      imageUrl: '', // 可以设置默认分享图片
      desc: '发现全球影视拍摄地,探索电影背后的故事'
    }
  }
})
</script>
<style lang="scss" scoped>
.header {
sub-pages/film-list/film-detail.vue
@@ -140,6 +140,8 @@
import { onLoad } from '@dcloudio/uni-app'
import { useGlobal } from '@/composables/useGlobal'
const { $http, $message, $store } = useGlobal()
// 在 film-detail.vue 的 script setup 部分添加
import { useUserStore } from '@/store/user'
import { FilmInfo, FilmPicture, CommentDTO } from '@/types/index'
import { formatRelativeTime } from '@/utils/time'
@@ -256,7 +258,22 @@
}
// film-detail.vue
const showCommentLayer = (parentId?: number | string) => {
// const showCommentLayer = (parentId?: number | string) => {
//   console.log('点击了评论按钮',parentId)
//   if (typeof parentId === 'object') {
//     parentId = ''
//   }
//   commentShow.value = true
//   // 如果有parentId,说明是回复评论,需要设置parentId
//   // 如果没有parentId,说明是直接评论,不需要设置parentId
//   commentParendId.value = parentId ? String(parentId) : ''
// }
// 修改 showCommentLayer 函数
const showCommentLayer = async (parentId?: number | string) => {
  // 检查是否登录
  const isLoggedIn = await checkLogin()
  if (!isLoggedIn) return
  console.log('点击了评论按钮',parentId)
  if (typeof parentId === 'object') {
    parentId = ''
@@ -367,7 +384,62 @@
    }
}
// const toggleLike = async () => {
//   console.log("toggleLike",filmInfo.value)
//   if (!filmInfo.value) return
//
//   const api = liked.value ? '/v2/film-likes/filmLikes/edit' : '/v2/film-likes/filmLikes/edit'
//
//   try {
//     const res = await $http.request('post', api, {
//       data: { filmId: filmInfo.value.id }
//     })
//
//     if (res.code === 0) {
//       // 更新本地状态
//       liked.value = !liked.value
//       filmInfo.value.voLikeCount += liked.value ? 1 : -1
//
//       // 提示信息
//       $message.showToast(liked.value ? '点赞成功' : '取消点赞')
//     }
//   } catch (error) {
//     console.error('点赞失败:', error)
//     $message.showToast('操作失败')
//   }
// }
//
// const toggleFavorite = async () => {
//   console.log("toggleFavorite",filmInfo.value)
//   if (!filmInfo.value) return
//
//   const api = collected.value ? '/v2/film-collects/filmCollects/edit' : '/v2/film-collects/filmCollects/edit'
//
//   try {
//     const res = await $http.request('post', api, {
//       data: { filmId: filmInfo.value.id }
//     })
//
//     if (res.code === 0) {
//       // 更新本地状态
//       collected.value = !collected.value
//       filmInfo.value.voCollectCount += collected.value ? 1 : -1
//
//       // 提示信息
//       $message.showToast(collected.value ? '收藏成功' : '取消收藏')
//     }
//   } catch (error) {
//     console.error('收藏失败:', error)
//     $message.showToast('操作失败')
//   }
// }
// 修改 toggleLike 函数
const toggleLike = async () => {
  // 检查是否登录
  const isLoggedIn = await checkLogin()
  if (!isLoggedIn) return
  console.log("toggleLike",filmInfo.value)
  if (!filmInfo.value) return
@@ -392,7 +464,12 @@
  }
}
// 修改 toggleFavorite 函数
const toggleFavorite = async () => {
  // 检查是否登录
  const isLoggedIn = await checkLogin()
  if (!isLoggedIn) return
  console.log("toggleFavorite",filmInfo.value)
  if (!filmInfo.value) return
@@ -417,6 +494,35 @@
  }
}
const checkLogin = async () => {
  const userStore = useUserStore()
  try {
    await userStore.getCurrentInfo()
    if (userStore.hasLogin) {
      return true
    } else {
      showLoginModal()
      return false
    }
  } catch (err) {
    console.error('验证登录状态失败:', err)
    showLoginModal()
    return false
  }
}
const showLoginModal = () => {
  uni.showModal({
    title: '登录提示',
    content: '该操作需要登录,是否前往登录?',
    confirmText: '去登录',
    success: (res) => {
      if(res.confirm) uni.navigateTo({ url: '/pages/login/login' })
    }
  })
}
// 小程序分享配置
defineExpose({
  onShareAppMessage() {
sub-pages/film-list/film-list.vue
@@ -64,23 +64,29 @@
  getfilms()                     // 重新加载数据
}
// const handleDetailClick = async (item: FilmCategoryTree) => {
//   const userStore = useUserStore()
//   // 尝试获取最新用户信息验证登录状态
//   try {
//     await userStore.getCurrentInfo()
//     if (userStore.hasLogin) {
//       navigateTo(`/sub-pages/film-list/film-detail?id=${item.id}`)
//     } else {
//       showLoginModal()
//     }
//   } catch (err) {
//     console.error('验证登录状态失败:', err)
//     showLoginModal()
//   }
//     // const urlOfficicl=`/sub-pages/film-list/film-official-detail?id=${item.id}`;
//     // const url= `/sub-pages/film-list/film-detail?id=${item.id}`
//     // navigateTo(url)
// }
const handleDetailClick = async (item: FilmCategoryTree) => {
  const userStore = useUserStore()
  // 尝试获取最新用户信息验证登录状态
  try {
    await userStore.getCurrentInfo()
    if (userStore.hasLogin) {
      navigateTo(`/sub-pages/film-list/film-detail?id=${item.id}`)
    } else {
      showLoginModal()
    }
  } catch (err) {
    console.error('验证登录状态失败:', err)
    showLoginModal()
  }
    // const urlOfficicl=`/sub-pages/film-list/film-official-detail?id=${item.id}`;
    // const url= `/sub-pages/film-list/film-detail?id=${item.id}`
    // navigateTo(url)
  // 直接跳转到详情页,无需登录检查
  const url= `/sub-pages/film-list/film-detail?id=${item.id}`
  navigateTo(url)
}
const showLoginModal = () => {
@@ -165,7 +171,25 @@
    filmStatus.value = 'noMore'
  }
}
defineExpose({
  onShareAppMessage() {
    return {
      title: '影视地标推荐',
      path: '/pages/home/home',
      imageUrl: '', // 可以设置默认分享图片
      desc: '发现全球影视拍摄地,探索电影背后的故事'
    }
  },
  // 分享到朋友圈
  onShareTimeline() {
    return {
      title: '影视地标推荐',
      query: '',
      imageUrl: '', // 可以设置默认分享图片
      desc: '发现全球影视拍摄地,探索电影背后的故事'
    }
  }
})
sub-pages/hot-city/index.vue
@@ -16,7 +16,7 @@
    </view>
    <!-- 标签切换部分 -->
    <up-tabs :list="tabList" @click="click">
    <up-tabs   :key="currentTab" :list="tabList" @click="click"  :current="currentTabIndex">
      <template #right>
        <view style="padding-left: 4px;" @tap="() => showToast('插槽被点击')">
          <up-icon name="list" size="40rpx" bold></up-icon>
@@ -158,7 +158,9 @@
  }
  return cities
})
const currentTabIndex = computed(() => {
  return tabList.value.findIndex(tab => tab.value === currentTab.value)
})
// 标签点击事件
// const click = (item: { name: string; value: string }) => {
//   currentTab.value = item.value
@@ -315,6 +317,26 @@
    $message.showToast("获取洲数据失败")
  }
}
defineExpose({
  onShareAppMessage() {
    return {
      title: '影视地标推荐',
      path: '/pages/home/home',
      imageUrl: '', // 可以设置默认分享图片
      desc: '发现全球影视拍摄地,探索电影背后的故事'
    }
  },
  // 分享到朋友圈
  onShareTimeline() {
    return {
      title: '影视地标推荐',
      query: '',
      imageUrl: '', // 可以设置默认分享图片
      desc: '发现全球影视拍摄地,探索电影背后的故事'
    }
  }
})
</script>
<style scoped>
sub-pages/hot-spot/index.vue
@@ -95,6 +95,26 @@
    $message.error('加载失败,请重试')
  }
}
defineExpose({
  onShareAppMessage() {
    return {
      title: '影视地标推荐',
      path: '/pages/home/home',
      imageUrl: '', // 可以设置默认分享图片
      desc: '发现全球影视拍摄地,探索电影背后的故事'
    }
  },
  // 分享到朋友圈
  onShareTimeline() {
    return {
      title: '影视地标推荐',
      query: '',
      imageUrl: '', // 可以设置默认分享图片
      desc: '发现全球影视拍摄地,探索电影背后的故事'
    }
  }
})
</script>
<style lang="scss" scoped></style>
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>