index.vue 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. <script lang="ts" setup>
  2. import { computed, ref } from 'vue'
  3. import ShortLinkModal from '@/components/ShortLinkModal.vue'
  4. import { useScroll } from '@/hooks/useScroll'
  5. import { useShare } from '@/hooks/useShare'
  6. import { safeAreaInsets } from '@/utils'
  7. import { getCouponByType, getCouponDetail } from '../../api/home'
  8. import SpendAndSaveCoupon from '../../components/SpendAndSaveCoupon_large.vue'
  9. definePage({
  10. style: {
  11. navigationBarTitleText: '',
  12. navigationStyle: 'custom',
  13. // 禁用默认下拉刷新
  14. enablePullDownRefresh: false,
  15. },
  16. })
  17. const params = ref()
  18. // 使用内置的useScroll hooks
  19. const {
  20. list: data, // 响应式的数据列表
  21. loading, // 是否加载中
  22. finished, // 是否已全部加载
  23. error, // 是否加载失败
  24. refresh: onRefresh, // 下拉刷新方法
  25. loadMore: onLoadMore, // 加载更多方法
  26. } = useScroll({
  27. fetchData: async (page, pageSize) => {
  28. const response = await getCouponByType({
  29. pageNo: page,
  30. pageSize,
  31. ...params.value,
  32. })
  33. return response.records || []
  34. },
  35. pageSize: 7,
  36. })
  37. // 计算底部安全区高度
  38. const safeBottomHeight = computed(() => {
  39. return safeAreaInsets?.bottom || 0
  40. })
  41. const topSafeAreaHeight = safeAreaInsets?.top || 0
  42. const couponShareLink = ref('')
  43. const showShareModal = ref(false)
  44. const shareHooks = ref()
  45. // 页面加载时获取数据
  46. onLoad((options) => {
  47. if (options.type) {
  48. params.value = options
  49. onRefresh()
  50. }
  51. })
  52. function handleShareClick(shareLink, hooks) {
  53. couponShareLink.value = shareLink
  54. showShareModal.value = true
  55. shareHooks.value = hooks
  56. }
  57. </script>
  58. <template>
  59. <view class="page-container">
  60. <view class="safe-top" :style="{ height: `${topSafeAreaHeight}px` }" />
  61. <up-navbar title="满减券" :auto-back="true" />
  62. <!-- <up-status-bar /> -->
  63. <scroll-view id="spendAndSaveCouponScrollView" :style="{ paddingTop: `${topSafeAreaHeight}px` }"
  64. class="discount-coupon-list" scroll-y refresher-enabled :refresher-triggered="loading"
  65. @refresherrefresh="onRefresh" @scrolltolower="onLoadMore">
  66. <view class="list-content">
  67. <view v-for="item in data" :key="item.templateId" class="discount-coupon-item">
  68. <SpendAndSaveCoupon :coupon="item" scroll-view-id="spendAndSaveCouponScrollView"
  69. :enable-custom-share="true" @share-click="handleShareClick" />
  70. </view>
  71. <!-- 加载状态提示 -->
  72. <view v-if="loading && data.length > 0" class="loadmore-container">
  73. <up-loadmore status="loading" loading-text="努力加载中..." icon-size="18" />
  74. </view>
  75. <view v-else-if="finished && data.length > 0" class="loadmore-container">
  76. <up-loadmore status="nomore" nomore-text="我们是有底线的" icon-size="18" />
  77. </view>
  78. </view>
  79. </scroll-view>
  80. <ShortLinkModal v-model:show-modal="showShareModal" :share-link="couponShareLink" :share-hooks="shareHooks" />
  81. <!-- 安全区底部占位 -->
  82. <view class="safe-bottom" :style="{ height: `${safeBottomHeight}px` }" />
  83. </view>
  84. </template>
  85. <style lang="scss" scoped>
  86. .page-container {
  87. height: 100vh;
  88. display: flex;
  89. flex-direction: column;
  90. }
  91. .discount-coupon-list {
  92. flex: 1;
  93. overflow-y: auto;
  94. .list-content {
  95. padding-top: 20rpx;
  96. padding-left: 24rpx;
  97. padding-right: 24rpx;
  98. display: flex;
  99. flex-direction: column;
  100. gap: 20rpx;
  101. }
  102. .loadmore-container {
  103. padding: 30rpx 0;
  104. text-align: center;
  105. }
  106. }
  107. .safe-bottom {
  108. width: 100%;
  109. background-color: #fff;
  110. }
  111. </style>