index.vue 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187
  1. <template>
  2. <s-layout class="activity-wrap" :title="state.activityInfo.title">
  3. <su-sticky bgColor="#fff">
  4. <view class="ss-flex ss-col-top tip-box">
  5. <view class="type-text ss-flex ss-row-center">{{ state.activityInfo.type_text }}:</view>
  6. <view class="ss-flex-1">
  7. <view class="tip-content" v-for="item in state.activityInfo.texts" :key="item">
  8. {{ item }}
  9. </view>
  10. </view>
  11. <image class="activity-left-image" src="/static/activity-left.png" />
  12. <image class="activity-right-image" src="/static/activity-right.png" />
  13. </view>
  14. </su-sticky>
  15. <view class="ss-flex ss-flex-wrap ss-p-x-20 ss-m-t-20 ss-col-top">
  16. <view class="goods-list-box">
  17. <view class="left-list" v-for="item in state.leftGoodsList" :key="item.id">
  18. <s-goods-column
  19. class="goods-md-box"
  20. size="md"
  21. :data="item"
  22. @click="sheep.$router.go('/pages/goods/index', { id: item.id })"
  23. @getHeight="mountMasonry($event, 'left')"
  24. >
  25. <template v-slot:cart>
  26. <button class="ss-reset-button cart-btn"> </button>
  27. </template>
  28. </s-goods-column>
  29. </view>
  30. </view>
  31. <view class="goods-list-box">
  32. <view class="right-list" v-for="item in state.rightGoodsList" :key="item.id">
  33. <s-goods-column
  34. class="goods-md-box"
  35. size="md"
  36. :data="item"
  37. @click="sheep.$router.go('/pages/goods/index', { id: item.id })"
  38. @getHeight="mountMasonry($event, 'right')"
  39. >
  40. <template v-slot:cart>
  41. <button class="ss-reset-button cart-btn"> </button>
  42. </template>
  43. </s-goods-column>
  44. </view>
  45. </view>
  46. </view>
  47. <uni-load-more
  48. v-if="state.pagination.total > 0"
  49. :status="state.loadStatus"
  50. :content-text="{
  51. contentdown: $t('activity.index.uploadMore'),
  52. }"
  53. @tap="loadmore"
  54. />
  55. </s-layout>
  56. </template>
  57. <script setup>
  58. import { reactive } from 'vue';
  59. import { onLoad, onReachBottom } from '@dcloudio/uni-app';
  60. import sheep from '@/sheep';
  61. import _ from 'lodash';
  62. const state = reactive({
  63. pagination: {
  64. data: [],
  65. current_page: 1,
  66. total: 1,
  67. last_page: 1,
  68. },
  69. loadStatus: '',
  70. leftGoodsList: [],
  71. rightGoodsList: [],
  72. activityId: 0,
  73. activityInfo: {},
  74. });
  75. // 加载瀑布流
  76. let count = 0;
  77. let leftHeight = 0;
  78. let rightHeight = 0;
  79. function mountMasonry(height = 0, where = 'left') {
  80. if (!state.pagination.data[count]) return;
  81. if (where === 'left') {
  82. leftHeight += height;
  83. } else {
  84. rightHeight += height;
  85. }
  86. if (leftHeight <= rightHeight) {
  87. state.leftGoodsList.push(state.pagination.data[count]);
  88. } else {
  89. state.rightGoodsList.push(state.pagination.data[count]);
  90. }
  91. count++;
  92. }
  93. async function getList(activityId, page = 1, list_rows = 6) {
  94. state.loadStatus = 'loading';
  95. const res = await sheep.$api.goods.activityList({
  96. list_rows,
  97. activity_id: activityId,
  98. page,
  99. });
  100. if (res.code === 1) {
  101. let couponList = _.concat(state.pagination.data, res.data.data);
  102. state.pagination = {
  103. ...res.data,
  104. data: couponList,
  105. };
  106. mountMasonry();
  107. if (state.pagination.current_page < state.pagination.last_page) {
  108. state.loadStatus = 'more';
  109. } else {
  110. state.loadStatus = 'noMore';
  111. }
  112. }
  113. }
  114. async function getActivity(id) {
  115. const { code, data } = await sheep.$api.activity.activity(id);
  116. if (code === 1) {
  117. state.activityInfo = data;
  118. }
  119. }
  120. // 加载更多
  121. function loadmore() {
  122. if (state.loadStatus !== 'noMore') {
  123. getList(state.activityId, state.pagination.current_page + 1);
  124. }
  125. }
  126. // 上拉加载更多
  127. onReachBottom(() => {
  128. loadmore();
  129. });
  130. onLoad((options) => {
  131. state.activityId = options.activityId;
  132. getList(state.activityId);
  133. getActivity(state.activityId);
  134. });
  135. </script>
  136. <style lang="scss" scoped>
  137. .goods-list-box {
  138. width: 50%;
  139. box-sizing: border-box;
  140. .left-list {
  141. margin-right: 10rpx;
  142. margin-bottom: 20rpx;
  143. }
  144. .right-list {
  145. margin-left: 10rpx;
  146. margin-bottom: 20rpx;
  147. }
  148. }
  149. .tip-box {
  150. background: #fff0e7;
  151. padding: 20rpx;
  152. width: 100%;
  153. position: relative;
  154. box-sizing: border-box;
  155. .activity-left-image {
  156. position: absolute;
  157. bottom: 0;
  158. left: 0;
  159. width: 58rpx;
  160. height: 36rpx;
  161. }
  162. .activity-right-image {
  163. position: absolute;
  164. top: 0;
  165. right: 0;
  166. width: 72rpx;
  167. height: 50rpx;
  168. }
  169. .type-text {
  170. font-size: 26rpx;
  171. font-weight: 500;
  172. color: #ff6000;
  173. line-height: 42rpx;
  174. }
  175. .tip-content {
  176. font-size: 26rpx;
  177. font-weight: 500;
  178. color: #ff6000;
  179. line-height: 42rpx;
  180. }
  181. }
  182. </style>