index.vue 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191
  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: '上拉加载更多',
  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.error === 0) {
  101. if (page >= 2) {
  102. let couponList = _.concat(state.pagination.data, res.data.data);
  103. state.pagination = {
  104. ...res.data,
  105. data: couponList,
  106. };
  107. } else {
  108. state.pagination = res.data;
  109. }
  110. mountMasonry();
  111. if (state.pagination.current_page < state.pagination.last_page) {
  112. state.loadStatus = 'more';
  113. } else {
  114. state.loadStatus = 'noMore';
  115. }
  116. }
  117. }
  118. async function getActivity(id) {
  119. const { error, data } = await sheep.$api.activity.activity(id);
  120. if (error === 0) {
  121. state.activityInfo = data;
  122. }
  123. }
  124. // 加载更多
  125. function loadmore() {
  126. if (state.loadStatus !== 'noMore') {
  127. getList(state.activityId, state.pagination.current_page + 1);
  128. }
  129. }
  130. // 上拉加载更多
  131. onReachBottom(() => {
  132. loadmore();
  133. });
  134. onLoad((options) => {
  135. state.activityId = options.activityId;
  136. getList(state.activityId);
  137. getActivity(state.activityId);
  138. });
  139. </script>
  140. <style lang="scss" scoped>
  141. .goods-list-box {
  142. width: 50%;
  143. box-sizing: border-box;
  144. .left-list {
  145. margin-right: 10rpx;
  146. margin-bottom: 20rpx;
  147. }
  148. .right-list {
  149. margin-left: 10rpx;
  150. margin-bottom: 20rpx;
  151. }
  152. }
  153. .tip-box {
  154. background: #fff0e7;
  155. padding: 20rpx;
  156. width: 100%;
  157. position: relative;
  158. box-sizing: border-box;
  159. .activity-left-image {
  160. position: absolute;
  161. bottom: 0;
  162. left: 0;
  163. width: 58rpx;
  164. height: 36rpx;
  165. }
  166. .activity-right-image {
  167. position: absolute;
  168. top: 0;
  169. right: 0;
  170. width: 72rpx;
  171. height: 50rpx;
  172. }
  173. .type-text {
  174. font-size: 26rpx;
  175. font-weight: 500;
  176. color: #ff6000;
  177. line-height: 42rpx;
  178. }
  179. .tip-content {
  180. font-size: 26rpx;
  181. font-weight: 500;
  182. color: #ff6000;
  183. line-height: 42rpx;
  184. }
  185. }
  186. </style>